Очень простой вопрос C - PullRequest
       10

Очень простой вопрос C

1 голос
/ 16 февраля 2010

Может ли кто-нибудь проверить мое понимание и исправить меня, если я ошибаюсь?

int p = 5; //create an int holding 5
int *ptr; //create a pointer that can point to an int
*ptr = &p; // not sure - does this mean that my pointer now points to memory address   five, or that the memory address my pointer points at contains 5?

Извините за основной вопрос - скоро у меня есть assignmnet, который требует использования указателей, и я действительно хочу взломать основы до его установки.

Ответы [ 8 ]

5 голосов
/ 16 февраля 2010

Почти там - измените его на:

int p = 5; // create an int holding 5
int *ptr; // create a pointer that can point to an int
ptr = &p; // ptr now points at p
3 голосов
/ 16 февраля 2010

Ваша программа неверна. ptr не инициализирован. Присвоение *ptr скорее всего приведет к нарушению памяти. Вы не можете присвоить int* (который &p есть) int (который *ptr есть).

Правильно это:

ptr = &p;
1 голос
/ 16 февраля 2010

Указатель - это, в основном, адрес. Думайте о указателе как о метке адреса, а о качестве как о реальном доме. Вы можете использовать ярлык для поиска дома, но ярлык не дома.

int *ptr; // declares a pointer to an int

Таким образом, ptr - это адрес памяти. (Возможно, спецификация C на самом деле не указывает, что это адрес, но потерпите меня).

int i = 5; // create a local int.

Объявляет целое число в стеке и устанавливает его значение 5. Адрес i находится где-то в пространстве стека.

Давайте посмотрим на один промежуточный шаг, прежде чем мы продолжим. Это, вероятно, не скомпилируется, и если бы это было так, на самом деле ничего не сделал бы .

&i;

То, что делает это выражение, возвращает адрес переменной i. Это местоположение i в памяти - адрес целого числа.

И последний ...

*ptr;

Опять же, это, вероятно, на самом деле ничего не сделает, это просто выражение. Но он разыменовывает указатель - он ссылается на фактический int, расположенный по адресу, указанному в ptr.

Хорошо, давайте посмотрим на несколько вещей, которые мы можем сделать.

ptr = i;

Это ничего не делает, по крайней мере, то, что мы хотим сделать. Вероятно, не скомпилируется, но я не проверил это. Он ничего не делает, потому что назначает целое число на адрес целого числа. Это похоже на отправку ящика через почтовое отделение на адресную этикетку - вы на самом деле хотите, чтобы он пошел домой!

i = ptr;

Хорошо, это то же самое, что и последний, но наоборот. Следуя нашей аналогии, мы пытаемся превратить дом в этикетку!

*ptr = i;

Здесь мы разыменовали указатель и присвоили ему значение i. Разыменование указателя по существу похоже на использование метки для проезда к дому. Как только мы окажемся там, мы сможем что-то сделать с настоящим домом. Это работает, потому что разыменованный указатель на int является int, а int также является int.

ptr = &i;

Это тоже работает. И я в основном делаю новый ярлык для дома «я». Поскольку у нас есть указатель с обеих сторон, мы можем назначить один другому. Это в основном копирование метки адреса для i в метку адреса с именем ptr.

*ptr = &i;

Это не имеет смысла. Мы начали с двух разных вещей и превратили друг в друга! Сейчас мы пытаемся присвоить метку дому, тогда как раньше мы присваивали дом метке адреса.

1 голос
/ 16 февраля 2010

Ваш ptr теперь указывает на адрес памяти, в котором хранится 5.

Кроме того, я не верю, что код компилируется. Вы, вероятно, хотите:

int p = 5; //create an int holding 5
int *ptr; //create a pointer that can point to an int
ptr = &p; // not sure - does this mean that my pointer now points to memory address   five, or that the memory address my pointer points at contains 5?
0 голосов
/ 07 июля 2016

int a = 5;

объявите тип указателя, который вы храните

int * ptr;

назначить адрес переменной указателю

PTR = & а;

0 голосов
/ 16 февраля 2010

Я знаю, что это не дает прямого ответа на ваш непосредственный вопрос (что уже сделали другие), но я бы порекомендовал прочитать раздел по указателям из c-faq.

Много полезной информации.

0 голосов
/ 16 февраля 2010

Другие уже объяснили, как исправить ваш код. Для понимания позвольте мне рассказать вам, что делает ваша неправильная строка:

*ptr = &p;

*ptr разыменования указатель, т. Е. *ptr = ... назначает что-то в слот памяти, на который указывает ptr. Поскольку ptr не был инициализирован, он указывает на какое-то неизвестное место в памяти, и *ptr = ..., вероятно, потерпит неудачу с Segmentation Fault или чем-то подобным.

Поскольку ptr является указателем на int, правая часть *ptr = ... также ожидает int, но вы передаете ему адрес int (&p). ), что приводит к предупреждению компилятора.

0 голосов
/ 16 февраля 2010

Вы хотите

ptr = &p; // set ptr to point to the location holding p
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...