C语言系统化精讲(三): 运算符与表达式

文章目录

  • 一、运算符与表达式
    • 1.1 运算符
    • 1.2 表达式
  • 二、赋值运算符与赋值表达式
    • 2.1 赋值运算符
    • 2.2 赋值表达式
  • 三、算术运算符与算术表达式
    • 3.1 算术运算符
    • 3.2 算术表达式
    • 3.3 自增/自减运算符
  • 四、关系运算符与关系表达式
    • 4.1 关系运算符
    • 4.2 关系表达式
  • 五、逻辑运算符与逻辑表达式
    • 5.1 逻辑运算符
    • 5.2 逻辑表达式
  • 六、位运算符与位表达式
    • 6.1 位运算符
    • 6.2 位运算表达式
  • 七、逗号运算符与逗号表达式
  • 八、复合赋值运算符
  • 九、优先级和结合性

说到减肥就要运动,看似简单的运动也是能消耗热量的,那么本文的示例就来实现用行走的步数来计算消耗的热量值,具体代码如下所示:
C语言系统化精讲(三): 运算符与表达式_第1张图片
从代码中可以看到,代码中的 int,printf,scanf 等函数,大家已经了解了,可能唯一看不懂的就是橙色框中的代码――运算符表达式,简单来说,它就是用来计算的,在数学中有各种运算符,例如:加、减、乘、除、大于等等。在C语言中也会用到各种运算符来计算数据。本文就来详细讲解C语言中用到的运算符。

一、运算符与表达式

在C语言中,程序需要大量的运算,就必须利用表达式和运算符操纵数据,用来表示各种不同运算的符号称为运算符,而运算符和操作数组成的式子称为表达式。

1.1 运算符

在数学中,总会用到加、减、乘、除这四则运算,用符号表示分别是 +,-,*,÷ 同样,在C语言中也有加各种各样的运算符。例如,C语言中也有 加(+),减(-),乘(*),除(/) 当然除了这些运算符,还有其他运算符,如下表所示:
C语言系统化精讲(三): 运算符与表达式_第2张图片

1.2 表达式

看到 表达式 就会不由自主地想到数学表达式,数学表达式是由数字、运算符和括号等组成,如下图所示:
C语言系统化精讲(三): 运算符与表达式_第3张图片
数学表达式在数学当中是至关重要的,那么表达式在C语言中也同样重要,它是C语言的主体。在C语言中,表达式由操作符和操作数组成。根据表达式所含操作符的个数,可以把表达式分为简单表达式和复杂表达式两种,简单表达式是只含有一个操作符的表达式,而复杂表达式是包含两个或两个以上操作符的表达式,例如:

5+20;// 简单表达式
(iNumber+3)*Bate-2;// 复杂表达式

表达式本身什么事情也不做,只是返回结果值。在程序对返回的结果值不进行任何操作的情况下,返回的结果值不起任何作用。例如上面两行代码,这两个表达式只能得出结果,在表达式的左边没有常量和变量,那么,这个表达式得出的结果就不会被输出使用。表达式产生作用主要包括两种情况:

放在赋值语句的右侧
放在函数的参数中

表达式返回的结果值是有类型的。表结果值的数据类型取决于组成表达式的变量和常量的类型。

ps: 每个表达式的返回值都具有逻辑特性。如果返回值是非零的,那么该表达式返回真值,否则返回假值。通过这个特点,可以将表达式放在用于控制程序流程的语句中,这样就构建了条件表达式。

二、赋值运算符与赋值表达式

在开篇示例中,代码的第08行,使用了 = 这个运算符,
在这里插入图片描述
在数学中,它的含义是 等于,而在C语言中,与数学中的含义不同,它有另外的含义――赋值。 本小节就来介绍 = 在C语言的意义。

2.1 赋值运算符

在C语言中,= 就是赋值运算符,作用就是将一个数值赋给一个变量,如下图所示:
C语言系统化精讲(三): 运算符与表达式_第4张图片
就像男孩给女孩礼物一样,女孩就相当于变量,男孩相当于赋值运算符,而礼物就相当于值。

