Причина вывода - PullRequest
       2

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

4 голосов
/ 07 октября 2010
#include<stdio.h>
int main(void)
{
 int a=5;
 printf("%d"+1,a);
}

Вывод: d.Я не понял, как идет вывод: d?

Ответы [ 6 ]

24 голосов
/ 07 октября 2010

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

a не используется, но это не должнобыть проблемой, поскольку в целом ( я не знаю, является ли это стандартным Edit: да, см. внизу) ответственность за очистку стека для функций с переменными значениями лежит на вызывающей стороне(по крайней мере, 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.
12 голосов
/ 07 октября 2010

Строковые литералы являются указателями.Перемещение указателя к "%d" на 1 приводит к "d".Аргумент отбрасывается.

2 голосов
/ 07 октября 2010

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

1 голос
/ 07 октября 2010

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

char x[] = "%d";

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

printf(x + 1, a);

для печати?

Подсказка: tc: 5: warning: слишком много аргументов дляформат

1 голос
/ 07 октября 2010

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

0 голосов
/ 07 октября 2010

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

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