2013-05-12 3 views
5

Программа:Указатели и распределения памяти в C

int x; 
int *y; 
int **z; 

z = (int **) malloc (sizeof(int *)); 
y = (int *) malloc (sizeof(int)); 
x = 1; 
*z = &x; 
*y = x; 
. 
. 
. 

Вопрос: Какова разница между:

*z = &x; 
*y = x; 

Из того, что я понимаю, * Z указывает на адрес х и * у точек к x, но для * y указывать на x не требуется адрес x? Я не совсем понимаю, что происходит с этими двумя переменными.

Редактировать: Я также хочу знать, когда мы узнаем, когда переменная выделена в стеке или в куче?

  • Почему x, y и z выделены в стеке?
  • Почему * y, ** y, * z, ** z, выделенные на кучу?

И, наконец, меняется * z, изменение ** z?

+0

«Из того, что я понимаю ...» Вы неправильно поняли. z и y все еще указывают на любой блок памяти, на который они указывали, когда вы их выделили. –

+0

Вы не должны указывать возвращаемое значение 'malloc()' в C. Это поможет идентифицировать ошибку, когда у нее нет прототипа. – jxh

+1

Прежде всего вам нужно понять, что эти последние два утверждения совершенно разные. Первый присваивает * адрес * x любому z, на который указывает точка, а второй присваивает * значение * x для x, к которому указывает y. Если вы присвоите значение, оригинал и копия станут «отключенными», так что изменение одного не изменит другого. Но когда вы используете только адрес, то два соединяются на тазобедренном - меняют одно, а вы меняете другое. –

ответ

6

z - указатель на указатель (который обычно укажет на динамически выделенный массив указателей).

y является указателем на int. Опять же, чаще всего это указывает на динамически выделенный массив из int.

Таким образом, *z = &x; устанавливает указатель, который z ссылается на точку x. I.e., z указывает на указатель, который (в свою очередь) указывает на x.

*y = x; принимает значениеиз x и назначая его на int указывает y.

Для таких вещей часто бывает полезно изображение.Таким образом, наши основные определения дают нам это:

enter image description here

ЗЕ сделать:

z = (int **) malloc (sizeof(int *)); 
y = (int *) malloc (sizeof(int)); 

Что дает нам это:

enter image description here

Тогда мы делаем:

*z = &x; 
*y = x; 

Что дает нам это:

enter image description here

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

Затем мы можем рассмотреть долгосрочные различия между ними. Например, подумайте, что произойдет, если мы добавим x=2; после всех назначений выше.

В этом случае *y будет по-прежнему равна 1, потому что мы скопировали значение 1 из x в *y. **z будет равно 2, хотя это всего лишь указатель на x - любое изменение в x будет отражено в **z.

2

Эта строка хранит адрес переменной x в памяти, на которую указывает z:

*z = &x; 

Эта строка хранит значение из x в память, на которую указывает y:

*y = x; 

Два присваивания не связаны друг с другом: вторая делает копию, wh ile первого нет. Если вы измените значение x и затем получите **z, вы увидите новое значение x; однако получение *y вернет вам старое значение x (т. е. 1).

+0

Спасибо! Это имеет такой смысл! –

0

разность между двумя заданий является то, что первый (* г) назначение из типа адреса в качестве значения указателя, где второй (* у) является присвоение значения на адрес указывает на по y.

они оба присваивают значения памяти, на которую они направлены.

Разница - это тип значения, записанного в выделенную память. Первое значение - это адрес, и именно поэтому он получает адрес x как значение. второе значение является целым числом, и для него оно получает значение x.

* y не указывает на x.

указывает на неизвестную ячейку памяти, в которой скопировано значение x. - это присвоение значения x пространству памяти, выделенному для y.

Смежные вопросы