2.2 赋值表达式

赋值表达式就是为变量赋值。在声明变量时,可以为其赋一个值,就是将一个常数或者一个表达式的结果赋值给一个变量,变量中保存的内容就是这个常量或者赋值语句中表达式的值。这就是为变量赋值。为变量赋值为常数的一般形式如下:

数据类型 变量名 = 常数; //举例:
char cChar = 'Z';
int iFirst = 1314;
float fPlace= 1314.520f;

赋值语句把一个表达式的结果值赋给一个变量。一般形式如下:

类型 变量名 = 表达式; //举例:float fPrice=fBase+Day*3;

这句代码得到赋值的变量 fPrice 称为左值,因为它出现的位置在赋值语句的左侧。产生值的表达式称为右值,因为它出现的位置在表达式的右侧。

注意: 这是一个重要的区别,并不是所有的表达式都可以作为左值,如常数只可以作为右值。

三、算术运算符与算术表达式

生活中,常常会遇到各种各样的计算,例如下图所示,某超市老板每天需要计算本日的销售金额,他就会将每种产品的销售额相加,来计算本日的总销售额,而此处的 相加 即为数学运算符的 ++ 在C语言中称为算术运算符。
C语言系统化精讲(三): 运算符与表达式_第5张图片
除上图所示的 +,在开篇示例中,我们可以看到使用了 *,它也是运算符之一,那么,在C语言中除了这两种运算符,还有其他运算符吗?其实,C语言中有两个单目算术运算符、5个双目算术运算符。下面详细进行介绍。

3.1 算术运算符

算术运算符包括两个单目运算符(正和负),五个双目运算符,即乘法、除法、取模、加法和减法。具体符号和对应的功能如下表所示:
C语言系统化精讲(三): 运算符与表达式_第6张图片
在上表中,取模运算符 % 用于计算两个整数相除得到的余数,并且取模运算符的两侧均为整数,如 7%4 的结果是3。其中的单目正运算符是冗余的,也就是为了与单目负运算符构成一对而存在的。单目正运算符不会改变任何数值,例如,不会将一个负值表达式改为正。

注意: 运算符 - 可作为减法运算符,此时为双目运算符。- 也可作负值运算符,此时为单目运算,如 -5 等;运算符 + 也是如此,当 + 作为加法运算符时,它为双目运算符,为正值运算符时,它为单目运算符。

3.2 算术表达式

如果在表达式中使用的是算术运算符,则将表达式称为算术表达式。下面是一些算术表达式的例子,其中使用的运算符就是之前所列出的算术运算符,代码如下:

Number=(3+5)/Rate;
Height=Top-Bottom+1;
Area=Height * Width;

需要说明的是,两个整数相除的结果为整数,如 7/4 的结果为1,舍去的是小数部分。但是,如果其中的一个数是负数时会出现什么情况呢?此时机器会采取 向零取整 的方法,即为 -1.75,取正后是1.75,取整之后是1或者2,采用向0靠拢,那么就要取1,最后结果则为-1。这种方法也称为 向零去尾,把小数点后的尾去掉 。

注意:如果用 +,-,*,/ 运算的两个数中有一个为实数,那么结果是 double 型,这是因为所有实数都按 double 型进行运算。实数的定义:
C语言系统化精讲(三): 运算符与表达式_第7张图片

对取余运算的补充说明: 取余,也就是求余数,使用的运算符是 %。C语言中的取余运算只能针对整数,也就是说,% 的两边都必须是整数,不能出现小数,否则编译器会报错。另外,余数可以是正数也可以是负数,由 % 左边的整数决定:

  1. 如果 % 左边是正数,那么余数也是正数;
  2. 如果 % 左边是负数,那么余数也是负数。

示例:

