Почему эта программа выдает результат 'y'
#include <stdio.h>
int main(void) {
char ch='abcdefghijklmnopqrstuvwxy';
printf("%c",ch);
return 0;
}
Почему эта программа выдает результат 'y'
#include <stdio.h>
int main(void) {
char ch='abcdefghijklmnopqrstuvwxy';
printf("%c",ch);
return 0;
}
int
, но вы присваиваете ей char
, поэтому она должна быть усечена до одного символа. 10.07.2015 Это многосимвольный литерал.
Обычный символьный литерал, содержащий более одного c-char, является многосимвольным литералом. Многосимвольный литерал имеет тип int и значение, определяемое реализацией.
Также из 6.4.4.4/10 в спецификациях C11
Целочисленная символьная константа имеет тип int. Значение целочисленной символьной константы, содержащей один символ, который отображается на однобайтовый символ выполнения, является числовым значением представления отображаемого символа, интерпретируемого как целое число. Значение целочисленной символьной константы, содержащей более одного символа (например, 'ab') или содержащую символ или управляющую последовательность, которая не соответствует однобайтовому символу выполнения strong>, определяется реализацией. Если целочисленная символьная константа содержит одиночный символ или escape-последовательность, ее значение равно тому, которое получается, когда объект с типом char, значение которого является значением одиночного символа или escape-последовательности, преобразуется в тип int.
Таким образом, строка char ch = 'abcdefghijklmnopqrstuvwxy'
в вашей системе (предполагая 4 байта int), возможно, компилируется в:
char ch = 0x76777879; // SOME int value (may be different, but documented in the compiler documents)
ch
будет назначено 'abcdef...y'
что может быть эквивалентно (int)0x616263646566...79
в кодировке ascii и переполняет целое число. По этой причине gcc
выдает следующее предупреждение:
multicharlit.c: В функции 'main':
multicharlit.c:4:13: предупреждение: символьная константа слишком длинная для своего типа [включено по умолчанию]
multicharlit.c:4:5: предупреждение : переполнение при неявном преобразовании констант [-Woverflow]
В вашей системе младшие 8 бит используются для назначения ch
. Поскольку ваш символьный литерал является постоянным, это, скорее всего, происходит во время компиляции: (Например, следующее происходит, когда я компилирую с gcc
)
$ cat multicharlit.c
#include <stdio.h>
int main(void) {
char ch='abcdefghijklmnopqrstuvwxy';
printf("%c",ch);
return 0;
}
$ gcc -O2 -fdump-tree-optimized multicharlit.c
$ cat multicharlit.c.143t.optimized
;; Function main (main) (executed once)
main ()
{
<bb 2>:
__builtin_putchar (121);
return 0;
}
Также украл немного добра из комментария unwind
Помните, что символьная константа в одинарных кавычках имеет тип
int
, но вы присваиваете ейchar
, поэтому она должна быть усечена до одного символа.
Тип 'a'
, например, int
в C
. (Не путать с 'a'
в C++
, который является символом. С другой стороны, тип 'ab'
— это int
в оба C
и C++
.)
Теперь, когда вы назначаете этот тип int
типу char
, а значение больше, чем может быть представлено char
, тогда необходимо сделать некоторое сжатие, чтобы результат соответствовал менее широкому типу char
, а фактический результат определяется реализацией.
Если вы намеревались вывести abcdefghijklmnopqrstuvwxy, вы должны были сохранить его в строковой переменной, а не в символьной (char ch[50] = char abcdefghijklmnopqrstuvwxy;).
Строковые переменные могут содержать более одного символа, тогда как переменная char предназначена для хранения одного символа.