C 中,有特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,被用来表示如换行符(\n)或制表符,下表列出了一些这样的转义序列码:
转义序列 | 含义 |
---|---|
\\ | \ 字符 |
\' | ' 字符 |
\" | " 字符 |
\? | ? 字符 |
\a | 警报铃声 |
\b | 退格键 |
\f | 换页符 |
\n | 换行符 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ooo | 一到三位的八进制数 |
\xhh . . . | 一个或多个数字的十六进制数 |
C存储类
存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。这些关键字放在被描述的类型前面。C 程序中可用的存储类:
- auto:所有局部变量默认的存储类,
- register:用于声明存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个词),且不能对它应用一元的 '&' 运算符(因为它没有内存位置)。寄存器用于需要快速访问的变量,定义 'register' 并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中
- static:指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁,因此,使用 static 声明的局部变量可以在函数调用之间保持局部变量的值。static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量或者方法的作用域限制在声明它的文件内,能被当前文件的任意函数和方法调用。
- extern:用于提供一个全局变量的引用,该声明的全局变量对所有的程序文件都是可见的。对于extern 声明的未初始化的变量,会把变量名指向一个之前定义过的存储位置。
C 运算符
算术运算符
+(加),-(减),*(乘),/(整除),%(取余),++(自增),--(自减)
对于++与-- ,当与赋值表达式一起使用时,在变量右则先赋值再自增或自减运算,在变量左则先自增或自减运算再赋值
关系运算符
==(相等),!=(不相等),>(大于),<(小于),>=(大于等于),<=(小于等于)
逻辑运算符
&&(逻辑与),||(逻辑或),!(逻辑非)
位运算符
位运算符作用于位,并逐位执行操作。
&(按位与), | (按位或), ^(按位异或),~(按位取反),<<(位左移运算符),>>(位右移运算符)
赋值运算符
=(赋值)
杂项运算符
sizeof()(返回变量大小), &(返回变量的地址),* (指向一个变量),a?b:c( a真则为b,否则为c)。
运算符优先级
下表将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算
类别 | 运算符 | 结合性 |
---|---|---|
后缀 | () [] -> . ++ - - | 从左到右 |
一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
乘除 | * / % | 从左到右 |
加减 | + - | 从左到右 |
移位 | << >> | 从左到右 |
关系 | < <= > >= | 从左到右 |
相等 | == != | 从左到右 |
位与 AND | & | 从左到右 |
位异或 XOR | ^ | 从左到右 |
位或 OR | | | 从左到右 |
逻辑与 AND | && | 从左到右 |
逻辑或 OR | || | 从左到右 |
条件 | ?: | 从右到左 |
赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 |
逗号 | , | 从左到右 |
C 判断
C 语言把任何非零和非空的值假定为 true,把零或 null 假定为 false。
if...else if...else 和 switch
switch 语句必须遵循下面的规则:
- switch 语句中的 expression 是一个常量表达式,必须是一个整型或枚举类型。
- 在一个 switch 中可以有任意数量的 case 语句。每个 case 后跟一个要比较的值和一个冒号。
- case 的 constant-expression 必须与 switch 中的变量具有相同的数据类型,且必须是一个常量或字面量。
- 当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 break 语句为止。
- 当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。
- 不是每一个 case 都需要包含 break。如果 case 语句不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。
- 一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
C 循环
while 循环(当给定条件为真时,重复语句或语句组。),for 循环,break(终止循环或 switch 语句)、continue关键字(立刻停止本次循环迭代,重新开始下次循环迭代。)
for ( init; condition; increment )
{
statement(s);
}
for 循环的控制流:
- init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
- 接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
- 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
- 条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,for 循环终止。
使用 for(;;) 或者 while{} 结构来表示一个无限循环。当条件表达式不存在时,它被假设为真。按 Ctrl + C 键终止一个无限循环。
C函数
定义函数
return_type function_name( parameter list )
{
body of the function
}
- 返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。
- 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
- 参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
- 函数主体:函数主体包含一组定义函数执行任务的语句。
声明函数和调用函数
return_type function_name( parameter list );
在函数声明中,参数的名称并不重要,只有参数的类型是必需的。
在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,应该在调用者所在的文件顶部声明函数。
调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。
函数参数
传值调用:向函数传递参数的传值调用方法,把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
引用调用:通过引用传递方式,形参为指向实参地址的指针,当对形参的指向的地址进行操作时,就相当于对实参本身进行的操作,即改变了实参。
C 作用域规则
作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量:
- 在函数或块内部的局部变量
- 在所有函数外部的全局变量
- 在形式参数的函数参数定义中
局部变量
在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部的语句使用。局部变量在函数外部是不可知的。
全局变量
全局变量是定义在函数外部。全局变量在整个程序生命周期内都是有效的,在任意的函数内部能访问全局变量。
在函数内,如果局部变量的名字和全局变量名相同,会使用局部变量值,全局变量不会被使用。
全局变量与局部变量在内存中的区别:
- 全局变量保存在内存的全局存储区中,占用静态的存储单元;
- 局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
局部变量和全局变量初始化
局部变量被定义时,系统不会对其初始化,使用前必须自行对其初始化。而定义全局变量时,系统会自动对其初始化。全局变量初始化默认值如下:
数据类型 | 初始化默认值 |
---|---|
int | 0 |
char | '\0' |
float | 0 |
double | 0 |
pointer | NULL |