#include 
int main() {
  printf(
      "100%%12=%d \n100%%-12=%d \n-100%%12=%d \n-100%%-12=%d \n",
      100 % 12, 100 % -12, -100 % 12, -100 % -12
  );
  return 0;
}

程序运行结果如下图所示:
C语言系统化精讲(三): 运算符与表达式_第8张图片

3.3 自增/自减运算符

在C语言中还有两个特殊的运算符,即自增运算符 ++ 和自减运算符 -- 就像公交车的乘客数量,每上来一位乘客,乘客的数量就会增加一个,此时的乘客数量就可以使用自增运算符,而自增运算符的作用就是使变量值增加1。同样,自减运算符的作用就是使变量值减少1,例如,客车的座位,每上来一位乘客,客车的座位就会减少一个,此时座位这个变量就可以使用自减运算符。

注意:在表达式内部,作为运算的一部分,两者的用法可能有所不同。如果运算符放在变量前面,那么变量在参加表达式运算之前完成自增或者自减运算;如果运算符放在变量后面,那么变量的自增或者自减运算在变量参加了表达式运算之后完成,如下图所示:
C语言系统化精讲(三): 运算符与表达式_第9张图片
常见错误:自加自减是单目运算符,因此表达式和常量不可以进行自加自减,例如:5++ 和 (a+5)++ 都是不合法的。

自增和自减的示例1:

/*================================================================
*   Copyright (C) 2023 AmoXiang All rights reserved.
*   
*   文件名称:05-test.c
*   创 建 者:AmoXiang
*   创建日期:2023年10月11日 16:56:39
*   描    述:
*
================================================================*/


#include 
#include 
int main() {
  int a = 10, b = 20;
  printf("a=%d, b=%d\n", a, b); // a=10, b=20
  ++a; //11
  --b; //19
  printf("a=%d, b=%d\n", a, b);// a=11, b=19
  a++;//12
  b--;//18
  printf("a=%d, b=%d\n", a, b);// a=12, b=18
  return 0;
}

程序运行结果如下图所示:
C语言系统化精讲(三): 运算符与表达式_第10张图片
自增和自减的示例2:

/*================================================================
*   Copyright (C) 2023 AmoXiang All rights reserved.
*   
*   文件名称:05-test.c
*   创 建 者:AmoXiang
*   创建日期:2023年10月11日 16:56:39
*   描    述:
*
================================================================*/


#include 
int main() {
  int a = 10, b = 20, c = 30, d = 40;
  int a1 = ++a, b1 = b++, c1 = --c, d1 = d--;

  // ++a先自增 后参与运算 故a=11,a1=11
  printf("a=%d, a1=%d\n", a, a1);
  //b++先参与运算 后自增 故b=21,b1=20
  printf("b=%d, b1=%d\n", b, b1);
  //下面同理
  printf("c=%d, c1=%d\n", c, c1);//29 29
  printf("d=%d, d1=%d\n", d, d1);//39 40
  return 0;
}

程序运行结果如下图所示:
C语言系统化精讲(三): 运算符与表达式_第11张图片
自增和自减的示例3:

/*================================================================
*   Copyright (C) 2023 AmoXiang All rights reserved.
*   
*   文件名称:05-test.c
*   创 建 者:AmoXiang
*   创建日期:2023年10月11日 16:56:39
*   描    述:
*
================================================================*/


#include 
int main() {
  int a = 12, b = 1;
  // 12 - 1 ==> c = 11, b = 0
  int c = a - (b--);  // ①
  // 13 - (-1) == > 14
  int d = (++a) - (--b);  // ②
  printf("c=%d, d=%d\n", c, d);
  return 0;
}

程序运行结果如下图所示:
C语言系统化精讲(三): 运算符与表达式_第12张图片

四、关系运算符与关系表达式

在数学中,经常会比较两个数的大小。例如,如下图所示,爸爸的身高是1.80米,儿子的身高是1.20米,很明显,爸爸的身高比儿子的身高要高。这句话中,隐含的意思用到了比较,那么这个比较就是关系运算符的一种,在C语言中,关系运算符的作用就是判断两个操作数的大小关系。
C语言系统化精讲(三): 运算符与表达式_第13张图片

