本次我会分享在学习C语言操作符后对它的理解,希望能帮到大家。
一.原码、补码、反码
1.数字在内存中储存的是它二进制的补码,对数字进行操作是操作它的补码,再换成原码输出结果。原码、反码、补码都是二进制数
2.正数的原码、反码、补码相同
3.如果是有符号的类型,原码的最高位储存的是数字的正负性。最高位为0表示正数,最高位为1表示负数
4.原码-->反码:最高位不变,其余位相反,即0变为1,1变为0
反码-->补码:反码+1
int a=8;
//原码:00000000000000000000000000001000
//反码:00000000000000000000000000001000
//补码:00000000000000000000000000001000
int b=-8;
//原码:10000000000000000000000000001000
//反码:11111111111111111111111111110111
//补码:11111111111111111111111111111000
二.算数操作符
1.种类:+ - * / %
2.除了%操作符之外,其它几个操作符都可以作用于整数和浮点数
3.对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数就执行浮点数除法
4.%操作符的两个操作数必须为整数,返回的是整除之后的余数
三.位移操作符
1.种类:<<左移操作符 >>右移操作符
2.负数右移先原码到补码,补码右移,再补码到原码,换成十进制数
3.负数右移,高位补1;正数右移,高位补0
4.左移低位补0
5.原码、反码、补码变换时,符号位(即最高位)不变
6.上面是有符号数字左右移,无符号数字左右移都是在空位补0
int main ()
{
int a = -12;
//原码:10000000000000000000000000001100
//反码:11111111111111111111111111110011
//补码:11111111111111111111111111110100
int b = a >> 2;
//右移:11111111111111111111111111111101
//补码:11111111111111111111111111111101
//反码:11111111111111111111111111111100
//原码:10000000000000000000000000000011
//十进制数:-3
int c = a << 2;
//左移:11111111111111111111111111010000
//补码:11111111111111111111111111010000
//反码:11111111111111111111111111001111
//原码:10000000000000000000000000110000
//十进制数:-48
printf("%d %d", b,c);
return 0;
}
//输出:-3 -48
四.位操作符
1.& 按位与(对应的二进制位都为1才为1)
int a = 3; //00000000000000000000000000000011
int b = 5; //00000000000000000000000000000101
int c = a & b;//00000000000000000000000000000001
printf("%d\n",c)
2.| 按位或(对应的二进制位有1就为1)
int a = 3; //00000000000000000000000000000011
int b = 5; //00000000000000000000000000000101
int c = a | b; //00000000000000000000000000000111
printf("%d", c);
3.^ 按位异或(对应的二进制位相同为0,相异为1)
int a = 3; //00000000000000000000000000000011
int b = 5; //00000000000000000000000000000101
int c = a ^ b; //00000000000000000000000000000110
printf("%d", c);
eg:
//不使用第三个变量,交换两个数的值
int a = 3;
int b = 5;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a=%d b=%d\n", a,b);
五.单目操作符
1.sizeof
eg1:
int a = 0;
char b = '#';
int arr[10] = { 0 };
printf("%d", sizeof(a));
printf("%d", sizeof(int));
printf("%d", sizeof(b));
printf("%d", sizeof(arr));
printf("%d", sizeof(int [10]));
//输出: 4 4 1 40 40
eg2:
short a = 0;
int b = 10;
printf("%d", sizeof(a));
printf("%d", sizeof(short));
printf("%d", sizeof(a=b+5));//sizeof里的表达式不直接参与运算
printf("%d", a);
输出: 2 2 2 0
2.~ 按位取反
(1) 按位取反是将补码所有位,包括符号位取反(仅此一处将符号位取反)
(2)正数按位取反将补码(补码与原码相同)按位取反,然后将补码转换为反码再转换为原码输出(此处不能将正数的补码直接等成原码,需要转换)
(3)负数按位取反将原码先转换为补码,补码按位取反,然后直接输出,不需要再转换成原码再输出
(4)简单方法:如对a按位取反,则得结果为-(a+1)。此运算方式对正数、负数和0都适用
eg:
int a =-10;
//原码:10000000000000000000000000001010
//反码:11111111111111111111111111110101
//补码:11111111111111111111111111110110
int b = 10;
//补码:00000000000000000000000000001010
printf("~a=%d", ~a);
//取反:00000000000000000000000000001001
//十进制数:9
printf("~b=%d", ~b);
//取反:11111111111111111111111111110101
//补码:11111111111111111111111111110101
//反码:11111111111111111111111111110100
//原码:10000000000000000000000000001011
//十进制数:-11
//输出:~a=9 ~b=-11
六.逻辑操作符
1.&&逻辑与(两个数都是真才为真,只要有假就为假)
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
//因为a=0,&&里只要有假就为假,所以不会再往后计算,只有a的值增加了1
printf(" a=%d\n b=%d\n c=%d\n d=%d\n",a,b,c,d);
输出: a=1
b=2
c=3
d=4
2.||逻辑或(只要有真就为真,两个都为假才为假)
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ || ++b || d++;
//因为||a=1,||里只要为真就为真,所以也不会再往后计算,只有a的值增加了1
printf(" a=%d\n b=%d\n c=%d\n d=%d\n",a,b,c,d);
输出: a=2
b=2
c=3
d=4
七.三目操作符
(exp1?exp2:exp3) 如果exp1为真,输出exp2,反之输出exp3
eg:
//求两个数中的较大值
int a = 10;
int b = 20;
int max = (a > b ? a : b);
printf("%d\n",max);
八.逗号表达式
逗号表达式是用逗号隔开的多个表达式,它从左到右依次执行。整个表达式的结果是最后一个表达式的结果
int a = 1, b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("c=%d", c);
输出:c=13
九.
.结构体操作符
->结构体指针操作符
eg:
struct Stu
{
char name[10];
int age;
char id[20];
};
int main()
{
struct Stu s1 = { "张三",20,"2019010305" };
struct Stu* ps = &s1;
printf("%s\n", (*ps).name);
printf("%s\n", ps->name);
printf("%s\n", s1.name);
printf("%d\n", (*ps).age);
printf("%d\n", ps->age);
printf("%d\n", s1.age);
printf("%s\n", (*ps).id);
printf("%s\n", ps->id);
printf("%s\n", s1.id);
return 0;
}
输出: 张三
张三
张三
20
20
20
2019010305
2019010305
2019010305
十.隐式类型转换
C的整型算数运算总是至少以缺少整型类型的精度来进行的。
为了提示这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通型,这种转换称为整型提示
1.负数的整型提示
char c1=-1
变量c1的二进制位(补码)中只有8个比特位:11111111
因为char为有符号的char
所以整型提升的时候,高位补充符号位,即为1,提升之后的结果是:
11111111111111111111111111111111
2.正数的整型提升
char c2=1
变量c2的二进制位(补码)中只有8个比特位:00000001
因为char为有符号的char
所以整型提升的时候,高位补充符号位,即为0,提升之后的结果是:
00000000000000000000000000000001
3.无符号整型提升,高位补0
int main()
{
char a=3;
//00000000000000000000000000000011
//00000011 //从最低位开始,截断8位
char b=127;
//00000000000000000000000001111111
//01111111 //从最低位开始,截断8位
//a和b如何相加为c(二进制相加)
//00000000000000000000000000000011
//00000000000000000000000001111111
//00000000000000000000000010000010
char c= a + b;
//10000010 //从最低位开始,截断8位
//11111111111111111111111110000010补码
//11111111111111111111111110000001反码
//10000000000000000000000001111110原码
//十进制数:-126
printf("%d",\n);
return 0;
}
输出:-126