文章目录
1.原码,反码,补码
整数的2进制表示方法有3种即原码,反码,补码
3个表示方法均有符号位和数值位
符号位中用正整数的原、反、补码都相同。负整数的三种表⽰⽅法各不相同。
原码:将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
整形数据存放在内存中的是补码、因为用补码可以符号位和数值位相统一
源码补码相转换都是取反+1
有符号整数:正整数,负整数
无符号整数可以按照正数理解
所以无符号整数原码,反码,补码相同
2.移位操作符
.<< 左移操作符
.>> 右移操作符
2.1左移操作符
左边抛弃,右边补0
2.2右移操作符
逻辑右移:左边用0补充抛弃,右边丢弃
算术右移: 左边用原该值的符号位填充,右边丢弃
逻辑右移还是算术右移取决于编译器,大部分编译器采用算术右移
不要移动负数位,这个是标准未定位的
3.位操作符
运算的两个数,按二进制位进行“与”运算。
1 &按位与
运算规则:只要两个数中的一个为0,结果就为0,否则为1。
1&0为0
0&1为0
1&1为1
0&0为0
2 | 按位或
运算规则:只要两个数中的一个为1,结果就为1,否则为0。
1|0为1
0|1为1
1|1为1
0|0为0
3 ^ 按位异或
运算规则:两个相应位为“异”,那么该位结果为1,否则为0.
1^0为1
0^1为1
1^1为0
0^0为0
注:他们的操作数必须是整数
一道有趣的题目
不能创建临时变量(第三个变量),实现两个数的交换
以下为方法:
a ^ a = 0
0 ^ a = a
a = a ^ b;
b = a ^ b; //a^b^b=a
a = a ^ b; //a^b^a=b
这种异或操作有局限性
1.只可以用于整数交换
2.代码的可读性差
3.代码的执行效率也是低于使用3个变量的方法
4.逗号表达式
exp1, exp2, exp3, …expN
表达式1,表达式2,…,表达式n
逗号表达式(优先级最低)
从左到右依次运算,整个表达式的结果是最后一个表达式的结果。
比如
i=3,i++,++i,i+5
这个逗号表达式的值为10,i的值为5
5.按位取反操作符 ‘~’(二进制是0的变成1,是1的变成0)
让13的2进制的第4位赋成1然后反赋回来
方法如下:
int main()
{
int a=13
a=a|(1<<4);
printf("a=%d\n",a);
a = a & ~(1<<4);
printf("a=%d \n",a)
return 0;
}
6.下标引用操作符[ ]
操作数+一个数组名
int arr[10];//创建数组
arr[9]=10;//引用下标操作符
[]的两个操作数是arr和9。
3+5
+ 3和5是加号的两个操作数
7.函数调用操作符
int add(int x,int y)
{
return x+y;
}
int main()
{
int ret =add(2,3);()-函数调用操作符
//()的操作数:add,2,3
//()函数调用操作符,最少有1个操作数
printf("%d",ret);
return 0;
}
那么sizeof是不是函数呢?
int a =10;
int n=sizeof a;// int n=sizeof (a);
printf("%d\n",n);
return 0;
//去了括号可以运行结果还是4。所以不是函数。
8.操作符属性:优先级,结合性
一定程度上决定了表达值的计算顺序。
8.1优先级
如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是不⼀样的。
参考:https://zh.cppreference.com/w/c/language/operator_precedence
8.2结合性
优先级相同的情况下考虑结合性,下⾯是部分运算符的优先级顺序(按照优先级从⾼到低排
列),建议大概记住这些操作符的优先级就行
9.整型提升
C语⾔中整型算术运算总是⾄少以缺省整型(int)类型的精度来进⾏的。
为了获得这个精度,表达式中的字符(char)和短整型(short)操作数在使⽤之前被转换为普通整型(int or unsigned int),这种转换称为整型提升。
1.有符号整数提升是按照变量的数据类型的符号位来提升的
2.无符号整数提升,高位补0
int main()
{
//char - signed char
char a=5;
//5-int-4个字节-32bit
//00000000000000000000000000000101
//00000101 - a (截断后存储到a中)
char b=127;
//00000000000000000000000001111111
//01111111 - b(截断后存储到b中)
char c=a+b;//发生整型提升
//00000000000000000000000000000101-a
//00000000000000000000000001111111-b
//00000000000000000000000010000100-a+b
//10000100-c
printf("%d\n",c);
//这里c还是要整形提升
//11111111111111111111111110000100-原码
//10000000000000000000000001111011-取反
//10000000000000000000000001111100-加1
//%d是按照10进制的形式打印有符号的整数
//结果是-124
return 0;
}