4.1 关系运算符

关系运算符包括大于、大于等于、小于、小于等于、等于和不等于,如下表所示:
C语言系统化精讲(三): 运算符与表达式_第14张图片
注意: 符号 >=(大于等于)<=(小于等于) 的意思分别是大于或等于、小于或等于。

4.2 关系表达式

关系运算符用于对两个表达式的值进行比较,返回一个真值或者假值。返回真值还是假值取决于表达式中的值和所用的运算符。其中真值为1,假值为0,真值表示指定的关系成立,假值则表示指定的关系不正确。例如:

18>3 /*因为18大于3,所以该关系成立,表达式的结果为真值 即为1*/
18>=3/*因为18大于3,所以该关系成立,表达式的结果为真值 即为1*/
18<3 /*因为18大于3,所以该关系不成立,表达式的结果为假值 即为0*/
18<=3 /*因为18大于3,所以该关系不成立,表达式的结果为假值 即为0*/
18==3 /*因为18不等于3,所以该关系不成立,表达式的结果为假值 即为0*/
18!=3 /*因为18不等于3,所以该关系成立,表达式的结果为真值 即为1*/

关系运算符通常用来构造条件表达式,用在控制程序的流程语句中,如 if 语句是用于判断条件而执行语句块,在其中使用关系表达式作为判断条件,如果关系表达式返回的是真值则执行下面的语句块,如果为假值就不去执行,如下图所示:
C语言系统化精讲(三): 运算符与表达式_第15张图片
常见错误:例如 i==3 中的 == 是合法的关系运算符,而 i=3 中的 = 不是合法的关系运算符,它是赋值运算符。示例,将关系运算符的结果输出:

#include 
int main() {
  char c = 'k';
  int i = 1, j = 2, k = 3;
  float x = 3e+5, y = 0.85;
  // 'a'->97 + 5 --> 102 'f' < 'k' 'a' + 5 < c==> 1
  int result_1 = 'a' + 5 < c, result_2 = x - 5.25 <= x + y;
  printf("%d, %d\n", result_1, -i - 2 * j >= k + 1);
  printf("%d, %d\n", 1 < j < 5, result_2);
  printf("%d, %d\n", i + j + k == -2 * j, k == j == i + 5);
  return 0;
}

程序运行结果如下图所示:
C语言系统化精讲(三): 运算符与表达式_第16张图片

五、逻辑运算符与逻辑表达式

目前考驾驶证的人越来越多了,报考驾驶证也是有一定要求的,当然,考不用型号的驾驶证对年龄要求也不同,例如考A1驾照要求年龄在 26~50 岁之间,B1驾照要求年龄是 21~50 岁之内,C1驾照要求年龄是 18~70 岁之内,在数学中可以如图8所示表示这些年龄区间,而在C语言中,需要如图9所示的形式表示年龄区间。
C语言系统化精讲(三): 运算符与表达式_第17张图片
如图9所示的 && 就是逻辑运算符,在C语言中,不仅有 && 一个逻辑运算符,接下来我们就来详细介绍C语言中的逻辑运算符和逻辑表达式。

5.1 逻辑运算符

逻辑运算符有3种,如下表所示:
C语言系统化精讲(三): 运算符与表达式_第18张图片

5.2 逻辑表达式

已经介绍过关系运算符可用于对两个操作数进行比较,使用逻辑运算符可以将多个关系表达式的结果合并在一起进行判断。其一般形式如下:

表达式 逻辑运算符 表达式

举例:

age > 18 && age < 70;//逻辑与运算,表示年龄大于18并且小于70
height > 155 || height < 190;//逻辑或运算,表示身高大于155cm或者小于190cm
!weight;//逻辑非运算,表示体重的非值

