标识符取名规则:
1、由数字、字母、下划线组成。
2、不能以数字开头。
3、不能与关键字重名(C语言中有32个关键字)。
4、见名知义,类型、功能、使用范围、归属模块。
在C语言中使用占位符来表示变量的类型:
%hhd %hd %d %ld %lld 有符号整型的占位符
%hhu %hu %u %lu %llu 无符号整型的占位符
%f %lf %Lf 浮点型的占位符
%c 字符型的占位符
布尔类型是用来逻辑运算的,不参与输入、输出,如果要强行输出,把它当整型即可。
运算符:
算术运算符:+ - * / %
整数/整数 结果没有小数点,例如:5/3 结果是1。
/和% 都是进行除法运算,/结果是商,%结果是余数(取模),它们除数不以为零,否则会出现浮点数例外的错误,该错误会让程序立即结束。
浮点型的数据不能使用 % 运算符。
关系运算符:> >= < <= == !=
它们运算结果是逻辑值,C语言中的逻辑值是用0(假)和1(真)模拟的,计算出的结果还能进行数学运算。
与数学中的用法不同,10 < x < 100,在数学中表示是x的取值范围,但在C语言中它就是需要运算的表达式,会先计算 10 < x 得到0|1,然后再把这个结果与100比较,所以该表达的结果永远是真。
使用==运算符时,非常容易出错误,容易漏写一个=,该错误编译器检查不出,阅读代码也很难查出来,所以在使用==时,把常量放在左边,变量写右边,这样当漏写=时,编译器会报错误。
100 = num;
num = 100;
逻辑运算符:&& || !
它们会把运算对象转换成逻辑值再运算,零值转换为假,非零值转换为真,它们的运算结果也就是逻辑值。
A && B 一假即假
A || B 一真即真
!A 求反,单目运算符,比&&、||的运算级别高。
&& ||短路特性:当左边的值已经可以确定运算结果时,右边的不再计算,适当的使用可以实现精简的if结构。
(表达式1) && (表达式2)
(表达式1) || (表达式2)
num >10 && (num=0); // 等价于下面的if语句
if(num > 10)
{
num = 0;
}
自变运算符:++/--
该运算符可以让变量的值自加或自减1。
前自变:++/--i
变量的值立即加1或减1。
后自变:i++/--
变量的值加1或减1,下一行代码有效。
注意:不要在复杂表达式中过度使用自变运算符,不同的编译器对它的运算规则不同,编译器会把合适的后自变优化成前自变。
赋值运算符:= += *= /= ...
a += b; <=> a = a + b;
三目运算符:[A]?[B]:[C];
它的运算对象有三个,所以叫三目运算符,先把[A]转换成逻辑值,为真执行[B],为假执行[C],相当于精简的 if else 结构。
注意:与 if else 不同的是三目运算符必须有运算结果,所以它里面不能使用流程控制语句,比如:return、break、continue。
字节运算符:
它不是函数,是C语言的32个关键字之一,如果运算对象不是表达式,它可以不使用小括号。
注意:sizeof不会执行表达式,它只时推算表达式的执行结果是什么类型,然后计算出该类型在内存中占用多少个字节。
类型转换:
前提:只有相同类型的数据才能在一起进行运算,因为不同类型的数据,字节数不同、格式、运算规则不同,必须把不同类型的数据转换成同一类型才能运算。
自动类型转换(隐式类型转换):
不同类型的数据组成的表达式,编译器会把先它们转换成相同的类型再计算,这叫作自动类型类型或隐式类型转换,它们的转换规则是以不丢失数据为前提:
1、字节数不同,字节少的向多的转换。
2、整型向浮点型转换。
3、有符号的向无符号转换。
4、char、short会先转换成int类型,如果不能满足运算条件再转换成其它。
强制类型转换:
(目标类型)数据,会把数据强制转换为目标类型,这种转换方式有可能会造成数据丢失,慎重使用。
使用if语句要注意的问题:
1、if的小括号后面一旦有分号,那么下面的代码就与它没有关系。
2、如果它的分支只有一行代码,从语法角度来说,大括号可以省略,但会影响代码的安全性、健壮性、可扩展性,所以商业项目中不要省略if语句的大括号。
开关语句:
switch (数据) // 小括号中必须是整型数据
{
case v1: 语句1; // case后面必须是整型常量(字面值常量、宏常量、枚举常量),如果小括号中的数据与小case后的数据相等,则打开执行开关,如果不关闭开关,接下来case后的语句都可以执行。
case v2: 语句2; break; // break语句可以关闭执行开关,如果每个case后都break语句,就形成了多分支结构
case v3: 语句3;
default: // 如果所有的case都没有匹配成功,则打开执行开关,就相当于多分支if语句最后的else,可以有也可以没有
}
循环语句:
do while 先执行循环体,后判断循环条件,循环体至少执行一次,相同条件下do while会比for和while多执行一次循环体。
for、while 先判断循环条件,再执行循环体,循环体可能一次都不执行。
for 适合解决循环次数确定的问题,可以使用循环变量清楚表示循环的次数。
while 适合解决只知道循环条件但不知道具体循环次数的问题(开始条件、结束条件)。
do while 适合解决 先处理 后检查的问题。
for、while 的小括号后面不能跟分号,否则下面的代码就不属于它们的循环体。
do while 的小括号后面必须有分号,它的这个特点适合定义宏函数。
跳转语句:
break 语句有两种用法:
用法1:在 switch 语句中可以关闭执行开关。
用法2:在循环语句中,它可以跳出一层循环,也是结束死循环的一种方式,一般用它来提前结束循环,提高程序的执行效率。
continue 语句只能在循环语句中使用,停止执行循环体,直接进行下一次循环,一般用于改善大括号的嵌套层数。
goto 语句可以跳转到函数内的任意位置(在函数内通过定义标签确定代码的位置),由于它过度灵活、自由可能会破坏已经设计好的分支、循环语句,因此一般公司都禁止使用(通过预处理指令把goto关键字定义为病毒,一旦在代码中使用编译器就会报错),新的编程语句中已经取消该关键字。
goto非常适合在驱动程序中处理异常、释放资源,所以C语言中从语法设计上就非常适合控制硬件。
return 语句可以跳出函数,并附加一个数据给函数的调用者。
什么是数组:
数组就是变量的组合,是一种批量定义变量的方式。
数组的定义与初始化:
数组元素的默认值与普通变量一样,是随机的。
类型 数组名[长度] = {v1,v2,v3,...};
1、如果初始化数据不够,编译器会自动补0。
int arr[5] = {};
2、如果初始化数据过多,编译器会提示警告并丢弃多余数据。
int arr[5] = {1,2,3,4,5,6,7};
3、对数组进行初始化时,数组的长度可以省略,编译器会自动统计数据的数量设置给数组。
int arr[] = {1,3,1,2,1,3,2,5,3,5,2,3,6,3};
size_t len = sizeof(arr)/sizeof(arr[0]);
for(int i=0; i<len; i++)
{
printf("%d ",arr[i]);
}
4、初始化语法只能在定义数组时使用,这也是唯一一次能对数组批量访问的机会,数组定义完成后就只能单个访问。