C语言 *** 作符 详解及二进制,八进制,十进制,十六进制的转换

C语言 *** 作符 详解及二进制,八进制,十进制,十六进制的转换,第1张

金时虚度不觉察,技到用时慌匮乏。劝君莫生无用悔,一分一秒惜年华。

文章目录
  • 前言
  • 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 转为十进制。

1.1.1.3 十进制

十进制数由数字0~9构成,和数学中的数字计算意义无异。
十进制转二进制:如下图,方法是除2取余数,最后从下至上,写下来,就是转换后的二进制数

1.1.1.4 十六进制

十六进制代码由数字0~9,和字母A–F构成,A–F代表数字10–15.
二进制转十六进制:如下图,将二进制代码从右至左,每四位一组,不足时补0.计算出每一组的值,合起来就是转换后的十六进制。十六进制一般以0x开头。

十六进制转十进制,方法与八进制转十进制相同。

1.1.2 原码,反码,补码

二进制代码最高位为符号位,最高位为0,此数为正数,最高位为1,说明此数为负数。
正数的原码反码补码都是本身。
负数的反码:符号位不变,其余按位取反
负数的补码:反码加1.
如下图实例。
注意:编译系统中,储存的是补码,打印出来的是原码

1.2 左移 *** 作符,<< 1.2.1 正数左移

5<<1,方法为5的补码左边删去1位,右边补0.
如下示例,将此二进制代码向左移一位,右边补0。大家可以在编译器上自行编写检验。

1.2.1 负数左移

前面已经提到,编译器储存的是补码,打印出来的是原码,所以,如果是负数,需要先找到它的补码,计算完,再转为原码打印出来。例-5>>3
1.找到-5补码,左删一位,右边补0.
2.此时代码为补码,需要减1变成反码,之后取反变为原码,输出。

1.3 右移 *** 作符,>>

右移 *** 作分为算术右移和逻辑右移。

1.3.1 算术右移

算术右移:右边丢弃,左边全补符号位。注意负数需要先找补码,计算完,在转原码
方法与左移相同,大家自己要动手算一遍

1.3.2 逻辑右移

右边丢弃,左边补0.不常用,因为可能会改变负数的符号。
注意左移右移只能移整数位。

2.位 *** 作符 2.1 按位与,&

&的计算规则是,例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

2.2 按位或,|

按位或的计算原则是,例3 | 5,写出3,5的二进制补码,每一位二进制代码进行比较,同0位0,其余情况为1,如下图所示 3 | 5 = 7。

2.3 按位异或,^

按位异或^ 的计算原则是,例3 ^ 5,依然,将3 5 的二进制代码列出,每一位进行比较,相异为1,相同为0,如下图所示,3 ^ 5=6.

2.4 应用演示

这种运算符有什么用处呢?
例题:交换两个整数值,不能创建临时变量
说到交换两个数的数值,我们首先考虑的是,创建临时变量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); 

答案如下,你都做对了没?

这种方法比较慢,并且只适用于整型,所以正常情况不使用这种方法,在面试题中,面试官为考察基础,可能会考到。

3.赋值 *** 作符,=

连续赋值的代码,例如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 计算内存大小,sizeof

sizeof a 计算变量内存大小,以字节为单位,点下面链接,可详细了解sizeof与strlen的应用,此处不做赘述。
链接: https://editor.csdn.net/md/?articleId=124376581

4.5 间接访问 *** 作符,解引用 *** 作符,*
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

4.8 关系 *** 作符,&&

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

4.11 逗号 *** 作符

从左到右算,最后的表达式为整条表达式结果
如下图所示,依次从左向右执行,最终为a的值

4.12 下标引用 *** 作符,[ ]

即数组下标,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,作用相同


总结

本篇讲的是进制转换和 *** 作符,一定要亲手实践呀~无误,记录第一次使用画图,也没有很难,嘻嘻。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/920839.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存