《C和指针》第4章主要介绍C语言的语句,第5章介绍了操作符和表达式,阅读完这两章后,尽管是些非常非常基础的知识点,但我还是想将这两章一起做一个总结。一方面是为了保持该系列文章的完整性;另一方面,语句、表达式、操作符三者之间从宏观上来看,还是有内在联系的,而这种联系才是我想总结的重点。
文章目录
因为c语言是Dennis MacAlistair Ritchie他老人家发明的,所以在文字也就是用英语表述了。语句就是statement,表达式就是expression,操作符就是operator。在看英文文档时,不要对这些单词感到陌生。
在C语言中,语句是由表达式和(或)分号组成;表达式是由标识符或操作符组成。这句话可以说是这两章内容的核心,所有其他的相关知识点,都是以这句话为中心展开。例如,
sum = a + 1;
这条语句就是一个表达式语句,语句是由表达式"sum = a +a"和";"号构成,而表达式是由标识符(sum,a)和操作符(+)构成。
再比如,
a + 1;
也是合法的表达式语句,只不过它没有将表达式的值存储在某个变量中。所以从语法层面上,一定要理解c语言语句的构成,不能含糊不清。
语句
C语言的语句大致可以分为7类:
普通表达式语句,if语句,while语句,for语句,do-while语句,switch语句,goto语句;
普通表达式语句
语法上,在表达式后加一个分号,即将表达式转换成了语句。语法如下:
expression;
if语句
if语句是一种条件判断语句。语法如下:
// 形式1
if ( expression )
statement // 如果表达式的值为真,执行本语句
else
statement // 如果表达式的值为假,执行本语句
// 形式2
if ( condition-expression1 )
statement // 如果满足condition-expression1,执行本语句
else if ( condition-expression2 )
statement // 如果满足condition-expression2,执行本语句
else
statement // 都不满足,执行本语句
说明1:从形式上来看,statement似乎只能执行一条语句,但是代码块可以使在语法上要求只出现一条语句的地方使用多条语句。所以statement可以是代码块。
说明2:这里只列举了if-esle,if-else if-else形式,除了if是必须的外,其他关键词都是可选的,可根据实际逻辑进行组合。
while语句
while语句是一种循环语句。语法如下:
while (expression)
statement // 只要expression为真,statement一直循环执行
可以通过break
语句来跳出循环;使用continue
语句来结束本次循环;同样statement也支持代码块。
for 语句
for语句是另一种形式的循环语句。语法如下:
for ( expression1; expression2; expression3 )
statement
通常,expression1称为初始化部分,expression2称为条件部分;expression3称为调整部分;statement称为循环体。expression1只在循环开始前执行一次;expression2在循环体执行之前都有执行一次,来判断条件是否成立,只有条件成立,循环体才会执行;expression3在循环体执行完后才会执行,来更新某些条件。
同样,也可以使用bread
语句或continue
语句,statement也支持代码块。for循环在编码风格上会相对简练一些。
do-while语句
do-while语句也是一种循环语句,但它不同于while语句的地方在于,do-while语句的循环体至少会执行一次,而不管条件是否成立。语法如下:
do
statement
while ( expression );
同样,也可以使用bread
语句或continue
语句,statement也支持代码块。
switch 语句
switch语句是条件分支语句。语法如下:
switch ( expression )
statement
// 通常的使用语法
switch ( expression )
{
case constant-expression:
statement
break;
case constant-expression:
statement
break;
...
default:
statement
break;
}
switch语句的执行逻辑是:先计算expression的值,判断哪个case标签的常量表达式(constant-expression)的值和expression的值匹配,如果匹配,则执行相应的statement;注意,这里的break
语句非常重要,case标签并不能将语句列表划分为几个不同的执行部分,它只是用来确定语句列表的入口点,一旦找到入口点,就会从入口点开始一直往后执行。但是,如果我们加了break
语句,就可以将case列表划分成不同的执行部分。如果所有的case都不匹配,那么将会执行default部分。statement也支持代码块。
goto 语句
goto语句是一种跳转语句。语法如下:
goto 语句标签;
对goto的使用,你需要非常清楚自己的跳转逻辑。常用的一种使用场景是跳出多层嵌套循环。
操作符
算术操作符
加,减,乘,除,求余
移位操作符
左移位(<<),右移位(>>)。
特别说明:逻辑移位和算术移位。逻辑移位用0填充;算术移位用符号位填充。所以要想保证程序的可移植性,在涉及移位操作时,使用无符号数。
位操作符
位与(&)、位或(|)、位异或(^)
赋值操作符
=
复合赋值符
+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=
单目操作符
! 逻辑反,通常也说 非
++ 自增操作符
- 负号符
& 取址操作符,获取变量的地址
sizeof 获取操作数的类型的长度。当操作数是数组名时,返回的是数组的长度
~ 取反操作符
– 自减操作符
+ 正数操作符
* 间接访问操作符,一般用于访问指针所指向的值
(类型) 强制类型转换
关系操作符
> 大于
>= 大于等于
< 小于
<= 小于等于
!= 不等于
== 等于
小技巧:有时候在条件判断时,容易少些一个"="而导致代码逻辑出现错误,但是语法上是允许,这样的隐藏性的问题很不容易发现,所以一般在进行等于判断时,将右值写在等于号左边,这样可以让编译器帮我们去检查。例如,
if (1 == a)
printf("yes\n");
即使你在书写时漏了一个"=",编译器会报错提示。
逻辑操作符
&& 逻辑与
|| 逻辑或
注意逻辑操作符的对象是表达式,而位操作符的对象是位。
逻辑与 的执行逻辑是:先判断左表达式的值是否为真,如果为真则再判断右表达式的值;如果为假,那么右表达式不再执行,因为整个表达式的值肯定为假。
逻辑或 的执行逻辑是:先判断左表达式的值是否为真,如果为真则右表达式不再执行,因为整个表达式的值已经为真。
逻辑与、逻辑或的这种执行逻辑通常叫做"短路求值"(short-circuited evaluation),在数字电路中,也是通过这种方式实现逻辑判断。
条件操作符
条件操作符是为唯一一个三目操作符。语法如下:
expression1 ? expression2 : expression3;
它的执行逻辑是:先执行expression1,如果expression1的值为真,则执行expression2;如果expression1的值为假,则执行expression3。在简单的条件判断中,有时使用条件操作符会使代码更加简洁。
逗号操作符
语法如下:
expression1,expression2,...,expressionN;
逗号表达式将多个表达式分隔开,这些表达式自左向右逐个执行,整个表达式的值就是expressionN的值。
说明:我们知道操作符都有各自默认的优先级,但是为了提高代码的可读性和可移植性,通常在工程中使用小括号来控制和区分复杂表达式的执行。尽量不要为了"更炫"而依赖操作符自身的优先级使代码难于阅读。
好了,第4章和第5章的阅读总结就是这些。
关注我
我的公众号二维码,欢迎关注
QQ讨论群:679603305