Причина вывода

#include<stdio.h>
int main(void)
{
 int a=5;
 printf("%d"+1,a);
}

Выход: д. Я не понял, как получится: d?

Ответы на вопрос(6)

Решение Вопроса

printf "%d"+1; "%d" на самом деле рассматривается какconst char * это указывает на область памяти, где%d хранится. Как и в случае с любым указателем, если вы увеличите его на единицу, результат будет указывать на следующий элемент, который в данном случае будетd.

a не используется, но это не должно быть проблемой, так как в целом (Я не знаю, является ли это стандартным Редактировать: да, см. внизу) ответственность за очистку стека для функций с переменными значениями лежит на вызывающей стороне (по крайней мере,cdecl делает это такэто однако может или не может быть UB, я не знаю*).

Вы можете увидеть это проще так:

#include<stdio.h>
int main(void)
{
    int a=5;
    const char * str="%d";
    printf(str + 1, a);
}

 

str ---------+
             |
             V
          +----+----+----+
          |  % |  d | \0 |
          +----+----+----+

str + 1 ----------+
                  |
                  V
          +----+----+----+
          |  % |  d | \0 |
          +----+----+----+

Таким образом, ("%d"+1) (который"d") интерпретируется как строка формата, иprintf, не найдя ни одного%, просто распечатает как есть. Если вы хотите вместо этого напечатать значениеa плюс 1, ты должен был сделать

printf("%d", a+1);

Редактировать: * хорошо, это не UB, по крайней мере для стандарта C99 (§7.19.6.1.2) нормально иметь неиспользуемые параметры вfprintf:

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

а такжеprintf определено, чтобы иметь то же самое поведение в §7.19.6.3.2

Функция printf эквивалентна fprintf с аргументом stdout, вставленным перед аргументами printf.
 Daren Thomas07 окт. 2010 г., 11:58
+1 за хорошую диаграмму!
 Matteo Italia07 окт. 2010 г., 12:01
Спасибо :) (случайный текст для достижения 15 символов)
 Jim Balter11 авг. 2014 г., 08:11
«хотя бы для стандарта C99» - и остальные. Было бы ужасно, если бы стандарт требовал, чтобы функция varargs использовала все свои аргументы для определения поведения.
 Matteo Italia07 окт. 2010 г., 12:07
@ Роджер Пэйт: нашел, я отредактирую ответ.
 Matteo Italia13 авг. 2014 г., 08:20
@JimBalter: определенно прошло много времени с тех пор, как я написал этот ответ, но я полагаю, что написал это, потому что у меня не было стандарта C89 (что касается C11, его еще не было). Не стесняйтесь добавлять соответствующие цитаты из других версий стандарта.
 Roger Pate07 окт. 2010 г., 12:03
Передача неиспользуемого значения в printf не должна быть проблемой по стандарту. Реальная реализация, конечно, может изменяться, но я не видел ничего, кроме того, что вы описываете.

"%d" по 1 результату в"d", Аргумент отбрасывается.

printf("%d", a+1). "%d" + 1 это указатель на"d" внутри массиваchar ({'%','d','\0'}).

«% d» является строковой константой, она будет сохранена в char [] в памяти. []. Увеличение указателя массива символов на единицу будет указывать на следующий символ. Следовательно, только d передается в функцию printf. так что вывод «д»

+1, Если вы хотите увеличитьa делать:printf("%d", a + 1); вместо.

Предположим, у вас было:

char x[] = "%d";

Что вы ожидаете

printf(x + 1, a);

печатать?

Подсказка: t.c: 5: предупреждение: слишком много аргументов для формата

Ваш ответ на вопрос