0x00 前言概览
这个系列主要是整理 C 语言相关的一些知识,方便后期的复习与检索,适用者为学过基础的入门者编写程序时提供快捷便利的检索条件,纯小白可先收藏。此系列大致分为基础篇、进阶篇、高级篇,本文为基础篇,主要是一些零散知识点的整理,内容没有先后顺序,建议读者 Ctrl+F 查询;同时本着极简原则,一些知识点会直接举例说明。
0x01 切入正题
注释
1 | /*单多行注释*/ |
命名
编译器只识别前 63 个字符,对于外部标识符只允许使用 31 个字符(C99/C11);名称第一个字符必须是大小写字母或下划线,不能是数字,区分大小写,但标识符最好不要超过 8 位。
变量与常量
变量未初始化可能为 0 或垃圾值,不允许连续赋值,如 int a=b=c=5;
是不合法的。
1 | 定义常量: |
参数
实参是传递给函数的特定值;形参是函数中用于存储值的变量。
编译器
编译器报错的位置比真正的错误位置滞后一行;无法检测语义错误,即遵循了 C 规则,但输出结果错误。
使用调试器,通过跟踪程序执行步骤,记录每个变量,监视程序状态排错。
关键字和保留标识符
1 | auto 声明自动变量 |
1 | C99 新增关键字 |
基本数据类型及取值范围
注:ANSI 标准定义 int 是占 2 个字节,TC 是按 ANSI 标准的,它的 int 是占 2 个字节的。但是在 VC 里,一个 int 是占 4 个字节的。
类型转换
自动类型转换:如下图
强制类型转换:(数据类型) (表达式)
注:转换后不会改变原数据的类型及变量值,只在本次运算中临时性转换;强制转换后的运算结果不遵循四舍五入原则。
常用的算术转换是隐式地把值强制转换为相同的类型。编译器首先执行整数提升,如果操作数类型不同,则它们会被转换为上列层次中出现的最高层次的类型;常用的算术转换不适用于赋值运算符、逻辑运算符 && 和 ||。
printf
输出 double
和 float
都可以用 %f
混用,而 double
还可用 %lf
。而 scanf
输入情况下 double
必须用 %lf
,float
必须用 %f
不能混用。
格式符/占位符
sizeof
是内置运算符,以字节为单位给出指定类型的大小。C99 和 C11 提供 %zd
转换说明匹配 sizeof
的返回类型。一些不支持 C99 和 C11 的编译器可用 %u
或 %lu
代替 %zd
。默认右对齐,%-d
为左对齐。
转义序列
用于代表难以表示或无法输入的字符。
从 C90 开始,可以用十进制、八进制、十六进制形式表示字符常量。
运算符及优先级
注释:https://zh.cppreference.com/w/c/language/operator_precedence#cite_note-1
同一优先级的运算符,运算次序由结合方向所决定。
1 | 括号成员是老大; // 括号运算符 []() 成员运算符. -> |
循环
- 在没有循环结构的情况下,
break
不能用在单独的if-else
语句中。 - 在知道循环次数的情况下更适合使用
for
循环。 - 在不知道循环次数的情况下适合使用
while
或者do-while
循环。 - 如果有可能一次都不循环应考虑使用
while
循环。 - 如果至少循环一次应考虑使用
do-while
循环。
switch 语句时还应注意以下几点:
- 在
case
后的各常量表达式的值不能相同,否则会出现错误。 - 在
case
子句后如果没有break;
会一直往后执行直到遇到break;
才会跳出switch
语句。 switch
后面的表达式语句只能是整型或者字符类型。- 在
case
后,允许有多个语句,可以不用{}
括起来。 - 各
case
和default
子句的先后顺序可以变动,而不会影响程序执行结果。 default
子句可以省略不用。- 自定义函数尽量放在
main
函数之前,若要放在main
函数后面,需要在main
函数之前先声明自定义函数。
编译器不优化情况下,for 循环里 ++i 比 i++ 要快一些。
存储类别
1 | 自动(auto) |
只有 局部自动变量 和 形式参数 可以作为 寄存器变量;
一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量;
局部静态变量 不能定义为 寄存器变量。
1 | auto 是局部变量的默认存储类, 限定变量只能在函数内部使用; |
VS2019 中,看任何变量的内存,将该变量取地址&,拖入内存窗口来看
微软的编译器设计,不同的变量之间有 8 个字节的保护空间(Mac 和 Linux是没有的)
字符串函数
获取数组长度
1 | int length = sizeof(arr)/sizeof(arr[0]); |
二维数组定义的时候,可以不指定行的数量,但是必须指定列的数量。
0x02 References
《C Primer Plus》
C语言入门这一篇就够了-学习笔记
C语言教程
0x03 写在最后
因为基础篇的知识点比较零散,好在断断续续写了几天总算写完了,细心的朋友可以发现我在文中指出了一些 C99 和 C11 的新特性与 C89 和 C90 作为区分,以便在不同的编译器上能够更好的排错。还有很多知识点没有提到,后期补充时会写在进阶篇和高级篇中,文中难免有纰漏之处,请读者不吝指出。