предупреждение: формат "% p" ожидает аргумент типа "void *", но аргумент 3 имеет тип "char **" - PullRequest
0 голосов
/ 07 сентября 2018

Я пытаюсь распечатать значение argv на этом этапе в моем коде, но когда я пытаюсь его скомпилировать, я получаю warning: format ‘%p’ expects argument of type ‘void *’, but argument 3 has type ‘char **. Я не уверен, что означает это предупреждение. %p не предназначено для argv, даже если это указатель?

int main(int argc, char* argv[])
{
    printf("%s%p", "argv = ", argv);
}

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Для того, чтобы напечатать argv и его адрес, нужно сделать

int main(int argc, char* argv[])
{
    int i;
    printf("address of argv = %p\n", (void *)argv);
    for (i = 0; i < argc; ++i)
    {
        printf("%s\n", argv[i]);
    }
    return 0;
}
0 голосов
/ 07 сентября 2018

Так почему бы вам не разыграть его?

printf("argv = %p\n", (void *)argv);`

Указан указатель %p (POSIX printf(); C11 §7.21.6.1 Функция fprintf ):

p - Аргумент должен быть указателем на void. Значение указателя преобразуется в последовательность печатных символов способом, определяемым реализацией.

Поскольку char ** не является void *, вам необходимо выполнить явное преобразование. Стандарт не разрешает компилятору выполнять для вас преобразование в void * - многоточие в объявлении printf() означает, что происходит продвижение аргументов по умолчанию, но это влияет только на тип float и целочисленные типы поменьше. чем int (short, char и т. д.).

На большинстве машин в наши дни это не работает. На (давно устаревшей) машине, где я научился программировать на C, еще не было void * (слишком стар для стандарта), но эквивалент был char *, а значение адреса char * для данное расположение в памяти отличалось от значения указателя для любого другого типа - приведение не было обязательным.

Обратите внимание, что я предполагаю, что вы намереваетесь напечатать значение адреса. Если вы намереваетесь распечатать содержимое, тогда еще многое предстоит сделать.

0 голосов
/ 07 сентября 2018

Ну, а не любой указатель (тип).

В соответствии с C11, глава §7.21.6.1, для спецификатора преобразования %p,

p

Аргумент должен быть указателем на void. Значение указателя преобразуется в последовательность печатных символов в определенной реализацией образом.

Таким образом, аргумент должен иметь тип void * (или char*, если они имеют одинаковые требования выравнивания). Любые другие типы указателей должны быть преобразованы с помощью явного приведения, поскольку для указателей не предусмотрено повышение аргументов по умолчанию.

что-то вроде

printf("%s%p", "argv = ", (void *)argv);

должен сделать.

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