C语言 - 运算符 | 数据类型

■ 算术运算

C 语言一共有 34 种运算符,其中算术运算有 7 种

1. 加 +     还可表示正号

2. 减 -      还可表示负号

3. 乘 *   

4. 除 /        于浮点型是除运算;于整型是取整运算

5. 取余 %   注:参与运算的数据都必须是整数,且运算结果只和左侧数据的正负相关:左为负则结果就是负;左为正则结果就是正

6. 自增 ++

7. 自减 --

代码示例:如何实现加 1 运算

int a = 1;
a=a+1;// 方式一
a+=1; // 方式二
a++;  // 方式三
++a; // 方式四

a++ 和 ++a 的区别:a++ 先参与运算后再加 1;++a 先加 1 后再参与运算

 1 int a = 10;
 2 int b = 0;
 3 int c = 6;
 4 
 5 printf("a++ = %d\n",a++);// 输出 10   a 的实际值是 11
 6 printf("++a = %d\n",++a);// 输出 12   a 的实际值是 12
 7 
 8 b = ++a;
 9 printf("a = %d b = %d\n",a,b);// a = 13   b = 13
10 
11 b = a++;
12 printf("a = %d b = %d\n",a,b);// a = 14   b = 13  因 a++ 先参与运算,所以 b 经赋值后是 13
13 
14 b = (a++)+(++c);// 14 + 7
15 printf("a = %d b = %d c = %d\n",a,b,c);// a = 15   b = 21  c = 7

■ 赋值运算

赋值运算共计 11 种

1. 简单赋值     =

2. 复合算术赋值       +=     -=     *=     /=     %=

3. 复合位运算赋值    &=     |=      ^=     >>=   <<=

int b;
int a = 10+5;
a = b = 10;// 从右向左赋值,左值不能是常量
int a;
a+=5;// 等价于 a = a+5;
a*=5;// 等价于 a = a*5
a+=5*6+4;// 等价于 a = a+(5*6+4);

代码示例:错误地使用运算符

// 对常量进行自加或自减
int d = 10++; // 编译报错

// 切勿使同一变量在同一运算中多次自增或自减
int d = 10;
int c = d++ + ++d;// 计算机并没有那么智能,存在歧义的指令,会产生警告
// 如何改正:添加小括号的目的,就是明确执行顺序
int x = (d++)+(++d);

■ 关系运算

关系运算的结果只有 2 种情况:真和假。注:C 语言中没有布尔类型

条件成立就为真,值是 1;条件不成立就为假,值是 0

有 6 种关系运算符,分别是:<     <=     >     >=     ==     !=  其中 == 和 != 优先级相等、其他四个关系运算符的优先级相等,注意 == 和 != 的优先级低于后四者

关系运算符中若优先级相同则 从左往右 结合,比如 4 > 3 < 2 则运算顺序是  (4 > 3) < 2。关系运算的优先级小于算术运算,比如 3 + 4 > 8 -2   相当于  (3 + 4) > (8 - 2)

■ 逻辑运算

逻辑运算有 3 种:与 &&、或 ||、非 !

逻辑运算结果也只有两个:真或假

 1 #include <stdio.h>
 2 #include <stdbool.h>
 3 /*
 4  *  C 语言里面虽然没有布尔类型的,但是在 C99 标准里又定义了布尔类型变量
 5  *  C 语言要使用布尔类型,只需引入头文件 #include <stdbool.h> 即可
 6  */
 7 int main(int argc, const char * argv[]) {
 8 
 9     int a = 7;
10     int b = 9;
11     bool result = a > b;
12     printf("%d\n", result);// 0
13 
14     // 逻辑与的短路现象:逻辑与后面的不再判断
15     int c = -5;
16     result = a > b && ++c;
17     printf("逻辑与结果:%d\n", result);   // 0
18     printf("验证逻辑与的短路现象 %d\n",c); // -5
19 
20     // 逻辑或的短路现象:逻辑或后面的不再判断
21     result = a < b  ||  c--;
22     printf("逻辑或的结果:%d\n",result);   // -5
23     printf("验证逻辑或的短路现象 %d\n", c );// 0
24 
25     return 0;
26 }

■ 条件运算

单目运算:1 个数值参与的运算 

双目运算:2 个值参与的运算

三目运算:3 个数值参与的运算。注:C 语言中唯一的一个三目运算,格式如 条件表达式 ? 数值 x : 数值 y

■ 位运算

