[x] 掌握 C 入门知识
操作符 | |
算术操作符 | + - * / % |
移位操作符 | << >> |
位操作符 | 按位与(&)按位或()按位异或(^) |
赋值操作符 | = += -= *= /= %= >>= <<= &= ^= |
单目操作符 | !+ - & sizeof ~ - - ++ * (类型) |
关系操作符 | > < = >= <= != == |
逻辑操作符 | 逻辑与 逻辑或 |
条件操作符 | exp1?exp2:exp3 |
逗号表达式 | exp1,exp2,exp3, …expN |
下标引用、函数调用和结构成员 |
注意
1.除了%操作符之外,其他的几个操作符可以作用于整数和浮点数。
2.对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法(用%lf)。
3.%操作符的两个操作数必须为整数。返回的是整除之后的余数。
思考
如图上示例:
(1).为什么表示数值10的2进制位是1010呢?
二进制数、转换为十进制数的规律是:把二进制数按位权形式展开多项式和的形式,求其最后的和,就是其对应的十进制数——简称“按权求和”。
解:
=1×(2的3次方)+0×(2的2次方)+1×(2的1次方)+0×(2的0次方)
=8+0+2+0
=10
(2).为什么表示数值10的8进制位是12呢?
八进制转十进制是用按权相加法进行计算的,计算方法是将八进制每位上的数乘以位权,最后将得出来的数加在一起,结果就是转化完的十进制数字
解:
=1×(8的1次方)+2×(8的0次方)
=8+2
=10
(3).那么表示数值10的16进制位是什么呢?
(4).每四个二进制位可以换算成一个16进制
移位操作符移动的是二进制的位
整数的二进制表示形式有3种:原码、反码、补码
整数在内存中存储的是补码
正整数的原码、反码、补码是相同的.
负整数的原码、反码、补码是(原码的符号位不变,其他位按位取反就是反码,反码+1就是补码)
原码:把一个数按照正负直接翻译成二进制就是原码
5,-5是整数,整数是存放在整型变量中的一个整型变量是4个字节-32比特位(一个字节等于8个比特位)
00000000000000000000000000000101(这是5)
10000000000000000000000000000101(这是-5)
最高的一位表示符号位0表示正数,1表示负数
反码:
补码:
由上知识可知:
-5的原码:10000000000000000000000000000101
-5的反码:11111111111111111111111111111010
-5的补码:11111111111111111111111111111011
左移:丢弃最高位(符号位同样丢弃),0补最低位
右移:
(1).算术右移:右边丢弃,左边用原来的符号位来填充
(2).逻辑右移:右边丢弃,左边直接用0填充
警告:
对于移位运算符,不要移动负数位,这个是标准未定义的。
例如下面这种就是错误的
int num = 10; num >> -1;
#includeint main() { int a = 3; a = a + 3; a += 3; a = a >> 3; a >>= 3; a = a ^ 5; a ^= 5; return 0; }
#includeint main() { int flag = 5; if (flag) // flag为真 { } if (!flag)// !flag为假 { } return 0; }
int main() { int a=10; int* p = &a;//&取地址操作符 *p =20;//解引用操作符(间接访问操作符) //int arr[10]; //&arr;//取出数组的地址 return 0; }
#includeint main() { int a = 10; printf("%d\n", sizeof(a)); printf("%d\n", sizeof(int)); printf("%d\n", sizeof a); //printf("%d\n", sizeof int);//sizeof后面是类型则括号不能省略 int arr[10] = { 0 }; printf("%d\n", sizeof(arr)); printf("%d\n", sizeof(arr[0])); return 0; }
#includeint main() { int a = 0; //原码:00000000000000000000000000000000 //反码:11111111111111111111111111111111 //补码: 11111111111111111111111111111110 //二进制按位取反:10000000000000000000000000000001 printf("%d\n", ~a); return 0; }
警告
在编程的过程中==和=不小心写错,导致的错误。
0为假,非0为真
逻辑与(&&):两个数中有一个为假,则判断为假
#includeint main() { int a = 3 && 5; printf("%d\n", a); return 0; }结果为真所以运行结果是1
#includeint main() { int a = 3 && 0; printf("%d\n", a); return 0; }结果为假所以运行结果是0
逻辑或(||):两个数中有一个为真,则判断为真
#includeint main() { int a = 3 || 0; printf("%d\n", a); return 0; }因为3为真所以运行结果为真
注意
&&操作符左边为假,右边不再计算
||操作符左边为真,右边不再计算
#includeint main() { int i = 0, a = 0, b = 2, c = 3, d = 4; i = a++ && ++b && d++; printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d); return 0; }
因为a++先使用,a为0为假所以后面不用再计算了所以结果是 1234
#includeint main() { int i = 0, a = 1, b = 2, c = 3, d = 4; i = a++ || ++b || d++; printf("a=%d\nb=%d\nc=%d\nd=%d\n", a, b, c, d); return 0; }
因为a++先使用,a为1为真所以后面不用再计算了所以结果是 2234
exp1 ? exp2:exp3
如果表达式1为真,那么就计算表达式2,表达式2的结果为整个式子的 结果;
如果表达式1为假,那么就计算表达式3,表达式3的结果为整个式子的结果。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
#includeint main() { int a = 1; int b = 2; int c = (a > b, a = b + 10, a, b = a + 1); printf("%d\n", c); return 0; }
a>b为假,对表达式不产生影响,a=b+10,所以a=12,b=a+1,所以b=13,又因为整个表达式的结果是最后一个表达式的结果所以c是13.
1.[ ]下标引用操作符
操作数:一个数组名+一个索引值
#includeint main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("%d\n", arr[5]); return 0; }
[ ]的两个操作数是arr和9。
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
#includeint main() { int len = strlen("abc");//()函数调用操作符 printf("%d\n", len); return 0; }
#includestruct S { int num; char c; }; void test(struct S* ps) { //->结构成员访问操作符 //结构体指针->结构体成员 printf("%d\n", ps->num); printf("%d\n", ps->c); } int main() { struct S s = {100,'b'};//结构体的初始化使用{} //打印结构中的成员数据:结构体变量.结构体成员名(. 操作符) printf("%d\n", s.num); printf("%d\n", s.c); test(&s); return 0; }
Copyright © 2023 leiyu.cn. All Rights Reserved. 磊宇云计算 版权所有 许可证编号:B1-20233142/B2-20230630 山东磊宇云计算有限公司 鲁ICP备2020045424号
磊宇云计算致力于以最 “绿色节能” 的方式,让每一位上云的客户成为全球绿色节能和降低碳排放的贡献者