博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言函数传指针和传值的区别
阅读量:3737 次
发布时间:2019-05-22

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

前言

  在C语言很多函数中,传入的参数有些是直接传值,有些是传指针,这二者有什么区别呢?如果不能好好理解,在使用函数过程中会增加出bug的几率。

传值

  传值很好理解,就是直接把变量的值传入,下面用一个函数来举例:

void swap(int a, int b){
int temp = a; a = b; b = temp;}

  上面函数的目的是要交换a和b的值,但是实际使用中发现,并无法交换a和b的值。

在这里插入图片描述

  原因在于:函数参数在传递的时候,都是传原数据的副本,也就是说,swap内部使用的a和b只是最初始a和b的一个副本而已,所以无论在swap函数内部对a和b做任何改变,都不会影响初始的a和b的值。

  正因如此,我们常常被告知,不要把直接把结构体直接作为参数,这样效率会很低。由于结构体本身占用字节数较大,如果直接作为参数,那么将会产生一个较大的”副本“,如此一来,效率也就很低了。

  swap函数调用前后的情况:

在这里插入图片描述

传指针

  为了解决上面无法交换的问题,改为用传指针的方式:

void swap(int *a, int *b){
int temp = *a; *a = *b; *b = temp;}

  函数使用情况如下:

在这里插入图片描述

  看到这里,不知道你是否会疑惑,为什么给函数传递参数的时候,一会是传值,一会是传指针呢?为什么传指针就能改变参数的值呢?实际上,C语言里,参数传递都是值传递!也就是说,你认为的传指针也是传值,只不过它的值是指针类型罢了。

  我们再通过图来理解前面为什么传指针就可以交换a,b的值:

在这里插入图片描述
  从图中可以看出,虽然传递给函数的是指向a和b的指针的副本,但是它的副本同样也是指向a和b,因此虽然不能改变指针的指向,但是能改变参数a和b指向的内容,即改变原始a和b的值。

  下面再看一个指针作为参数的例子:

void getMemery(int *p){
/*申请1024个int大小*/ p = (int *)malloc(sizeof(int)*1024); if(NULL == p) {
printf("malloc failed\n"); p = NULL; }}

  使用该函数,结果如下:

在这里插入图片描述
  发现结果并不是预期的那样,问题在哪呢?

  原因在于:传入指针p后,函数getMemery函数内部的p其实是原始p的副本,因此即便在函数内部,将p指向了一块新申请的内存,仍然不会改变外面p的值,即p还是指向NULL。

在这里插入图片描述
  既然我们的目的是修改指针p的值,那么,就得把指针p看成普通变量,然后把指针p的指针传入函数,即二级指针。

void getMemery(int **p){
/*申请1024个int大小*/ *p = (int *)malloc(sizeof(int)*1024); if(NULL == *p) {
printf("malloc failed\n"); *p = NULL; }}

  运行结果如下:

在这里插入图片描述

  从运行结果可以看到,p的值被改变了,而不再是初始的NULL。

在这里插入图片描述

总结

  • 函数的参数都是原数据的“副本”,因此在函数内无法改变原数据;
  • 函数中参数都是传值,传指针本质上也是传值;
  • 如果想要改变入参内容,则需要传该入参的地址(指针和引用都是类似的作用),通过解引用修改其指向的内容;
  • 以上结论不限于C语言。

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

你可能感兴趣的文章
Python心得--新手开发注意
查看>>
计算机网络-网络应用
查看>>
国际电汇的清算代码是什么?
查看>>
浅谈CC攻击原理与防范
查看>>
CentOS7 Cloudera Manager6 完全离线安装 CDH6 集群
查看>>
Robot Framework自动化测试框架核心指南-如何使用Java编写自定义的RobotFramework Lib
查看>>
整理了Linux常用命令变量
查看>>
五种编程语言解释数据结构与算法——顺序表3(JavaScript与Python语言实现)
查看>>
MTU(Maximum Transmission Unit),最大传输单元
查看>>
lua学习之函数篇
查看>>
leetcode| 94. 二叉树的中序遍历
查看>>
内网学习之MySQL服务提权
查看>>
lua学习之类型与值篇
查看>>
机器学习算法总览
查看>>
洛谷P5661 公交换乘(CSP-J 2019 T2)
查看>>
开箱即用~基于.NET Core的统一应用逻辑分层框架设计
查看>>
隐马尔可夫(HMM)/感知机/条件随机场(CRF)----词性标注
查看>>
HanLP《自然语言处理入门》笔记--5.感知机模型与序列标注
查看>>
Codeforces Round #617 (Div. 3) String Coloring(E1.E2)
查看>>
思科命令 service password-encryption
查看>>