按位取反是对补码的取反,和之前的求反码的规则类似,但是首位的符号位是改变的,剩下的位数0和1互换,说白了就是每一位都取反
//例 int main() { int a = 10; //00000000 00000000 00000000 00001010 补码 a = ~a; //11111111 11111111 11111111 11110101 结果的补码 //11111111 11111111 11111111 11110100 反码 //10000000 00000000 00000000 00001011 原码,结果为-11 a |= (1<<5); a &= (~(1<<5))//这两个公式算出来的结果相同,这也是这些符号的一些用法,目的是对与a中存储的32位比特位的任意一位进行修改 可以自行计算一下 }h.++ 自增 前置++:先++再使用 后置++:先使用后++ //++可以看作a = a + 1 i.-- 自减 前置--:先--再使用 后置--:先使用后-- //--可以看作a = a - 1 //对操作数加一或减一,对于使用操作数的场景,其放在操作数前后产生效果不同关于自增自减的使用问题,可以理解为当有某个过程调用了被自增自减的变量时,视作被使用了,如果此时为后置的自增自减,那么就得先执行被函数调用或者计算过程,前置则先进行计算
j.* 间接访问操作符(解引用操作符)解引用操作符多用于指针的访问上
//例: int main() { int a =10; int* p = &a; *p = 20;//此时a中的值变为二十,*的作用就是通过p中存放的地址找到a变量,所以*p就等于a }k.(类型) 强制类型转换对数据类型进行强制转换
#include<stdlib.h> #include<time.h> int main() { int a = (int)58.5148951;//a现在等于58,相当于把浮点型强制转换成了整数,后面的小数位丢失了 0r srand((unsigned int) time(NULL)) 这是一个关于伪随机数起始种子的一种可变写法,由于srand()中只能接收无符号整型,而time返回值时long long,所以要强制类型转换 }6.关系操作符
(不是所有内容都可以用关系操作符比较)
a.> 大于 b.< 小于 c.>= 大于等于 d.<= 小于等于 e.!= 不等于 f.== 等于 //一定要注意不要把==写成=,一个是等于,一个是赋值,这是个很常见的错误 //如果对于变量和常量,我们可以把顺序反着写比如 8==a ,这样如果少写了个等号,就会报错了7.逻辑操作符
只对真假进行判断,结果也只有0或1
&& 逻辑与(全真为真,一假则假)//当其左边为假,直接出结果,右边整个过程不进行计算int main() { int a = 4; int b = 3; int c = 0; int d = a && b//此时d的值为 1 int e = b && c//此时e的值为 0 }|| 逻辑或(一真则真,全假为假)//当其左边为真,直接出结果,右边整个过程不进行计算int main() { int a = 4; int b = 3; int c = 0; int d = a || b;// 1 int e = b || c;// 1 d = 0; e = d || c;// 0 }逻辑操作符在从左往右进行计算时,一旦得到确切结果,后面一律不再计算
int e = b && c || b || c || f || 666 && 0 && a+=100
如果b&&c等于0,结果为假了,后面就全部不计算,直接输出结果0
8.条件操作符
三目操作符(从左向右依次计算)
表达式1 ? 表达式2 :表达式3 //表达式1如果为真,则计算表达式2,表达式2的结果为整个表达式的结果,表达式3不进行计算 //表达式1如果为假,则计算表达式3,表达式3的结果为整个表达式的结果,表达式2不进行计算9.逗号表达式
表达式1,表达式2,表达式3,表达式4,.....,表达式n逗号表达式就是用逗号隔开的多个表达式,从左到右依次执行,表达式的结果就是最后一个表达式的结果
//例子 int main() { while(a = get_val(), count_val(a),a > 0 ) { ; } //等价于 do { a=get_val(); count_val(a); }while(a>0) }10.我不知道怎么分了
a.下标引用操作符
[] 下标引用,数组常见 int main() { int arr[10] = { 0 }; arr[9]=10;//使用下标引用,两个操作数分别为数组名和下标数9 9[arr]=10;//两者可以交换arr[9] ---> *(arr + 9) ---> *(9 + arr) --->9[arr] } 比如 int arr1[4] = {1,2,3,4}; int arr2[4] = {1,2,3,4}; int arr3[4] = {1,2,3,4}; int* parr[3] = {arr1,arr2,arr3}; int i = 0; int j = 0; for(i = 0; i < 3; i++) { for(j = 0; j < 4; j++) { printf("%d ",parr[i][j]);//下标引用本质上就是指针偏移 + 解引用 } //parr[i]->*(parr + i) printf("\n"); //parr[i][j]->*(parr[i] + j)->*(arr(i + 1) + j) } //上面的arr(i+1)代指arr1 or arr2 or arr3b.函数调用操作符
() 函数调用,函数常见 //函数定义 int ADD(int a, int b) { return a + b; } int main() { int a = 10; int b = 20; //函数调用 int c = ADD(a,b);//()就是函数调用操作符,操作数为函数名和参数,至少有一个操作数(函数名) return 0; }c.访问结构体成员
-> 结构体指针变量 -> 成员名 . 结构体名 . 成员名都是对于结构体的成员使用时才会用到
#include<stdio.h> #include<string.h> struct a { char name[20]; int age; double score; } void set_a(struct a* s) { strcpy((*s).name,"zhangsan"); (*s).age = 18; (*s).score = 100.00; //or strcpy(s->name,"zhangsan"); // s->age = 18; // s->score = 100.00 } void print_a(struct a s) { printf("%s %d %lf",s.name,s.age,s.score); } int main() { struct a s = { 0 }; set_a (&s); print_a(s); return 0;