Почему -1>strlen(t) верно в C?
Работаем над этим небольшим фрагментом кода в VS2013, но по какой-то причине он не печатает. Кажется, что -1>strlen(str)
Кто-нибудь понял, что я делаю неправильно
char *str="abcd";
if(-1<strlen(str))
printf("The size of the string is %d", strlen(str));
return 0;
3 ответа
Кто-нибудь понял, что я делаю неправильно
strlen()
возвращает size_t
, который является целым типом без знака. -1
интерпретируется как целое число без знака - это большое значение, поэтому в итоге оно превышает длину вашей строки. Вы можете использовать -Wsign-compare
флаг в gcc
и некоторые другие компиляторы, чтобы предупредить вас, когда вы пытаетесь сравнить значения со знаком и без знака.
Кроме того, не имеет смысла сравнивать длину строки с -1
, Длина никогда не может быть отрицательной; это всегда будет 0
или больше Так что вы, вероятно, захотите переписать свой код для проверки 0
или иным образом правильно выполнить любое условие, которое вы пытаетесь проверить.
if(-1<strlen(str)) printf("The size of the string is %d", strlen(str));
В этом коде можно ожидать, что тест всегда будет успешным, а printf()
выполнить, так как длина всегда 0
или больше. Но вы обнаружите, что тест на самом деле не проходит и printf()
никогда не бывает, потому что -1
повышен до неподписанного, так что его можно сравнить с size_t
, Простое решение состоит в том, чтобы полностью удалить условие: вы знаете, что тест всегда будет успешным, поэтому в этом нет необходимости. Просто удалите if
*:
printf("The size of the string is %zu", strlen(str));
* Также измените спецификатор формата печати с %d
в %zu
поскольку, как указал Мэтт Макнабб в комментарии, вы пытаетесь напечатать size_t
,
strlen(str)
возвращает целое число без знака. При сравнении целого числа со знаком и целого числа без знака компилятор преобразует значение со знаком в unsigned. Когда преобразовано в без знака, -1
становится 2^32 - 1
(при условии, что strlen возвращает 32-битное целое число), что больше, чем длина строки, с которой вы сравниваете.
strlen
возвращает значение типа size_t
, Это беззнаковый целочисленный тип.
Правило C при сравнении значения со знаком со значением соответствующего типа без знака заключается в том, что значение со знаком преобразуется в значение без знака.
Если значения имеют разные размеры, например, если ваша система имеет 4 байта int
и 8 байт size_t
тогда правило состоит в том, что значение меньшего типа преобразуется в значение большего типа.
В любом случае это означает, что -1
преобразуется в size_t
, в результате чего SIZE_MAX
что является большой положительной ценностью. (беззнаковые типы не могут содержать отрицательные значения).
Это большое положительное значение больше длины вашей строки, поэтому сравнение меньше, чем возвращает false.