1.算术运算符
运算符 | 功能说明 | 举例 |
+ | 双目加法,一目取正 | a+b,+c |
- | 双目减法,一目取负 | a-b,-h |
* | 乘法 | a*b |
/ | 除法(在整型的运算中小数部分会直接丢失) | a/b |
% | 取模(求余) | a%b |
++ | 自加1 | a++, ++b |
- - | 自减1 | a--, --b |
- 关注点:
- 减号也是负号,比如 -a 是取变量 a 的相反数。
- 取模运算要求左右两边操作数必须是整型数据。
- 自加和自减运算不仅可以对整型操作,也可以对浮点数、指针操作。
- 前缀自加自减运算:先进行自加自减,再参与表达式运算
- 后缀自加自减运算:先参与表达式运算,再进行自加自减
printf("c+++d:%d\n" , c+ ++d ); // ++d
printf("c:%d\n" , c );
printf("d:%d\n" , d );
int k = c+++b;
..
.....
printf("k:%d c:%d d:%d\n" , ...)
请写出程序运行后输出的结果:
注意:
gcc编译器默认是贪婪匹配规则 因此他在匹配运算符的时候,会尽可能多的从左往右把所有能组合在一起的符号组合成一个运算符
2.关系运算符
运算符 | 功能 | 举例 | 说明 |
> | 大于 | a > b | 判断a是否大于b |
>= | 大于或等于 | a >= 5 | 判断a是否大于或等于5 |
小于 | 3 < x | 判断3是否小于x | |
小于或等于 | x | 判断x是否小于或等于y+1 | |
== | 等于 | (x+1) == 0 | 判断x+1是否等于0 |
!= | 不等于 | c != ‘\0’ | 判断c是否不等于’\0’ |
- 关注点:
- 关系运算符用于判断运算符两边的表达式是否满足给定的大小条件。
- 由关系运算符组成的表达式称为关系表达式,其值为布尔型。
- 判断是否相等是双等号==,而不是一个等号(赋值符号 = )。
3.逻辑运算符
运算符 | 功能说明 | 举例 |
! | 逻辑反 | !(x==0) |
&& | 逻辑与 | x>0 && x |
|| | 逻辑或 | y<10 ||y>50 |
- 运算规则:
- 逻辑反:将逻辑真、假翻转,即真变假,假变真。
- 逻辑与:将两个或多个关系表达式串联起来,当且仅当左右两个表达式都为真时,结果为真。
- 逻辑或:将两个关系表达式并联起来,当且仅当左右两个表达式都为假时,结果为假。
- 特殊规则:
- 在逻辑与运算中,如果左边表达式的值为假,那么右边表达式将不被执行。
- 在逻辑或运算中,如果左边表达式的值为真,那么右边表达式将不被执行。
4.位运算符
所有的操作都是按二进制位进行操作.
运算符 | 名称 | 举例 | 功能说明 |
~ | 位逻辑反 | ~a | 将变量 a 中的每一位取反 |
& | 位逻辑与 | a & b | 将变量 a 和 b 逐位进行与操作 |
| | 位逻辑或 | a | b | 将变量 a 和 b 逐位进行或操作 |
^ | 位逻辑异或 | a ^ b | 将变量 a 和 b 逐位进行异或操作 |
左移 | a | 将变量 a 中的每一位向左移动4位 | |
>> | 右移 | x >> n | 将变量 x 中的每一位向右移动4位 |
- 位运算符操作的对象是数据中的每一位
- 运算规则:
- 位逻辑反: 把操作数的每一个位进行取反操作(0变1 1变0)
- 位逻辑与:把两个操作数的所对应的位进行与运算 ( & 有0得0)
- 位逻辑或 :把两个操作数的所对应的位进行或运算( | 有1得1 )
- 异或运算:把两个操作数的所对应的位进行异或运算 (相同为0,不同为1)
- 移位运算:移出去的不要,空出来的补零。移位运算都是针对无符号数的运算??
- 如果对负数进行右移运算那么空出来的部分补符号位 1 (对符号位进行一定的保护)
- 如果对负数进行左移动运算,那么符号位将会被直接覆盖 (对符号位没有任何的保护)
5.特殊运算符
- 赋值运算符
- 不能对常量、表达式赋值,只能对变量赋值 (赋值符号的左边(左值)不能是常量 或表达式 )
- 不能对数组赋值
- 可以连续赋值,顺序从右到左
int a, b; int x[5]; a = 100; // 对变量 a 赋值,正确 (a+b) = 100; // 对表达式赋值,错误! 【lvalue required as left operand of assignment】 3 = 100; // 对常量 3 赋值,错误! x = 123; // 对数组 b 赋值,错误! // 连续赋值 a = b = 50; // 先将 50 赋给 b,再将 b 的值赋给 a,正确 a = b++ = 50; // 连续赋值中也不允许出现左值为表达式或常量
6.复合赋值符
- 当左右两边有相同的操作数时,采用复合赋值符不仅直观,且能提高运算效率
- 除了下述10个复合运算符之外,生造别的复合运算符是非法的
// 加减乘除: a += n; // 等价于 a = a+n; a -= n; // 等价于 a = a-n; a *= n; // 等价于 a = a*n; a /= n; // 等价于 a = a/n; // 求余: a %= n; // 等价于 a = a%n; // 位运算: a &= n; // 等价于 a = a&n; a |= n; // 等价于 a = a|n; a ^= n; // 等价于 a = a^n; a >>= n; // 等价于 a = a>>n; a <<= n; // 等价于 a = a<<n;
6.条件运算符(三目运算符)
- 唯一需要三个操作数的运算符
- 语法:表达式1 ? 表达式2 : 表达式3;
- 释义:当表达式1为真时,取表达式2,否则取表达式3
- 当表达式1 为真的时候取 冒号左边的表达式 否则取冒号右边的表达式
- 举例:
int a = 100; int b = 200; int m = (a>b) ? a : b; // 如果 a>b 为真,则 m 取 a 的值,否则取 b 的值
7.sizeof 运算符
- 含义:计算指定数据类型或者变量所占据内存的字节数 - 语法:sizeof(类型) 、sizeof(变量) ,计算变量的字节数时圆括号可以省略 - 举例: printf("%d\n", sizeof(int)); printf("%d\n", sizeof(long double)); // 【拓展】 但是用sizeof来计算数组的时候得到的是数组的实际大小(占用内存的字节数) int a[5]; printf("%d\n", sizeof(a)); printf("%d\n", sizeof a);
8.return运算符
- 含义:退出某个函数(如果退出的是主函数main,那么整个程序也就退出了)
- 语法:必须出现在函数体内 { },可以带函数对应类型的数据
- 一般情况下 返回 0 表示正常退出 , 返回其他值表示异常退出
- 如果是自己写的函数,它的返回值完全可以由我们自己进行掌握可以返回任何类型的数据
- 举例:
float main() { return 12.30; }
9.优先级与结合性
- 当表达式中出现不同的运算符时,根据优先级来决定谁先执行,比如先乘除,后加减
- 当表达式中出现多个相同优先级的运算符时,根据结合性来决定谁先运行,比如从左到右
-
权威的结合性如何查询: man operator
10.类型转换
- 概念:不一致但相互兼容的数据类型,在同一表达式中将会发生类型转换。
- 转换模式:
- 隐式转换:系统按照隐式规则自动进行的转换 cel = (5*(fah-32)) / 9;
- 强制转换:用户显式自定义进行的转换 (double)a 强制把a转换成 doublie
- 语法: (目标类型)需要转换的变量名
- 隐式规则:从小类型向大类型转换,目的是保证不丢失表达式中数据的精度
注意:
不管是隐式转换,还是强制转换,变换的都是操作数只在运算过程中的类型,是临时的,操作数本身的类型不会改变,也无法改变。
11.数据类型的本质
- 概念:各种不同的数据类型,本质上是用户与系统对某一块内存数据的解释方式的约定。
- 推论:
- 类型转换,实际上是对先前定义时候的约定,做了一个临时的打破。
- 理论上,可以对任意的数据做任意的类型转换,但转换之后的数据解释不一定有意义。
12.整型数据尺寸
- 概念:整型数据尺寸是指某种整型数据所占用内存空间的大小
- C语言标准并未规定整型数据的具体大小,只规定了相互之间的 “ 相对大小 ” ,比如:
- short 不可比 int 长
- long 不可比 int 短
- long 型数据长度等于系统字长 (在32位系统中long = 32位= 4字节 、 在64为系统中 long = 64位 = 8字节)
- 系统字长:CPU 一次处理的数据长度,称为字长。比如32位系统、64位系统。
- 典型尺寸:
- char 占用1个字节
- short 占用2个字节
- int 在16位系统中占用2个字节,在32位和64位系统中一般都占用4个字节
- long 的尺寸等于系统字长
- long long 在32位系统中一般占用8个字节,在64位系统中一般占用8个字节
- 存在问题:
- 同样的代码,放在不同的系统中,可能会由于数据尺寸发生变化而无法正常运行。
- 因此,系统标准整型数据类型,是不可移植的,这个问题在底层代码中尤为突出。
可移植性整型
- 概念:不管放到什么系统,尺寸保持不变的整型数据,称为可移植性整型
- 关键:typedef 用于对变量类型进行取别名
- 思路: a.为所有的系统提供一组固定的、能反应数据尺寸的、统一的可移植性整型名称 .在不同的系统中,为这些可移植性整型提供对应的 typedef 语句