评论

收藏

[C++] 初识C语言(二)

编程语言 编程语言 发布于:2021-07-18 10:34 | 阅读数:294 | 评论:0

C语言学习笔记(二)

初识C语言(一)
主要内容:运算符的相关知识
 

一、位运算符

位运算符用来对二进制位进行操作

包括:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、按位左移(<<)、按位右移(>>)


  • 0 表示假
  • 1 表示真
在讲解之前先把十进制数对应的二进制数给一一列出来

十进制数二进制数
10001
20010
30011
40100
50101
60110
70111
81000
91001
 


  •   & :按位与
int a = 3;
int b = 5;
int c = a & b;
printf("%d\n",c);
运行结果:1
DSC0000.jpg

按位与:当上下两位同为真时结果为真,否则结果为假

 


  •   |   :按位或
int a = 3;
int b = 5;
int c = a | b;
printf("%d\n",c);
运行结果:7
DSC0001.jpg

按位或:上下两位只要有一位为真,结果就为真

 


  •   ^  :按位异或
int a = 3;
int b = 5;
int c = a ^ b;
printf("%d\n",c);
运行结果:6
DSC0002.jpg

按位异或:上下两位都为真时结果为假,相异时结果为真

 

二、复合赋值符

包括:=、+=、-=、*=、/=、&=、^=、|=、>>=、<<=

DSC0003.jpg
a = a + 10;
a + = 10;
上述两句代码是完全等价的,其他的复合赋值符也是同样的用法。

 

三、运算符

包括:单目运算符、双目运算符、三目运算符

(1)单目运算符:

单目运算符是指运算所需变量为一个的运算符,即在运算当中只有一个操作数,又叫一元运算符。

具体有哪些呢?下面就来一一讲解


  • 逻辑非运算符(!)
代码一
int a = 10;
printf("%d\n",a);
printf("%d\n",!a);
运行结果:
10
0
代码二
int a = 0;
printf("%d\n",a);
printf("%d\n",!a);
运行结果:
0
1
为什么会是这样呢?

前面我们说过了,在C语言中 0 表示假, 1 表示真(实际上所有非0的数都表示真,包括负数)

在代码一中 a 的值是 10 表示真,!a 逻辑取反,所以就为假,因为假对应的是 0 ,故输出结果为 0

在代码二中 a 的值是 0 表示假,!a 逻辑取反,所以就为真,因为真对应的是 1 ,故输出结果为 1 (这里不会是其它的值,就是1,不要误以为它还会是 10 或者其它的数)


  • 符号(-)
  • 正号(+)----这个正号无实际价值啊!
  • 取地址运算符(&)----这个后面再补充
  • 指针运算符(*)----这个后面再补充
  • 长度运算符(sizeof)
sizeof 是运算符,可用于任何变量名、类型名或常量值,当用于变量名(不是数组名)或常量时,它不需要用圆括号。它在编译时起作用,而不是运行时起作用。
何为不需要圆括号?举个栗子
int a = 10;
printf("%d\n",sizeof(a));
printf("%d\n",sizeof a );
这就是不需要圆括号,因为a是一个变量名
printf("%d\n",sizeof(int));
运行结果:4
当然,这种情况下就不能去圆括号了,否则就报错了

用sizeof来计算数组的长度,(单位:字节)
int arr[10] = {0};
printf("%d\n",sizeof(arr));
运行结果:40
       为什么是40呢?

先来了解一下数组吧:



  • 一个数组中的所有元素具有相同的数据类型
  • 将有限个类型相同的变量的集合命名,那么这个名称为数组名
我们把 arr 这个数组定义为 int 类型,我们知道 一个 int 类型大小为 4 个字节,arr 数组里一共有 10 个元素,都为 int 类型,那么整个数组大小就为:4 × 10 = 40,(单位:字节)

DSC0004.jpg

所以sizeof(arr)计算的就是数组的总大小,举一反三,我们是不是可以由总大小算出数组元素的个数,上代码:
int sz = 0;  //保存元素个数
int arr[10] = {0};
sz = sizeof(arr)/sizeof(arr[0]);
printf("sz = %d\n",sz);
运行结果:sz = 10

  • 按位取反运算符(~)
对一个数的二进制按位取反
int a = 0;
int b = ~a;
printf("%d\n",b);
运行结果:-1
什么叫取反,就是:我是 1 他就是 0 ;我是 0 他就偏是 1 

DSC0005.jpg

那么现在来解释一下为什么 b 的结果是 -1 ,这里涉及到原码、反码、补码、的知识点(不理解没关系,后面还会讲)

我们定义 0 是一个整型数字,大小为 4 个字节,一个字节 8 个位,4个字节就 32 个位

故a:00000000000000000000000000000000  (32个0,不用去数,我已经数过了!)

取反:11111111111111111111111111111111  (32个1,这个是补码)

负数在内存中存储的时候,存储的是二进制补码

二进制里最高位表示符号位

最高位为0表示正数,最高位为1表示负数

DSC0006.jpg

11111111111111111111111111111111  最高位为 1 所以为负数,这里就解决了 -1 中负号的来源

算法:

原码求补码:符号位不变,其它位按位取反,得到反码,反码加 1 得到补码

补码求原码:符号位不变,补码减 1 得到反码,反码按位取反得到原码

 

因为负数在内存中是以二进制补码的形式存储的,所以 11111111111111111111111111111111  是补码,我们要把他转成原码

符号位不变 ,其他按位取反得到反码,所以反码:10000000000000000000000000000000

反码加 1 得到原码,所以原码: 10000000000000000000000000000001

拆解一下就更清楚了:

最高位 1 对应负号 - 

后面 0000000000000000000000000000001 对应的十进制是1,所以 10000000000000000000000000000001 的结果是 -1

这里要补充一点:printf()函数打印一个数时,打印的是这个数的原码


  • 自增运算符(++)
int a = 10;
int b = a++;
printf("a = %d,b = %d\n",a,b);
运行结果:a = 11 ,b = 10
这个 a ++ 叫做 后置加加 作用是先使用 a 的值,即先把 a 的值赋给 b ,使 b 的值为 10 ,然后 a 再自增加 1 ,此时 a 的值为 11
int a = 10;
int b = ++a;
printf("a = %d,b = %d\n",a,b);
运行结果:a = 11 , b = 11
这个 ++ a  叫做 前置加加 作用是先让 a 自增加 1 ,此时 a 的值为 11 ,再把 a 的值赋值给 b ,此时 b 的值为 11


  • 自减运算符(--)
int a = 10;
int b = a--;
printf("a = %d,b = %d\n",a,b);
运行结果:a = 9 , b = 10
这个 a -- 叫做 后置减减 作用是先使用 a 的值,即先把 a 的值赋给 b ,使 b 的值为 10 ,然后 a 再自减 1 ,此时 a 的值为 9
int a = 10;
int b = --a;
printf("a = %d,b = %d\n",a,b);
运行结果:a = 9 , b = 9
这个 -- a  叫做 前置减减 作用是先让 a 自减 1 ,此时 a 的值为 9 ,再把 a 的值赋值给 b ,此时 b 的值为 9


  • (类型):强制类型转换
int a = 3.14;
int a = (int)3.14;   //强制类型转换
作用:让某一类型转成另一种类型(一般不建议去写强制转换)

 

 

DSC0007.jpg

博文如果有什么错误的地方,大家在评论区给我留言,我会及时纠正,谢谢!



关注下面的标签,发现更多相似文章