今天扫完今天的落叶,明天的树叶不会在今天落下。 —— 林清玄

C语言——基本运算符和其他运算符

  • 一、运算符
  • 二、基本运算符
    • 2.1赋值运算符:=
      • 2.1.1赋值
      • 2.1.2左值和右值(简单讲)
    • 2.2加法、减法运算符:+ –
    • 2.3符号运算符(+和 -)
    • 2.4乘法、除法运算符:* /
      • 乘法
      • 除法
    • 2.5优先级
  • 三、其他运算符
    • 3.1sizeof运算符
    • 3.2求模运算符:%
    • 3.3递增运算符:++
    • 3.4递减运算符:–、
    • 3.5优先级

一、运算符

C语言中用运算符表示算数运算,跟数学中的运算大致相同,只不过由于C数据类型的限制有了些许的调整,下面介绍一下基本运算符以及其他运算符(C没有指数运算符,但是C的标准数学库提供了pow()函数用于指数运算。例如pow(2,3)表示返回2的3次幂(即为8))

二、基本运算符

2.1赋值运算符:=

2.1.1赋值

C语言中“=”不是“等于”、“相等”的意思,它是一个赋值运算符。

比如下面的赋值表达式语句:

digit = 2022;

意思是把2022这个数赋值给变量digit。等号(=)左侧是一个变量名,右侧是赋给这个变量的值。读作“把值2022赋给变量digit”,而不是“digit等于2022”。

上面这个例子看上去读作什么没有多少区别,但是看下面这个例子:

i = i + 1//另一种写法:i += 1

在数学上这个表达式完全行不通,但是在C赋值表达式语句中,这非常合理。如何解释呢?
→先找出变量i的值,把这个值+1,再把新值赋给变量i,此时变量i存储的值就从比原来大1了

2.1.2左值和右值(简单讲)

C中这样的语句是无效的↓

2022 = digit
C语言中,=左侧必须是一个可修改的左值(变量名或指针),这样才可以引用一个存储位置右值是指能赋值给左值的量,但是它本身不是左值

在这个例子中,digit是变量;而2022是字面常量,本身就是一个确定的值,错的显而易见

2.2加法、减法运算符:+ –

+-的运算对象可以是常量,也可以是变量

加(减)法运算符+(-):跟数学中的加(减)法一样,“+”(“-”)表示其两侧是值相加(减)
比如↓

printf("%d",2+8);//打印的是10,不是表达式2+8int a = 1;int b = 20;int n = a + b;printf("%d",n);//打印的值是21//在这里a,b,n都是可修改的左值,而表达式a + b是一个右值

减法同理,这里就不多赘述了~
+和-运算符都是二元运算符(二元:即运算符需要两个运算对象)

2.3符号运算符(+和 -)

减号(-)还可以改变or标明一个值的符号

num = -5;num2 = -num1  //最后num2的值是5

“-”在这样的用法中是一元运算符,只需要一个运算对象
PS:

num_s = +6//没必要这样写,但是编译器也不会报错

2.4乘法、除法运算符:* /

乘法

*表示乘法。乘法运算符跟数学中的乘法一样,“*”表示其两侧是值相乘

除法

C中用/表示除法。/左侧的值是被除数,右侧的则是除数
与数学中除法不同,由于C中数据类型的不同,除法可分为整数除法和浮点数(即小数)除法。
例1:

int a = 6;int b = 2;printf("%d",a/b); //非常常规,打印结果为3

例2:

int num1 = 9;int num2 = 2;printf("%d",num1/num2);  //打印结果是4//因为这里num1和num2都是int类型(整型) //整数是没有小数部分的数//因此在C中,整数除法结果如果有小数,那么小数部分会被丢弃(不是四舍五入),只保留整数部分//(这个过程叫做“截断”)

例三:

double n = 20.6;double m = 3;printf("%lf",n/m);//double对应%lf//打印结果是6.866667//C中输出double类型或float类型时默认输出6位小数(不足六位用0补齐,超过六位按四舍五入截断)

这里补充一点,虽然默认输出6位小数,但如果要指定输出n位小数,那么可以用%.nlf的格式(对于float类型则是%.nf)。其中n为数字。
例如,想要只输出3位小数:

