C语言细节 运算符,表达式,语句

1.术语:

//数据对象(Data Object):
用于存储值的数据存储区域统称数据对象

//左值(Lvalue):
用于标识或定位特定数据对象的名称或表达式称为"左值"
对早期的C语言,"左值"意味着:①它指定1个对象,可以引用内存地址 ②用在赋值运算符(=)的左边
后来新增了const限定符,这么创建的变量不能用在赋值运算符左边
因此删除了标准②,增加了"可修改的左值"(Modifiable Lvalue)这个术语
当前标准建议使用术语"对象定位值"(Object Locator Value)而不是"左值"

//右值(Rvalue):
能赋值给"可修改的左值"且本身不是"左值"的量称为"右值"

//运算对象(Operand):
运算符操作的对象称为"运算对象",可以是变量/变量/二者的组合

//运算符(Operator):
C语言用运算符表示算术运算

2.多重赋值:

//从右往左依次赋值:
int a1,a2,a3;
a1=a2=a3=44;
printf("%d,%d,%d",a1,a2,a3);//结果:44,44,44

3.自增/减运算符的一些问题:???

自增/减运算符的优先级很高,仅低于括号,如x*y++表示(x)*(y++)而非(x*y)++
并且后者是无效的,因为自增/减运算符只能作用于1个可修改的左值,而x*y表示
嵌入表达式的++i表示i先自增再参与运算,i++表示i先参与运算再自增

//实例:
int x=2,y=3;
printf("%d\n",(x+y++)*6);//结果:30
printf("%d\n",y);//结果:4
printf("%d\n",(x*++y)*6);//结果:60
printf("%d\n",(x+++y)*6);//结果:60
//注意:(x+++y)*6是(x++ + y)*6而不是(x + ++y)*6,即是对x做了后自增

int num=5;
printf("%d,%d\n",num,num*num++);//结果6,30
//因为是从右往左进行的计算,故最右侧的num使用了5,左边2个num都是6
//还有可能是5,25,因为会先打印num,然后计算num*num,最后num自增
//还有可能是6.25,会先计算num*num,然后完成自增,最后打印,这都取决于编译器
printf("%d,%d\n",num,num+num++);//结果6,11

int n=3;
int y=n++ + n++;
printf("%d\n",y);//结果:7
在有些环境下

//为避免上述各种问题:
1.不要在表达式中使用自增/减运算符
2.如果1个变量出现在1个函数的多个参数中,不要对其使用自增/减运算符

4.表达式(Expression):

表达式由运算符和运算对象组成
最简单的表达式是1个单独的运算对象;有些表达式由子表达式(Subexpression)组成
在C语言中,每个表达式都有1个值,:
-4+6的值为8,c=3+8的值为11,5>3的值为1,6+(c=3+8)的值为17
最后1个表达式是2个子表达式的和,是合法的,但不建议使用

5.副作用(Side Effect)和序列点(Sequence Point):

副作用是对数据对象或文件的修改,如在下述语句中:
states=50;
从C语言的角度看,副作用是将变量的值设为500,而主要目的是对表达式求值
类似地,printf()的副作用是显示信息,主要目的是得到显示的字符数

序列点是程序执行的点,在该点处,所有副作用都在进入下1步之前发生
在C语言中,分号标记了1个序列点,所以赋值/自增/自减必须在下1条语句执行前完成
另外一些运算符也是序列点;此外,任何1个完整表达式的结束也是1个序列点
是序列点的运算符包括:逗号运算符,&&,||

完整表达式(Full Expression)是指这个表达式不是另1个更大的表达式的子表达式
例如,表达式语句和while循环中作为条件的表达式都是完整表达式

序列点有助于分析后缀递增何时发生,:
while (guests++<10) {
    printf("%d\n",guests);
}
由于guests++<101个完整表达式,因此可以保证自增一定发生在printf()前
同时使用后缀保证了先与19比较再自增
而在下述语句中:
y=(4+x++)+(6+x++);
printf("%d\n",x);
由于4+x++不是完整表达式,不能保证在其完成求值后立刻递增
而只能保证在printf()前x自增了2

6.语句(Statement)
(1)简单语句:

语句是C程序的基本构建块;1条语句相当于1条完整的计算机指令
根据C11标准,C语言共有6种语句:标号语句,复合语句,表达式语句,选择语句,迭代语句,跳转语句
  复合语句见 (2) 部分;选择语句和迭代语句见 C语言基础.流程控制 部分

//注意:
1.在C语言中,大部分语句都以分号结尾,因此:
legs=4
只是1个表达式(可能是1个更大的表达式的一部分),而
legs=4;1个语句
应该说,分号用于识别简单语句

2.最简单的语句是空语句,:
;    //空语句

3.C语言把结尾有分号的表达式都视为语句,:
8;
3+4;
但这些语句没有使用意义,通常语句用于改变值或调用函数,:
x=25;
++x;
y=sqrt(3);

4.1条语句是1个完整的指令,但并不是所有指令都是语句,:
x=6+(y=5);
中的y=51条完整的指令,但不是1个语句

5.常见语句:
根据C标准,声明不是语句,虽然其结尾有分号,这与C++不同
最常见的语句是"表达式语句",如赋值和函数调用
而while语句是1"迭代语句",有时被称为"结构化语句"
return则属于"跳转语句"

(2)复合语句(块;Compound Statement):

复合语句是用花括号括起来的1条或多条语句,也称为"块"(Block)
//格式:
{
...
}
//功能:
①用于标记函数体的开始和结束,即函数体必需被花括号包起来
②用于while等控制语句需要控制多条语句的情况
  • 2种风格:
//风格1:
while {
    ...
}
//风格2:
while
{
    ..
}

//这2种风格对编译器完全等价

7.逗号表达式的值:

整个逗号表达式的值就是最右侧项的值:
int x,y,z;
x=(y=3,(z=++y+2)+5);
printf("%d\n",x);//结果:11

8.备选拼写:

C99增加了可替代逻辑运算符的拼写,并将其定义在iso646.h中
and代替&&,or代替||,not代替!

//实例:
printf("%d\n",1 and 0);//结果:0
printf("%d\n",1 or 0);//结果:1
printf("%d\n",not 1);//结果:0//注意:空格不能省略

9.测试范围:

&&用于测试变量是否在某个区间内
if (90<=range && range>=30) {
    printf("%d\n",range);
}
if (c>='a' && c<='z') {
    printf("It is lowercase %c\n",c);
}
//注意:这么写表示90<=range的结果(0或1)是否小于等于100,故总为true
//if (90<=range<=100) {
//    ...
//}

//

||用于测试变量是否在某几个区间内
if (range>100 || range<30) {
    printf("Good\n")
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值