逻辑运算结果如下表所示:
C语言系统化精讲(三): 运算符与表达式_第19张图片
逻辑与运算符和逻辑或运算符可以用于相当复杂的表达式中。一般来说,这些运算符用来构造条件表达式,用在控制程序的流程语句中,例如,在后续博文中介绍的 if,for,while 语句等。

注意:不要把逻辑与运算符 && 和逻辑或运算符 || 与后续小节要讲的位与运算符 & 和位或运算符 | 混淆。

逻辑运算符举例:

#include 
int main() {
  char c = 'k';
  int i = 1, j = 2, k = 3;
  float x = 3e+5, y = 0.85;
  printf("%d,%d\n", !x * !y, !!!x); // 0, 0
  //i && j ==> 2 x||2-3 ==> 只要有一个不为0 就返回1
  // i < j && x < y ==> (i 1 && 0 ==> 0
  printf("%d,%d\n", x || i && j - 3, i < j && x < y); // 1
  printf("%d,%d\n", i == 5 && c && (j = 8), x + y || i + j + k);
  return 0;
}

程序运行结果如下图所示:
C语言系统化精讲(三): 运算符与表达式_第20张图片

六、位运算符与位表达式

学C语言可能总会听见,int占多少字节,char占多少字节,可能会有很多人疑问,字节是什么意思?那么在C语言中,说到字节就不得不说位。位是计算机存储数据的最小单位。一个二进制位可以表示两种状态(0和1),多个二进制位组合起来便可表示多种信息。

一个字节通常是由8位二进制数组成,当然有的计算机系统是由16位组成,本文中提到的一个字节指的是由8位二进制组成的。如下图所示,8位占一个字节,16位占两个字节。
C语言系统化精讲(三): 运算符与表达式_第21张图片
了解了字节和位的关系,本小节我们就来详细的介绍位运算符和位运算表达式。

6.1 位运算符

C语言既具有高级语言的特点,又具有低级语言的功能,C语言和其他语言的区别是完全支持按位运算,而且也能像汇编语言一样用来编写系统程序,这是C语言的特色之处。下表所示为C语言提供的位运算符:
C语言系统化精讲(三): 运算符与表达式_第22张图片

6.2 位运算表达式

假设有两个变量 m 和 n,用来保存逻辑结果,m 和 n 可以进行下表所示的4种逻辑运算。其中 1 表示 true(真),0 表示 false(假)。
C语言系统化精讲(三): 运算符与表达式_第23张图片

说明:按位与,遇0则0;按位或,遇1则1;按位异或相同为1,不同为0。不要将逻辑运算符和位运算符混淆,逻辑运算符返回的值是真假值,位运算符是二进制运算的运算符,最终计算的是一个数值。

上表介绍了按位与、按位或、取反以及按位异或,接下来介绍左移和右移。左移 运算符 << 是双目运算符。其功能是把 << 左边的运算数的各二进位全部左移若干位,由 << 右边的数指定移动的位数,高位丢弃,低位补0。例如,m<<2 即把 m 的各二进制位向左移动两位。假设 m=39,那么 m 在内存中的存放情况如下图所示:
在这里插入图片描述
若将 m 左移两位,则在内存中的存储情况如下图所示。m 左移两位后由原来的39变成了156。
在这里插入图片描述
右移运算符 >> 也是双目运算符。其功能是把 >> 左边的运算数的各二进制位全部右移若干位,>> 右边的数指定移动的位数。例如 m=30 在内存中的存储情况如下图所示:
在这里插入图片描述
m>>3 即 30 右移3位变成3,其存储情况如下图所示:
在这里插入图片描述
以上是正数移位,负数和正数在计算机存储形式不同,同样使用右移讲解负数移位,例如 m = -30,首先写出 -30,取绝对值,即 30 的二进制数,然后在这基础上按位取反,得到的二进制码再加一,得到下图所示的二进制数,这个数值就是 -30 在内存中存储的情况。
在这里插入图片描述
表达式 m>>3 的含义是将 -30 右移 3 位,结果是 -4,,其存储情况如下图所示:
在这里插入图片描述

