是什么?有什么用?用在什么地方?(理解)
养成良好的编程习惯;
培养编程思想;
写代码之前应该先分析需求,分析完需求再开始写代码;(写注释)
将人类的思维 --> 代码
1. C语言程序是由函数组成
2. 什么是函数? 函数就是一段具备特定功能的程序段
定义函数的目的: 将一个功能封装以来方便复用
不使用函数的弊端:
1.重复代码太多, 又臭又长
2.当需求变更, 很多地方都需要修改代码
使用函数的好处:
1.提高了代码的复用性, 代码更简洁
2.当需求变更, 不用修改很多地方
1.函数的定义
函数的定义格式:
返回值类型 函数名称(形参列表)
{
函数体; // 语句; ...
}
初学者如何定义函数:
应该有4个确定:
1.确定函数名称(给函数起一个有意义的名称, 让调用者一看到名称就知道这个函数是干什么的)
1.1函数是标示符的一种
遵守规则 : 26个字母 , 数字 , _组成, 遵守规范: 驼峰命名
2.确定形参列表
2.1形参列表的格式 (数据类型 变量名称, ...)
2.2如何确定形参列表? 就看看以后调用函数时, 是否需要传递一些辅助的数据给函数
3.确定返回值
4.确定返回值类型
4.1return的是什么类型, 那么返回值类型就写什么类型
return的作用:
1.返回数据给函数调用者
2.结束函数
3.提前结束函数
2.函数的参数及返回值
1.形参列表中的每一个变量我们称之为, 形式参数, 简称形参
形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只有在函数内部有效。函数调用结束返回主调函数后则不能再使用该形参变量。
2.调用函数时传入的参数, 我们称之为实际参数, 简称实参
实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传
??3.形式参数、实际参数注意点:
调用函数时传递的实参个数必须和函数的形参个数必须保持一致
int max(int number1, int number2) // 形式参数
{
return number1 > number2 ? number1 : number2;
}
int main()
{
max(88); // 报错
return 0;
}
当使用基本数据类型(char、int、float等)作为实参时,实参和形参之间只是值传递,修改形参的值并不影响到实参函数可以没有形参
形参实参类型不一致, 会自动转换为形参类型
??4.返回值类型注意点
C语言是弱语言
函数可以没有返回值类型
如果没有写返回值类型,默认是int
??5.return使用注意
一个函数内部可以多次使用return语句,使用了return语句后,函数就会马上停止执行,return语句后面的代码就不再被执行
int max(int number1, int number2) // 形式参数
{
return number1 > number2 ? number1 : number2;
printf("执行不到"); // 执行不到
return 250; // 执行不到
}
函数返回值的类型和return实际返回的值类型应保持一致。如果两者不一致,则以返回值类型为准,自动进行类型转换
3.函数的注意点??
1.如果"基本数据类型"(char int double float)作为函数的参数, 在函数中修改形参的值, 不会影响到外面实参的值
2.实参的个数, 必须和形参的个数相同
注意: 在函数中修改形参的值, 不会影响到外面实参的值(当然也有一定的前提)
3.返回值可以和返回值类型不一样,但是如果返回值和返回值类型不一样的时候
系统会对返回值进行自动类型转换(隐式类型转换), 将返回值转换为返回值类型
注意: 在企业级开发中千万不要这样写
4.函数可以有形参也可以没有形参
5.函数可以有返回值, 也可以没有返回值
如果函数没有返回值, 那么返回值类型就写viod
如果函数没饭返回值, 那么可以不写return, 但是如果写了return也不会报错
6.函数名称不能相同
形参列表不同也不可以
返回值类型不同也不可以
7.函数不能嵌套定义
3.函数的声明
函数的声明
在C语言中,函数的定义顺序是有讲究的:默认情况下,只有后面定义的函数才可以调用前面定义过的函数
如果想把函数的定义写在main函数后面,而且main函数能正常调用这些函数,那就必须在main函数的前面进行函数的声明
函数的声明格式:
返回值类型 被调函数名( 类型 形参, 类型 形参... );
返回值类型 被调函数名( 类型, 类型...);
函数的声明与实现的关系
?? 注意点:
如果被调函数的返回值是整型时,可以不对被调函数作说明,而直接调用。这时系统将自动对被调函数返回值按整型处理
4.函数的调用
1.函数的调用
函数调用的一般形式为
函数名(实际参数表);
对无参函数调用时则无实际参数表。
实际参数表中的参数可以是常数,变量或其它构造类型数据及表达式。
多个参数各实参之间用逗号分隔。
函数表达式
函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数 是有返回值的
函数语句
函数调用的一般形式加上分号即构成函数语句。
函数实参
函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实参进行传送,因 此要求该函数必须是有返回值的。
2. 函数的嵌套调用
- C语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下一级函数的问题。但是C语言允许在一个函数的定义中出现对另一个函数的调用。这样就出现了函数的嵌套调用。即在被调函数中又调用其它函数。这与其它语言的子程序嵌套的情形是类似的。其关系可表
main 函数
main是函数的名称, 是系统规定的名称, 系统启动程序就会调用名称叫做main的函数
main函数只能由系统调用 ,不能手动调用
int main(int argc, const char * argv[]){}
其实系统在启动程序的时候, 会给我们的程序传递一些参数
argc : 就是系统传递进来的参数个数, 默认是1
argv : 就是系统传递进来的参数实际的值, 默认是程序的名称
递归函数
1.递归函数概述及用法
一个函数在它的函数体内调用它自身称为递归调用。这种函数称为递归函数。C语言允许函数 的递归调用。在递归调用中,主调函数又是被调函数。执行递归函数将反复调用其自身,每调用 一次就进入新的一层
2.递归函数构成条件
自己调用自己
存在一个条件能够让递归结束
问题的规模能够缩小
??3.递归函数注意点
一般情况下, 能用循环做得事情, 用递归函数都能做
但是要注意: 不是什么时候都使用递归, 递归要慎用(性能问题)
什么是递归函数: 函数自己搞自己, 性能差
注意: 递归一定要由一个明确的结束条件, 否则会造成死循环(无限循环)
多文件开发
1.为了模块化开发,一般会将不同的功能写到不同的.c源文件中,这样的话,每个开发人员都负责修改不同的源文件,达到分工合作的目的,能够大大提高开发效率。也就是说,一个正常的C语言项目是由多个.c源文件构成。
2. 所谓模块化编程(多文件开发),就是多文件(.c文件)编程,一个 .c 文件和一个 .h 文 件可以被称为一个模块
通过头文件来调用库功能。
在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即
可。用户只需要按照头文件中的接口声明来调用库功 能,而不必关心接口怎么实现的。
多文件编译。
将稍大的项目分成几个文件实现,通过头文件将其他文件的函数声明引入到当前文件。
头文件能加强类型安全检查。
如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,
这一简单的规则能大大减轻程序员调试、改错的负担
??多文件开发的注意事项
- 1)头文件中可以和C程序一样引用其它头文件,可以写预处理块,但不要写具体的语句。
- 2)可以声明么函数, 当不可以定义函数
- 3)可以声明常量, 当不可以定义变量
- 4)可以“定义”一个宏函数。注意:宏函数很象函数,但却不是函数。其实还是一个申明。
- 5)结构的定义、自定义数据类型一般也放在头文件中。
- 6)多文件编程时,只能有一个文件包含 main() 函数,因为一个工程只能有一个入口函数。我们 把包含 main() 函数的文件称为主文件。
- 7)为了更好的组织各个文件,一般情况下一个 .c 文件对应一个 .h 文件,并且文件名要相同, 例如 fun.c 和 fun.h。
- 8)头文件要遵守幂等性原则,即可以多次包含相同的头文件,但效果与只包含一次相同。
- 9)防止重复包含的措施