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

算术运算

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

① 加 +      还可表示正号

② 减 -      还可表示负号

③ 乘 *   

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

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

⑥ 自增 ++

⑦ 自减 --

2 - 如何实现加 1

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

3 - 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

赋值运算

1 - 共 11 种

① 简单赋值     =

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

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

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);

2 - 错误地使用运算符

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

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

关系运算

1 - 关系运算的结果只有 2 种情况:真和假。注:C 语言中没有布尔类型。件成立就为真,值是 1;条件不成立就为假,值是 0

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

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

逻辑运算

1 - 有 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 - 单目: 1 个数值参与的运算 

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

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

位运算

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

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

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

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

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

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

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

④ 位非:~0111 = 1000

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

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

2 - 代码示例:位运算

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

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

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

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

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

 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 - 显式类型转化:采用强制手段进行数据类型转化

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

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

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

注:char 型和 short 型参与运算时必须先转换成 int 型

      所有浮点运算都是以双精度进行的,即使仅含 float 型运算的表达式也要先转化成 double 型后运算

3 - 代码示例

 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  低头捡石頭  阅读(131)  评论(0编辑  收藏  举报

导航