指针本身的地址和指向的地址的区别?
假设有一个指针,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,即使用*&。
纰漏之处,敬请指出!