Почему я не могу напечатать значение указателя, которое было инициализировано при объявлении указателя? - PullRequest
1 голос
/ 09 мая 2019

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

#include <stdio.h>

int main()
{
   int *i = (int *)1;

    printf("The value that i pointer points to is %d\n", *i);

    return 0;
}

Ответы [ 3 ]

5 голосов
/ 09 мая 2019

Кажется, вы думаете, (int *)1 создает адрес, где хранится значение 1.Это не так.

Когда приведение типа (int *) используется для преобразования целого числа в указатель, обычно получается, что значение превращается в адрес. 1

Таким образом, int *i = (int *)1; устанавливает i для указания адреса 1. Затем, при попытке вывести *i, ваша программа потерпела крах, потому что 1 не был действительным адресом памяти.(Как правило, первая страница памяти остается неотображенной, поэтому неправильное использование нулевого указателя приведет к сбою и выявит проблему, а не позволит программе продолжить выполнение с неверными данными.)

Для установки iчтобы указать int со значением 1, вы должны установить для него адрес int объекта со значением 1. Один из способов сделать это:

int n = 1;
int *i = &n;

Вы также можетесоздайте неназванный int со значением 1, используя составной литерал:

int *i = & (int) { 1 };

. (int) { 1 } создает составной литерал со значением 1, а & получает его адрес, а затем i инициализируется по этому адресу.

Сноска

1 В соответствии со стандартом C результат определяется реализацией.Таким образом, компилятор может определить любой результат, который он хочет.Однако каждый компилятор C, который я видел, так или иначе превращает целочисленное значение в адрес.Полученный адрес не обязательно допустим для использования для доступа к объекту.

5 голосов
/ 09 мая 2019

(int *) 1;это не указатель на значение 1. Это скорее указатель на ячейку памяти # 1. Что вы, вероятно, хотите, это

#include <stdio.h>

int main()
{
   int n=1;
   int *i = &n;

    printf("The value that i pointer points to is %d\n", *i);

    return 0;
}
3 голосов
/ 09 мая 2019
printf("The value that i pointer points to is %d\n", *i);

Вы пытаетесь разыменовать указатель i, но его значение (значение указателя) - это какое-то значение, которое вы устанавливаете сами. Можете ли вы гарантировать, что по адресу 0x0001 у вас есть целое число? Все, что вы можете сделать с таким указателем, это напечатать его значение указателя (а не значение, на которое он указывает):

printf("The value of pointer i is %p\n", i);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...