指针本身的地址和指向的地址的区别?

假设有一个指针,char *a = (char*)malloc(sizeof(char)),此时a的值是它所指向的内存的地址,&a的值是存放a指针的地址。指针本质上始终是一个long int的数据,计算机内需要一个地址来存放这个long int的数据。

如果需要在一个函数内部修改指针指向的内存地址,那么参数应为change(char *&ch),*(&ch)传入指向某个内存块的指针的地址,即指向某个long int型数据的地址。一共涉及到3个地址,存储字符数据的地址addr,存放指向addr的指针的地址addrPtr(long int 型),以及存储addrPtr的地址。

要改变指针指向的地址addr,测试代码如下:

#include <stdio.h>
#include <stdlib.h>

void func(char *&ch) //*&ch代表存放指针变量的地址
{
	if(!(ch = (char*)malloc(sizeof(char)))) return;
	*ch = '5';
}

int main()
{
	char *a = (char*)malloc(sizeof(char));
	printf("a指针指向的内存地址为*&a = %p\n",*&a);
	func(a);
	printf("func:a = %c,a指针指向的内存地址为*&a = %p\n",*a,*&a);
	
	return 1;
} 

输出结果为:

a指针指向的内存地址为*&a = 00681620
func:a = 5,a指针指向的内存地址为*&a = 00681630

那么如果参数中不加&可以修改指针指向的内存块地址addr吗?分析一下,如果参数是change(char  *ch),那么传进去的是存放了char字符的地址,我们可以修改这个地址中的内容,但不能修改这个地址,即不能修改指针指向的内存地址。试一下:

#include <stdio.h>
#include <stdlib.h>

void func(char *ch) //*ch代表存储字符数据的地址
{
	if(!(ch = (char*)malloc(sizeof(char)))) {printf("不能修改ch的地址\n");return;}
	*ch = '5';
}

int main()
{
	char *a = (char*)malloc(sizeof(char));
	printf("a指针指向的内存地址为*&a = %p\n",*&a);
	func(a);
	printf("func:a = %c,a指针指向的内存地址为*&a = %p\n",*a,*&a);
	
	return 1;
} 

运行结果如下。从运行结果来看,非常有意思,函数中成功对ch赋值了,但是出了函数之后,ch指向的地址却没有变。函数中也成功对ch指向的地址存入了一个5(*ch = '5')。虽然传进函数的是一个char *ch指针,指针变量依旧是一个变量,这个变量在函数内被修改了,但出了函数,依旧是原来的值。

a指针指向的内存地址为*&a = 00C01620
func:a = ?,a指针指向的内存地址为*&a = 00C01620

再做一个测试,找出来func函数内存储的5究竟在哪儿?添加一个全局变量char *p,在func中另p = ch,然后在main中输出p指向的内存和p指向的内存中的值。

#include <stdio.h>
#include <stdlib.h>

char *p;

void func(char *ch)
{
	if(!(ch = (char*)malloc(sizeof(char)))) {printf("不能修改ch的地址\n");return;}
	p = ch;
	*ch = '5';
}

int main()
{
	char *a = (char*)malloc(sizeof(char));
	printf("a指针指向的内存地址为*&a = %p\n",*&a);
	func(a);
	printf("func:a = %c ,a指针指向的内存地址为*&a = %p\n",*a,*&a);
	printf("func中ch = %p,指向的char为:%c",p,*p);
	return 1;
} 

运行结果:

a指针指向的内存地址为*&a = 006B1620
func:a = ?,a指针指向的内存地址为*&a = 006B1620
func中ch = 006B1630,指向的char为:5

最后再看这句话:一共涉及到3个地址,存储数据的地址addr,指向addr的指针的地址addrPtr,以及存储addrPtr的地址。那么可以得出结论:如果只是在函数中修改指针指向的地址的值,传入addr就可以了。如果要在函数中修改某个指针指向的内存,相当于修改addrPtr的内容,那么需要传入的是addrPtr,即使用*&。

 

纰漏之处,敬请指出!

posted @ 2019-08-22 12:37  昨夜昙花  阅读(186)  评论(0)    收藏  举报