Сравнение объектов со знаком и без знака в C: есть ли операторы, которые не вызывают преобразования? - PullRequest
0 голосов
/ 23 ноября 2011

Из K & R C

A.6.5 Арифметические преобразования Многие операторы вызывают преобразования и выдают типы результатов аналогичным образом .Эффект состоит в том, чтобы привести операнды в общий тип, который также является типом результата.Этот шаблон называется обычными арифметическими преобразованиями.

В приведенном ниже коде EOF определено как -1, что является целочисленной константой со знаком, затем следует преобразовать ch в int, и, в конце концов, цикл должен быть завершен, но неКажется, не случилось!Отсюда Qn.

int main()
{
 unsigned char ch;
 FILE* fp;
 fp = fopen("myfile.txt","r");
 while((ch=getc(fp)) != EOF)
 {
  printf("%c", ch);
 }
 fclose(fp);
 return 0;
}

Ответы [ 4 ]

5 голосов
/ 23 ноября 2011

getc возвращает int (поскольку он должен содержать все значения символов, а также EOF).

В своем коде вы усекаете это значение до unsigned char, когда присваиваете ему ch. Затем вы расширяете его до int, что никогда не приведет к EOF, так как усеченное -1 станет 255, что станет int 255.

2 голосов
/ 23 ноября 2011

Если вы скомпилируете его с GCC с дополнительными предупреждениями, вы получите предупреждение:

 warning: comparison is always true due to limited range of data type

Это из-за вашего использования unsigned char. Используйте обычный char или int для определения c, и он будет работать.

1 голос
/ 23 ноября 2011

Вы объявили ch как unsigned char, оно должно быть объявлено как int. Тип возвращаемого значения getc() - int.

0 голосов
/ 23 ноября 2011

Арифметическое преобразование действительно происходит в приведенном вами примере - результат unsigned char для ch = getc(fp) повышается до int при сравнении с EOF 1 .

Это преобразование не отменяет результат преобразования -1 в unsigned char, хотя - если это преобразование приводит к 255 (потому что unsigned char равно 8 битам), тогда оно останется как 255, когда онопреобразуется обратно в int, поскольку 255 находится в диапазоне int.


1.На платформах, где int не может представлять все значения unsigned char, оно будет повышено до unsigned int, но такие платформы очень редки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...