Почему -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.

Другие вопросы по тегам