C语言基础(一)——函数和数组
iwehdio的博客园:https://www.cnblogs.com/iwehdio/
导图
1、函数
函数:一块代码,接收零个或多个参数,进行一些操作并返回零个或一个值。
-
函数的定义:
- 函数头:格式为
返回类型 函数名(参数列表)
。- 返回类型,void表示没有返回值。
- 函数名,调用函数时使用的名称。
- 参数列表:参数类型1 参数名1, 参数类型2 参数名2 。
- 即使没有参数列表,定义和调用函数时也要加 圆括号 ( ) 。
- 函数体
- 函数头:格式为
-
函数的调用:
- 格式:
函数名(参数值)
。 - 圆括号 () 起到了表示函数调用的作用。
- 如果有参数,则需要给出正确的数量和顺序。这些值会被按照顺序依次用来初始化函数中的参数。
- 函数知道每次是哪里调用它,会返回调用它的下一步。
- 格式:
-
函数的返回:
-
格式:
return;
或return 表达式;
。 -
return 停止函数的执行,并送回一个值。
-
这个返回的值可以赋值给变量,也可以再传递给函数。
-
一个函数中可以有多个 return 。
-
返回类型为 void 的不能使用带值的 return,也可以不使用return 。
-
如果函数有返回值,必须使用带值的 return。
-
-
函数的先后关系:
- 函数的定义要在调用之前,因为C编译器自上而下顺序执行。
- 也可以先将函数头放在调用之前,以分号结尾,称为函数的原型声明。
- 函数的原型声明和函数定义的函数头必须一致。
- 函数原型告诉编译器函数的名称、返回类型和参数类型。
- 函数原型中参数可以只写类型,不写名称。也可以名称不一致。
-
参数传递:
- 可以传递给函数的值时表达式的结果,包括字面量、变量、函数返回值和计算的结果。
- 如果传入的参数与函数定义的参数类型不同,会发生自动类型转换(C++/Java不会)。
- C语言在调用函数时,永远只能传值给函数。
- 每个函数每次运行时有自己的变量空间,参数也位于这个独立的空间中,和其他函数没有关系。
-
本地变量(局部变量):
- 函数的每次运行,就产生了一个独立的变量空间,在这个空间中的变量,是函数的这次运行所独有的,称作本地变量
- 定义在函数内部的变量就是本地变量,参数列表中的参数也是本地变量。
- 对于本地变量,其生存期和作用域都是,变量所存在的大括号内——块。
- 生存期:什么时候这个变量开始出现了,到什么时候它消亡了;
- 作用域:在(代码的)什么范围内可以访问这个变量(这个变量可以起作用)。
- 本地变量是定义在块内的。
- 它可以是定义在函数的块内,也可以定义在语句的块内,甚至可以随便拉一对大括号来定义变量(代码块)。
- 程序运行进入这个块之前,其中的变量不存在,离开这个块,其中的变量就消失了。
- 块外定义的变量,在块内仍然有效。
- 如果块内定义了与块外同名的变量,则块内的变量会覆盖块外的变量。
- 本地变量不会被默认初始化,参数在进入函数时会被初始化。
-
函数的其他问题:
- 函数如果没有参数,参数列表应写 void ,不写参数表示的是不确定会传入怎样的参数。
- C语言不允许函数的嵌套定义。
- main 函数如果确定没有参数,可以写参数 void 。
- main 函数的 return 0 是有意义的,表示程序运行正常。
2、数组
数组是一种容器,用来盛放数据。
-
数组的特点:
- 其中所有的元素具有相同的数据类型;
- 一旦创建,不能改变大小;
- 数组中的元素在内存中是连续依次排列的。
-
数组的定义:
- 定义格式:
元素类型 变量名称[元素数量]
。 - 元素数量必须是整数,C99之前元素数量必须是字面量。
- 定义格式:
-
数组的索引:
-
数组的每个单元就是数组类型的一个变量;
-
使用数组时放在 [ ] 中的数字叫做下标或索引,下标从0开始计数,到数组的规模减一;
-
索引格式:
数组名称[索引值]
; -
数组索引可以出现在赋值的左边或右边,称为左值或右值。
-
编译器不会检查数组下标越界,需要在程序中保证数组下标不会越界。
-
-
数组的初始化:
- 在数组使用前,对数组中每个单元赋初值。
- 数组的集成初始化:
元素类型 变量名称[]={数组中的值}
。 - 数组的大小就等于集成初始化在的值的个数。
- 如果
int a[10]={2}
,表示第一个元素是2,其他元素是0。 - 在C99中,可以使用定位初始化
int a[10]={[1]=2, 4}
,表示索引为1的元素为2,索引为2的元素为4,也可以不指定数组大小10,会根据所指定的最大索引创建。
-
数组的大小:
sizeof(数组名)
得到的是数组中所占据的字节数。- 获取数组的大小:
sizeof(a)/sizeof(a[0])
。
-
数组的整体赋值:
- 不能直接赋值,只能通过遍历数组。
-
数组作为函数参数:
- 函数头中的参数:
元素类型 数组名[]
。 - 不能再使用 sizeof 函数计算数组元素个数。
- 必须再用另一个参数传入数组的大小。
- 函数头中的参数:
-
二维数组:
- 定义格式:
元素类型 数组名[m][n]
,可以理解为m行n列的矩阵。 - 列数n必须给出,行数m可以由编译器数出。
- 每行一个大括号 {} ,用逗号分隔。也可以没有大括号按序排列。
- 如果省略则表示补零,也可以用定位初始化。
- 定义格式:
-
数组的例子:找出小于某个数的所有素数。
#include <stdio.h> int isPrime(int x, int knownPrime[], int length){ int res = 1; int i; for(i=0; i<length; i++){ if(x % knownPrime[i] == 0){ res = 0; break; } } return res; } int main(void){ const int number = 30; int logPrime[30] = {2}; int count = 1; int i = 3; while(number > count){ if(isPrime(i, logPrime, count)){ logPrime[count++] = i; } i++; } int j; for(j=0; j<number; j++){ printf("%d", logPrime[j]); printf(" "); } }