首先看代码1
#include<stdio.h>
void change(char* p)
{
p = "bbb";
}
int main()
{
char *v = "aaa";
printf("%s\n",v);
change(v);
printf("%s\n",v);
}
输出结果如下
aaa
aaa
可以看到主函数中的指针v指向的内存中的数据并没有发生变化
接下来看代码2
#include<stdio.h>
int change(int ar[])
{
ar[1] = 100000;
}
int main()
{
int marbles[3] = {0,1,2};
printf("%d\n",marbles[1]);
change(marbles);
printf("%d\n",marbles[1]);
}
结果如下
1
100000
可以看到主函数中数组的第二个元素发生了改变
--------------------------------------------------------------------------------------------------------------------------------
接下来查看各变量的地址
代码1
#include<stdio.h>
void change(char* p)
{
printf("p地址为%p\n",p);
p = "bbb";
}
int main()
{
char *v = "aaa";
printf("%s\n",v);
printf("v地址为%p\n",v);
change(v);
printf("%s\n",v);
}
aaa
v地址为000000000040400F
p地址为000000000040400F
aaa
代码2
#include<stdio.h>
int change(int ar[])
{
printf("ar地址为%p\n",ar);
ar[1] = 100000;
}
int main()
{
int marbles[3] = {0,1,2};
printf("%d\n",marbles[1]);
printf("marbels地址为%p\n",marbles);
change(marbles);
printf("%d\n",marbles[1]);
}
1
marbels地址为000000000062FE10
ar地址为000000000062FE10
100000
--------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
这个时候关键的问题已经凸显出来了,代码1中的指针p和指针v指向的是同一块地址,那为什么在
p = "bbb";
之后,指针v指向的内存中的数据却没有变化?
#include<stdio.h>
void charge(int a,int b)
{
int c = a;
a = b;
b = c;
printf("--------------------\n");
printf("charge()中\na=%d\nb=%d\n",a,b);
printf("a地址=%p\nb地址=%p\n",&a,&b);
printf("--------------------\n");
}
int main()
{
int a = 1;
int b = 2;
printf("a=%d\nb=%d\n",a,b);
printf("a地址=%p\nb地址=%p\n",&a,&b);
charge(a,b);
printf("a=%d\nb=%d\n",a,b);
}
a=1
b=2
a地址=000000000062FE1C
b地址=000000000062FE18
--------------------
charge()中
a=2
b=1
a地址=000000000062FDF0
b地址=000000000062FDF8
--------------------
a=1
b=2
此处变量地址都已经改变,所以很好理解。
那么对代码1的解释只有,char *v在被传到charge(char *p)中时,产生了“替身”!
参考博客(54条消息) 如何理解双重指针_Hist_花透的博客-优快云博客_双重指针
char *x就是那个“凭空出现的替身”!!!
解决办法就是使用双重指针,代码如下
#include<stdio.h>
void change(char **p)
{
printf("p地址为%p\n",p);
*p = "bbb";
}
int main()
{
char *v = "aaa";
printf("%s\n",v);
printf("v地址为%p\n",v);
change(&v);
printf("%s\n",v);
}
aaa
v地址为000000000040400F
p地址为000000000062FE18
bbb
至于为什么会产生替身,我也不知道......欢迎大家评论解答!
在《C Prime Plus》中第九章(9.7)中有这样一段话
“从根本上看,指针是一个值内存地址的变量”,
希望这句话能帮大家“悟道”!
---------------------------------------------------------------------------------------------------------------------------------
回头再看了一下程序发现下段代码是可以改变指针内容的
#include<stdio.h>
void change(int* p)
{
printf("p地址为%p\n",p);
*p = 20;
}
int main()
{
int a = 10;
int *v = &a;
printf("%d\n",*v);
printf("v地址为%p\n",v);
change(v);
printf("%d\n",*v);
}
10
v地址为000000000062FE14
p地址为000000000062FE14
20
两个int *类型指针变量储存地址相同,改变后结果也改变,这样就显得合理了。
但为什么代码1中的char *类型就不行呢?
我终于想通了,请诸君看如下代码!
#include<stdio.h>
void change(char* p)
{
printf("p地址为%p\n",p);
p = "bbb";
printf("赋值后p地址为%p\n",p);
}
int main()
{
char *v = "aaa";
printf("%s\n",v);
printf("v地址为%p\n",v);
change(v);
printf("%s\n",v);
}
aaa
v地址为0000000000404020
p地址为0000000000404020
赋值后p地址为000000000040400B
aaa
简单来说
p = "bbb";
“bbb”也是将这段字符串的首地址赋给了p,指针变量p中的储存的地址再次被改变了,至于上面那个什么替身,什么char *x,就是瞎扯淡!
我对上述参考的博客表示强烈谴责!!!
不过上述博客中关于双重指针的这张图还是不错的,拿过来给大家做一个直观上的理解。
最后,总结一下:
实际上问题的关键在于要修改的数据类型,(就是所有指针指向的最下面那层数据),如果涉及到“指针”,“字符串”,“字符数组”......(即在理解上与'地址'有很强的关联,从《C Prime Plus》来看这三者有很大的相似性),建议设计函数时,形参要用双重指针。