Up_CrossYourHeart Ответов: 2

Не в состоянии понять поведение указателя


int * z=NULL;
int checkaddress(int * a)
{
 int * b = (int *)malloc(sizeof(int));
 fprintf(stderr,"b:%p\n",b);
 fprintf(stderr,"a:%p\n",a);
 a = b;
 fprintf(stderr,"a:%p\n",a);
 fprintf(stderr,"z:%p\n",z);
}

int main()
{
 checkaddress(z);
 fprintf(stderr,"z:%p\n",z);
 return 1;
}


Что я уже пробовал:

Я новичок в языке Си. Я столкнулся с этим поведением, которое мне было трудно понять. Я передаю адрес z в качестве аргумента функции checkAddress. Таким образом, в идеале a должен содержать адрес z. Теперь, насколько я понимаю, если указатель b назначен a. Тогда z также должен содержать адрес b. Хотя это не тот случай. Должно быть, в моем понимании есть какой-то пробел. Может ли кто-нибудь объяснить мне это поведение?

2 Ответов

Рейтинг:
2

Patrice T

Читайте справочник.
https://hassanolity.files.wordpress.com/2013/11/the_c_programming_language_2.pdf[^]
http://www.ime.usp.br/~ПФ/Керниган-Ритчи/с-Программирование-электронные книги.формат PDF[^]

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

Отладчик позволяет вам следить за выполнением строка за строкой, проверять переменные, и вы увидите, что есть точка, в которой он перестает делать то, что вы ожидаете.
Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]


Рейтинг:
15

User 59241

В этой статье см. раздел указатели на указатели: Указатель на указатель и ссылка на указатель[^]
Вы передаете фактическое значение указателя z вашей функции (то есть содержащееся в нем адресное значение). Таким образом, имея это значение, функция может изменять все, на что указывает этот адрес, но не сам адрес. Чтобы изменить значение адреса, нам нужен указатель на него, то есть указатель на указатель ( в данном случае указатель на z). Этот пример иллюстрирует, что:

#include <stdio.h>      /* printf, scanf, NULL */
#include <stdlib.h>     /* malloc, free, rand */

int * z = NULL;

int checkaddress(int * a)
{
	int * b = (int *)malloc(sizeof(int));
	fprintf(stderr, "b:%p\n", b);
	fprintf(stderr, "a:%p\n", a);
	a = b;
	fprintf(stderr, "a:%p\n", a);
	fprintf(stderr, "z:%p\n", z); // z remains unaffected. Correct.
	free(b);
	return 0;
}

int checkaddress2(int ** A)
{
	int * B = (int *)malloc(sizeof(int));
	fprintf(stderr, "B:%p\n", B);
	fprintf(stderr, "*A:%p\n", *A); // get the value A points to
	*A = B; // Set what A points to to B
	fprintf(stderr, "*A:%p\n", *A);
	fprintf(stderr, "z:%p\n", z); // Now z is the value of B
	// free(B); // Important: allocated memory must be free'd at some point.
	return 0;
}

int main()
{

	fprintf(stderr, "z:%p Before\n", z);
	checkaddress(z);
	checkaddress2(&z);
	fprintf(stderr, "z:%p After\n", z);
	return 1;

}

</stdlib.h></stdio.h>


CPallini

5.