七、逗号运算符与逗号表达式

提到逗号,它在我们心中是分隔符的作用,例如有这样一句话:救救我舅舅不救我舅舅我舅舅就没救了,这句话看起来(读起来)有点晕,到底是救舅舅,还是不救舅舅,这时候,可以加上逗号,改为 救救我舅舅,不救我舅舅,我舅舅就没救了,如果这样写就能明确意思了。那逗号在这里起到了一个断句的作用,在C语言中,逗号不仅可以用作分隔符,还可以用在表达式中。逗号表达式的一般形式如下:

表达式1,表达式2,,表达式n

逗号表达式的求解过程是:先求解表达式1,再求解表达式2,一直求解到表达式n,整个逗号表达式的值是表达式n的值。 逗号表达式称为顺序求值运算符。就像数学中常常求几何问题一样,需要按顺序写解题步骤。例如下面使用逗号运算符的代码:

Value=1+3,1+2,15+27;

上面语句中 Value 所得到的值为4,而非 42。由于赋值运算符的优先级比逗号运算符的优先级高,因此先执行赋值的运算。如果要先执行逗号运算,则可以使用括号运算符,代码如下:

Value=(1+3,1+2,15+27);

这句代码最终的结果是 42,因为使用了括号运算符,因此先计算括号内的表达式,然后再执行赋值的运算。

八、复合赋值运算符

复合赋值运算符是C语言一种缩写形式,可使得变量操作的描述方式更为简洁。例如 *= 复合,如下图所示:
C语言系统化精讲(三): 运算符与表达式_第24张图片
如果在程序中为一个变量赋值,代码如下:

Value=Value*3;

这一行语句是对一个变量进行赋值操作,值为这个变量本身与一个整数常量3相乘的结果值。使用复合赋值运算符可以实现同样的操作。例如上面的语句可以改写成如下语句:

Value*=3;

这种描述更为简洁。关于上面两种实现相同操作的语句,赋值运算符和复合赋值运算符的区别在于:

  1. 为了简化程序,使程序精练
  2. 为了提高编译效率。

下表是其他复合赋值运算符:
C语言系统化精讲(三): 运算符与表达式_第25张图片

九、优先级和结合性

在数学中,就规定了优先级,如果没有规定,就会出现争先恐后先计算情况。数学中规定:有括号先计算括号里的,没有括号先计算乘除再计算加减。那在C语言中,有这么多运算符,也需要进行规定,如下表所示是各个运算符的优先级和结合性,优先级1代表级别最高,优先级15表示级别最低。
C语言系统化精讲(三): 运算符与表达式_第26张图片
当一个表达式中出现多个运算符时,C语言会先比较各个运算符的优先级,按照优先级从高到低的顺序依次执行;当遇到优先级相同的运算符时,再根据结合性决定先执行哪个运算符:如果是左结合性就先执行左边的运算符,如果是右结合性就先执行右边的运算符。C语言的运算符众多,每个运算符都具有优先级和结合性,还拥有若干个操作数,为了方便记忆和对比,我们在上表中将它们全部列了出来。对于没有学到的运算符,大家不必深究,一带而过即可,等学到时再来回顾。

至此今天的学习就到此结束了,笔者在这里声明,笔者写文章只是为了学习交流,以及让更多学习C语言的读者少走一些弯路,节省时间,并不用做其他用途,如有侵权,联系博主删除即可。感谢您阅读本篇博文,希望本文能成为您编程路上的领航者。祝您阅读愉快!


在这里插入图片描述

    好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。
    如果我的博客对你有帮助、如果你喜欢我的博客内容,请 点赞评论收藏 一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。
 编码不易,大家的支持就是我坚持下去的动力。点赞后不要忘了 关注 我哦!

你可能感兴趣的:(C语言系统化精讲,c语言,开发语言)