左边丢弃,右边补0
1 2 3 4 5 6 7 8
| int main() { int a = 2; int b = a << 1; printf("b = %d\n", b); return 0; }
|
1.算术右移:右边丢弃,左边补原符号位
2.逻辑右移:右边丢弃,左边补0
1 2 3 4 5 6 7
| #include<stdio.h> int main() { int a = -3; int b = a >> 1; printf("%d", b); }
|
负数在内存中存放的是二进制的补码。
原码:直接根据数值写出的二进制序列
反码:符号位不变,其他位按位取反
补码:反码+1
以-3为例:
原码:10000000000000000000000000000011
反码:11111111111111111111111111111100
补码:11111111111111111111111111111101
同为0,异为1
练习:a=3,b=5,交换a、b两个数的值
方法1:创建中间变量
1 2 3 4 5 6 7 8 9 10 11
| #include<stdio.h> int main() { int a = 3; int b = 5; int temp = 0; temp = a; a = b; b = temp; printf("a=%d,b=%d", a, b); }
|
方法2:加减运算(数值太大可能溢出)
1 2 3 4 5 6 7 8 9
| int main() { int a = 3; int b = 5; a = a + b; b = a - b; a = a - b; printf("a=%d,b=%d", a, b); }
|
方法三:异或运算
1 2 3 4 5 6 7 8 9 10
| #include<stdio.h> int main() { int a = 3; int b = 5; a = a ^ b; b = a ^ b; a = a ^ b; printf("a=%d,b=%d", a,b); }
|
同值异或值为0,任何值异或0都是值本身。a^a=0 0^a=a
单目运算符:
sizeof
也是单目运算符,可以计算变量所占空间的大小,单位是字节。
1 2 3 4 5 6
| int a = 5; int arr[5] = { 0 }; printf("%d\n", sizeof(a)); printf("%d\n", sizeof(int)); printf("%d\n", sizeof(arr)); printf("%d\n", sizeof(int [5]));
|
sizeof
(),括号内可以说变量名,也可以是变量类型,如果是变量名可以去掉小括号,如sizeof a
思考一下下面这段代码,两次输出是什么?
1 2 3 4
| short s = 5; int a = 10; printf("%d\n", sizeof(s = a + 2)); printf("%d\n", s);
|
输出结果是2、5。s的类型是short,sizeof(short)结果必然是2,而sizeof括号里的表达式不参与运算,所以s仍未5。
前置和后置:
1 2 3 4
| int a = 10; int b = a++; printf("%d\n", a); printf("%d\n", b);
|
1 2 3 4
| int a = 10; int b = ++a; printf("%d\n", a); printf("%d\n", b);
|
指针大小永远是4字节或8字节
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| void test1(int arr[]) { printf("%d\n", sizeof(arr)); } void test2(char ch[]) { printf("%d\n", sizeof(ch)); } int main() { int arr[10] = { 0 }; char ch[10] = { 0 }; printf("%d\n", sizeof(arr)); printf("%d\n", sizeof(ch)); test1(arr); test2(arr); return 0; }
|
结构成员访问操作符:.
->
. 结构体.成员名
-> 结构体指针->成员名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include<stdio.h> struct students { char name[10]; int age;
}; int main() { struct students a = { "胖虎",20 }; struct students *pb = &a; printf("姓名:%s,年龄:%d\n", a.name,a.age); printf("姓名:%s,年龄:%d", pb->name,pb->age); }
|
整型提升:
C的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| int main() { char a = 3; char b = 127; char c = a + b; printf("%d", c); return 0; }
|
整形提升是按照变量的数据类型的符号位来提升的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| char c1 = -1; 变量c1的二进制位(补码)中只有8个比特位: 1111111 因为 char 为有符号的 char 所以整形提升的时候,高位补充符号位,即为1 提升之后的结果是: 11111111111111111111111111111111
char c2 = 1; 变量c2的二进制位(补码)中只有8个比特位: 00000001 因为 char 为有符号的 char 所以整形提升的时候,高位补充符号位,即为0 提升之后的结果是: 00000000000000000000000000000001
|
总结:char和short类型,在参与表达式运算时达不到整型长度,会发生整型提升。