文章目录

  • 一、指针与函数之间的关系
  • 二、复制传参
  • 三、地址传参
  • 四、传一维数组(地址)
  • 五、传二维数组(地址)
  • 六、传指针数组(地址)
  • 七、指针函数和函数指针

一、指针与函数之间的关系

1、我们可以给一个函数传一个整型、字符型、浮点型的数据,也可以给函数传入一个地址。

2、函数的传参方式:复制传参(数值)、地址传参(地址值)

3、如果实参是一个普通变量,那么地址传参时,形参就需要使用一级指针;
如果实参是一个一级指针,那么地址传参时,形参就需要使用二级指针;
以此类推…

二、复制传参

#include <stdio.h>//交换数值的一个函数
void fun(int a, int b)
{int temp;temp= a;a= b;b= temp;printf("在函数中数值:a=%d,b=%d\n", a, b);printf("在函数中地址:a=%p,b=%p\n", &a, &b);
}//测试函数
void test()
{int a=30, b=100;printf("传参之前数值:a=%d,b=%d\n", a, b);printf("传参之前地址:a=%p,b=%p\n", &a, &b);fun(a, b);printf("函数结束后数值:a=%d,b=%d\n", a, b);printf("函数结束后地址:a=%p,b=%p\n", &a, &b);
} int main()
{test();
}

测试结果:

可以看到,形参a与实参a的地址是不同的,说明形参a与实参a就是两个独立开来的变量,因为作用域的原因,它们可以重名,但实际上是两个不同的变量。
因此,改变形参的值,并不会影响到实参的大小。

三、地址传参

1、传一维指针

#include <stdio.h>//一个交换地址的函数
void fun2(int *p1, int *p2)
{int temp;temp= *p1;*p1= *p2;*p2= temp;printf("在函数中数值:*p1=%d,*p2=%d\n", *p1, *p2);printf("在函数中地址:p1=%p,p2=%p\n", &p1, &p2);} //测试函数
void test()
{int a=30, b=100;printf("传参之前数值:a=%d,b=%d\n", a, b);printf("传参之前地址:a=%p,b=%p\n", &a, &b);fun2(&a, &b);printf("函数结束后数值:a=%d,b=%d\n", a, b);printf("函数结束后地址:a=%p,b=%p\n", &a, &b);
} int main()
{test();
}

测试结果:

地址传参的分析方法与复制传参类似,可以看到形参的地址与实参的地址是一样的,说明实参就代表了形参,改变形参的值就是在改变实参的大小。

2、传字符串指针

#include <stdio.h>
void fun(char **q)
{*q= "Oh my love";
}
int main()
{char *p= "hello world";fun(&p);printf("%s", p); //输出字符串
}


这同样也是地址传参,因此会改变实参的数据值。

四、传一维数组(地址)

  • 只要是传入一维数组的数组名,都是地址传参,会改变原来数组的数据值。
    方式一:形参用一维数组,int p[]
    方式二:形参用一维指针,int *p
#include <stdio.h>
void fun1(int *p)  //也可以用int p[]
{p[2]= 520;printf("函数内:p[2]=%d\n", p[2]);printf("函数内:p[3]=%d\n", *(p+3));  //相当于p[3]
}
int main()
{int a[10]= {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};fun1(a);printf("函数结束后:a[2]=%d\n", a[2]);printf("函数结束后:a[3]=%d\n", a[3]);
}


因为传递的都是数组名,也就是地址传参了,所以修改形参的值就会改变实参的大小。

五、传二维数组(地址)

传递二维数组名都是地址传参,但是只有使用p[][]数组的方式才能改变原来数组的数据值。

#include <stdio.h>
void fun2(int (*p)[4])  //也可以用p[][4]
{p[0][2]= 520;  //这样不会改变原数组的数据*(*(p+1)+2)= 120; printf("函数内:p[0][2]=%d\n", p[0][2]);printf("函数内:p[1][2]=%d\n", *(*(p+1)+2));  //相当于p[1][2]
}
int main()
{int a[][3]= {{10, 9, 8},{7, 6, 5}, {4, 3, 2}};fun2(a);printf("函数结束后:a[0][2]=%d\n", a[0][2]);printf("函数结束后:a[1][2]=%d\n", *(*(a+1)+2));  //相当于a[1][2]
}

六、传指针数组(地址)

指针数组本质上就是一个数组,数组里面的每一个元素都是一个函数指针,返回值类型(*函数指针变量名[函数指针的个数])(形参列表);

例如:int(*p[10])(int,int);
定义了一个函数指针数组,有10个元素p[0]~p[9],每个元素都是函数指针变量,指向的函数,必须有整型的返回值,两个整型参数。

测试代码:

void fun3(int **q)
{int i;printf("函数内输出:\n");*(q)= "You";*(q+1)= "are";for(i=0; i<3; i++){printf("%s\n", q[i]);    }
}
int main()
{int i= 0;char *p[3]= {"I", "am", "here"};fun3(p);printf("函数结束后输出:\n");for(i=0; i<3; i++){printf("%s\n", p[i]);    }
}

测试结果:

七、指针函数和函数指针

指针函数:本质上就是一个函数,是一个返回指针的函数。
函数指针:本质上就是一个指针,是一个指向函数的指针。
详情请参见文章:
C语言指针深入透析(原来你一直没有搞懂C语言指针是因为没有理解其中的规律)

