1. 流程控制->循环控制语句->嵌套循环
- 嵌套循环: 是指一个循环结构A的循环体是另一个循环结构B。
//如:
for(;;){
for(;;){
}
}
- 实质:嵌套循环就是把内层循环当成外层循环的循环体,只有当内层循环的循环条件为false(值0)时,才会完全跳出内层循环,从而结束外层当次循环 ,开始下一次外层循环。
- 技巧: 从二维图形角度看,外层控制行数,内层控制列数
- 开发经验: 实际开发中,多两层循环,一般不会超过三层循环,超过三层,可重新梳理业务逻辑,思考算法实现。
- 执行特点:外层循环执行一次,内层循环执行一轮
2.流程控制->循环控制语句->break和continue
2.1使用说明
关键字 | 适用范围 | 循环结构中的作用 | 相同点 |
---|---|---|---|
break | switch-case | - | - |
break | 循环结构 | 一旦执行,就结束(或跳出)当前循环结构 | 此关键字的后面,不能声明语句 |
continue | 循环结构 | 一旦执行,就结束(或跳出)当次循环结构 | 此关键字的后面,不能声明语句 |
2.2 goto关键字
goto 标号;
//其中标号属于标识符,以":"为标记,位于某语句前面。
标号: 语句块;
执行 goto语句后,程序将跳转指定标号执行,这样可以随意将控制语句转移到程序中任意一条语句块上,然后执行。
-
实际使用中,goto语句通常会与条件语句配合,实现条件转移,跳出循环体等功能。
//无限循环 int main() { loop_label:printf("Hello, world!\n"); goto loop_label; return 0; }
3. 数组
3.1 数组的概念
数组(array): 是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,通过编号的方式对这些数据进行统一管理。
数组四要素: 数组名, 下标(或索引、index),元素, 数组的长度。
-
数组特点: ①数组中的元素在内存中时依次紧密排列的,有序的。 ②创建数组对象会在内存中开辟一整块连续的空间,占据空间的大小,取决于数组的长度和数组中元素的类型。
③数组一旦初始化完成,其长度就是确定的,数组的**长度一旦确定** ,就不能修改。 ④数组名中引用的是这块连续空间的首地址。
3.2 数组的分类
按照数组维度分:
- 一维数组:存储一组数据
- 二维数组:存储多组数据,相当于二维表,一行代表一组数据,每一行长度可以不同。
按照元素的数据类型划分:
- int类型数组
- char类型数组
- double类型数组
3.3 数组的操作
①如何定义数组
(1)先制定元素的个数和类型,再进行初始化(先声明,再进行初始化赋值)
(2) 指定元素的类型和个数并同时初始化(声明并同时初始化赋值)
(3) 指定元素类型,不指定元素个数,同时进行初始化(声明是不指定长度,必须同时进行初始化赋值)
②访问数组元素
(1) 修改其中某个元素的值
(2) 通过下标读取指定元素的值
(3) 访问越界
(3) 计算数组的长度
(4) 遍历数组
③数组越界
访问超出下标范围的位置,得到随机值,访问的是数组以外的内存
④数组的长度计算
sizeof 数组名/sizeof 数组名[0]
sizeof 数组名/sizeof(数据元素的类型)
⑤遍历数组
使用循环,让循环控制变量作为下标,循环控制变量从0到长度-1。
for(int i = 0;i<数组长度;i++){
数组名[i];
}
4. 字符数组(字符串)
①字符串的的本质
1. 字符串就是字符数组。每个数组元素是char类型
2. 作为字符数组的特殊性:
具有专门的占位符%s。
字符数组的最后一个元素是\0,是字符串结束标记。
②如何定义字符串
1.跟定义数组相同,需要设置字符串结束标记
2. 定义字符串的简化写法(双引号写法),自动添加字符串结束标记
③字符串的访问和遍历
可以通过下标访问字符串的中的各个字符。
5. 多维数组
①概念
1.如果数组的元素还是数组,这样的数组就称为多维数组
2.多维数组可以分为二维数组、三维数组、四维数组...等
3. 可以把二维数组想象成表格形式,相关概念有行数、列数、行下标、列下标
②二维数组定义
// 定义一个4行6列的二维数组,以为矩阵的形式初始化
int a[4][6] = {
{10, 20, 30, 30, 40, 60},
{100, 200, 300, 400, 500, 600},
{1000, 2000, 3000, 4000, 5000, 6000},
{10000, 20000, 30000, 40000, 50000, 60000}
};
// 定义一个4行6列的二维数组, 会自动匹配到各行各列
int b[4][6] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
// 省略行下标
int b[][6] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
③二维数组的访问和遍历
行下标
列下标
④二维数组的内存形式
内存中是线性存储,先存储第一行的元素,再依次存储
4.函数
1. 函数的基本概念
①什么是函数
函数是一种可重复执行的代码块,用于执行特定的任务或操作
②函数的分类
库函数: 内置函数,由系统提供,会定义在标准库头文件。
自定义函数
③函数四要素
1.函数名: 是个标识符,需要符合标识符规范。
2.函数体:函数代码块,负责实现具体的功能。
3.参数:需要传入函数体的数据。
4.返回值:作为函数提的计算结果,定义函数时需要在函数名的前面指定返回值类型。
2. 函数的基本语法
①声明函数(定义函数)
1.定义函数时需要指定函数名、参数、函数体、返回值、以及返回值类型。
2.定义函数最少可以指定函数名和函数体体(有{}就有函数体了);参数和返回值可以没有。
3.没有返回值的函数,定义函数时,函数的前面需要使用void 关键字指定返回类型。
②调用函数
1. 函数体代码块语句只有调用才会被执行,且调用一次就执行一遍。
2.函数名和小括号组成一个表达式(函数调用表达式),该表达式的值是函数的返回值。
3.只有函数名加小括号才是调用函数,光一个函数名无法调用函数
③返回值
1.函数体中,return 右边表达式的值就是函数的返回值。
2.return右边表达式的值的类型,应该与函数名前面指定的返回值类型保持一致,如果不一致,会自动转为函数名前面指定的类型。
3.函数体中没有return或者return的右边是空的,表示没有返回值;函数名前面使用void指定返回类型。
4.函数体中一旦执行到了return 语句,表示函数结束,后面语句将不再执行。
④参数
1.形参
定义函数所设置的参数:形参本质上就是变量,只能在函数类使用
2.实参
调用函数时所传递的参数,实参用于给形参赋值,实参数量要与形参数量保持一致,否则会报错。
注意:调用函数的时候,实参个形参赋值,实参是右值,形参是左值。
3. 主函数
①主函数的返回值
C语言约定,主函数默认返回值0表示运行成功,如果返回其他非零整数,就表示运行失败,默认情况下,如果主函数里面忽略return 0这一行,编译器会自动加上,即main()的默认返回值为0,但为了保持统一的代码风格,不建议省略。
②主函数参数
参数一:命令选项的数量。
参数二:由所有命令选项组成的数组
4.函数原型
1.如果想把函数定义语句写在函数调用的语句后面,可以在调用语句的前面使用函数原型提前声明函数。
例子: int max(int,int);
2.函数原型需要指定函数的返回类型、函数名、参数类型、不需要设置函数体和参数名字。
5.作用域
①作用域的概念
1. 作用域用于确定在代码中某个标识符(如变量、标识符常量、数组等)的可见性和访问范围,它决定在程序的哪些部分可以引用或访问该标识符。
2.函数原型需要指定函数的返回类型、函数名、参数类型,不需要设置函数体和参数名字。
②全局作用域
1.在函数和代码块(分支语句、循环语句等)以外的定量、标识符常量、数组等具有全局作用域、在程序的任何地方都可以被访问,通常称他们为全局变量、全局常量、全局数组等。
2.全局的标识符如果没有初始化赋值,系统会自动初始化为0
③局部作用域
1.在函数内定义的数量、标识符常量、数组等具有局部作用域,只有在该函数内部才能被访问,通常称他们为局部变量
2.局部的标识符没有初始化,系统不会自动初始化,内存是原来的内容。
3.函数的参数是局部变量,只能在函数内部使用。
4.当使用某个标识符的时候,先在所在作用域中查找,如果能找到就使用;如果所有作用域中没有定义,去上层查找,一直到全局。
C语句中,函数的上层作用域就是全局!与函数调用的位置无关!
④块级作用域
1.在代码块(分支、循环语句等)中定义的变量、标识符常量、数组等具有块级的作用域,只有在该代码块内部才能被访问,代码块通常具有{}结构。
2.具有块级作用域的标识符,特点同局部。具有块级作用域的标识符也可以被称为局部变量、局部常量、局部数组等。
⑤作用域和内存
变量(标识符常量、数组等)的内存存储区域:
内存区域 | 存放数据 |
---|---|
栈区(Stack) | 局部变量(局部标识符常量、局部数组) |
全局静态区 | 全局变量(全局标识符常量、全局数组) |
堆区 | ....... |
代码区具有 | ....... |
变量(标识符常量、数组)的生命周期
局部:函数调用结束或代码块执行结束。
全局:整个程序结束
⑥作用域总结
1.可作用范围
2.是否自动初始化
3.内存存储区域(栈、全局静态区)
4.生命周期
6.static和extern关键字
①静态局部变量(标识符常量、数组)
1.局部变量(标识符常量、数组)的声明语句前面添加static关键字,就表示定义了静态局部变量
2. 静态局部变量的特点:
①可作用范围仍然是所在函数(局部)
②如果没有初始化。系统会自动初始化为0(同全局)
③存储在内存的全局静态区(同全局)
④函数调用结束不销毁,直到程序执行结束(同全局)
② 声明其它源文件的标识符
1.一个C项目文件可以包含多个C源文件,该项目下所有源文件会共同编译成一个可执行程序。
2.同一个项目,只能有一个主函数。
3.如果要使用其它同一个项目中的源文件中定义的全局变量(全局表示符),需要在本源文件中使用extern关键字声明全局变量(声明外部全局标识符)
注意:当前源文件和其他文件不能有同名标识符,不然两个文件无法编译成同一个执行文件,但是其中一个标识符是静态的话,编译可以通过,当有静态的全局标识符源文件执行时,里面的函数调用的就是当前静态全局变量,非引入的外部变量。
③静态全局变量(静态全局标识符)
1.静态全局变量(静态全局标识符)仅对当前源文件可见
2.静态全局变量对于需要编译多个源代码文件的程序,能够有效降低源文件之间的耦合,避免不同文件同名变量
④静态函数
同静态全局变量
总结
可作用范围 | 是否自动初始化 | 内存存储区域 | 生命周期 | |
---|---|---|---|---|
局部变量 | 所在的函数或代码块 | 否 | 栈 | 函数调用结束 代码块执行结束 |
静态局部变量 | 所在的函数或代码块 | 是 | 静态区 | 整个程序 |
全局变量 | 全局(整个程序) | 是 | 静态区 | 整个程序 |
静态全局变量 | 全局(整个源文件) |