c语言的操作符详解(数的源反补和整型提升,及进制转换)

操作符详解

  • 二进制介绍
    • 1.二进制
      • 1.1 2进制转10进制
      • 1.1.1 10进制转二进制数字
      • 1.2 2进制转8进制和16进制
        • 1.2.1 2进制转8进制
        • 1.2.2 2进制转16进制
  • 二.源码、反码、补码
  • 三.位移操作符
      • 3.1左移操作符
      • 3.1右移操作符
  • 四.位操作符:&、|、^
  • 五.逗号表达式
  • 六.下标访问[]、函数调用()
    • 6.1 [ ]下标引用操作符
    • 6.2 函数调用操作符
  • 七. 操作符的属性:优先级、结合性
    • 7.1 优先级
    • 7.2结合性
  • 八. 表达式求值
      • 8.1整型提升

二进制介绍

1.二进制

其实我们经常能听到2进制、8进制、10进制、16进制这样的讲法,那是什么意思呢?其实2进制、8进
制、10进制、16进制是数值的不同表⽰形式⽽已。
⽐如:数值15的各种进制的表⽰形式:

152进制:1111
158进制:17
1510进制:15
1516进制:F

⾸先我们还是得从10进制讲起,其实10进制是我们⽣活中经常使⽤的,我们已经形成了很多尝试:

  1. 10进制中满10进1
  2. 10进制的数字每⼀位都是0~9的数字组成
    二进制也是一样的
  1. 2进制中满2进1
  2. 2进制的数字每⼀位都是0~1的数字组成,那么 1101 就是⼆进制的数字了。

1.1 2进制转10进制

其实10进制的123表⽰的值是⼀百⼆⼗三,为什么是这个值呢?其实10进制的每⼀位是权重的,10进
制的数字从右向左是个位、⼗位、百位…,分别每⼀位的权重是 10^0 , 10 ^1 , 10 ^2 …
c语言的操作符详解(数的源反补和整型提升,及进制转换)_第1张图片

2进制和10进制是类似的,只不过2进制的每⼀位的权重,从右向左是: 2 , 2 , 2 … 0 1 2
如果是2进制的1101,该怎么理解呢?
c语言的操作符详解(数的源反补和整型提升,及进制转换)_第2张图片

1.1.1 10进制转二进制数字

c语言的操作符详解(数的源反补和整型提升,及进制转换)_第3张图片

1.2 2进制转8进制和16进制

1.2.1 2进制转8进制

8进制的数字每⼀位是0 ~ 7的,0~7的数字,各⾃写成2进制,最多有3个2进制位就⾜够了,⽐如7的⼆进制是111,所以在2进制转8进制数的时候,从2进制序列中右边低位开始向左每3个2进制位会换算⼀个8进制位,剩余不够3个2进制位的直接换算

:2进制的01101011 ,换成8进制:0153,0开好头的数组,会被当做8进制。

c语言的操作符详解(数的源反补和整型提升,及进制转换)_第4张图片

1.2.2 2进制转16进制

16进制的数字每⼀位是0~9,a ~f 的,0~9,a ~f的数字,各⾃写成2进制,最多有4个2进制位就⾜够了,⽐如 f 的⼆进制是1111,所以在2进制转16进制数的时候,从2进制序列中右边低位开始向左每4个2进制位会换算⼀个16进制位,剩余不够4个⼆进制位的直接换算

:2进制的01101011,换成16进制:0x6b,16进制表⽰的时候前⾯加0x
c语言的操作符详解(数的源反补和整型提升,及进制转换)_第5张图片

二.源码、反码、补码

整数的2进制表表示法有三种,即原码、反码和补码
三种表示方法均有符号位和数值位两部分,符号位都是⽤0表示“正”,⽤1表⽰“负”,⽽数值位最⾼位的⼀位是被当做符号位,剩余的都是数值位。

有符号的char取值范围是:-128-127
无符号的char取值范围是:0-255

正整数的源码、反码、补码相同
负整数的三种表示方法各不相同
源码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
对于整形来说:数据存放内存中其实存放的是补码。

c语言的操作符详解(数的源反补和整型提升,及进制转换)_第6张图片

三.位移操作符

3.1左移操作符

移位规则:左边抛弃、右边补0

c语言的操作符详解(数的源反补和整型提升,及进制转换)_第7张图片

3.1右移操作符

移位规则:⾸先右移运算分两种

  1. 逻辑右移:左边⽤0填充,右边丢弃
  2. 算术右移:左边⽤原该值的符号位填充,右边丢弃

