自学者的C语言笔记(上)
一、声明
- 如果文章中出现一些日期,后面带着编码的是正常的,应该当时我自学C语言的时候,分成了半个月来学,每天学一点就做一点笔记😊,所以就会用日期区分(虽然我在发文章之前删了,但也有可能会有漏网之鱼💀)
- 如果在看文章的时候,看到有时候出现重复的知识点,是我在学后面的知识的时候忘记前面了😰,所以又补充了一次笔记,不需要的话可以跳过
- 这一次的笔记,只是一半,后面我在整理一下后面的笔记,在发布
二、正式笔记
1. 说明 / 特殊便利小操作
| 操作 | 说明 |
|---|---|
| 创建 C 语言文件 | 文件的创建只能在 “源文件” 中创建右键 “源文件” - 添加 - 新建项 - 修改 “文件名” 与 “后缀”(C 语言,后缀是 .c) |
| 列块选中 | 按住 alt 不送手,鼠标左键选中,你先选中的内容 就会选中 |
| 修改编辑器字体大小 | 工具栏上的工具 - 选项 - 环境 - 字体和颜色 永久调节文字大小 / 字体 |
2. 函数 / 代码
| 作用 | 语法 | 说明 |
|---|---|---|
| 预处理 | #include <stdio.h> | - #include:找- <stdio.h>:标准输入输出(黑屏)【提前找到 stdio.h 这个文件】 |
| 程序主入口 | int main() { 操作代码; return 0; } | - int:整个程序的运行结构是一个整数- main ():程序执行的入口,具有唯一性、不可更改性 (int main ():程序主入口)- return 0 :return 程序结束了,0:正常结束,非 0:异常结束【前面是 int,后面返回就一定要是整数,要呼应】【一定要加分号】 |
| 输出语句 | printf("你好,C语言") | 输出内容 |
| 单行注释 | // 注释信息 | 注释是:程序中解释说明性的文字,作用:提高代码的阅读性 |
| 多行注释 | /*注释信息*/ | - |
3. C 语言文件执行流程
| 过程 | 说明 |
|---|---|
| 编写 | 在 vs 平台上,编写的 C 语言文件 HelloWorld.c |
| 编译 | 1. 将 HelloWorld.c 文件翻译成 HelloWorld.obj 文件2. 找到其他需要用到的文件,如 stdio.h 文件 |
| 链接 / 连接 | 将编译所有找到、生成的文件,打包成一个 HelloWorld.exe(可执行文件) |
| 运行 | 运行 HelloWorld.exe(可执行文件) |
查询:
运行后,在总项目右键 - 在文件资源管理器中打开(在系统文件路径中打开)‑ 可以看到运行后,新增的文件
可以在路径栏中输入 cmd,进入控制台,输入可执行文件名 HelloWorld.exe,回车,就可以运行了
在源文件,如果有多个文件,有多个 main () 主入口,会报错,只能注释掉只剩下一个 main ()
1. 注释
| 说明 / 作用 | 操作 |
|---|---|
| 注释添加快捷键(单行光标点到哪一行,多行要全选中) | ctl+K + ctl+C |
| 注释取消快捷键(单行光标点到哪一行,多行要全选中) | ctl+K + ctl+U |
| 注释擦除 | 在.c 文件翻译成.obj 文件时,是不会翻译注释的【注释擦除:注释的内容,不参与运行】自动运行,不用手动操作 |
| 注意 | 注释最好不要嵌套,特别是多行注释(因为它只会找离自己最近的结束注释) |
2. 关键字
- 关键字定义:被 C 语言赋予了特定含义的英文单词
- 关键字的特点
- 关键字字母全部小写
- 常用的代码编辑器中,针对关键字有特殊的颜色标记,如蓝 / 紫色
3. 常量
- 常量的定义:在程序执行过程中,其值不能发生改变的数据
常量的分类
| 常量类型 | 说明 | 举例 |
|---|---|---|
| 整型 | 正数、负数、0 | 12、15 |
| 实型 | 所有带小数点的数字 | 1.23 、1.34 |
| 字符 | 单引号引起来的单个的大小写字母、数字、英文符号 (连空格都没有 / 羊角符号的单引号会报错,但如果中间有空格是字符常量) | ‘A’,‘B’ |
| 字符串 | 双引号引起来(对里面的内容没有要求) | “我讨厌你” |
常量的补充细节
| 定义 | 举例 |
|---|---|
| 实型常量小数点前后为 0,可以省略 | .93 等同于 0.93 |
| 科学计数法是实型常量,但是要写 E | 1.2340000 * 10^7:不是常量,是一个计算的过程1.2340000E7:实型常量 |
4. 函数 printf ()
- 作用:打印文字
- 格式:
printf(参数1,参数2)- 参数 1 (必填):输出内容的最终样式,以字符串的形式体现
- 参数 2(选填):填补内容(在使用占位符时,使用)
- 【不进行特殊处理,默认会打印在同一行里】
- 举例:
printf("最终结果:%d",18+18)输出:最终结果:36
占位符 / 格式控制符
| 占位符 | 说明 | 英文单词 |
|---|---|---|
| %d | 整型 | decimal |
| %f | 实型(默认保留小数点 6 位) | floating‑point |
| %c | 字符 | character |
| %s | 字符串 | string |
其他补充
| 补充 | 说明 | 例子 |
|---|---|---|
| 输出多个常量 | 利用占位符的形式进行输出,但是占位符和填补的数据要一一对应 | printf("我的好朋友叫:%s ,今年%d岁了","小光",18); |
| 让多个 printf () 换行输出 | 直接在 printf () 后面写\n就可以了(但是在不同的操作系统里面,\n 会被转换成对应操作系统的换行符) | printf("我的好朋友叫:%s\n","小光");``printf("今年%d岁了\n", 18); |
\n 在不同操作系统下真正转换成的换行符
| 操作系统 | 换行符 |
|---|---|
| windows | \r\n |
| mac (苹果) | \r |
| Linux | \n |
1. 变量
经常发生改变的数据可以定义为变量(在 C 语言中,所有执行代码都必须写在函数内部,一般是在 main () 里面)
| 格式 / 说明 | 例子 |
|---|---|
| 变量的定义:数据类型 变量名; | int a; |
| 变量的使用① 赋值 / 修改值② 获取值 | ① a = 10;② 直接使用 |
| 细节 | ① 一定要先定义,后赋值,否则会报错② 在明确变量的值时,数据类型 变量名 = 数据值;(定义 + 赋值) |
补充小细节:在 VS 中,变量可以写在函数内的任意位置;但在 VC 中,变量需统一的定义写在函数最上面,再开始使用
变量的注意事项
| 注意事项 | 报错 / 举例 |
|---|---|
| 1. 变量只能存一个值,再次赋值,会覆盖前面的值 | - |
| 2. 变量名不允许重复定义,会报错的 | C2374 报错:多次初始化 |
| 3. 一条语句可以定义多个变量 | int e = 2 , d = 3; |
| 4. 变量使用之前一定要进行赋值,会报错 | C4700 报错:使用未初始化 / 未定义 |
| 5. 变量的作用域范围 | - |
2. 计算机的存储规则
① 二进制的含义
存储有种类有:Text 文本(字母、数字、汉字)、Image 图片、Sound 声音
| 十进制 | 二进制 | 举例 |
|---|---|---|
| 逢十进一 借一当十 | 逢二进一 借一当二 | 二进制0 = 01 = 12 = 1 + 1 = 10 (逢二进一)3 = 2 + 1 =10 + 1 = 114 = 3 + 1 = 11 + 1 = 100 |
在计算机电路板中,以 1.5V 作为分界点,小于 1.5V 是 0,大于 1.5V 是 1
② Text 文本转换成二进制的过程
| 内容 | 转换工具 |
|---|---|
| 数字 | 直接通过换算关系转换 |
| 字母、英文符号 | 通过查询 ASCII 码表,获得其对应的二进制【在这个码表中每一个字母跟唯一的一个数字产生对应关系】 |
| 汉字 | 通过查询表获得的(window 默认是 GBK 编码表)【在这个码表中每一个汉字跟唯一的一个数字产生对应关系】 |
字母、汉字:计算机无法直接将字母转换成二进制
数字的转换,不想手动计算,可以使用电脑的计算器
电脑的 “程序员” 状态的计算器(点重那个进制,就只能输入对应进制的数值)
HEX:十六进制 DEC:十进制 OCT:八进制 BIN: 二进制
1. 图片在计算机里的存储
| 组成 | 含义 |
|---|---|
| 分辨率 | 1920 * 1080:宽有 1920 个小格子,高有 1080 个小格子,每一个小格子就是一个像素(方格的总数就是分辨率) |
| 像素 | 一个个小方格,1920 * 1080 表示一共有 2304000 个像素 (像素越多,分辨率越大,显示的图片就越清晰) |
| 光学三原色 | 红绿蓝(也叫 RGB 三原色),三种颜色可以组成各种颜色,值越大,颜色越浓(取值范围在 0~255 内) |
2. 声音存储
- 对声音进行采样,采样频率:一般是 44.1kHz(44100 次 / 秒),低于它就是全损音质
- 将数据绘制成采样波形图(由每一个采样数据‑小黑点组成,每个小黑点都对应着一个二进制)
- 采集的数据越多,小黑点就越多,音质效果就越好,但同样它的存储文件大小就越大
3. 进制
八进制、十六进制怎么来的(解决二进制太长,不方便阅读的原因)
| 八进制 | 十六进制 |
|---|---|
| 三个二进制分为一组范围:最小值 000,最大值 111(0~7) | 四个二进制分为一组范围:最小值 0000,最大值 1111(0~15) |
代码的书写:定义不同进制变量书写(字母大小写都行)
| 进制 | 规则 | 代码演示 |
|---|---|---|
| 二进制 | 由 0 和 1 组成,代码中以 0b 开头 | int a = 0b10; |
| 八进制 | 由 0~7 组成,代码中以 0 开头 | int a = 010; |
| 十进制 | 由 0~9 组成,前面不加任何前缀 | int a = 10;(可省略) |
| 十六进制 | 有 0~9 还有 a~f 组成,代码中以 0x 开头 | int a = 0x10; |
- 占位符
%d,打印出来的会把其他进制的变量,转换成十进制再打印出来 - 在书写时,不仅要看前缀,还要看后面的数据是否符合要求
进制转换
| 公式 | 例子 |
|---|---|
| 任意进制转十进制公式:系数 * 基数的权次幂 相加系数:就是每一位上的数基数:当前进制数权:从右往左,依次为 0,1,2,3… | 八进制 101 = 1 * 8^2 + 0 * 8^1 + 1 * 8^0 = 64+0+1=65 |
| 二进制转十进制【8421 快速转换法】其实,记下 2 的各种次方,将二进制和 2 的 0 次方对齐,直接把 1 的部分的数字相加,0 不管 | 1101 = 8+4+0+1 = 13 |
| 十进制转换成其他进制不断地除以基数(几进制,基数就是几)得到余数,直至商为 0,再将余数倒着拼接起来即可 | 十进制 11 -> 二进制 1011 |
4. 数据类型
- 作用说明
- 变量中能存储什么类型的数据
- 存储的空间的大小,不同数据类型(如 int),所规定占据的固定字节都不一样
关于存储说明:计算机都是由二进制存储的,每一个 0 或 1,都是一个比特位(bit);计算机中,将 8 个 bit 组成一个字节,这是计算机中最小的存储单元;选中文件,右键属性,可以查看这个文件占了多少字节。
存储单位说明
1024 字节 = 1KB
1024KB = 1MB
1024MB = 1GB
1024GB = 1TB
1. 整数类型
| 类型 | 代码写法 | 说明 |
|---|---|---|
| short 短整型 | short a = 10; | windows 2 个字节(‑32768 ~ 32767) |
| int 整数 | int b = 100; | windows 4 个字节(‑2147283648 ~ 2147483647)【C 语言的默认类型】 |
| long 长整数 | long c = 1000L;``printf("%ld\n",c); | windows 4 个字节(‑2147283648 ~ 2147483647)Linux 32 位 4 字节 64 位 8 字节【没写后缀,默认隐形转成 int 不报错,但超过 int 类型范围报错,后缀大小写不限】【但是打印时,占位符不同了】 |
| long long 超长整数 | long long d = 10000LL;``printf("%lld\n",d); | windows 8 个字节(19 位数)【没写后缀,默认隐形转成 int 不报错,但超过 int 类型范围报错,后缀大小写不限】【但是打印时,占位符不同了】 |
- 不同的数据类型所表述范围和内存大小都不一样,由编译器来决定,可以用 sizeof 确定,但遵守原则:
short <= int <= long <= long long
测试其占用字节
| 代码 | 说明 |
|---|---|
printf("%zu\n", sizeof(short)); | sizeof(变量名 / 数据类型),占位符也是特定的 |
数据格式的完整形态
| 不完整 | 完整格式(但 int 可以不写) |
|---|---|
short a = 10; | short int a = 10; |
int b = 100; | - |
long c = 1000L; | long int a = 10; |
long long d = 10000LL; | long long int a = 10; |
有符号整数、无符号整数的定义
| 代码书写 | 说明 |
|---|---|
signed 有符号整数(正数 负数)signed int e = -100; printf("%d\n", e); | - |
unsigned 无符号整数 (正数)unsigned short num1 = 1234; printf("%u\n",num1); | 打印占位符:% u【short:‑32768 ~ 32767】【unsigned short:0~65535】 |
1. 小数类型
要点
- 同样的不同的数据类型所表示范围和内存大小不一样,有编译器决定,可以用 sizeof 函数决定(window 中 float(4 字节)double(8 字节))
- 小数的取值范围比整数要大
- C 语言中的小数默认 double 类型
- 小数 不可以和 unsigned 组合,unsigned 只能和整数类型组合
写法:保留 n 位小数,就是在占位符的 % 后,写.n,如%.nf
| 小数类型 | 代码写法 | 说明 |
|---|---|---|
| float 单精度小数(精确度小数点后 6 位) | float a = 3.14F; printf("%.2f\n",a); | 1. 要有后缀 F2. 占位符是 % f,保留 n 位小数%.nf |
| double 双精度小数(精确度小数点后 15 位) | double b = 1.24; printf("%.2lf\n",b); | 占位符是 % lf,保留 n 位小数%.nlf |
| long double 高精度小数(精确度小数点后 18~19 位) | long double c = 3.1234234L; printf("%.2lf\n",c); | 1. 要有后缀 L2. 占位符是 % lf,保留 n 位小数%.nlf |
2. 字符类型
| 代码写法 | 说明 |
|---|---|
char a1 = '1'; printf("%c",a1); | 取值范围:ASCII 码表中的字母、数字、英文符号,在 windows 中,所占用内存为 1 |
3. 数据类型小结
- 数据类型在内存占比都是不确定的,可用 sizeof 函数确定
- 后缀:long(L)、long long(LL)、float(F)
- 取值范围:
double>float>long long>long>int>short - unsigned 只可以跟整数组合,占位符是 % u
4. 标识符
标识符的定义:代码中所有我们自己起的名字。比如变量名,函数名等
命名规则(硬性要求)
- 由数字、字母、下划线( _ )组成
- 不能以数字开头
- 不能是关键字(但是一旦英文单词是大写,它就不是关键词)
- 区分大小写
命名规则(软性建议)
- 用英文单词,见名知意
- 变量名:全部小写
- 代码文件名:全部小写,单词之间用下划线隔开,开头可以用数字(如
01_hello_world.c)
1. 键盘录入
- 说明:键盘录入函数是:
scanf("占位符",&变量名) - 作用:接收用户键盘输入的数据并赋值给对应的变量
- 注意:
- 占位符要个后面的变量一一对应
- 第一个参数尽量只写占位符
- 直接使用会报错(方法:1. 加上
#define _CRT_SECURE_NO_WARNINGS每个文件都要 2. 要么修改全局预处理器)
- 顺序:定义变量 ‑ scanf 函数获得键盘输入 ‑ 打印
# define _CRT_SECURE_NO_WARNINGS
# include <stdio.h>
int main() {
// 1. 定义一个变量来接收数据
int a;
// 2. 键盘录入
printf("请输入一个整数");
scanf("%d", &a);
// 3. 打印一下
printf("变量a里的值为:%d\n",a);
return 0;
}
想要全局都可以使用 scanf,但不用加# define _CRT_SECURE_NO_WARNINGS
做法:右键总项目名 ‑ 属性 ‑ 配置属性 ‑ C/C++ ‑ 预处理器 ‑ 预处理器定义 ‑ 编辑 ‑ 在下面添加_CRT_SECURE_NO_WARNINGS ‑ 确定
键盘输入多个数据(占位符的数量、类型,要个变量一一对应)
输入时,输入完第一个数,可以选择空格 / 回车,间隔输入下一个数字
【间隔可以是空格,数字,逗号等,但是同一行输入除了空格可以替换用回车,其他间隔是什么,你就要原封不动写什么】
scanf("%d %d",&a,&b);
2. 函数
- 定义字符串变量:
char 变量名[所占用内存大小] = 字符串; - 内存占用大小的计算方法:
英文:1 个字母、符号、数字占用一个字节
中文:在 vs 或 vc 中,默认,一个中文占用 2 个字节
结束标记:1 个字节
3. 算术运算符
| 符号 | 说明 |
|---|---|
| + | 加 |
| - | 减 |
| * | 乘 |
| / | 除 |
| % | 取余 |
细节
通用细节内容
- 整数计算,结果一定是一个整数
- 小数计算,结果一定是一个小数
- 整数和小数计算,结果一定是一个小数
- 小数直接参与计算,结果是有可能不精准的(涉及小数在计算机内的存储方式)
特殊运算符小细节
取余:
- 运算的数据必须全部是整数
- 获取余数的正负,是跟第一个数字保持一致的(10 % 3 = 1;‑10 % 3 =‑1;10 % ‑3=1)
- 不能除以 0
除法:不能除以 0
4. 数值拆分
| 要求 | 公式总结 |
|---|---|
| 输入一个 n 位数,将其拆分个位、十位、百位… | 个位:数值 %10十位:数值 / 10 % 10百位:数值 / 100 % 10千位:数值 / 1000 % 10… |
5. 隐式转换 (程序自动转换的)
取值范围从大到小:double > float > long long > long > int > short > char
| 内容 | 说明 |
|---|---|
| 隐式转换定义 | 不同的数据类型进行计算、赋值等操作,会触发隐式转换;把取值范围小的,转成取值范围大的(自动补零) |
| 规则 1 | 取值范围小的,和取值范围大的计算,小的会自动提升为大的,在进行运算 |
| 规则 2 | short char 类型的数据在运算的时候,先提升为 int,再进行运算;所以两个 short 类型的数据相加,等于的结果是 int 类型的 |
6. 强制转换(虽然 VS 也会帮你强制转换,但最好还是要自己手动书写)
| 内容 | 说明 |
|---|---|
| 强制转换定义 | 大的赋值给小的时候,需要强制转换 |
| 方法 | 目标数据类型 变量名 = (目标数据类型)原变量名例如:short i = (short)b``short result = (short)(s1 + s2) |
| 强制转换弊端 | 有可能会导致数据错误 |
1. 字符相加
字符跟数字相加:在计算过程中,计算机会查询 ASCII 码表,查询到这个字符的十进制,变成 int 数据类型,再进行计算
如果一个字符,以占位符 % d 进行打印:会进行查表,在打印出对应的十进制
2. 自增自减运算符
基础用法
- 说明:自增运算符:变量名的值 + 1;自减运算符:变量名的值 ‑ 1
- 单独使用:代码写法:
变量名--; / --变量名;变量名++; / ++变量名;
【++ 和‑‑放在变量的前面 / 后面,单独写一行结果是一样的】
【++/‑‑在前,先加后用;++/‑‑在后,先用再加】
扩展用法(写入到计算过程中的时候)
不论哪种操作系统,【++/‑‑在前,先加后用;++/‑‑在后,先用再加】
| 操作系统 | 核心运算规则(一句话概括) | 示例代码 | 运算逻辑说明 | 运行结果 |
|---|---|---|---|---|
| Windows | 先统一计算所有前缀自增减,表达式全部取值结束后批量执行所有后缀自增减 | int i = 10; int j = 5; int k = i++ + ++i - --j - i--; | 前缀 ++i 统一计算为 11,后缀 i++/i‑‑延后执行,先完成表达式所有取值再批量自增减 | 7 |
| Mac、Linux | 前缀、后缀优先级相同,严格从左到右逐个实时计算,无批量延后逻辑 | int i = 10; int j = 5; int k = i++ + ++i - --j - i--; | 从左到右依次执行,i++ 先取 10 再自增,++i 先自增为 12 再取值,依次实时计算 | 6 |
1. 赋值运算符
| 符号 | 说明 | 举例 |
|---|---|---|
| = | 直接赋值 | int a = 10,将 10 赋值给 a |
| += | 加后赋值(将左右相加,在赋值给左边) | a+=b,将 a+b 的值给 a |
| -= | 减后赋值 | a-=b,将 a‑b 的值给 a |
| *= | 乘后赋值 | a*=b,将 a*b 的值给 a |
| /= | 除后赋值 | a/=b,将 a/b 的值给 a |
| %= | 取余赋值 | a%=b,将 a% b 的值给 a |
2. 关系运算符
成立 1(真);不成立 0(假)【打印的占位符是 % d】
| 符号 | 说明 |
|---|---|
| == | 等于 |
| != | 不等于 |
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
3. 逻辑运算符
成立 1(真);不成立 0(假)【打印的占位符是 % d】
注意点
- C 语言中,不可以连起来写
1<a<3,只能分开1<a && a<3 - 多个数值连起来,可以不写空号
(a != 7 && a != 4 && a != 8) - 表达式中,只有
++b,表示只要在加完后,等于非 0 的值,就是 1,否则就是 0
| 符号 | 作用 | 说明 | 代码 | ||
|---|---|---|---|---|---|
| && | 与(而且) | 两边都为真,结果才是真(同时成立) | 1&&0,结果是假,不成立,自动返回 0 | ||
| || | 或(或者) | 两边都是假,结果才为假 (二选一) | `0 | 0`,结果是假,都不成立,自动返回 0 | |
| ! | 非(取反) | 【奇数!表取反,偶数!表不变】取反 | !0 = 1 |
扩展:短路效果
当左边的表达式能确定整个表达式的结果了,为了提高效率,右边就不会参与计算了(右边也就不会有任何数值变化)
4. 三元运算符
| 要点 | 说明 |
|---|---|
| 格式 | 关系表达式?表达式1:表达式2; |
| 计算步骤 | 1. 计算关系表达式的值2. 关系表达式成立,执行表达式 1;3. 不成立,执行表达式 2【我们可以将它返回的结果赋值给一个变量】 |
| 嵌套示例 | int result = (a > b ? a : b) > c ? (a > b ? a : b) : c; |
5. 逗号运算符(分隔符)
逗号运算符规则
表达式 1,表达式 2,表达式 3…,表达式 n
- 从左往右
- 最后一个子表达式的结果,是整个表达式的结果
- 优先级最低(永远最后执行)
int i; i = 3; ++i; i++; i + 5 完全等价于 i = 3,++i,i++,i + 5;
但是如果直接在打印函数中,传入表达式,要用括号括起来,因为逗号原本是占位符填充内容
printf("%d\n",(i = 3,++i,i++,i + 5));
其他小知识点:想区一个负数的相反数 - 变量名;
6. 运算符的优先级
所有运算符(优先级从高到低)
| 运算符 | 说明 | 元数 |
|---|---|---|
() | 括号 | 无 |
++、-- | 自增、自减 | 一元(只对一个变量进行操作) |
+、-、! | 正号、负号、逻辑非 | ‑ |
* 、/、% | 乘除取余 | 二元(需要两个变量才能进行操作) |
+、- | 加、减(和正号、负号长得一样) | ‑ |
>、>=、<、<= | 关系运算符 | ‑ |
==、!= | 等于 / 不等 | ‑ |
&& | 逻辑与 | ‑ |
|| | 逻辑或 | ‑ |
?: | 三元运算符 | 三元(需要三个变量才能进行操作) |
=、*=、/=、%=、+=、-= | 赋值运算符 | 无 |
, | 逗号运算符 | 无 |
记忆小技巧
- 小括号优先于所有
- 一元 > 二元 > 三元
&& > || > 赋值
7. 解题技巧
三元运算符的解题技巧
| 解题关键 | 例子 |
|---|---|
| 1. 从左边的第一个问号开始往后找冒号2. 如果过程中,遇到 n 个其他问号,那么要找的那个冒号,是第 n+1 个冒号 | x > h ? ( h > x ? w : x) : w |
很多逻辑运算符的解题技巧
| 解题关键 | 例子 | ||
|---|---|---|---|
| 1. 从优先级最低的运算符开始找,把整个的表达式分成 N 个小段2. 先找赋值运算符3. 再找 ||4. && | `int num = a | (b+c && b-c);`【成立结果是 1,不成立结果是 0】 |
8. 流程控制语句
流程控制语句:通过一些语句,控制程序的执行流程
| 分类 | 说明 | 细节 | 代码 |
|---|---|---|---|
| 顺序结构 | 从上往下依次执行,是程序默认的执行过程 | - | - |
| 分支结构 | 程序在执行的过程中出现了岔路 | 1. if 语句:作用:如果满足条件,才可以执行花括号里的指定代码,使用场景:某些代码,在满足条件的时候才执行第一种格式 (只能对单一条件进行判断):if (关系表达式) { 语句体; }第二种格式:if (关系表达式) { 语句体A; } else { 语句体B; }第三种格式:if (关系表达式) { 语句体A; } else if (关系表达式) { 语句体B } ................. else { 语句体C; }2. switch 语句作用:把所有的选择一一列举出来,根据不同的条件任选其一计算步骤:① 先计算表达式的结果 ② 拿着表达式的结果,再依次和 case 的值进行比较,有相等的值,就执行对应的语句 ③若所有 case 的值都不匹配,就执行 defaultswitch(表达式) {``case 值1:语句体; break;``case 值2:语句体; break;``.......``default: 语句体; break;``} | - |
| 循环结构 | - | - | - |
分支结构小细节
(1)if 结构
- 在 C 语言中,如果判断的结果是一个数字,非 0 表示条件成立,0 表示条件不成立
- 如果大括号里面的语句体只有一行,那么 大括号可以省略不写(建议不要)
- 对于一些异常数据,过滤的方法:① if 嵌套 ② 将对于过滤的异常数据写在最前面,if () 中
(2)switch 语句:
- 表达式:计算结果只能为(字符 / 整数)
- case:值只能是(字符 / 整数)的字面量,不能是变量
- case:值不允许重复
- break:表示终端,结束的意思,结束 switch
- default:所有情况都不匹配,执行该处的内容(default 可以写在任意位置,甚至可以省略不写)
字面量:裸写的数字、字符,在代码中写死,不能改
switch 和 if 的区别
- switch:有限个 case 进行匹配的情况,10 个左右
- if:一般是对一个范围进行判断
【switch 它的速度会快点,因为 if 还需要去依次比对,但是 switch 可以直接定位到】
case 穿透的规则
- 还是根据小括号中表达式的结果去匹配对应的 case
- 执行对应 case 里面的代码
- 如果在执行过程中,遇到了 break,那么会直接结束整个 switch;如果没有遇到 break,就会继续执行下面 case 中的代码,知道遇到 break,或者把整个 switch 中所有代码全部执行完了,才会结束
- 细节:case 穿透只会往下穿,不会回到上面
我们可以用 case 穿透,简化代码
switch (month) {
case 1:
case 2:
case 12: printf("冬季\n"); break;
case 3:
case 4:
case 5: printf("春季\n"); break;
}
9. 小细节
- 在 C 语言中,只有 main () 函数,在 C99 及之后标准,末尾没有写 return 0 会自动隐式补充,但其他函数会报错
1. 循环
定义
| 内容 | 说明 |
|---|---|
| 循环定义 | 重复的执行某件事情 |
| 需要的内容 | 1. 开始条件 / 初始化语句2. 结束条件 / 条件判断语句3. 控制开关(控制循环的次数)/ 条件控制语句4. 循环内容 / 循环体语句 |
C 语言的循环结构
| 循环结构 | 在 VS 格式 | 在 VC 格式 |
|---|---|---|
| for 循环 | for (初始化语句 ; 条件判断语句 ; 条件控制语句) { 循环体语句; } | (1)方法一:先定义初始化,循环内的初始化不写for ( ; 条件判断语句 ; 条件控制语句) { 循环体语句; }(2)方法二:先定义初始化,循环内的赋值int i; for ( i=1 ; 条件判断语句 ; 条件控制语句) { 循环体语句; } |
| while 循环 | 初始化语句 while (条件判断语句) { 循环体语句 条件控制语句 }【从上往下执行】 | - |
| do … while 循环 | 【从上往下执行】初始化语句 do { 循环体语句; 条件控制语句; } while (条件判断语句); | - |
for 循环的执行流程
- 执行初始化语句(只执行一次)
- 执行条件判断语句,看其结果是否成立
- 成立:执行循环体语句
- 不成立:结束循环
- 执行条件控制语句
- 回到②继续执行条件判断语句
写 for 循环的技巧
- 循环的开始条件
- 循环的结束条件
- 要重复执行的事情
- 每次循环结束之后,变量 i 如何改变
i++
for 循环的细节
- 变量的生命周期:变量只在所属的大括号中有效(局部变量 / 全局变量)
- 在循环中定义的变量,每一次循环结束都会被删除,从程序中消失
while 循环的细节
- while 循环的条件判断语句,是写循环在可以继续执行的情况
for 和 while 的区别
- for 循环中:知道循环次数或者循环的范围
- while 循环:不知道循环的次数和范围,只知道循环的结束条件
额外小知识点:计算机中的乘法和除法
- 乘法:
2 * 3 = 2 + 2 + 2 - 除法:
11 / 311 ‑ 3 ‑ 3 ‑ 3 = 2 【商:执行减法的次数,余:剩下的数字】
do…while 循环的小细节
- 从上往下执行,先执行后判断,循环体至少执行一次
1. 无限循环
无限循环定义:循环永远停不下来
注意点:无限循环因为永远停不下来,所以下面那不能再写其他的代码了
无限循环的三种格式
| 类别 | 代码 |
|---|---|
| for 循环 | for ( ; ; ) { 循环体语句; } |
| while 循环 | while (1) { 循环体语句; } |
| do … while 循环 | do { 循环体语句; } while (1); |
无限循环的停止方法
- 按 Ctrl + C
- 直接叉掉小黑屏
跳转控制语句
跳转控制语句的定义: 在循环的过程中,跳到其他语句上执行
| 语句 | 说明 | 代码 |
|---|---|---|
| break | 不能单独书写,只能写在 switch,或者是循环中,表示结束,跳出的意思【break:只能跳出单层循环】 | for (int i=1 ; i<=100 ; i++) { if (i == 5) { break; } } |
| continue | 只能写在循环中,结束本次循环,继续下次循环 | for (int i=1 ; i<=100 ; i++) { if (i == 5) { continue; } printf("%d",i); } |
| goto | 通过标号,我们可以跳转到任意代码行,并且它是无限次执行的【但一般,为了阅读性,只用于跳出循环嵌套】 | a: printf("你好"); goto a; // 回到 a标号的那一行 |
循环嵌套
| 说明 | 解释 / 代码 |
|---|---|
| 循环嵌套表现 | 循环里面还有其他循环格式// 外循环``for (int j = 1;j<=3;j++) {`` // 内循环`` for (int i = 1;i <= 5;i++) {`` printf("*");`` }`` printf("\n");``} |
| 思考小技巧 | 1. 先确定内循环是做什么事情2. 外循环其实就是把内循环里面的代码重复执行 N 次 |
小细节
- 制表符:
\t长度可变的大空格
原理:会根据前面字母的个数在后面补空格,让整体的长度达到 8 或者 8 的倍数,最少 1 个,最多 8 个
作用:打印表格数据的时候,可以对齐(不齐:可以添加多个 \t,如\t\t) - 想对修改一个全局的变量,可以按 2 次 ctrl+R,根据提示修改
通用小技巧:剥丝抽茧法
- 判断一个整数是否是一个
- 添加范围 1 ~ 100
- 统计
2. 函数
说明
| 说明 | 解释 |
|---|---|
| 函数的定义 | 函数就是程序中独立的功能【就是会反复书写的代码,又不确定什么时候会用到的代码打包起来】 |
| 函数的基本定义格式 | 【void:表示的是没有返回值的】void 函数名() { 函数体; }【定义函数,能不能写在其他函数内部,如 main () 里面】 |
| 调用函数格式 | 函数名();【要在主函数入口 main () 中调用】 |
| 带有参数的函数定义格式 | 【void:表示的是没有返回值的】void 函数名(形参1,形参2.....) { 函数体; }【形参:数据类型 形参名】 |
| 调用带有参数的函数 | 函数名(实参1,实参2....);【形参和实参一定要一一对应】 |
| 带有返回值的函数定义格式 | 返回值类型 函数名(形参1,形参2.....) { 函数体; return 返回值; }【返回值类型 和 返回值本身的数据类型 要相对应】 |
| 调用带有返回值的函数 | 数据类型 变量名 = 函数名(实参...);``printf("占位符",函数名(实参...));【返回值类型 和 返回值本身的数据类型 要相对应】 |
定义函数的终极绝招:问自己三个问题
- 我定义函数,是为了干什么事情? → 函数体
- 我干这件事情,需要什么才能完成? → 形参
- 我干完了,调用处是否需要继续使用? → 返回值类型;需要继续使用必须写 return;不需要返回 void 类型
函数的注意事项
- 函数不调用就不执行
- 函数名不能重复
- 函数与函数之间是平级关系,需要在上方申明
- 自定义函数写在 main 函数的下面,需要在上方申明,写在上面就不需要;声明:自定义函数最开头的那一行
int contains(int arr[], int len, int num) - return 下面,不能编写代码,永远执行不到,属于无效的代码
- 函数的返回值类型为 void,表示没有返回值,return 可以省略不写【如果书写了 return,后面不能跟具体的数据仅表示结束函数】
3. C 语言内部的函数
查找网址:http://zh.cppreference.com
注意点
- 想要使用 C 语言内置的函数前,要先导入这个函数所在的头文件,如
<math.h>
【 C 语言函数,会把同一类型的函数打包到同一文件中】# include <stdio.h>
内置函数
| 所属文件 | 常见函数 | 说明 |
|---|---|---|
<math.h> | pow() | 幂 |
| sqrt() | 平方根 | |
| ceil() | 向上取整(不管小数,直接进一) | |
| floor() | 向下取整 | |
| abs() | 绝对值 | |
<time.h> | time() | 获取当前时间;形参:表示获取的当前时间是否需要再其他地方进行存储,一般不用(我们可以传入 NULL(要大写));返回值:long long;结果:时间戳(从 1970 年 1 月 1 日 0:0:0 开始过了 1709817925) |
有意思的知识点:按住 ctrl,然后鼠标左键一点,可以反复点,不断找到你想找到 C 语言中层层嵌套的文件,但我很少用🤔
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)