Печать символа с помощью printf

Оба эти кода одинаковы

char ch = 'a';
printf("%d", ch);

Будет ли он печатать значение мусора?

я в замешательстве по этому поводу

printf("%d", '\0'); 

Будет ли это печатать 0 или значение мусора? Потому что когда я делаю это

printf("%d", sizeof('\n')); 

Он печатает 4. Почему sizeof('\n') 4 байта? То же самое в С++ печатает 1 байт. Это почему?

Так вот главный вопрос

на языке c printf("%d", '\0') должен печатать 0

а в C++ printf("%d", '\0') должен печатать фигню?


person Community    schedule 19.01.2011    source источник


Ответы (6)


%d печатает целое число: он печатает ASCII-представление вашего персонажа. Вам нужно %c:

printf("%c", ch);

printf("%d", '\0'); печатает ASCII-представление '\0', равное 0 (экранируя 0, вы указываете компилятору использовать ASCII-значение 0.

printf("%d", sizeof('\n')); печатает 4, потому что символьный литерал - это int в C, а не char.

person peoro    schedule 19.01.2011
comment
@nightcracker: хм? Если printf("%d", ch); печатает значение мусора, я думаю, это потому, что он хотел напечатать A вместо значения ascii... - person peoro; 19.01.2011
comment
Он никогда не говорил, что что-то печатает мусорное значение, он спрашивал, будет оно или нет. - person orlp; 19.01.2011
comment
@nightcracker: хм, какая разница? Я не понимаю вашу точку зрения. - person peoro; 19.01.2011
comment
Проще говоря, ваш ответ не является ответом на вопрос ОП. Ему просто были любопытны результаты %d печати символов, %c совершенно не связанного. - person orlp; 19.01.2011
comment
@nightcracker, я не нахожу это некоррелированным. ОП задавался вопросом, напечатает ли printf("%d", 'a'); мусор, не означает ли это, что он ожидал, что будет напечатано a вместо 96? Помимо объяснения того, что %d печатает значение ascii, сказано, что %c будет печатать символ. Я думаю, что этот ответ похож на Скоффи и Джона Боде, не так ли? Они не говорят, что %c используется для символов, но это просто дополнительный пункт этого ответа... - person peoro; 19.01.2011
comment
Я видел ваш ответ до того, как вы его отредактировали, он состоял только из одной строки, что ОП нужно %c. Пожалуйста, не пытайтесь обмануть меня или других посетителей, говоря, что это только часть вашего ответа. Либо откажитесь от своего ответа, либо перестаньте защищать его, если он ошибочен. - person orlp; 19.01.2011
comment
@nightcracker: он также содержал %d печатает целое число: он будет печатать представление вашего персонажа в формате ascii. Позже я расширил его, добавив пример с \0 и комментарий о том, почему sizeof(int) печатает 4, но семантика моего ответа не меняется (кроме добавления комментария о sizeof). - person peoro; 19.01.2011
comment
На самом деле это именно то, что я искал (нашел здесь поисковой системой). Даже если это не ответит на исходный вопрос ОП, это поможет другим. - person bobroxsox; 24.02.2017

Предполагается, что это напечатает значение символа ASCII, поскольку %d — это escape-последовательность для целого числа. Таким образом, значение, указанное в качестве аргумента printf, при печати принимается как целое число.

char ch = 'a';
printf("%d", ch);

То же самое относится и к printf("%d", '\0');, где символ NULL интерпретируется как целое число 0.

Наконец, sizeof('\n') равно 4, потому что в C это обозначение символов означает соответствующее целое число ASCII. Таким образом, «\n» — это то же самое, что и 10 как целое число.

Все зависит от интерпретации, которую вы даете байтам.

person scoffey    schedule 19.01.2011
comment
+1, поэтому printf(%d, ch) выведет (int) 97, а printf(%d, '\0') (int) 0 - person BlackBear; 19.01.2011
comment
Я бы сказал, что поскольку So '\n' - это int, 32 бита, 4 байта, а sizeof() возвращает 4. value '\n' равно 10, десятичное число. NEWLINE в формате ASCII. Исходное единственное предложение верно, но, возможно, слишком кратко. - person Bill IV; 09.04.2011

В C символьные постоянные выражения, такие как '\n' или 'a', имеют тип int (таким образом, sizeof '\n' == sizeof (int)), тогда как в C++ они имеют тип char.

Оператор printf("%d", '\0'); должен просто печатать 0; тип выражения '\0'int, а его значение — 0.

Оператор printf("%d", ch); должен вывести целочисленную кодировку значения в ch (для ASCII 'a' == 97).

person John Bode    schedule 19.01.2011

В C char повышается до int в выражениях. Это в значительной степени объясняет каждый вопрос, если подумать.

Источник: Язык программирования C Брайана В. Кернигана и Денниса М. Ричи.

Обязательна к прочтению, если вы хотите изучить C.

Также см. эту страницу переполнения стека , где люди, гораздо более опытные, чем я, могут объяснить это намного лучше, чем я.

person orlp    schedule 19.01.2011
comment
@BlackBear: Да, потому что (в большинстве систем) char — это один байт, а int — четыре, так что это продвижение. - person orlp; 19.01.2011
comment
Я буквально цитирую книгу, они используют слово продвижение. Это то же самое, что и int cast (я думаю). - person orlp; 19.01.2011
comment
Ставлю +1 за ссылку. Хотя слово «продвижение» меня все еще смущает, но я думаю, вам все понятно ;). - person ; 19.01.2011
comment
Термин продвижение также используется в стандарте языка C, раздел 6.3.1.1. - person John Bode; 19.01.2011
comment
Объяснение продвижения не очень точное. sizeof('a') равно 4, но sizeof(ch) равно 1, если ch равно char. В C выражение 'a' совпадает с (int) 97. Продвижения нет. Однако в C++ это выражение имеет тип char. - person scoffey; 19.01.2011

Да, он печатает МУСОРА, если вам не повезет.

ОЧЕНЬ ВАЖНО.

Тип аргумента printf/sprintf/fprintf ДОЛЖЕН соответствовать соответствующему типу формата char.

Если типы не совпадают и он компилируется, результаты очень неопределенные.

Многие новые компиляторы знают о printf и выдают предупреждения, если типы не совпадают. Если вы получаете эти предупреждения, ИСПРАВИТЕ их.

Если вы хотите преобразовать типы для аргументов переменных функций, вы должны предоставить приведение (т. е. явное преобразование), потому что компилятор не может понять, что преобразование необходимо выполнить (как это может быть с прототипом функции с типизированными аргументами). .

printf("%d\n", (int) ch)

В этом примере printf сообщается, что в стеке есть «int». Приведение гарантирует, что независимо от того, что возвращает sizeof (обычно какое-то длинное целое число), printf получит значение int.

printf("%d", (int) sizeof('\n'))
person davep    schedule 19.01.2011
comment
-1 Тут почти все не так. Предполагая, что прототип для printf виден, совершенно нормально передать char или короткое значение %d из-за интегральных преобразований, происходящих для функций с переменным числом аргументов. Кастинг в лучшем случае глуп. - person Jens; 17.05.2012

person    schedule
comment
Пожалуйста, ограничьте длину строк до 90 символов. Половина вашего текста скрыта. - person A.L; 01.03.2014
comment
@A.L Во всем виноваты эти сумасшедшие дисплеи с высоким разрешением 16:9! С удобным для программиста соотношением сторон 4:3 никто никогда не напишет такие сумасшедшие длинные строки ;) - person BitTickler; 17.02.2021