逻辑右移1位演示
c语言的操作符详解(数的源反补和整型提升,及进制转换)_第8张图片
算术右移一位演示

c语言的操作符详解(数的源反补和整型提升,及进制转换)_第9张图片
警告⚠️:对于移位运算符,不要移动负数位,这个是标准未定义的。
例如:

int num = 10;
num>>-1;//error

四.位操作符:&、|、^

位操作符有:

& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数。

下面展示一道题目:

不能创建临时变量(第三个变量),实现两个数的交换。

#include 
int main()
{
 int a = 10;
 int b = 20;
 a = a^b;
 b = a^b;
 a = a^b;
 printf("a = %d b = %d\n", a, b);
 return 0;
}

五.逗号表达式

exp1, exp2, exp3, …expN

逗号表达式,就是⽤逗号隔开的多个表达式。
逗号表达式,从左向右依次执⾏。整个表达式的结果是最后⼀个表达式的结果。

int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);
//逗号表达式

这里的结果是c语言的操作符详解(数的源反补和整型提升,及进制转换)_第10张图片

六.下标访问[]、函数调用()

6.1 [ ]下标引用操作符

操作数:⼀个数组名 + ⼀个索引值

int arr[10];//创建数组
arr[9] = 10;//实⽤下标引⽤操作符。
[ ]的两个操作数是arr和9

6.2 函数调用操作符

接受⼀个或者多个操作数:第⼀个操作数是函数名,剩余的操作数就是传递给函数的参数。

#include 
void test1()
{
 printf("hehe\n");
}
void test2(const char *str)
{
 printf("%s\n", str);
}
int main()
{
 test1(); //这⾥的()就是作为函数调⽤操作符。
 test2("hello bit.");//这⾥的()就是函数调⽤操作符。
 return 0;
}

七. 操作符的属性:优先级、结合性

C语⾔的操作符有2个重要0属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。

7.1 优先级

优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是不⼀样的。

3 + 4 * 5;

上⾯⽰例中,表达式 3 + 4 * 5 ⾥⾯既有加法运算符( + ),⼜有乘法运算符( * )。由于乘法的优先级⾼于加法,所以会先计算 4 * 5 ,⽽不是先计算 3 + 4 。

7.2结合性

如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执⾏顺序。⼤部分运算符是左结合(从左到右执⾏),少数运算符是右结合(从右到左执⾏),⽐如赋值运算符( = )。

5 * 6 / 2;

上⾯⽰例中, * 和 / 的优先级相同,它们都是左结合运算符,所以从左到右执⾏,先计算 5 * 6 ,再计算 6 / 2 。运算符的优先级顺序很多,下⾯是部分运算符的优先级顺序(按照优先级从⾼到低排列),建议⼤概记住这些操作符的优先级就⾏,其他操作符在使⽤的时候查看下⾯表格就可以了。

•圆括号( () )
• ⾃增运算符( ++ ),⾃减运算符( – )
• ⼀元运算符( + 和 - )
• 乘法( * ),除法( / )
• 加法( + ),减法( - )
• 关系运算符( < 、 > 等)
• 赋值运算符( = )

由于圆括号的优先级最⾼,可以使⽤它改变其他运算符的优先级。

c语言的操作符详解(数的源反补和整型提升,及进制转换)_第11张图片
参考链接:https://zh.cppreference.com/w/c/language/operator_precedence

八. 表达式求值

8.1整型提升

首先来介绍整数是占用4个字节,也就是我们说的32个bit位
有符号的整数:1位(符号位)+31位*(数值位)
符号位是1表示负数
符号位是0表示正数

C语⾔中整型算术运算总是⾄少以缺省整型类型的精度来进⾏的。
为了获得这个精度,表达式中的字符和短整型操作数在使⽤之前被转换为普通整型,这种转换称为整型提升。

char a,b,c;
...
a = b + c;

b和c的值被提升为普通整型,然后再执⾏加法运算。
加法运算完成之后,结果将被截断,然后再存储于a中。

如何进行整型提升

  1. 有符号整数提升是按照变量的数据类型的符号位来提升的
  2. ⽆符号整数提升,⾼位补0

下面我们来看代码

//负数的整形提升
char c1 = -1;

//正数的整形提升
char c2 = 1;

//⽆符号整形提升,⾼位补0

变量c1的⼆进制位(补码)中只有8个⽐特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
00000001
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001

你可能感兴趣的:(c语言,开发语言)