左值和右值以及操作数的概念
a=1 a:左值 1:右值
error C2166:左值指定 const 对象 左值一般是变量
右值:没有什么太多要求
操作数:=需要两个数字运算符,操作数2
单目,双目, 三目
优先级:计算表达式的顺序(先算*/ 再算+ -)
结合性:a=1; 正确应该是把1赋值给a
逗号→赋值→逻辑→条件→算术→位→括号
- const int c_num = 1;
- //报错: 表达式必须是可修改的左值
- c_num = 1;
-
- //[]的优先级最高 数组 存储指针 指针数组
- int* p[3];
- //指针指向数组 数组指针
- int(*p) [3];
a=1;
算术运算符
- //+ -
- //* /
- //2(3+4)
- int a=2*(3+4); //在写表达式的时候乘法不能省略
- //除法
- 1/3=0; //当除法的两边都是整数的时候,会自动取整 需要把一部分转换为浮点数结果才是小数
- //1/2+2/3+3/4;
- double result=1/2.0+2/3.0+3/4.0
- //取模:%
- int num=1%3 //1 x%n [0,n-1]--->随机数
- //余数的符号
- num=1%-2; //1 余数只和被取余数的正负有关
复合赋值运算符
- int a=1;
- a+=2; //a=a+2
- a/=2; //a=a/2
- a*=2; //a=a*2
- a=2;
- a*=1+2*3; //表达式右边有没有括号,都没关系,都是一个整体
- //a=a*(1+2*3); //14
条件表达式只有两个结果: 0(表示不成立) 或者 1(成立)
在计算机中非零值表示成立,只有0(\0)或者NULL 表示不成立
不存在连续操作,例如描述 a 大于 1 并且小于2,1 < a < 2 错误
1 < a < 2是永远成立的 1 < a 结果[0,1],[0,1] < 2 永远成立
- //> <
- //不等于 != //中间没空格,有空格是错误的
- //等于 ==
- //>= <=
-
- print("%d\n",1 > 2); //0
- if(a = 3)
- {
- print("执行"); //执行
- }
逻辑运算符
- &&: 逻辑与运算 并且
- ||: 逻辑或运算 或者
- !: 逻辑取反 成立变不成立,不成立变成立
- !3 0
- !0 1
a | b | a&&b | a||b |
---|---|---|---|
0 | 0 | 0 | 0 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 |
0 | 1 | 0 | 1 |
综上:
0 表示假,1 表示真
a&&b:a和b都成立它才能成立,其他情况都是不成立
a||b:a和b都不成立它才能不成立,其他情况都是成立
逻辑与运算、逻辑或运算都会存在短路现象(计算机偷懒现象)
- int a = 2;
- a > 1 || (a = 4); //a > 1成立 所以a > 1 || (a = 4)成立
- a < 1 && (a = 5); //a < 1不成立 所以a < 1 && (a = 5)不成立
- printf("%d\n", a); //2
学会运算符方式即可
- &: 按位与
- |: 按位或运算
- ~: 按位取反
- ^: 异或
- >>: 左移
- <<: 右移
箭头指向哪边就朝哪边移位,左移两位就是把左边的两位截取掉
左移:正负数都是右边补0
右移:正数:左边补0 负数:左边补1
首先转换为二进制,一个数用一个字节表示,正数三码合一,直接使用补码,需要还原成原码才能得到十进制数
- #include <stdio.h>
- int main()
- {
- printf("%d\n", 1 & 2); //0
- printf("%d\n", 1 | 2); //3
- printf("%d\n", 1 ^ 2); //3
- printf("%d\n", ~1); //-2
- printf("%d\n", 8 << 2); //32
- printf("%d\n", 8 >> 2); //2
- printf("%d\n", -1 >> 3); //-1
- printf("%d\n", -1 << 2); //-4
- return 0;
- }
++ - -
- int a=1;
- a++; //后置 先做其他运算,再改变自己
- ++a; //前置 先改变自己,再做其他运算
- //a++ a=a+1;
- a--;
- --a;
- //a-- a=a-1
- int a = 1;
- int b = 1;
- int result;
- result = a++; //result=a,再a=a+1
- printf("result=%d\ta=%d\n", result, a); //1 2
- result = ++b; //先b=b+1 再做result=b
- printf("result=%d\tb=%d\n", result, b); //2 2
- a = 1;
- result = 3 * a++; //result=3*a,再a=a+1
- printf("result=%d\ta=%d\n", result, a); //3 2
sizeof
统计类型、变量占用字节数
执行过程在编译期(把代码翻译成二进的时候)完成,编译期变量没有内存
- //统计类型所占用的字节数
- printf("size_t:%d\n", sizeof(unsigned int)); //4
- printf("long:%d\n", sizeof(long)); //4
- //统计变量所占用的字节数
- int a = 1;
- printf("a:%d\n", sizeof(a)); //4
-
- int i = 1;
- result = sizeof(++i);
- //i等于1,不会改变,因为sizeof运算在编译期完成,变量没有存储这个值就已经计算好了,不会运行++i,只会检查i类型占用字节数
- printf("result=%d\ti=%d\n", result, i); //4 1
?:
- 表达式1 ? 表达式2 : 表达式3
- 1成立 2
- 1不成立 3
-
- a = 2;
- b = 3;
- //求a与b的最大值
- int max = a > b ? a : b;
- //3
- printf("max=%d\n", max);
- //求a与b与c的最大值
- int c = 4;
- // ( a > b ? a : b) > c ? ( a > b ? a : b) : c;
- int maxabc = (max) > c ? (max) : c;
- printf("maxabc=%d\n", maxabc);
- //函数也可以算是一个表达式
- a > 3 ? printf("a=%d\n", a) : printf("3\n");
逗号运算符
有效值 是最右边的值
- result = (1 + 2, 3 + 4, 4 + 5, 5 + 6);
- //11
- printf("result=%d\n", result);
计算的时候用的 a 或 b 都是一个值
- #include <stdio.h>
- int main()
- {
- int a = 1;
- int resultFirst = a++ + a++ + ++a + ++a; //a:3
- //只看前置,不看后置,再看几部分
- //resultFirst:3+3+3+3=12 a:5
- //只看前置:a++ + a++ + ++a + ++a 两个前置:a要加两次,运算时a的值3
- //再看几部分:a++ + a++ + ++a + ++a 有四部分:3+3+3+3
- //无论前置还是后置 a都需要加四次 a最终结果是5
- printf("result=%d\ta=%d\n", resultFirst, a); //12 5
-
- int b = 1;
- int resultSecond = b++ * b++ * ++b * b++ * b++;
- //b运算时候:b=2
- //resultSecond:2^5;
- printf("result=%d\tb=%d\n", resultSecond, b); //32 6
- int c = 1;
- int resultThree = c++ * c-- * c++ * ++c * --c * c++;
- printf("result=%d\tc=%d\n", resultThree,c); //1 3
- return 0;
- }