就是按二进制位进行运算,有 6 种:位与 &、位或 |、位非 ~、位异或 ^、左移 <<、右移 >>

1. 位与:两个二进制位均为 1         则结果为 1 否则为 0

2. 位或:两个二进制位有一个为 1  则结果为 1 否则为 0

3. 位异或:两个二进制位不相等     则结果为 1 否则为 0。它有以下特点

    ① 相同的整数异或后的结果是 0

    ② 异或运算顺序可以交换,比如 9^5^9 == 9^9^5

    ③ 任何数值跟 0 进行异或,结果还是原来的数值。比如 a^b^a == b

4. 位非:~0111 = 1000

5. 左移 <<:a<<n 把整数 a 的二进制位全部左移 n 位,高位丢弃,低位补零。左移 n 位的实质其实是乘以 2 的 n 次方,但是要考虑到符号位会被丢弃,所以结果可能会改变正负性。比如 9<<2 的结果 9 * 2^2 = 36:0000 1001  ->  0010 0100

6. 右移 >>:a>>n 把整数 a 的二进制位全部右移 n 位,低位丢弃,符号位不变。一般情况下高位用符号位补齐,右移的实质其实是除以 2 的 n 次方

代码示例:位运算

1. 通过位异或运算可交换两个变量的值

int a = 101;
int b = 202;
a = a^b;
b = a^b;
a = a^b;
printf("a=%d,b=%d\n",a,b);

2. 通过按位与运算可判断整数奇偶性

printf("请输入需要判断的整数:\n");
int n = 0;
scanf("%d",&n);
if((n&1)==1)
  printf("这个数是奇数\n");
else if((n&1)==0)
  printf("这个数是偶数\n");

3. 把一个整数按照二进制格式输出

 1 void putBinary(int number){
 2 
 3     // 以 32 位机器数为例:int 占 4 字节
 4     int count = (sizeof(number)<<3) - 1;
 5     printf("%d\n",count);// 31
 6 
 7     // 遍历输出二进制
 8     while(count >= 0){
 9         // 将这个整数右移 count 位后,进行位与 1 的操作,即可获取到该位数
10         int value = (number >> count)&1;
11         printf("%d",value); // 输出
12 
13         // 每四位搞一个间隔
14         if(count % 4 == 0){
15 
16              printf(" ");
17         }
18         count--;
19     }
20     printf("\n");
21 }

日志输出

■ 其他运算符

其他常见的运算符还有以下几种

1. 逗号运算

2. 指针运算符:取内容 * 和 取地址 &

3. 求字节运算符 sizeof:用于计算数据类型所占的字节数。 注:它是个运算符,不是函数

4. 特殊运算符:括号() 、下标[ ]、成员 (-> 和 . ) 

■ 类型转化

显式类型转化:采用强制手段进行数据类型转化

隐式转换发生在不同数据类型的量混合运算时,由编译器系统自动完成,自动转换遵循以下规则

1. 若参与运算量的类型不同,则先转换成同一类型然后进行运算。转换按数据长度增加的方向进行,以保证精度不降低(如 int 和 long 运算时,先把 int 转成 long 后再进行运算)

2. 在赋值运算过程中,赋值号两边量的数据类型不同时,赋值号右边量的类型转换成左边量的类型。比如右边数据类型长度比左边数据类型长时将丢失一部分数据(丢失的部分按四舍五入向前舍入)

注:char 型数据和 short 型数据参与运算时,必须先转换成 int 型数据!另外,所有浮点运算都是以双精度进行的,即使仅含 float 型运算的表达式也要先转化成 double 型后运算

代码示例:数据类型转化

 1     double d = (double)3/2;  // d 是 1.500000,
 2     double e = (double)(3/2);// 先计算 3/2 值,再对结果进行强制类型转换 e 是 1.000000
 3 
 4     int a = 10/3;      // a 是 3
 5     double b = 10/3;   // b 是 3.000000
 6     double c = 10.0/3; // c 是 3.333333
 7 
 8     int x = 10.8;     // 会有数据精度丢失警告 x 是 10
 9     double y = 10.6+6;// y 是 16.600000
10     int z = (int)10.8;// z 是 10
11 
12     float pi = 3.14;
13     int s = 0,r = 5;
14     s = r * r * pi;// r 和 pi 会转换成 double 型进行计算,结果为 double 型。但是 s 是整型,故最终结果是整型
15     printf("s = %d\n",s);// 78

 

posted on 2017-08-02 11:30  低头捡石頭  阅读(192)  评论(0)    收藏  举报

导航