博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c语言的传值和传址
阅读量:4185 次
发布时间:2019-05-26

本文共 1401 字,大约阅读时间需要 4 分钟。

我们都知道C语言中函数传参有两种方式:传值和传址

传值:

实参把值传给形参,但没有传地址,即对实参的修改无效;生成临时变量

核心原理:函数会对形参和中间变量重新分配空间

Void Swap(int pLeft, int pRight){int a=10,b=20;Swap(a,b);}优点:安全(函数的副作用不会影响外部实参),局部变量值的交换对主函数的变量无影响。缺点:不能通过修改形参来改变外部实参

传地址:

实参把自己的内存地址传给了形参,这样对实参的修改就有效了;同样也生成临时变量-该临时变量为外部实参地址

Void Swap(int* pLeft, int* pRight){    int tmp=*pLeft;    *pLeft=*pRight;    *pRight=tmp;} 优点:节省空间,效率高,改变形参可以修改外部实参 缺点:指针不安全,代码难度提高,可能在不用修改外部实参时反而将其修改了

传地址有以下3种方法:

(1)全局变量(把参数定义为全局变量,一次性分配空间,传地址,函数调用时无需访问直接使用)

(2)指针是传值的,但指针的间接引用是传地址的

(3)数组是传地址的,因为数组对内存要求比较苛刻,系统对数组不再分配空间,而是传地址

实例分析:

例1:

void swap(int x,int y){    int tmp=x;    x = y;    y = tmp;}int main(void){    int a = 3;    int b = 4;    swap(a,b);}

传值时,在主函数中调用swap()无法改变a,b的值,因为传给swap()的参数实际上是a,b变量的一份拷贝_a,_b,他们和a,b的地址并不一样,当调用完swap后,它所占的内存空间会被释放,所以a,b的值并没有被改变。

例2:

void swap(int* x,int* y){    int tmp;    tmp = *x;    *x = *y;    *y = tmp;}int main(void){    int a = 3;    int b = 4;    swap(&a,&b);}

传址时,通过调用swap()可以改变a,b的值,因为此时传递的是a,b的地址,在swap()中改变*x,*y的值就相当于在改变a,b的值,因为他们的地址是一样的,即使调用完swap后,它所占的内存空间会被释放,但a,b的值已被改变。

例3:

void getMemory(char* p,int num)  {p = (char*)malloc(num);}int main(void){    char* str = NULL;    getMemory(str,10);    strcpy(str,"hello");    printf("%s\n",str);    return 0;}

运行会报段错误,它和传址调用有区别:getMemory()函数是想改变指针变量str本身的值,而不是改变*str的值,虽然在getMemory()函数中p的值会被改变,但当它调用完后,p会被释放,所以str的值还是为空,要想改变str的值,应该传&str。

通过例子可以看出,不管是传址还是传值都是传的变量的一份拷贝,要想改变变量本身的值,就应该传该变量本身的地址。

转载地址:http://ovuoi.baihongyu.com/

你可能感兴趣的文章
在TensorFlow中编程
查看>>
用c实现一个压力测试工具
查看>>
圆周率计算公式
查看>>
排序算法之-选择排序
查看>>
排序算法之-基数排序
查看>>
scikit-learn
查看>>
原生java方法操作SQLite数据库
查看>>
sqlite 数据库驱动框架
查看>>
B树、B+树、B*树 总结
查看>>
kafka常用命令
查看>>
kafka顺序消息
查看>>
kafka 消息服务
查看>>
从零开始玩转JMX(一)——简介和Standard MBean
查看>>
究竟啥才是互联网架构中的高并发!
查看>>
数据库水平扩展与垂直扩展
查看>>
第二章 HttpClient 连接管理
查看>>
tcpdump抓包分析TCP三次握手过程
查看>>
IO模型及select、poll、epoll和kqueue的区别
查看>>
Nginx+Keepalived高可用集群
查看>>
IP协议详解
查看>>