C语言操作符
目录
C语言操作符
位运算
补充:
对于数来说内存中存储的是二进制的补码,正数的原码,反码,补码相同,负数不同
原码:原始的二进制数字,-1的二进制数字为eg:10000000000000000000000000000001
反码:原码符号位保持不变,其他位按位取反eg:11111111111111111111111111111110
补码:反码+1eg:11111111111111111111111111111111
用二进制的最高位表示符号位,0为正,1为负。
左移操作符
左边丢弃,右边补0
右移操作符
右移操作符分为:
- 算数右移:右边丢弃,左边补原符号位
- 逻辑右移:右移丢弃,左边补0
#include <stdio.h>
int main(void)
{
int number_1 = 11;
number_1 = number_1 << 2; // 11*2的2次方
int number_2 = 22;
int number_3 = -1;
number_2 = number_2 >> 2; // 22/2的2次方
number_3 = number_3 >> 1;
printf("%d\n", number_1); // 44
printf("%d\n", number_2); // 5
printf("%d\n", number_3); // 算数右移
}
&,|,^ (按位与,按位或,按位异或)操作符
#include <stdio.h>
int main(void)
{
int number_1 = 3, number_2 = 5, number_3 = -1;
// &,|,^必须是整数
printf("%d\n", number_1 & number_2); // 有0则0
printf("%d\n", number_1 | number_2); // 有1则1
printf("%d\n", number_1 ^ number_2); // 相同为0,相异为1
printf("%d\n", number_1 ^ number_1); // 0
printf("%d\n", 0 ^ number_1); // 3
printf("%d\n", ~number_3); // 按位取反 0
return 0;
}
关于^操作符
任何两个相同的数字^结果都是0,0^任何一个数都是本身
实现两数交换
第一种实现方法
定义一个临时变量
#include <stdio.h>
int main(void)
{
int number_1 = 1, number_2 = 2, temp;
temp = number_1;
number_1 = number_2;
number_2 = temp;
printf("%d,%d\n", number_1, number_2);
return 0;
}
第二种实现方法
不使用临时变量,使用简单的加减法,但是这样会有一个错误,如果一个数,超过了32767这个数,会造成栈的溢出,所以不建议使用这种方法
#include <stdio.h>
int main(void)
{
int number_1 = 10, number_2 = 13;
number_1 = number_1 + number_2;
number_2 = number_1 - number_2;
number_1 = number_1 - number_2;
printf("%d,%d\n", number_1, number_2);
return 0;
}
第三种实现方法
这种方法是在第二种方法的基础上进行延申过来的,这个使用了按位异或运算符
#include <stdio.h>
int main(void)
{
int number_1 = 10, number_2 = 13;
// 1010 = 10
// 1101 = 13
// 0111 = 7
number_1 = number_1 ^ number_2; // 0111 = 7
number_2 = number_1 ^ number_2; // 1010 = 10
// <==> number_1 ^ number_2 ^ number_2 <==> number_1 ^ 0 = number_1
number_1 = number_1 ^ number_2; // 1101 = 13
// 异或是相同为0,不同为1
printf("%d,%d\n", number_1, number_2);
return 0;
}
|(按位或操作符)
#include <stdio.h>
int main(void)
{
// 将二进制位中的第五位改为1
int number_1 = 13, number_2 = 0, number_3;
// 01101 = 13
// 10000 = 1 << 4 "|"
// 11101
number_2 = number_1 | (1 << 4);
printf("%d\n", number_2);
// 将number_2修改为原来的数字,即将二进制位中的第五位改为0
number_3 = number_2 & ~(1 << 4);
// 11101 = 29
// 01111 = ~10000 = 1 << 4 "&"
// 01101 = 13
printf("%d\n", number_3);
return 0;
}
三目运算符
注意表达式的结构
#include <stdio.h>
int main(void)
{
// 三目运算符
int number_1 = 5, number_2 = 0;
if (number_1 > 10)
{
number_2 = 1;
}
else
{
number_2 = -1;
}
// 三目运算符,与上面的if-else语句类似
number_2 = (number_1 > 10) ? 2 : -2;
printf("%d\n", number_2);
return 0;
}
逗号表达式","
逗号表达式:要从左向右依次计算,但是整个表达式的结果是最后一个表达式的结果,不能直接计算最后一个表达式,因为前面的表达式也有可能影响后面的结果
#include <stdio.h>
int main(void)
{
// 逗号表达式
int number_1 = 3, number_2 = 5, number_3 = 0;
int number_4 = (number_3 = 5, number_1 = number_3 + 3, number_2 = number_1 - 4, number_3 += 5);
printf("%d\n", number_4); // 10
return 0;
}
结构成员访问操作符
分为.操作符(值操作符),和->操作符(地址操作符)
.:结构体变量名.成员名,->:结构体指针->成员名
#include <stdio.h>
struct Book
{
char *BookName;
char *BookNumber;
int BookMoney;
};
int main(void)
{
struct Book book = {"杀死一只知更鸟", "123456789", 100};
struct Book *pbook = &book;
// . 结构体变量名.成员名
// -> 结构体指针->成员名
// 这三种方式的实现效果是一样的
printf("%s\n", book.BookName);
printf("%s\n", (*pbook).BookNumber);
printf("%d\n", pbook->BookMoney);
return 0;
}