Ваше colspan="2"
для решения «Имя» <th>
будет работать, если вы добавите дополнительный столбец.
Для этого измените
<tr>
<th colspan="3"></th>
<th colspan="4">Total</th>
<th colspan="4">Total</th>
</tr>
на
<tr>
<th colspan="4"></th>
<th colspan="4">Total</th>
<th colspan="4">Total</th>
</tr>
Это действительно зависит от типа данных. Этого можно избежать, неявно приведя значения к типу, который содержит надмножество всех значений, доступных в типах со знаком и без знака. Например, вы можете использовать 64-битное значение со знаком для сравнения 32-битного беззнакового и 32-битного значений со знаком.
Однако это крайний случай, и вам нужно выполнять такие операции, как проверка размера ваших типов. Лучшее решение - использовать один и тот же тип для обоих операндов.
Если вам необходимо выполнить приведение, примите во внимание, что вы можете вызвать переполнение, и подумайте, важно ли это для вашего приложения.
Мы подавляем это предупреждение в наших компиляциях Visual Studio, так как это происходит часто и почти никогда не означает ничего значительного. Конечно, не все стандарты кодирования это допускают.
Вы можете согласовать типы (например, объявив переменные как size_t или unsigned int вместо int), или вы можете привести, или вы можете изменить свою строку компиляции. Вот и все.
Замените
int x;
/* ... */
for(x=0;x<sizeof(arr) / sizeof(int);x++)
на
for(size_t x=0;x<sizeof(arr) / sizeof(int);x++)
. Но это не решает общую проблему, когда мне приходится сравнивать подписанные значения со значениями без знака, используя эти параметры компилятора. Есть ли более чистый способ приведения типов?
В таких случаях попытайтесь выяснить, может ли число со знаком когда-либо иметь значение, которое вызовет переполнение. В противном случае вы можете проигнорировать предупреждение. В противном случае приведение к беззнаковому типу (если он того же размера или больше, чем подписанный компонент) достаточно.
test.c:11: error: comparison between signed and unsigned
Вы можете объявить x как unsigned int, поскольку size_t беззнаковый
EDIT:
Если вы не хотите преобразовывать и не хотите объявлять его как unsigned , я не думаю, что есть что делать.
Возможно, побитовые операции - способ решить эту проблему, удалив знаковый бит. Я должен сказать, ИМО, это очень сомнительно.
Суть в том, что сравнение значений со знаком и без знака допускает некоторые странные случаи. Рассмотрим, например, что происходит в беззнаковом массиве, длина которого превышает максимум, который может быть представлен знаком int. Переполнение счетчика со знаком (оставшееся «меньше» размера массива), и вы начинаете адресацию памяти, которую не собирались делать ...
Компилятор генерирует предупреждение, чтобы убедиться, что вы думаете о них. Использование -Werror
превращает это предупреждение в ошибку и останавливает компиляцию.
Либо будьте осторожны при выборе значимости ваших типов, либо устраните проблему, если вы уверены, что она не применима, или избавьтесь от -Werror
и сделайте своей политикой устранение всех предупреждений с исправлением или объяснением ...
Независимо от дилеммы об устаревании приведения, я все же предлагаю отделить логику от цикла for.
int range = (int)(sizeof(arr) / sizeof(int));
int x;
for(x = 0; x < range; x++)
{
printf("%d\n", arr[x]);
}
Хотя здесь используется приведение, которое, как вы сказали, устарело, оно очищает место, где идет кастинг. В общем, я не советую втискивать много логики в объявления цикла for. Особенно в вашем случае, когда вы используете деление size_t, которое (поскольку это целочисленное деление) может иметь возможность усечения ответа. Объявление цикла for должно быть чистым и не должно генерировать ошибок. Ваше приведение выполняется в другом месте, а это означает, что если вы хотите изменить способ создания диапазона, вам не нужно беспокоиться о том, чтобы сделать объявление for еще более длинным.
one option would be the additional flag "-Wno-sign-compare" :)