十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
void fun(int i);
创新互联建站是一家专业提供黄陂企业网站建设,专注与成都网站制作、网站设计、H5开发、小程序制作等业务。10年已为黄陂众多企业、政府机构等服务。创新互联专业网站建设公司优惠进行中。
假设有参数int a = 5;
调用fun的时候类似 fun(i = a);是这样调用的 把a的值赋给i 你修改i的值 改不了a.
函数在C语言中是必不可少的一部分,大致可以分为两种:系统定义好的和我们自己写的。不管是哪种函数,它们都默默地、兢兢业业地完成着属于自己的任务。只要给它一些参数,它就会把参数处理好、有些函数还会把处理结果返回出来。以下几种特殊函数,你有见过吗?会用吗?
1、静态函数
普通的函数一般是全局的,可见范围是跨文件的,比如a.c 这个文件中有一个函数名为 func() , b.c文件 中是可以直接调用a.c中的func函数的。而静态函数不同,它被static修饰之后可见范围缩小到本文件可见,其它文件不可见。
如果真的是闲得蛋疼想在一个文件中调用一个别的文件中的静态函数,也有办法:
1.直接把func所在的函数包含进来 #include "b.c"
2.可以把static 修饰的函数写在头文件中
2、递归函数:
这个名字看起来有一点数学味,比较高级的样子。其实它的定义也很简单:在一个函数内部调用了自身,那这个函数就是递归函数。
下面写了一个例子:
使用递归函数的时候有几个问题要注意:
1.只有能被递归解决的问题才可以使用递归来解决。(阶乘、幂运算、字符翻转等)
2.递归函数中必须有一个可以直接退出(返回)的条件,否则会进入无限循环。
3.递归的过程包含两个:逐渐递进,层层回归。
4.递归函数会使用大量的栈内存空间,要注意递归的层次不要太深,如果一定要用的话可以尝试把栈空间的大小临时设置一下。(ulimit -s)
3.指针函数
这种函数是什么其实很明显了,指针函数就是返回值是指针类型的函数。
使用的时候要确保该函数的返回值是指针,不然编译器会报警告。
4、回调函数
函数的实现方,它不方便直接调用该函数,而是由第三方接口来调用该函数,该函数就是回调函数。概念有点绕,我们直接看代码:
可以看到我们在主函数main里面并没有直接调用func()函数,而是运用函数指针P通过一个signal函数去调用它。在实际工程中回调函数会用得比较多,就像图中的signal函数,假设这个函数是从别人手上买回来的,我们无权访问其源码,只能够使用。卖家给我们留下了接口让我们使用它,因此我给了它两个参数,当它收到信号2的时候,我希望它能帮我调用我写的func()函数。那么func()就是所谓的回调函数。
5、内联函数
如果有一个函数被多次调用,那么该函数在调用过程中会消耗程序执行的时间, 而内联函数指的就是可以把需要调用的函数副本拷贝到调用者的内部,节约了调用过程中的时间。
普通函数的调用与切换过程:
内联函数示意图:
内联语法:
什么时候应该用内联函数:一个函数在另一个函数多次被调用,而且被调用函数的内容比较少的情况。
6、变参函数
如果一个函数的参数类型以及参数的数量都是可变的,那么这个函数就称之为变参函数(如我们常用的printf)。
函数形参在栈中分配内存的顺序,从右到左的独特顺序使得第一个参数是栈顶元素(即示例中的参数 format),我们就可以根据第一个已知的参数(绿色)所提供的线索, 来回溯剩下的未知的参数(黄色)
以上六种特殊函数,你看懂了吗?有任何疑问可以评论区告诉我哦!
森式嵌入,持续分享嵌入式硬知识。欢迎志同道合的朋友关注一起交流进步!
传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址。
void func(int array[10])
void func(int array[])
void func(int *array)
所以以上三种函数声明完全等同。
实际情况是,数组做参数,完全无法按值传递。这是由C/C++函数的实现机制决定的。
下一个问题是:为什么偏要按值传递呢?当要在一个函数内使用一个数组时,传一个指针进去不就行了?只要能访问到我们所要的数据并对其进行操作,何苦钻牛角尖。
首先说swap(int a,intb)与main函数调用的sawp(a,b),首先讨论变量的作用域,也就是变量的生存周期,main函数中的swap(a,b)中的a与b的作用域是整个main函数,而swap(int a,intb)中的a,b是swap的函数参数,作用域是swap函数,而main函数调用swap函数时会把main函数中的a与b的值传递给swap函数中的
a与b(所以把swap函数中的a与b称作是副本,因为他们本身的值就是main函数的a b复制过来的),这里两对a与b仅仅是值相等(在内存里地址是不同的),我们在swap函数中操作a,b让a与b交换,仅仅是让swap函数中的a b交换了,而a,b出了swap函数就不起作用了,不能实现main函数中的交换,因为这里用的是值传递的方式。
而要想让main函数中的a,b值交换怎么办呢?这就需要swap函数中的两点参数的内存地址与main函数中的相同。而C语言中存储地址的数据类型是指针,所以把swap函数中的参数换成指针就好了,也就是swap(int*a,int*b),这里的a,b都是指针变量,用来保存两个整型数字的内存地址,而main函数中需要调用swap函数把main函数的a,b的地址传过来,也就是swap(a,b)这里的是取地址符,这样swap函数就得到了对应的两个地址,由于这样*a(这里的*代表解引用)与main函数中的a 具有了一样的地位,操作*a与main函数中操作a是一样的,因为内存地址是一样的,*b也一样。这样就可以完成在swap函数中交换*a与*b后,就实现了main函数中的a,b交换。
这个程序,就是让你搞清楚函数传值和传址的区别。
这里fun第一个参数是传址(值改变外部函数对应的变量值也改变)。第二个参数是传值(值改变外部函数对应的变量值不变)。
所以这个程序,x传地址x,y传值。经过fun函数改变后,x的值改变了,而y的值不变。