目录
概述
操作对象:又称操作数,是参与计算求值的最小数据单元。操作数可以为常量、变量、函数等。
运算符:又称操作符,用于执行程序代码运算。按照运算性质可以分为:算术运算符、关系运算符、逻辑运算符、赋值运算符、逗号运算符和 sizeof 运算符五种类型。按照参与运算的操作数数量可以分为:一元运算、二元运算和三元运算。
表达式:表达式是用于计算的式子,是计算求值的基本单位。用运算符将操作对象连接起来可以构成表达式。
NOTE:运算符的优先级和结合性决定了表达式的求值顺序,当一个表达式中出现了多个运算符时,需要考虑运算符的优先级和结合性是否满足表达式的求值顺序。
- 优先级:高优先级的运算符先进行运算,低优先级的运算符后进行运算。
当两个运算符相同优先级时,由其结合性来决定运算顺序。 - 结合性:运算符的结合性体现了运算符对其操作数进行运算的方向。
- 左结合性:当一个运算符对其操作数为从左到右进行运算,则称此运算符为左结合性运算符。
- 右结合性:当一个运算符对其操作数为从右到左进行运算,则称此运算符为右结合性运算符。
- 在表达式中使用圆括号 () 可以改变表达式的运算顺序。
算术运算符
算术运算符:实现算术运算功能的运算符。
运算优先级:
算术表达式:算术运算符连接操作数组成算术表达式。
Example:算术表达式
-n
+n
i++
++i
j--
--j
k * l
k / l
k % l
a + b
a - b
NOTE:
- 求余运算符的操作数只可以为整型
自增、自减运算符:
- i++ :先取值,后自加。使用 i 之后,
i = i + 1
- ++i :先自加,后取值。
i = i + 1
后,再使用 i - i- - :先取值,后自减。使用 i 之后,
i = i - 1
- - -i :先自减,后取值。
i = i - 1
后, 再使用 i - 自增运算符和自减运算符的操作数只可以为变量,不能为常量或表达式
Example:自增、自减运算符
- i++ :先取值,后自加。使用 i 之后,
int main()
{
int i = 0, j = 0;
int n = 0, m = 0;
// Example 1 : i++
printf(" Example 1: i++\r\n");
printf(" i = %2d\r\n", i);
printf(" i++ = %2d\r\n", i++); //先使用 i 做输出,再 i = i + 1
printf(" After i++, i = %2d\r\n", i);
// Example 2 : ++j
printf("\r\n Example 2: ++j\r\n");
printf(" j = %2d\r\n", j);
printf(" ++j = %2d\r\n", ++j); //先 j = j + 1,再使用 j 做输出
printf(" After ++j, j = %2d\r\n", j);
// Example 3 : n--
printf("\r\n Example 3: n--\r\n");
printf(" n = %2d\r\n", n);
printf(" n-- = %2d\r\n", n--); //先使用 n 做输出,再 n = n + 1
printf(" After n--, n = %2d\r\n", n);
// Example 4 : --m
printf("\r\n Example 4: --m\r\n");
printf(" m = %2d\r\n", m);
printf(" --m = %2d\r\n", --m); //先 m = m - 1,再使用 m 做输出
printf(" After --m, m = %2d\r\n", m);
return 0;
}
输出结果:
Error Example:自增运算符和自减运算符的操作数不能为常量或表达式
5++; // Error
++5; // Error
(a+b)++ // Error
关系运算符
关系运算符:用于确定操作对象之间关系的运算符。 关系运算符都是双目运算符,具有左结合性。
运算优先级:
关系运算表达式:用关系运算符将操作对象连接起来的式子,称为关系运算表达式。
Example:关系运算表达式
a < b
a + b != c + d
'a' > 'b'
NOTE:
- 关系表达式的运算结果值是 0(假)或 1(真)。C 语言没有 bool 类型,用整数值 0 来表示 假,用非 0 值来表示真 。C++ 为提高程序的可读性引入了 bool 类型,bool 类型变量的值为 true 或 false。C++ 为了保持对 C 语言的兼容性,false 用 0 来表示,ture 用 1 来表示。
- 关系运算符两侧的操作数可以是常量、变量、函数或表达式(算术表达式、关系表达式、逻辑表达式、赋值表达式或字符表达式)。
Example:使用关系运算符实现起泡法排序。
#include<stdlib.h>
#define ARRAY_LENGTH 8
int main()
{
int a[ARRAY_LENGTH] = { 0 };
int temp = 0;
printf(" 起泡法排序\r\n The original Array: a[%d] = {", ARRAY_LENGTH);
for(int i = 0; i < ARRAY_LENGTH; i++)
{
a[i] = rand(); // 生产随机数
if (i == ARRAY_LENGTH - 1)
{
printf("%d", a[i]);
}
else
{
printf("%d, ", a[i]);
}
}
printf("}\r\n");
// 起泡法排序
for(int j = 0; j < ARRAY_LENGTH - 1; j++)
{
for(int k = 0; k < ARRAY_LENGTH - j - 1; k++)
{
temp = a[k];
// 使用大于运算符。每次将相邻两个数比较,将小的调到前头。
if (a[k] > a[k + 1])
{
a[k] = a[k + 1];
a[k + 1] = temp;
}
}
// 每排序一次,打印一次结果。
printf(" Time%d: a[%d] = {", j, ARRAY_LENGTH);
for(int i = 0; i < ARRAY_LENGTH; i++)
{
if (i == ARRAY_LENGTH - 1)
{
printf("%d", a[i]);
}
else
{
printf("%d, ", a[i]);
}
}
printf("}\r\n");
}
return 0;
}
输出结果:
逻辑运算符
逻辑运算符:用于确定操作数之间逻辑关系的运算符。
运算优先级:
逻辑表达式:用逻辑运算符连接操作数的式子,称为逻辑表达式,用于表达复杂的逻辑运算条件。
Example:逻辑表达式
x > 0 && x <= 1 // 0 < x <= 1
x != 0 && y != 0 // x ≠ 0 并且 y ≠ 0
x > 1 || x < -1 // x > 1 或者 x < -1
NOTE:
- 0 表示逻辑假, 非 0 表示逻辑真
- 逻辑运算时,只考虑操作数的值是否为 0(逻辑假)
- 逻辑运算结果为真,则产生整数 1,否则产生 0
- 当逻辑表达式中同时出现多种运算符时,按下列顺序进行运算:算术运算→关系运算→逻辑运算
Example:逻辑运算
int main()
{
int a = 11, b = 0;
printf(" a = %d, b = %d\r\n", a, b);
printf(" !a = %d\r\n", !a);
printf(" !b = %d\r\n", !b);
printf(" a && b = %d\r\n", a && b);
printf(" a || b = %d\r\n", a || b);
return 0;
}
输出结果:
赋值运算符
赋值运算符:实现将数据赋给变量功能的运算符,即将数据存入变量所对应的内存空间中。赋值运算符可分为:
- 基本运算符:“=”,将一个数据赋给一个变量功能的运算符
- 复合赋值运算符:基本赋值运算符可以与算术运算符、位运算符等组成复合赋值运算符
Example:
a += b // 等效于 a = a + b
a -= b // 等效于 a = a - b
a *= b // 等效于 a = a * b
a /= b // 等效于 a = a / b
a >>= b // 等效于 a = a >> b
a <<= b // 等效于 a = a << b
赋值运算表达式:用赋值运算符将变量和表达式连接起来的式子,称为赋值表达式。
变量 = 表达式 // 整体构成赋值运算表达式
NOTE:
- 赋值运算符的左侧必须为变量名,右边必须为表达式
- 赋值运算表达式的值为赋值运算符左边的变量值
赋值运算表达式的数据类型为左边变量的数据类型。当出现右边表达式的数据类型与左边变量的数据类型不一致时,则会先把右边表达式的值进行强制切换数据类型后,再进行赋值。
Error Example:赋值运算符的左侧必须为变量名,右边必须为表达式
int x = 0, y = 0, z = 2;
x + y =z // Error, 赋值运算符的左侧必须为变量名,不能是表达式
sin(a) = 2 + x // Error,赋值运算符的左侧必须为变量名,不能是函数
- 多重赋值:V1 = V2 = … = Vn = 表达式。执行时,把表达式的值按照 Vn、… 、V2、V1 的顺序依次赋给每个变量。
a = b = c = 1 // 先将 1 赋给 c, 再将 c 的值赋给 b , 最后将 b 的值赋给 a。
- 复合赋值表达式:由复合赋值运算符连接操作数构成复合赋值表达式。
V oper= E
其中: oper为算术运算符,E为表达式,V为变量。
V oper= E 等价于 V = V oper E
Example:
a += 3 等价于 a = a + 3
a %= 2 等价于 a = a % 2
a %= b + 2 等价于 a = a % (b + 2)
a *= x - y 等价于 a = a * (x - y)
- 赋值表达式后面加分号
;
可以构成赋值表达式语句
Example:赋值表达式语句
a += 3;
a %= 2;
a %= b + 2;
a *= x - y;
逗号运算符
逗号运算符:又称为顺序求值运算符,功能是将表达式连接起来,从左向右求解各个表达式,整个表达式的值作为最后求解的表达式的值。
// C/C++ 按顺序计算表达式 1,表达式 2, .....,表达式 n 的值
// 整个表达式的值为表达式 n 的值
表达式1, 表达式2, 表达式3, ......, 表达式n
NOTE:逗号运算符的优先级最低,引入逗号表达式的目的是为了简化程序书写。
Example:
int main()
{
int a, b, c, d;
d = (a = 1, b = a + 1, c = b + 1);
printf("a = %d, b = %d, c = %d, d =%d\r\n", a, b, c, d);
return 0;
}
输出结果:
sizeof 运算符
sizeof 运算符:求某一数据类型或某一变量在内存空间中所占空间的字节数。
sizeof (变量名或数据类型)
Example:获取不同数据类型占用内存空间的字节数和不定长数据占用的字节数
int main()
{
char stringA[] = "Hello World!\r\n";
printf(" sizeif( char ) = %d\r\n", sizeof(char));
printf(" sizeif( int ) = %d\r\n", sizeof(int));
printf(" sizeif( long int ) = %d\r\n", sizeof(long int));
printf(" sizeif( float ) = %d\r\n", sizeof(float));
printf(" sizeif( double ) = %d\r\n", sizeof(double));
// 注意 stringA 的末尾还存放着 '\0'
printf(" sizeif( stringA ) = %d\r\n", sizeof(stringA)/sizeof(char));
return 0;
}
输出结果: