运算符和表达式

运算符和表达式

类型 符号
算术运算符 + - * / %
关系运算符 < > == >= <= !=
逻辑运算符 ! && ||
赋值运算符 =及其拓展赋值运算符
求字节数运算符 sizeof
强制类型转换运算符 (类型)
... ...

算术运算符及算术表达式

算术运算符包含+、-、、/和%,当一个表达式中同时出现这5种运算符时,先进行乘()、除(/)、取余(%),取余也称取模,后进行加(+)、减(-),也就是乘、除、取余运算符的优先级高于加、减运算符.除%运算符外,其余几种运算符既适用于浮点型数又适用于整型数当操作符的两个操作数都是整型数时,它执行整除运算,在其他情况下执行浮点型数除法.%为取模运算符,它接收两个整型操作数,将左操作数除以右操作数,但它的返回值是余数而不是商.由算术运算符组成的式子称为算术表达式,表达式一定有一个值.
#include <stdio.h>

int main(){
    int result=4+5*2-6/3+11%4; 
    printf("result=%d",result);
    return 0; 
}  
此代码输出结果为result=15

关系运算符和关系表达式

关系表达式的值只有真和假,对应的值为 1和 0。由于 C 语言中没有布尔类型,所以在 C 语言中 0 值代表假,非 0 值即为真。关系运算符的优先级低于算术运算符。
#include <stdio.h>
#include <stdlib.h> 
int main(){
    int a;
    while(scanf("%d"),&a)
    {
        if(3<a<10)
        {
            printf("the number between 3 and 10\n");
        }else{
            printf("the number not between 3 and 10\n");
        }
    }
    return 0; 
}  
上面的代码无论输入什么,结果提示输入的字符在3和10之间,这是因为在程序判断时,比如开始输入的a为11,那么程序判断3<11正确,返回值为1,此时程序再去用1与10做比较,1<10,所以输出第一条printf语句,读者可以自行思考如果输入的数值小于3,返回结果又是如何,总而言之,无论 a 的值为多少,这个表达式的值始终 为真,因此在判断变量 a 是否大于 3 且同时小于 10 时,要写成 a>3 && a<10,这才是正确的写法。

运算符优先级表

image-20240321134723413

逻辑运算符和逻辑表达式

逻辑运算符!、&&、‖依次为逻辑非、逻辑与、逻辑或,这和数学上的与、或、非是一致的逻辑非的优先级高于算术运算符,逻辑与和逻辑或的优先级低于关系运算符。逻辑表达式的值只有真和假,对应的值为1和0。下例中的代码是计算一年是否为闰年的例子,因为需要重复测试,所以使用while循环。 针对代码中的逻辑非,首先给变量j赋值10,因为j的值非0,所以!的值为0;然后,由于逻辑非是单目运算符,结合顺序为从右至左,得到!!j的值为1。也就是说,对0取非,得到的值为1;对非0值取非,得到的值为0。
#include <stdio.h>
#include <stdlib.h> 
int main(){
//  int i,j;
    int i=0,j=1; //在变量声明时,就对变量进行赋值 
    while(scanf("%d",&i))
    {
        /*
        闰年的判断条件,年份能被4整除并且不能被100整除,或者年份能被 400整除 
        */ 
        if(i%4==0&&i%100!=0 || i%400==0)
        {
            printf("%d is leap year\n",i);
        }else
        {
            printf("%d is not leap year\n",i);
        }
    }
    i=!!j;
    printf("i的值=%d\n",i);
    return 0; 
}  
读者可以尝试在声明变量时,不进行赋值,观察代码中逻辑非的结果是否有区别。
短路运算
逻辑与短路运算是当前面一个表达式为假时,后面的表达式不会得到执行,逻辑或短路运算是当前面一个表达式为真时,后面的表达式不会得到执行。(王道的C语言老师在课上讲过,短路运算可以缩减代码量)
#include <stdio.h>

int main(){
    int i=0;
    i&&printf("Caijxlinux"); //printf语句其实并不会运行 
    return 0; 
}  
其实读者可以理解为,当前的变量i为某个需要判断的参数,但是正常来说我们需要通过if-else去判断真假,但是现在只需要通过短路运算,如果i为真就再去判断下一个条件,如果i为假,就可以继续执行下一条语句。
赋值运算符
左值是那些能够出现在赋值符号左边的东西,右值是那些可以出现在赋值符号右边的东西。他们不可以互换,因为每个位置都包含一个值,所以原先用作左值的a此时也可以作为右值;然而,b+25不能作为左值,因为它并未标识一个特定的位置(并不对应特定的内存空间)。
a = b+25
#include <stdio.h>

int main(){
    int a=1,b=2;
    b+18 =a;
    return 0;
}  
上述代码报错为[Error] lvalue required as left operand of assignment(左值需要作为赋值的左操作数)
复合赋值运算符
复合赋值运算符操作是一种缩写形式,使用复合赋值运算符能使对变量的赋值操作变得更加简洁。
i = i+5
对变量i的赋值进行操作,值为这个变量本身与一个整型常量5相加的结果,使用复合语句可实现同样的操作,上面的语句可修改如下
i+=5
赋值运算符与复合赋值运算符的区别如下: (1)复合赋值运算符简化了程序,可使程序精炼,提升阅读速度。 (2)复合赋值运算符提高了编译效率。
#include <stdio.h>
#include <stdlib.h>

int main(){
    int a=8,b=2;
    a+=2;
    b*=5;
    printf("a=%d\n",a);
    printf("b=%d\n",b);
    return 0;
}  
上诉代码输出结果为a=10,b=10