赞
踩
首先要声明c语言是没有引用传参的哈,引用传参是c++的语法。但是如果我们也想实现一样的效果该怎么写呢?(函数内的值变化可以直接对原参数的值进行更改)
其实原理都是一样的,我们细想c++的引用传参,其实就是把参数的地址作为参数传进了函数体内。函数体内的操作都是基于该地址上的参数进行变化的,而不是将参数的值进行拷贝传进函数体内。
同样,c语言也可以实现上述效果。我们怎么做呢?也是传地址,传地址,再对该地址上的值进行变化即可。代码如下:
void add(int *s){ // 这个*s是其实要的是一个地址,因为指针本身就是地址
int a=199;
*s=a; // 这里的*s是在将s这个地址上的值进行变化
}
int main(){
int s=1; //实参s
printf("变化前地址:%d\n",&s);
printf("变化前:%d\n",s);
add(&s);
printf("变化后地址:%d\n",&s);
printf("变化后:%d\n",s);
return 0;
}
结果如下:
变化前地址:6422044
变化前:1
变化后地址:6422044
变化后:199
当然,我们s也可以定义成指针,同样也是传地址,现在要传的是指针的地址,并且一定记得要给指针分配内存,要不然会有段错误(Segmentation fault)!!!!代码如下:
void add(int *s){ // 这个*s是是一个指针
int a=321;
*s=a; // 这里就是这一步就是把a的值给指针s
}
int main(){
int *q; //实参p
q=(int *)malloc(sizeof(int));
printf("变化前地址:%d\n",&q);
printf("变化前:%d\n",*q);
add(q);
printf("变化后地址:%d\n",&q);
printf("变化后:%d\n",*q);
return 0;
}
结果如下:
变化前地址:6422040
变化前:-1163005939
变化后地址:6422040
变化后:321
这里我们也可以练一下二级指针,加深一下理解,代码如下:
int a=321; void add(int **s){ // 这个**s是其实是一个二级指针 *s=&a; // 这里就是将a的地址让*s存起来,传递的是址 } int main(){ int **p; //实参p p=(int *)malloc(sizeof(int)); int x=123; *p=&x; // 这里要定义一个x,让*p存x的址,否则会段错误 printf("变化前地址:%d\n",&p); printf("变化前:%d\n",**p); add(p); printf("变化后地址:%d\n",&p); printf("变化后:%d\n",**p); return 0; }
结果如下:
变化前地址:6422040
变化前:123
变化后地址:6422040
变化后:321
可能你会好奇,为啥这里要用二级指针?为啥a要定义成全局变量?
用二级指针是因为我们要在函数体内对指针进行变化,且函数运行结束后,对指针的更改仍然有效。
这里为什么不是和刚才一样定义成局部变量是因为涉及到c的内存分配,我们这里是传址。局部变量是开辟在栈内存中的,局部变量的址和值在函数体内有效,出了函数体就销毁了,也就是看起来为啥用了二级指针还是改不了?因为是局部的。所以我们改成全局的,放在堆内存中,这样就实现了我们对指针进行变化的想法。
段错误处理:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。