文章目录金时虚度不觉察,技到用时慌匮乏。劝君莫生无用悔,一分一秒惜年华。
- 前言
- 1.移位 *** 作符
- 1.1 代码基础介绍
- 1.1.1 二进制,八进制,十进制,十六进制
- 1.1.1.1 二进制
- 1.1.1.2 八进制
- 1.1.1.3 十进制
- 1.1.1.4 十六进制
- 1.1.2 原码,反码,补码
- 1.2 左移 *** 作符,<<
- 1.2.1 正数左移
- 1.2.1 负数左移
- 1.3 右移 *** 作符,>>
- 1.3.1 算术右移
- 1.3.2 逻辑右移
- 2.位 *** 作符
- 2.1 按位与,&
- 2.2 按位或,|
- 2.3 按位异或,^
- 2.4 应用演示
- 3.赋值 *** 作符,=
- 4.单目 *** 作符
- 4.1 逻辑反,!
- 4.2 + - ,正负值
- 4.3 取地址 *** 作符,&
- 4.4 计算内存大小,sizeof
- 4.5 间接访问 *** 作符,解引用 *** 作符,*
- 4.6按位取反,~
- 4.7 a++,++a
- 4.8 关系 *** 作符,&&
- 4.9 关系运算符,||
- 4.10 条件 *** 作符,表达式1 ? 表达是2 : 表达式3,
- 4.11 逗号 *** 作符
- 4.12 下标引用 *** 作符,[ ]
- 4.13 函数调用 *** 作符,()
- 4.14 成员 *** 作符 . 和 ->
- 总结
前言
*** 作符,是一个很容易被忽视,被遗忘的知识,所以,yena将这个知识点整理出来,供大家和自己随时查阅和巩固。
1.移位 *** 作符 1.1 代码基础介绍 1.1.1 二进制,八进制,十进制,十六进制 1.1.1.1 二进制
二进制由数字 0 1 组成,例如00000101,计算方法为从右向左看
从右向左分别是1*2^0,0*2^1, 1*2^2,……相加,得出次二进制代码等于5.
1.1.1.2 八进制
8进制由数字0~7 组成。
二进制转八进制:二进制代码从右向左,每3位二进制数转为1位8进制。
第一步:分组,从右至左,每三位一组,不够三个数在左边补0.
第二步:计算出每一组的值,每一组按2的0次方,2的1次方,2的二次方计算,例如第一组是2+4=6.
第三步:将每组的值合到一起,就是转换后的8进制。如下,转换后的8进制为146
8进制转十进制:如下图,将8进制数146 转为十进制。
十进制数由数字0~9构成,和数学中的数字计算意义无异。
十进制转二进制:如下图,方法是除2取余数,最后从下至上,写下来,就是转换后的二进制数
十六进制代码由数字0~9,和字母A–F构成,A–F代表数字10–15.
二进制转十六进制:如下图,将二进制代码从右至左,每四位一组,不足时补0.计算出每一组的值,合起来就是转换后的十六进制。十六进制一般以0x开头。
十六进制转十进制,方法与八进制转十进制相同。
二进制代码最高位为符号位,最高位为0,此数为正数,最高位为1,说明此数为负数。
正数的原码反码补码都是本身。
负数的反码:符号位不变,其余按位取反
负数的补码:反码加1.
如下图实例。
注意:编译系统中,储存的是补码,打印出来的是原码。
5<<1,方法为5的补码左边删去1位,右边补0.
如下示例,将此二进制代码向左移一位,右边补0。大家可以在编译器上自行编写检验。
前面已经提到,编译器储存的是补码,打印出来的是原码,所以,如果是负数,需要先找到它的补码,计算完,再转为原码打印出来。例-5>>3
1.找到-5补码,左删一位,右边补0.
2.此时代码为补码,需要减1变成反码,之后取反变为原码,输出。
右移 *** 作分为算术右移和逻辑右移。
1.3.1 算术右移算术右移:右边丢弃,左边全补符号位。注意负数需要先找补码,计算完,在转原码。
方法与左移相同,大家自己要动手算一遍
右边丢弃,左边补0.不常用,因为可能会改变负数的符号。
注意左移右移只能移整数位。
&的计算规则是,例3&5,将3和5的每一位二进制代码比较,同1为1,其余情况为0。如下图所示,将3和5的二进制代码列出来,经&计算,得出c = 1
为什么a的二进制代码有32位1呢?因为,a是int整型,占4个字节,一个字节为8个bit位,4个字节就占32位啦。这里给出换算关系。8bit = 1 byte ,1024byte = 1KB。1024KB = 1MB, 1024MB = 1GB。
按位或的计算原则是,例3 | 5,写出3,5的二进制补码,每一位二进制代码进行比较,同0位0,其余情况为1,如下图所示 3 | 5 = 7。
按位异或^ 的计算原则是,例3 ^ 5,依然,将3 5 的二进制代码列出,每一位进行比较,相异为1,相同为0,如下图所示,3 ^ 5=6.
这种运算符有什么用处呢?
例题:交换两个整数值,不能创建临时变量
说到交换两个数的数值,我们首先考虑的是,创建临时变量temp
{
int temp = a;a = b ; b = temp ;
}
但是不允许创建临时变量temp,就是只能有a,b两个变量。大家想一下,还有什么下出办法呢?
这里提供两种思路,
第一种:若a,b有范围限制的话,可通过:a=a+b, b=a-b, a=a-b;来进行数值交换,如下图所示。
但这种方法存在问题,若a,b数值特别大,则a+b有可能超出整型所能表示的范围(-2147483648 ~ 2147483647)。
这里推荐第二种,利用 ^ 支持交换律
大家可以按照上面所讲的按位异或计算原则,计算
3 ^ 5 ^ 3和3 ^ 5 ^ 5 的计算结果,这里给出答案。
3 ^ 5 ^ 3 = 5 ;
3 ^ 5 ^ 5 = 3 ;
同样,请大家猜一下如下代码的输出结果
printf("%d\n", 5 ^ 5 ^ 3);
printf("%d\n", 5 ^ 3 ^ 3);
printf("%d\n", 3 ^ 5 ^ 3);
printf("%d\n", 5 ^ 5 ^ 3 ^ 3);
printf("%d\n", 5 ^ 5 ^ 3 ^ 3 ^ 5);
答案如下,你都做对了没?
这种方法比较慢,并且只适用于整型,所以正常情况不使用这种方法,在面试题中,面试官为考察基础,可能会考到。
连续赋值的代码,例如a = x = y+1 ,运算顺序是从右向左,不建议这么写,代码应追求简洁易读易修改。
4.单目 *** 作符 4.1 逻辑反,!(!1)=0,(!0=1)用于if判断语句
4.2 + - ,正负值%d表示无符号整型,即不带符号,%u为有符号整型,可获取负数。
4.3 取地址 *** 作符,&得出变量地址,例int 型四个字节,int a;int *p = &a ;取的是a的首字节地址,x86环境下,指向各种数据类型的指针统一为四个字节
4.4 计算内存大小,sizeofsizeof a 计算变量内存大小,以字节为单位,点下面链接,可详细了解sizeof与strlen的应用,此处不做赘述。
链接: https://editor.csdn.net/md/?articleId=124376581
int a = 1;
int *p = &a;//此处的*代表p是指针变量,int表示指针指向的变量为int型
*p; //此处的*指的是访问指针p所指向的变量
4.6按位取反,~
二进制代码,每一位1变0,0变1,负数需要找到补码,运算后,减1取反变原码,输出·
4.7 a++,++a文章链接如下,之前写过一次,本篇不赘述。
链接: https://editor.csdn.net/md/?articleId=124348426
a. && ,a&&b,同真为真,只要不是0,就是真,注意a&&b&&c,若a为假,则可以判断语句为加假不执行b,c
4.9 关系运算符,||a||b||c,有真则真,同假为假,若a为1,则可以判断语句为真,不执行b,c
4.10 条件 *** 作符,表达式1 ? 表达是2 : 表达式3,表达式1 ? 表达是2 : 表达式3,例b=(2>3)?1: 0;int max=(a>b?a:b)
意思为,若表达式1成立,执行表达式2,否则,执行表达式3
从左到右算,最后的表达式为整条表达式结果
如下图所示,依次从左向右执行,最终为a的值
即数组下标,arr[7]执行顺序为[],arr,7;与7 [arr]的作用相同, 7 [arr]的执行顺序是[],7,arr。
4.13 函数调用 *** 作符,()add(a,b)中的()为函数调用 *** 作符,不能省略
4.14 成员 *** 作符 . 和 ->用于结构体变量访问结构体成员
struct Stu a ;
a.name="fudsb";
struct Stu *b=&a;
b->name="abcds";
b->name,(*b).name,作用相同
总结
本篇讲的是进制转换和 *** 作符,一定要亲手实践呀~无误,记录第一次使用画图,也没有很难,嘻嘻。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)