printf("%.3lf\n", n/m);//输出结果就变成了6.867

例四:
整数和浮点数混和运算的结果是浮点数

double k = 6.9;int j = 3;printf("%d",sizeof(k/j) );//打印结果为8,即double类型的字节长度//sizeof运算符在下面的3.1中会讲printf("%lf",k/j);//打印结果为2.300000

2.5优先级

执行各种操作的顺序很重要

思考一下,下面这个表达式的结果是什么呢
sum = 2.0 + 16*(9/6)
要知道,先运算2.0 + 16再*(9/6),跟先算16*(9/6)再+2结果是不一样的。
因此C中明确规定了运算符的优先顺序,并以此来决定执行各种操作的顺序。(→与数学中加减乘除的执行顺序一样)

三、其他运算符

3.1sizeof运算符

sizeof运算符以字节为单位返回运算对象的大小

运算对象可以是具体的数据对象(比如变量名)或数据类型,如果数据对象是类型,那么必须用圆括号把数据类型给括起来
例如:

int a = 0;//创建一个变量就给它初始化是个好习惯printf("%d \n",sizeof(int)); //必须加圆括号,打印结果为4printf("%d \n",sizeof n);//变量名可以不加括号,打印结果为4printf("%d \n",sizeof(char));//打印结果为1printf("%d \n",sizeof(long));//打印结果为4printf("%d \n",sizeof(long long));//打印结果为8printf("%d \n",sizeof(float));//打印结果为4printf("%d \n",sizeof(double));//打印结果为8

C语言规定,sizeof 返回 size_t类型的值。(这是一个无符号(unsigned)整型)C99新增%zd转换说明用于printf()显示size_t类型的值。(如果系统不支持可以用%u或%lu代替)

3.2求模运算符:%

求模运算符(%)只能用于整数,不能用于浮点数

求模运算符给出左侧整数除以右侧整数的余数。例如

printf("%d",17 % 4);//打印结果为1,即17比4的四倍多1

3.3递增运算符:++

递增运算符有两种模式,前缀模式(如++i)和后缀模式(i++)。两者的区别在于递增行为发生的时间不同 。
//简单的说,i++是先使用,再++;++i是先++再使用
举个栗子:
例1:后缀++

int a = 100;int b = a++;printf("a = %d,b = %d",a,b);//打印结果:a = 101,b = 100//对应上面说的,先使用:变量a的值先赋给b;再++:a = a + 1//因此最后a = 101, b = 100

例2:前缀++

int a = 100;int b = ++a;printf("a = %d,b = %d",a,b);//打印结果:a = 101,b = 101//对应上面说的,先++:a += 1;再使用:b = a(=101)//因此最后a = 101, b = 101

但是当单独使用递增(递减)运算符时,使用前缀or后缀都可,如:

i++;    //或++i;

*在条件的判断中(比如下面这个),建议用前缀模式

while++age < 60

如果使用age++,age最后会增至61,多了一次判断,总归是比只递增到60来的不那么好

3.4递减运算符:–、

跟递增运算符道理相同,这里大抵就举两个例子罢

例1:后缀–

int a = 100;int b = a--;printf("a=%d b=%d\n", a, b);//打印结果:a = 99,b = 100//先使用:b = a(=100);再--:a = a - 1//因此最后a = 99, b = 100

例2:前缀–

int a = 100;int b = --a;printf("a = %d,b = %d",a,b);//打印结果:a = 99,b = 99//对应上面说的,先--:a = a - 1;再使用:b = a(=99)//因此最后a = 99, b = 99

3.5优先级

递增/递减运算符的优先级很高,只有圆括号()的优先级比他们高。

  • 如果i++是表达式的一部分,依旧是“先使用i,再++”
    举个栗子:
int w = 2;int i = 6;int mix = (w + i++)*2;printf("%d",mix);//打印的结果是16//这里要注意,i的值只有被使用以后才会递增为7//还有一点,递增/递减运算符只能作用于一个变量//具体到这段代码,++只作用于i而不是w+i