C语言·函数

1. 函数的概念

        C语言中函数(function)最直观的翻译是"子程序",它是一小段代码,用来完成某个特定的任务的代码。

        函数的好处:1.可以拆分任务 2.可以复用,提升开发效率

2. 库函数

        C语言并不直接提供库函数,它只是规定了语法规则,让C语言编译器的厂商来根据国标(ANSI C)来实现库函数。

        库函数相关头文件 https://zh.cppreference.com/w/c/header    中文版

                                      https://cplusplus.com/reference/clibrary/    英文版

3. 自定义函数

3.1 函数的语法形式

        ret_type 是函数返回类型

        fun_name 是函数名

        括号中是形参

        {}括起来的是函数体

3.2 函数举例

        写一个加法函数,完成两个整形变量相加

        上面一段代码展示了函数定义和应用的最简单最基本情况,读者可以仿照着敲一下来深度理解函数的定义和应用,以及函数的传参过程。

        函数名是自定义的,根据实际情况起名。

        参数也是自定义的,需要几个,需要什么类型都视情况而定。

        函数是否返回值也跟据实际情况设定,如果不需要返回就用void定义函数返回类型。

4. 形参和实参

4.1实际参数

        函数调用时传递给函数的参数

        在上面一段代码中,a和b实际给到了函数add()所以它们是实参

4.2 形式参数 

        在函数中定义的参数

        在上面一段代码中,x和y是形式参数,如果只定义了add函数但是不传参调用的话,x和y是不向内存申请空间的,它们只是形式上存在,当传参后形参才被实例化了。

4.3 实参和形参的关系

        形参是实参的一份临时拷贝,对形参的修改是不会影响实参的,它们是各自独立的内存空间。

5. return语句

return语句的注意事项:

        1.return后面可以跟一个数值,也可以跟一个表达式,表达式计算完后返回结果。

        2.return后面可以什么都不跟,代表什么都不返回,函数一般是void型。

        这段代码是void型函数提前返回的实例,也就是说即使是void型函数也可以写return只是不返回任何值而已。

        3.return的返回类型和函数返回类型不一致,系统会隐式将其改成函数返回类型

        4.return执行后,函数会彻底结束,函数后面的代码不再执行

        5.如果函数中存在if分支语句,要保证每种if分支都有return返回,否则编译错误
 

        当函数不接受参数时又不写void,就可以随意向函数中传参,只是没有人接收参数,函数也能正常执行。

        如果注明void(函数不接收传参),这时再鲁莽的传参,编译器就会提醒和报错
 

        当函数返回类型什么都不写的时后默认返回int形

6. 数组做函数的参数

        写一个函数,将一个整形数组中的内容都改为-1,再写一个函数打印整个数组

        上面一段代码展示了数组如何在函数中传参,以及数组传参的特性(数组的形参的改变可以影响实参)

        注意:

        1.实参和形参的名字可以相同

        2.数组传参写的是数组名

        3.形参数组可以省略元素个数(一维数组)(写上也是摆设),(二维数组可以省略行,不能省略列)

        4.数组传参后形参数组和实参数组是同一块地址,改变形参就改变了实参(因为在数组传参的时候传的是首元素地址,形参接收的是地址,在指针中有讲解)

7. 函数的嵌套调用和链式访问

7.1 嵌套调用

        写一个程序计算某年某月有多少天

        这段代码中展示了在days_of_month函数中嵌套了if_leap_year的实例,因为有闰年的存在,所以二月份的天数并不稳定,因此在判断二月份天数的时候要判断一下是否是闰年,而我把判断闰年的功能用函数封装起来了,这样就形成了函数的嵌套。

7.2 链式访问

        将一个函数的返回值作为另一个函数的参数,将两个函数像链条一样串起来

        上面这段代码是用上一个printf函数的返回值,作为下一个printf函数的参数,形成了函数的链式访问,这段代码同时也展示了printf函数的一个特性(在代码注释中已经提到),就是printf函数的返回值是在屏幕上打印的总共的字符个数

        我可以在前面提到的网址中找到关于printf函数返回值的描述。

8.函数的声明和定义

8.1单个文件  

        之前的代码中我都是将函数的定义放在主函数的前面,而这次的代码我将函数放在主函数的后面,这样的话就需要在主函数之前声明这个函数,告诉编译器我的程序中有这个函数。

        注意:

        编译器在编译的时候是从上往下扫描的,如果在调用函数之前没有定义的话会报警告

        C语言中要求函数要先声明再使用

        函数的定义是一种更强大的声明,所以把函数定义在要使用它之前就不用再特别声明了
 

8.2 多个文件

        在企业中函数的声明和定义是怎么使用的?

        .c 是源文件(存放函数的实现)

        .h 是头文件(存放函数的声明)

这是主函数源文件

这是函数源文件

这是包含声明函数的头文件

        上面的项目中,我将函数存放在别的源文件中,这时我就需要声明这个函数,无论是用一个头文件声明,还是直接在主函数上面声明都行。但是推荐使用头文件声明函数,这样项目看起来会过呢共有调理,而且注意在包含自己创造的头文件的时候要注意用双引号包含

8.3 static 和 extern

        static 和 extern 都是C语言中的关键字
        static是静态的意思,可以用来:

                1.修饰全局变量

                2.修饰局部变量

                3.修饰函数

        extern 是用来声明外部符号的

        全局变量:在main()函数外面定义的变量,全局变量的作用域是整个工程(能在自定义的函数中直接使用)

        局部变量:在main()函数内部定义的变量,作用域只是自己的大括号内

        生命周期:变量从向内存申请空间到销毁的过程

8.3.1 static修饰局部变量

        static修饰局部变量本质上影响了变量的存储类型,一个局部变量应该放在栈区,但是被static修饰后就放在了静态区.

        

        这也是为什么上面这段代码a的值继承下来了。但是要注意的是 a 的作用域并没有变还是只能在test()函数中使用,并不能在函数外使用。

8.3.2 extern声明外部符号

        

        

        我在另外一个源文件中定义了一个整形变量a,用extern声明它我就可以使用了,此时的a相当于一个全局变量。

        但是如果把a在外部的源文件中定义成 static int a 就会发现即使声明之后也不能用了,这是因为static在修饰全局变量的时候将它的外部链接属性变成了内部链接属性,也就是变成了只能在变量原本存在的源文件中全局使用了,其他源文件是看不到这个全局变量的,这就是static修饰全局变量的特点。

8.2.2 static修饰函数

        与static修饰全局变量相似,在定义函数类型前用static修饰后,函数的外部链接属性也变成了内部链接属性,只能在自己所在源文件中使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值