在看题解的时候发现了这样一句话:
if(sum>=n)
sum-=(l*l),l++;
这里的两个赋值表达式竟然可以用逗号分隔。这样就只需要一个分号,可以不加大括号了,太舒服了,因为我个人写代码的习惯就是尽量简洁,能不加大括号那肯定不加。所以逗号和分号到底有什么区别呢,什么时候可以用逗号代替分号呢?
百度了一下C语言中逗号和分号的区别,看到这样一个解释:逗号是表达式结束标志,分号是语句结束标志。(前者并不确切,逗号其实属于一种运算符,后文会解释)
咦?什么是表达式,和语句有啥区别?阿巴阿巴。突然觉得自己对C语言的了解太肤浅了。
下面是正文:
一.表达式:
定义:由操作符和操作数构成的式子。
操作数就是常量或变量。
操作符则是+,=,/,*,/=,(),[],&,&&等等等等,也可以叫做运算符。
注:任何表达式都是有返回值的。可以理解为表达式本身也有值。
不知道你们有没有遇到过这样的错误:
比如:手残把while(x==10) 写成了 while (x=10),然后程序就在这里死循环了,永远出不来。
编译器不会向我们报错,因为这样的写法其实是合法的,赋值表达式是有(返回)值的。经查询,赋值表达式的返回值是赋值符号右边的值。x=10的值就是10,所以while永远不会结束。我写了一段很简单的程序实验了一下。
int n=0;
int t;
if(t=n)
cout<<"hello world"<<endl;
结果是没有任何输出。说明t=n的值是0,cout语句没有执行。
除了赋值表达式,其他的表达式也都是有返回值的。汇总如下:
赋值表达式:赋值符号(等号)右边的值。
算术表达式:由算术运算符连接而成的式子,比如3+7,4+x/2,它的返回值就是运算的结果,这个应该很好理解。
关系表达式:由关系运算符连接而成的式子,比如3<7,x≥5,它的返回值取决于式子的真假,比如3<7是真的,返回1,3>7是假的,返回0.
逻辑表达式:逻辑运算符(&&,||,!)连接而成的式子,这个返回值就是逻辑运算结果,比如1&&0返回0,2||0返回1,!0返回1。顺便说下,在C语言中0代表假,非0就是真(而不仅仅是1为真)
位逻辑表达式:位逻辑运算符(&,|,^,~)连接而成的式子,返回值就是位逻辑运算结果,只要对位逻辑运算符有了解即可。因为主要是想讲返回值,就不展开了。
逗号表达式:逗号的作用是分隔表达式,例:表达式1,表达式2,表达式3。而他们整体又称作逗号表达式,逗号表达式从左往右执行每一个表达式,且返回最后一个表达式的值。即逗号表达式这个整体的值就是它最后一个表达式的值
当然还可以将上述表达式组合起来成为更复杂的表达式。
插两道题讲:
1.求表达式(k=3*2,k+4),k+2 的值
根据逗号表达式从左往右运算的规则:
1)k=3*2 这是一个赋值表达式,表达式的值为等号右边的值:6, 且k被赋值为6
2)(6,k+4) k+4为10(此时k为6,因为先执行了逗号前的赋值表达式) ,逗号表达式的值为最后一个表达式的值即10.但注意k此时仍然为6,因为没被赋值。
3) 10,k+2 k+2为8,总体值为后者,也就是8。
综上,答案为8。
2.求下面程序的输出结果
int x,y,z;
x=1;
y=1;
z=x++,y++,++y;
printf("%d,%d,%d\n",x,y,z);
答案是2,3,1。这里面要注意的就是z,因为逗号符的运算优先级是最低的,所以z=x++被看作了逗号表达式的第一个表达式。
二.语句
语句是什么?
C程序的执行部分是由语句组成的。 程序的功能也是由执行语句实现的。
C语言中共有五种语句,分别为:
1.表达式语句
表达式语句由表达式加上分号组成。其一般形式为: 表达式;
写到这里,其实我已经彻底明白了博客一开头的疑问,那句话就是将两个赋值表达式组合成了一个逗号表达式而已!但是要注意的是,逗号只能分隔表达式,因此如果我们如下这么写,编译器是会报错的,因为break是语句而不是表达式!
if(sum>=n)
sum-=(l*l),l++,break;
执行表达式语句就是计算表达式的值
2.函数调用语句
由函数名、实参加上分号组成。其一般形式为:函数名(实参表);
我们调用的函数可以是自己写的,也可以是头文件中包含的。
例如 printf("Hello"); 就是一个函数调用语句,printf是<stdio.h>中的一个头文件
3.控制语句
控制语句用于控制程序的流程,以实现程序的各种结构方式。它们由特定的语句定义符组成。C语言有九种控制语句。 可分成以下三类:
条件判断语句:if、switch语句;
循环执行语句:do while语句、while语句、for语句;
转向语句:break语句、goto语句、continue语句、return语句。
4.复合语句
把多个语句用括号{}括起来组成的一个语句称复合语句。在程序中应把复合语句看成是单条语句,而不是多条语句。
例如:
int main()
{
int x;
{
for(int i=1;i<=3;i++)
3+4;
x=6;
x++;
printf("%d\n",x);
;;;;
{
x++;
printf("%d",x);
;;;;
}
}
return 0;
}
这段代码没有任何意义,但在语法上是正确的,编译器不会报错。这个复合语句里包括了控制语句,表达式语句,空语句,函数调用语句,甚至还有一个复合语句。
5.空语句。
只有分号,啥也没有的语句。
三.总结
表达式与语句的区别
1.二者功能不同:
表达式本身是什么都不做的,只返回值,只是单纯的计算过程。它可以被放在任何需要值的地方。当然赋值表达式是比较特殊的,它虽然也返回值,但主要作用显然是改变变量的值,其实赋值表达式更像一个语句。
语句则是一个行为,负责执行某种操作,没有返回值。程序就是通过语句来执行功能的。语句由分号(或花括号)来结尾。
2.二者本质不同:
表达式由操作符(运算符)和操作数构成的式子。
语句的组成相对复杂,多种多样。
表达式与语句的联系
1.表达式语句就是仅有表达式组成的语句(其实就是指赋值语句,或者由赋值语句组成的逗号表达式,不然根本没有意义)
2.很多语句需要用到值,也就是表达式。比如while()的括号中需要一个值来告诉它循环是否结束且我们一般都会用关系表达式
其实深究表达式与语句的区别并没有什么意义。我们只需要记住,表达式是值,而语句是操作即可。