& 按(2进制)位与
| 按(2进制)位或
^ 按(2进制)位异或
1,不创建临时变量(第三个变量),实现两个数的交换
2,~ 单目运算符 按位取反
3,按位与,按位或 的使用
4,sizeof的应用
5,按位与,按位或 同 逻辑与,逻辑或
6,逻辑与,逻辑或 的应用
7,关于 [] 引用符的深刻理解
8,结构体的练习
1,不创建临时变量(第三个变量),实现两个数的交换
#include<stdio.h>
//不创建临时变量(第三个变量),实现两个数的交换
//方法一:这种方法会有溢出问题
//int main() {
// int a = 3;
// int b = 5;
// printf("交换前: a=%d b=%d\n", a, b);
// a = a + b;
// b = a - b;
// a = a - b;
// printf("交换前: a=%d b=%d\n", a, b);
// return 0;
//}
//方法二:正确的方法 -> 异或
//异或支持交换律
//3^3^5=5
//3^5^3=5
int main() {
int a = 3;
int b = 5;
printf("交换前: a=%d b=%d\n", a, b);
a = a ^ b;//011^101 = 110
b = a ^ b;//110^101 = 011
a = a ^ b;//110^011 = 101
printf("交换前: a=%d b=%d\n", a, b);
return 0;
}
2,~ 单目运算符 按位取反
#include<stdio.h>
// ~ 单目运算符 按位取反
int main() {
//int a = 0;
//// ~ 是按二进制位取反
////00000000000000000000000000000000000000000000000 补码
////11111111111111111111111111111111111111111111111 ~a
////11111111111111111111111111111111111111111111110 ~a-1
////10000000000000000000000000000000000000000000001 (~a-1)取反 ==>得到(~a)的源码
//printf("%d\n", ~a);//-1
int a = 3;
// ~ 是按二进制位取反
//00000000000000000000000000000000000000000000011 补码
//11111111111111111111111111111111111111111111100 ~a
//11111111111111111111111111111111111111111111011 ~a-1
//10000000000000000000000000000000000000000000100 (~a-1)取反 ==>得到(~a)的源码
printf("%d\n", ~a);//-4
}
3,按位与,按位或 的使用
#include<stdio.h>
int main() {
int a = 13;
//a |= (1 << 1);
a |= (1 << 4);
printf("%d\n", a);
//29又如何恢复到13
a &= (~(1 << 4));//1先左移四位,然后全部按位取反,然后相与
printf("%d\n", a);
//0000000000000000000000000000000011101 29
//1111111111111111111111111111111101111 相与
//0000000000000000000000000000000001101
//
//0000000000000000000000000000000001101 13
//0000000000000000000000000000000000010 1左移1位
//0000000000000000000000000000000001111 相或 15
//0000000000000000000000000000000001101 13
//0000000000000000000000000000000010000 1左移4位
//0000000000000000000000000000000011101 相或 29
}
4,sizeof的应用
#include<stdio.h>
//sizeof的应用
void test1(int arr[]) {
printf("%d\n", sizeof(arr));// 4/8
}
void test2(char ch[]) {
printf("%d\n", sizeof(ch));// 4/8
}
int main() {
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("%d\n", sizeof(arr));//40
printf("%d\n", sizeof(ch));//10
test1(arr);//注意这两个传的都是地址
test2(ch);
return 0;
}
5,按位与,按位或 同 逻辑与,逻辑或
#include<stdio.h>
//按位"与&"和按位"或|" 同二进制位相关
// 逻辑"与&&"和逻辑"或||" 同值的真假相关
int main() {
int a = 3;
int b = 6;
int c = a && b;//并且
int c = a || b;//或者
printf("%d\n", c);//输出1
return 0;
}
6,逻辑与,逻辑或 的应用
#include<stdio.h>
//&& 左边为假,右边就不计算了
//|| 左边为真,右边就不计算了
//
int main() {
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++; //输出: 1 2 3 4
//注意:a++ 是先用 所以说&&符号前是 0 ,之后++b根本都没有计算,只有a++先用后加,变为1
i = a++ || ++b || d++;//输出: 1 3 3 4
//注意:a++先用 所以||符号前为 0 ,之后++b为真,那么d++根本都不用计算
printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d);
return 0;
}
7,关于 [] 引用符的深刻理解
#include<stdio.h>
//关于 [] 引用符的深刻理解
int main() {
int arr[10] = { 0 };
//
//arr[7] ---> *(arr+7) --> *(7+arr) --->7[arr]
//
// arr是数组首元素的地址
//arr+7就是跳过7个元素,指向了第8个元素
//*(arr+7) 就是第8个元素
//
arr[7] = 8;// 引用符: [] 操作符: 7 arr
7[arr] = 9;//定义(初始化时不行),访问时可以
return 0;
}
8,结构体的使用
#include<stdio.h>
#include<string.h>
struct Stu
{
char name[20];
int age;
double score;
};
void set_stu(struct Stu *ps) {
/*strcpy((*ps).name, "zhangsan"); // 结构体对象.成员
(*ps).age = 20;
(*ps).score = 100;*/
//更简化的做法
strcpy(ps->name, "zhangsan"); //结构体指针->成员
ps->age = 20;
ps->score = 100.0;
}
void print_stu(struct Stu ss) {
printf("%s %d %lf\n", ss.name, ss.age, ss.score);
}
int main() {
struct Stu s = { 0 };
set_stu(&s);//希望函数可以把s改掉,就要使用s的地址
print_stu(s);
return 0;
}