Да, printf
с "%c"
требует аргумента int
- более или менее.
Если аргумент имеет тип, более узкий, чем int
, то это будет продвинутый. В большинстве случаев поощрение составляет int
, с четко определенным поведением. В очень редком случае, что равнина char
является неподписанной и sizeof (int) == 1
(что подразумевает CHAR_BIT >= 16
), довод char
составляет unsigned int
, который может вызывать неопределенное поведение.
Постоянная символа уже имеет тип int
, поэтому printf("%c", 'x')
четко определен даже на экзотических системах. (Не по теме: В C++ символьные константы имеют тип char
.)
Это:
unsigned int foo = 42;
fprintf(fp, "%c\n", foo);
строго говоря имеет неопределенное поведение. N1570 7.1.4p1 говорит:
Если аргумент функции имеет тип ... (после продвижения) не ожидаемую функцию с переменным числом аргументов, поведение не определено.
и fprintf
Звонок явно работает от этого. (. Благодаря ouah за указание, что выход)
С другой стороны, 6.2.5p6 говорит:
Для каждого из подписанных целочисленных типов, существует соответствующее (но разные) целое число без знака типа (обозначается ключевым словом unsigned), который использует тот же объем хранения (включая информацию о знаке) и имеет те же требования к выравниванию.
и 6.2.5p9 говорит:
Диапазон неотрицательных значений знакового целого типа является поддиапазоном соответствующего типа целого числа без знака, и представление одинакового значения в каждом типе та же.
сноски:
То же требование представления и выравнивания имели в вид, взаимозаменяемости в качестве аргументов функции, возвращать значения из функций, а также члены профсоюзов.
Сноска говорит, что аргументы функции типов int
и unsigned int
являются взаимозаменяемыми, до тех пор, пока значение находится в пределах диапазона представимых обоих типов. (Для типичной 32-битной системы, это означает, что значение должно быть в диапазоне от 0 до 2 -1; int
значения от -2 -1, а unsigned int
значения от 2 до 2 -1, находятся за пределами диапазона другого типа, и не являются взаимозаменяемыми.)
Но сноски в стандарте C являются ненормативного. Они, как правило, предназначены для уточнения требований, изложенных в нормативном тексте, а не для введения новых требований. Но в этом нормативном тексте просто говорится, что соответствующие подписанные и неподписанные типы имеют одинаковое представление, которое не обязательно обязательно подразумевают, что они передаются так же, как аргументы функции. В принципе, компилятор может игнорировать эту сноску и, например, передавать int
и unsigned int
аргументы в разных регистрах, что делает fprintf(fp, "%c\n", foo);
неопределенным.
Но на практике нет никакой возможности для реализации игры такого рода, и вы можете положиться на fprintf(fp, "%c\n", foo);
для работы, как ожидалось. Я никогда не видел и не слышал о реализации, где это не сработало.
Лично я предпочитаю не полагаться на это. Если бы я писал этот код, я хотел бы добавить явное преобразование, с помощью актеров, просто так эти вопросы не возникают в первую очередь:
unsigned int foo = 42;
fprintf(fp, "%c\n", (int)foo);
Или я сделаю foo
в int
в первом место.
Ну, вы всегда можете написать 'fprintf (fp,"% c \ n ", 'B');'. –
Ах да, я забыл, что символьные константы имеют тип 'int' в C, не так ли? –