Программирование на C: объяснение того, почему указатель не дает ожидаемого значения - PullRequest
0 голосов
/ 27 июня 2018

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

#include <stdio.h>

int main() {
    int a;
    int *pA = &a;

    a = 9;

    *pA = 4;

    int *pA2 = &a;

    printf("pA = %p, *pA = %d, *pA2 = %d\n", *pA, *pA2);
}

В (виртуальной) реальности не должно ли ` pA2 выплевывать 4 ? Вместо этого он дает то, что выглядит как число, связанное с адресом памяти.

Спасибо

1 Ответ

0 голосов
/ 27 июня 2018

Вы оставили аргумент для printf(). Учтите следующее:

#include <stdio.h>

int main() {
   int a;
   int* pA= &a;

   a = 9;

   *pA = 4;

   int* pA2 = &a;

   printf("pA=%p, *pA=%d, *pA2=%d\n", (void*) pA, *pA, *pA2);
}

Выводит адрес памяти, 4 и 4 снова. Попробуйте онлайн.

Чтобы заменить каждый %, вы должны передать дополнительный аргумент printf(). Когда вы пропускаете аргумент, функция все равно попытается получить аргумент - это приводит к неопределенному поведению . В вашем случае ему удалось взять число (предположительно из стека). Это также может привести к аварийному завершению программы - поскольку поведение не определено, невозможно последовательно его предсказать.

Также обратите внимание, что у меня есть cast ваш указатель на void* для вывода - спецификатор формата %p требует этого. Другие указатели будут работать большую часть времени, но это не гарантируется. Подробнее о printf() здесь .

Чтобы помочь вам обнаружить подобные и другие проблемы в будущем, включите предупреждения компилятора. В начале это может показаться ошеломляющим, но они действительно полезны. См. Ваш код, скомпилированный с флагами компилятора, предложенными комментарием @ Davislor здесь .

Я добавил -Werror к ним. Это заставляет вас фактически иметь дело с предупреждениями, поскольку компилятор не будет генерировать исполняемый файл, пока ваш код генерирует предупреждения.

Я также добавил те же флаги к первой ссылке в моем ответе, чтобы вы могли видеть, что она не генерирует никаких предупреждений.

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