Предупреждение о типе данных при инициализации указателей - PullRequest
3 голосов
/ 16 декабря 2010

В настоящее время я пытаюсь обернуть голову вокруг указателей на C, исходя из внешнего интерфейса, развивая это не совсем легкое начинание.Я следую этому учебнику , и все идет гладко, пока я не попытаюсь скомпилировать следующий пример:

#include <stdio.h>

int main(int argc, char *argv[]) {
    int **ramon;
    int *paul;
    int melissa = 5;
    paul = &melissa;
    ramon = &paul;
    printf("ramon = %d\n", ramon); // <- warning: format '%d' expects type 'int'...
    printf("&paul = %d\n", &paul); // <- warning: format '%d' expects type 'int'...
    printf("*ramon = %d\n", *ramon); // <- warning: format '%d' expects type 'int'...
    printf("&melissa = %d\n", &melissa); <- warning: format '%d' expects type 'int'...
    printf("**ramon = %d\n", **ramon);p1); <- warning: format '%d' expects type 'int'...
    return(0);  
}

С первой строки printf я получаю эту ошибку:"% d" ожидает тип "int", но аргумент 2 имеет тип "int **" "

Я считаю, что это связано с тем, как я инициализирую свои указатели, но стоит на дне крутого обученияКривая Я не знаю, как прогрессировать.Что не так, как мне инициализировать указатели, чтобы избежать предупреждений?

Ответы [ 8 ]

4 голосов
/ 16 декабря 2010

Ваша инициализация указателя выглядит правильно. Проблема заключается в том, что вы пытаетесь напечатать переменную типа int** (то есть «указатель на указатель на int»), используя спецификатор формата %d, который предназначен для значений int.

Печать int значение

Если вы хотите напечатать значение melissa (т.е. 5), которое, по сути, косвенно указывает на ramon, вам необходимо отменить ссылку на значение указателя правильное число раз.

Разыменование указателей выполняется с помощью оператора *, и это по существу означает «значение, на которое указывает указатель».

  • Однажды отменив ссылку на него (т.е. *ramon), вы получите значение int*, на которое указывает ramon.
  • Повторная ссылка на него получит значение int, на которое указывает обратное значение int*.
  • Вы можете связать вместе операторы де-ссылки, чтобы получить то, что вы хотите:

    printf("ramon = %d\n", **ramon);

Значение указателя печати

Если вы хотите напечатать значение указателя (то есть ячейки памяти), вы можете использовать спецификатор формата %p. Это выведет адрес памяти в шестнадцатеричном виде:

printf("ramon = %p\n", ramon); // Print the "pointer to the pointer to melissa"
printf("ramon = %p\n", *ramon); // Print the "pointer to melissa"
1 голос
/ 16 декабря 2010

Вы объявили ramon типа "указатель на указатель на тип int". то есть он содержит адрес "указателя на тип int". %d с другой стороны - это спецификатор формата для int, поэтому вы получаете ошибки. Вместо этого попробуйте следующее:

printf("&paul = %p\n", ramon);     //print the address that ramon points to
printf("&melissa = %p\n", *ramon); //print the address that paul points to
printf("&melissa = %p\n", paul);   //same as above
printf("melissa = %d\n", **ramon); //print the contents of melissa
printf("melissa = %d\n", *paul);   //same as above
printf("melissa = %d\n", melissa); //same as above

выход

&paul = 0xbf8072f4
&melissa = 0xbf8072f0
&melissa = 0xbf8072f0
melissa = 5
melissa = 5
melissa = 5
1 голос
/ 16 декабря 2010

Предупреждение не имеет ничего общего с инициализацией указателей, оно связано с несоответствием типов между printf '%d определителем и типами, которые вы ему передаете.

Если вы хотите напечатать указатель, используйте %p.

1 голос
/ 16 декабря 2010

ramon и paul являются указателями, а спецификатор формата printf для печати значений самих указателей (не тех, на которые они указывают) равен %p.Попробуйте

printf("ramon = %p\n", ramon);
1 голос
/ 16 декабря 2010

Тип выражения ramon - int **, а спецификатор %d ожидает int. *ramon будет иметь тип int *, а **ramon будет желаемым int.

Если вы хотите напечатать сам указатель, используйте спецификатор %p.

1 голос
/ 16 декабря 2010

читать man printf. Не ясно, хотите ли вы напечатать значение, на которое указывает ramon или фактическое значение ramon, которое является адресом указателя на int То же самое и для других предупреждений.

1 голос
/ 16 декабря 2010

ramon - не int, это указатель на указатель на int.** Рамон будет Int.Вы пытаетесь напечатать кучу целых чисел с% d, но в основном вы пытаетесь напечатать указатели, которые используют формат% p.

0 голосов
/ 16 декабря 2010

Я считаю, что это связано с тем, как я инициализирую свои указатели

Почему вы считаете, что сообщение об ошибке ничего не говорит об инициализации? Прочитайте еще раз:

"warning: format '%d' expects type 'int', but argument 2 has type 'int **'"

У вас есть %d в строке формата для вашего вызова printf(), в качестве заполнителя для значения, которое вы хотите напечатать. %d используется в качестве заполнителя для значений, которые int s. Значение, которое вы хотите напечатать, ramon. Эта переменная имеет тип int**. Тип int и тип int** не совпадают.

Если вы хотите напечатать указатель, вы должны написать строку формата, чтобы ожидать указатель. Мы форматируем указатели с %p.

но стоя на дне крутой кривой обучения, я не знаю, как прогрессировать.

Путь к прогрессу - читать сообщения об ошибках и / или предупреждения и пытаться их понять. Сообщения об ошибках говорят о типах. Вам не следует пытаться что-либо делать с указателями, если вы сначала не поняли, что у значений есть тип (то есть, что это за вещи).

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