函数
什么是函数?
函数是一段能够被重复调用的具有特定功能的代码段
为什么需要函数?
提高代码的复用率 减少代码量
函数是什么样子?
标准库函数 printf scanf time pow
直接包含头文件 在程序中直接使用即可
自定义函数
这个函数还没有,需要自己实现
函数四要素: 返回值类型 函数名 形参列表 函数体
返回值类型 函数名(形参列表){
函数体
}
.返回值类型 函数返回结果的类型 类型名字
有一些函数没有返回结果,该函数可以声明为 void
所谓void 就表明函数没有返回结果
返回值类型 和 return 语句后面的数据的类型要一致
return语句有两个作用:
1.返回一个结果给调用者
2.结束一个函数调用(如果一个函数的返回值类型为void 可以直接用return;)
一个函数默认的返回值类型为int,如果一个函数的返回值类型为int则可以省略(仅是编译报警告)
如果一个函数没返回值时 可以声明为void
2.函数名 标识符
函数名 就 标识了该函数 函数名不同一样
3.形参列表
当一个函数如果没有参数时,该函数的结果也将是固定的
如果要设计一个灵活的函数,需要设置形参
形参的个数可以有多个,每个形参之间用逗号隔开,每个形参必需要有形参类型
一个形参一个类型 即使形参类型一样也不能省略
在函数调用时,实参的个数必须和形参的个数一样(个数相等)
实参数据的类型和形参的类型一般来说要一致(除非实参可以自动转换为形参类型)
如果一个函数的形参列表为空(形参列表中没写任何东西)
则表示在调用该函数时可以传递任意多个任意类型的实参
如果一个函数的形参列表声明为void
则表明在调用该函数时不能传递参数(实参只能为空)
4.函数体
实现函数功能的代码
函数定义的位置:
在C89中,只能定义在函数外部
在C99中,函数也可以定义在函数内部(不常见)
5.函数调用
函数名(实参列表);
实参列表和形参列表是一一对应的
C语言中函数的隐式声明:
c语言程序在编译过程中,从上往下进行编译的
如果编译到函数调用时,会检查该函数是否编译过,如果编译过则检查其它语法
如果该函数调用之前没有定义过(在调用函数之前 没有定义)
则编译器会自动隐式声明一个同名的函数,并且返回值类型默认为int
链接阶段:把所有的函数调用指定绑定具体的函数地址
如果链接阶段找不到该函数,则报错
如果链接阶段找到该函数,但该函数的返回值类型和int相冲突,直接报错
在一个程序中,函数的声明可以重复,但函数的下定义不能重复
函数声明: 缺少了函数体的函数
函数定义: 有函数体的
编译四步骤:预处理、编译、汇编、链接
结束程序的方式:
1.在main函数中return
2.在任意函数中调用 void exit(int status); #include <stdlib.h>
6.函数的隐式声明
在编译代码阶段,编译到一个没有被编译的函数时,会隐式声明一个同名的函数
并且返回值类型为int, 当链接阶段如果确实有该函数,且返回值类型为int,则编译通过
如果最终没有定义该函数,则链接失败
如果有该函数,但返回值类型和int冲突,则编译也会报错
7.函数一般来说,先声明 后定义
一个函数可以多次声明,但是只能定义一次
函数声明时,形参名可以省略,只保留形参类型
数组:
需要同时定义多个类型相同的变量
类型相同
1.数组的定义 定义数组变量
数据类型 数组名[数组长度];
数据类型是指数组中存储数据元素的类型
数组名 标识符
数组长度 指数组中最多存储元素的个数
int ages[100]; //数组中最多能够存储100个int类型的元素
元素:数据
定义一个数组用于保存10个员工的工资
double salary[10];
定义一个数组用于保存班级中30个学生的语句成绩
int score[30];
数组本身也是变量 可以对数组中的元素进行赋值 修改等操作
数组需要先定义,然后才能使用
2.数组的下标
int score[30];//定义一个长度为30的数组 数组用于存储int类型的元素
定义了30个int类型的变量 30个变量的名字都叫score 如何区分这30个变量?
给每一个变量进行编号,可以用编号来区分数组中的每一个变量。
编号是从0开始,逐一递增
这个编号就称为数组的下标
数组名[下标] 只要下标唯一,能够确定唯一的变量
下标的取值范围从0开始 到数组长度-1 很关键!!!
千万要注意:
如果下标的取值超出[0,数组长度-1]这个取值范围,则数组下标越界
数组下标越界非常危险,是一种非常非常危险的错误
数组下标越界在代码编译时不能检查出来,在程序运行过程中可能运行正常,
但是也可能使程序崩溃,或者程序结果不正确
数组千万别越界访问!!
数组下标是一个整数 不能是小数!
3.通过数组下标对数组进行操作
int score[10];
score[0] = 100;
score[1] = 98;
对数组进行操作,其实是对数组中的元素进行操作 通过[]运算符进行
[] 下标访问运算符
数组名[下标] = x; 对数组中元素进行赋值
int y = 数组名[下标]; 取数组中的元素
一个数组的下标取值范围是 从0开始逐一递增
一般来说,对数组元素的操作,会使用循环进行
循环数组下标 能够依次对数组中元素进行操作
4.数组的初始化
int arr[10]; //数组中元素都是垃圾值
数组初始化是用 {}
在C语言中,参数的传递是值传递 用实参初始化形参 (实参和形参仅仅是值相等)
在函数内部,并不可以修改实参的值 (如果要达到修改实参的结果 指针)
数组作为函数参数时,在函数内部,可以直接修改实参数组元素的值
二维数组:
1.二维数组的定义
数据类型 数组名[二维长度][一维长度];
int scores[4][30];
二维数组有两个维度,二维长度理解成行 一维长度理解为列
int arr[3][4]; //二维数组可以理解为3行4列
二维数组变量(元素)的个数 = 二维长度*一维长度
二维数组中所有的变量名字都一样,得由编号来区分
二维数组中,有行和列两个编号来决定一个元素
行(二维)下标是从0开始,逐一递增到二维长度-1
列(一维)下标是从0开始,逐一递增到一维长度-1
由行和列的下标唯一决定了一个元素
2.二维数组下标
int arr[3][4];// arr[0] 第一行 arr[1]第二行 arr[2]第三行
arr[0][3]: 第一行第四列的元素
arr[2][2]: 第三行第三列的元素
arr[3][1]: 不是数组中的元素 因为 arr[3] 已经越界
3.二维数组的初始化
(1)int arr[3][4] = {{1,2,3,4},{1,2,3,4},{1,2,4,8}};
(2)int brr[2][3] = {1,2,3,4,5,6};
(3)int crr[2][3] = {{1,2},{3}};
(4)int drr[2][3] = {1,2,3};
(5)int err[2][3] = {1,2,3,4,5,6,7};//警告
(6)int frr[2][3] = {{},{},{}};//警告 多了警告 少了补0
(7)int grr[2][3] = {0};//全部初始化为0
(8)int hrr[2][3] = {};//全部初始化为0
(9)int irr[2][3] = {[0][1]=1,[1][2]=100};//给指定元素赋值,其余为0
(10)int jrr[][] = {1,2,3,4,5,6};//不可以 错误的