深入理解C语言系列之函数传参的那些事儿(函数参数、指针、地址、数组)相关推荐

  1. 函数传参的三种方式(详细)

    最近又碰到了函数传参的问题,每次碰到都会让作者疑惑一段时间,这次干脆总结整理一下,顺便让自己更加透彻的了解传参的问题.咱们开始吧. c语言中,函数调用时传送给形参表的实参必须与形参有三个一致:类型.个 ...

  2. Shell函数(函数定义、函数变量、函数调用、函数传参、函数返回值、获取函数返回值)

    分享知识 传递快乐 1.函数定义 linux shell 可以用户定义函数,然后在shell脚本中可以随便调用.Shell 函数定义的语法格式如下: [function] funname [()]{函 ...

  3. Javascript 之《函数传参到底是值传递还是引用传递》

    前言 这个问题其实困惑了我好久,但是在实际使用中总是得过且过,不想去深究.由于这种态度,在学习 Javascript 过程中,水平一直都是出于半桶水状态,很多概念和原理似懂非懂,模糊不清. 所以,写了 ...

  4. shell函数传参和返回

    文章目录 一.一个简单shell函数 二.shell函数传参 三.shell函数返回结果 一.一个简单shell函数 #!/bin/bash function SayHi() {echo " ...

  5. vue 事件调用 传参_Vue 事件如何传递参数?

    Vue 事件如何传递参数? 事件函数参数传递: 普通参数和事件对象传递格式如下: 调用函数传参 点秋香 vue事件绑定-参数传递实例如下: vue事件绑定-参数传递 xinbiancheng.cn { ...

  6. C语言与java中函数传参比较

    C语言与java中函数传参比较 首先先说结论:C语言中参数传递有值传递,地址传递,引用传递.但java中的参数传递只有值传递 1.C语言中的参数传递 1>值传递 值传递非常好理解,其实就是对函数 ...

  7. C语言 指针在函数传参中的使用

    int add(int a, int b)   //函数传参的时候使用了int整型数据,本身是数值类型.实际调用该函数时,实参将自己拷贝一份,并将拷贝传递给形参进行运算.实参自己实际是不参与运算的.所 ...

  8. python函数参数传递机制_Python 学习笔记(一) 理解Python的函数传参机制

    对于刚接触Python不久的新手,Python的函数传参机制往往会让人迷惑.学过C的同学都知道函数参数可以传值或者传地址.比如下面这段代码 点击(此处)折叠或打开 void func(int inpu ...

  9. 【C语言进阶】数组、指针、函数——传参篇

    目录 写在前面 一.数组传参 一维数组传参 二维数组传参 二.指针参数 一级指针传参 二级指针传参 三.函数传参 四.看懂代码 写在最后 写在前面 上篇文章介绍了指针数组和数组指针,有兴趣的小伙伴可以 ...

最新文章

  1. P6134 [JSOI2015]最小表示(拓扑排序递推 + bitset优化,可达性统计变种)
  2. machine learning (6)---how to choose features, polynomial regression
  3. python列表字典如何提取_怎么提取字典里面的列表里面的字典的value
  4. 流程DEMO-合同会审表
  5. redis 存入mysql_数据存到redis 过后怎么处理放到数据库?
  6. 【机器学习】ICA 原理以及相关概率论,信息论知识简介
  7. 运维部门工作总结_运维部工作总结
  8. android 判断资源是否使用6,android-download-manager – Android 6获取下载文件的路径
  9. oracle查看脚本,oracle 查看表空间的脚本
  10. Java单链表头插法和尾插法以及增删改查方法
  11. mongodb数据的导入导出备份恢复_万金油_新浪博客
  12. S7-200SMART PLC与V20变频器MODBUS通讯示例程序
  13. 内容安全策略(CSP)详解
  14. win10电脑虚拟内存怎么设置?win10虚拟内存设置多少合适?
  15. Alphabetic Removals
  16. Windows系统开机自动运行程序和自动启动服务
  17. 解密阿里云效女程序员辰颜、异新代码诗!
  18. 大学生静态HTML网页源码 我的校园网页设计成品 学校班级网页制作模板 web课程设计 dreamweaver网页作业
  19. 如何写linux软件专利,Linux之父:软件专利和方法专利都挺扯淡
  20. Cadence Allegro使用过程中出现的常见问题-原理图和PCB

热门文章

  1. php设计验证码图片,php实现简单的图片验证码
  2. python对象传递_Python参数传递对象的引用原理解析
  3. java下载上传远程文件
  4. 干活的不如写ppt的吗_干活的干不过写PPT的?或许只是工作汇报的方式错了……...
  5. miniblink载入html,(转)miniblink跨线程异步JS回调,及miniblink提升首屏加载速度的代码...
  6. # 字节数组转uint32_字节跳动客户端校招面经(21届秋招内推)
  7. 解决oracle客户端乱码问题,如何解决oracle客户端中文乱码问题?-Oracle
  8. pinpoint 监控mysql_基于Centos7系统安装部署Pinpoint分布式监控
  9. wps如何保存最终状态_怎么让word显示最终状态
  10. sql2000数据类型对应的数值_Qlikview---数据类型