使用指针作函数形参遇到的问题及解决办法

首先看代码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_花透的博客-CSDN博客_双重指针

 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》来看这三者有很大的相似性),建议设计函数时,形参要用双重指针。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值