目录
1. 操作符分类:
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
下标引用、函数调用和结构成员
int main()
{
double m = 3.0 / 2;//如果/两边全为整型,则进行的是整型的计算,只保留整数部分
printf("%lf\n", m);
int n = 3 % 2;//%的两边必须为整型,范围0~1
printf("%d\n", n);
return 0;
}
int main()
{
int a = 5;
a <<= 1;
printf("%d", a);//a=10 左移产生*2的效果
return 0;
}
负数<<
int main()
{
int a = -5;
a <<= 1;
printf("%d", a);//a=-10 左移产生*2的效果
return 0;
}
int main()
{
int a = 5;
int b = a >> 1;
printf("%d", b);//2
return 0;
}
负数右移:
int main()
{
int a = -5;
int b = a >> 1;
printf("%d", b);//-3
return 0;
}
int main()
{
int a = 3;
int b = -5;
int c = a & b;
printf("%d", c);//3
return 0;
}
a|b:
int main()
{
int a = 3;
int b = -5;
int c = a | b;
printf("%d", c);//-5
return 0;
}
a^b:
int main()
{
int a = 3;
int b = -5;
int c = a^b;
printf("%d", c);//-8
return 0;
}
异或带来的性质:
a^a=0,每个二进制位都相同,所有二进制位异或的结果都为0。
a^0=a,因为二进制位相异为1,所以二进制位异或的结果还是为a。
例题:有一数组,假设不知道该数组的大小,但是除了只有1个数字只出现一次外,其他的数字都出现了两次,求这个只出现一次的数字,假设该数组为{1 2 3 4 5 1 2 3 4 }。
方法:将相同的两个数异或,得到结果0,再将所有的0与这个单独出现的数字异或就可以求出这个单独出现的数字。
练习
两个变量的交换
1.引入中间变量tmp:
int main()
{
int a = 10;
int b = 20;
int tmp = a;//引入第三个参数,来实现两个变量的交换
a = b;
b = tmp;
printf("%d %d", a, b);
return 0;
}
2.利用两个变量的和:
int main()
{
int a = 10;
int b = 20;
a = a + b;
b = a - b;//b=a
a = a - b;//b=a,a=a+b-a => a=b
printf("%d %d", a, b);
return 0;
}
3.异或:
int main()
{
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;//(a^b)^b=a^0=a
a = a ^ b;//a^b^a=b^0=b
printf("%d %d", a, b);
return 0;
}
第二种与第三种都没有在创建新的变量。但是第一种是可读性最高的。
代码:
int main()
{
int a = 5;
int i = 0;
int count = 0;
for (i = 0; i < 32; i++)
{
int b = a >> i;//依次右移i位
if (b & 1 == 1)
{
count++;//统计1的个数
}
}
printf("%d", count);
return 0;
}
int main() { int flag = 0; if(!flag)//当判断是假的时候执行 return 0; }
int main() { int flag = 1; if(flag)//当判断是真的时候执行 return 0; }
C语言中c99之前没有表示真假的类型,在c99中引用了布尔类型。
#include
int main() { _Bool flag1 = false; bool flag2 = true; if (flag1) { printf("hehe"); } return 0; }
struct s { char name[20]; int age; }; int main() { int a = 10; int* pa=&a; *pa;//解引用操作符/间接访问操作符 *&a==a int arr[10] = { 0 }; &arr;//取出数组的地址,数组的地址应该放到【数组指针】当中 struct s s1 = { 0 };//初始化一个结构体 struct s* ps=&s1;//结构体指针 *struct s; return 0; }
int main() { int c = 10; printf("%d\n", sizeof(c));//4 printf("%d\n", sizeof c);//4 sizeof 不是函数而是一个单目操作符 printf("%d\n", sizeof(int));//4 int arr[10] = { 0 }; printf("%d\n", sizeof(arr));//40 这里函数名表示整个数组,计算类型创建的变量所占内存的大小,单位是字节 int a = 10; short b = 0; printf("%d\n", sizeof(b = a + 2));//2 printf("%d\n", b);//0 sizeof中的表达式不参与计算 return 0; }
sizeof 和 数组
#include
void test1(int arr[]) { printf("%d\n", sizeof(arr));//(2) 4/8 } void test2(char ch[]) { printf("%d\n", sizeof(ch));//(4) 4/8 指针的大小是4/8 } int main() { int arr[10] = { 0 }; char ch[10] = { 0 }; printf("%d\n", sizeof(arr));//(1) //数组名表示数组首元素地址,是指针 printf("%d\n", sizeof(ch));//(3) test1(arr); test2(ch); return 0; }
int main() { int a = 0; printf("%d", ~a);//-1 return 0; }
int main() { //int a = 0; //printf("%d", ~a);//-1 int a = 11; //000000000000000000001011 a的补码 a =11 //000000000000000000000100 按位或上1<<2,将a的第三个二进制位变为1 a |= (1 << 2); printf("%d\n", a);//15 //如何将第三位二进制位又改为1 //000000000000000000001111 a的补码 a=15 //111111111111111111111011 按位&上整个二进制的补码,则第三位二进制位可变为0 //000000000000000000000100 这个二进制补码取反就可以得到我们要按位&上的二进制补码 a &= (~(1 << 2)); printf("%d\n", a);//11 return 0; }
int main() { int a = 3; int b = ++a;//++表示自增,前置表示先自增,后使用 printf("%d %d\n", b,a);//4 4 printf("%d\n", ++a);//5 前置++ 先自增在打印4+1=5 return 0; }
后置++:
int main() { int a = 3; int b = a++;//++表示自增,后置表示先使用,后自增 printf("%d %d\n", b,a);//3 4 printf("%d\n", a++);//4 后置++ 先打印4 再自增4+1=5 return 0; }
--与++一样。
(类型) 强制类型转换
int main() { int a = (int)3.14;//强制类型转换,将double类型转换为int类型,只保留整数部分3 printf("%d\n", a);//3 return 0; }
#include
int main() { int i = 0, a = 0, b = 2, c = 3, d = 4; i = a++ && ++b && d++;//a=0,逻辑与1假全假,后面的全部不会计算量了,++后置,先使用后自增 //i = a++||++b||d++; printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);// a=1,b=2,c=3,d=4 return 0; } //程序输出的结果是什么?
#include
int main() { int i = 0, a = 1, b = 2, c = 3, d = 4; i = a++ && ++b && d++;//没有=0的变量,所以会计算问完++后置,先使用后自增 /*i = a++||++b||d++;*/ printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);// a=2,b=3,c=3,d=5 return 0; } //程序输出的结果是什么?
#include
int main() { int i = 0, a = 1, b = 2, c = 3, d = 4; //i = a++ && ++b && d++;//没有=0的变量,所以会计算问完++后置,先使用后自增 i = a++||++b||d++; printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);// a=2,b=2,c=3,d=4 return 0; } //程序输出的结果是什么?
#include
int main() { int i = 0, a = 0, b = 2, c = 3, d = 4; //i = a++ && ++b && d++;//没有=0的变量,所以会计算问完++后置,先使用后自增 i = a++||++b||d++; printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);// a=1,b=3,c=3,d=4 return 0; } //程序输出的结果是什么?
int main()
{
int a = 3;
printf("%d\n", a > 0 ? 3 : -3);//3
int b = 0;
int m = a > b ? a : b;
printf("%d\n", m);//3
return 0;
}
int main() { //代码1 int a = 1; int b = 2; int c = (a > b, a = b + 10, a, b = a + 1);//逗号表达式 // 0 a=2+10=12 a=12 b=12+1=13 printf("%d", c);//13 //c是多少? }
//代码2 if (a =b + 1, c=a / 2, d > 0)
if判断的是最后一个语句d>0。
//代码3 a = get_val(); count_val(a); while (a > 0) { //业务处理 a = get_val(); count_val(a); } 如果使用逗号表达式,改写: while (a = get_val(), count_val(a), a>0) { //业务处理 }
int main()
{
int arr[10] = { 0 };
arr[4] = 5;//[] 就是下标引用操作符 arr 4是它的两个操作数
return 0;
}
[]只是一个操作符而已。
add(int x, int y) { return x + y; } int main() { int x = 10; int y = 20; int ret = add(x, y);//add x,y 是函数调用符的两个操作数 return 0; }
函数操作符至少有一个操作数:函数名。
struct Stu { char name[20]; int age; float score; }; void print(struct Stu s) { printf("%s %d %f\n", s.name,s.age,s.score );//结构体.成员名 } int main() { struct Stu s1 = { "张三",18,100.5f }; print(s1); return 0; }
struct Stu { char name[20]; int age; float score; }; void print(struct Stu *ps) { printf("%s %d %f\n", (*ps).name,(*ps).age,(*ps).score );//结构体.成员名 } int main() { struct Stu s1 = { "张三",18,100.5f }; print(&s1); return 0; }
struct Stu { char name[20]; int age; float score; }; void print(struct Stu* ps) { printf("%s %d %f\n", ps->name, ps->age, ps->score);//-> 结构体指针->成员名 } int main() { struct Stu s1 = { "张三",18,100.5f }; print(&s1); return 0; }
#include
struct Stu { char name[20]; int age; float score; }; void print(struct Stu* ps) { printf("%s %d %f\n", ps->name, ps->age, ps->score);//-> 结构体指针->成员名 } int main() { struct Stu s1 = { "张三",18,100.5f }; strcpy(s1.name, "张三丰");//改变结构体里的字符串数组,用strcpy //scanf("%s", s1.name);//s1.name是数组的首地址,将字符串放入这个地址所在的内存中 print(&s1); return 0; }