**************************************************************************************************************************************************************************************************************** 操作符解释: 1,算术操作符: ‘ ’、‘-’、‘*’、‘/’、‘%’ %取模操作符只能用于整数, /除法操作符,两个操作数均是整数时为整数除法,有一个是浮点数则执行浮点数除法。 如:int a = 6/5;//->a==1 double b = 6/5;//->b==1.000000 double c = 6.0/5//->c==1.200000,即实际运算与定义的储存类型无关 2,移位操作符 左移‘<<’、右移‘>>’ 左移操作符: 如: int a=2; int b = a << 1;//a向左移动一位,结果存入变量b中,结果b为4 正整数2在内存中存放的补码为: 00000000000000000000000000000010 向左移动一位,左边的首位0去掉,右边的缺一位补0:00000000000000000000000000000100 ->4(十进制) 右移操作符: 右移时分为算数右移和逻辑右移。 算数右移:右边丢弃,左边补符号位。 逻辑右移:右边丢弃,左边补0。 如:int a = -10; int b = a >> 1;//a向右移动一位,结果存入变量b中 正整数10在内存中的补码为11111111111111111111111111110110//若为负数则原码与补码不同。 算术右移: 11111111111111111111111111111011 ->-5 逻辑右移: 01111111111111111111111111111011 ->2,147,483,643 对移位操作符移动负数位,这时C语言未定义的,不要使用。 3,位操作符 按位与‘&’、按位或‘|’、按位异或‘^’ 位解释为二进制的一位。 &按位与,全为1时结果才为1,其他情况结果均为0 如:int a = 3;// 00000000000000000000000000000011 int b = 5;// 00000000000000000000000000000101 int c = a & b;// 00000000000000000000000000000001->1(十进制) eg:找出一个整数的二进制的1的个数。 #include <stdio.h> int main(){ int a=1; int cnt=0; for(int i=0; i<31; i ){ if((a&1) == 1){//整数的二进制数的1的个数 cnt ; } a=a >> 1; } printf("%dn",cnt); return 0; } |按位或,全为0时结果才为0,其他情况结果均为1 如:int a = 3;// 00000000000000000000000000000011 int b = 5;// 00000000000000000000000000000101 int c = a | b;// 00000000000000000000000000000111->7(十进制) ^按位异或,不同为1,相同为0。一个数a与另一个数b异或两次结果仍是a本身,数a与0异或结果仍为数a。 如:int a = 3;// 00000000000000000000000000000011 int b = 5;// 00000000000000000000000000000101 int c = a ^ b// 00000000000000000000000000000110->6(十进制) eg:交换两个数a=3,b=5,要求不使用第三个变量。 #include <stdio.h>//此法适用于a,b相加的结果不超过类型范围的情况,有缺点 int main(){ int a=3; int b=5; a = a b;//变量a储存a与b的和 b = a -b;//变量b储存原来a的值 a = a - b;//变量a储存原来b的值 return 0; } #include <stdio.h>//此法适用于a,b相加的结果不超过类型范围的情况,有缺点 int main(){ int a=3; int b=5; a = a ^ b; b = a ^ b;//3 ^ 5 ^ 5的结果3存入到b中 a = a ^ b;//3 ^ 5 ^ 3的结果5存入到a中 return 0; }; 4,赋值操作符 = = -= *= /= %= <<= >>= ‘=’是赋值,‘==’是等号。 int a = a 4;//等价于a =4; 连续赋值: 如:int b = a = a 1;//等价于a = a 1; b = a; 连续赋值不好进行调试,阅读不便。 5,单目操作符 !(逻辑反) -(负值) (正值) ~(按位取反) sizeof(操作数的类型长度,按字节计算) -- &(取地址) *(间接访问操作符或解引用操作符) (类型名)强制类型转化 ‘i’一般用于条件判断,0的反是1,非0的反是0; 如: #include <stdio.h> int main(){ int flag =0; if(flag){ printf("Yesn");//条件为假,语句不执行 } if(!flag){ printf("YesYesn");//条件为真,语句执行 } return 0; }; ‘~’对二进制位的操作,类比按位与、按位或、按位异或。最高位也参与取反。 如:int a = 13;//00000000000000000000000000001101 int b = ~a; //11111111111111111111111111110010 -> b==-14; ‘sizeof’是单目操作符,可求内存大小。 如: int a =13; int b = sizeof(a);//结果为4,是一个int类型变量所占字节个数,也可写为int b = sizeof a; 不需要加括号 int arr[10]={0}; int c = sizeof(arr);//结果为40,是十个int类型变量所占字节个数 int g = sizeof(int [10]);//结果为40,数组的类型实际上是去掉数组名(arr)之后留下的(int [10])。 如: #include <stdio.h> int main(){ short s = 5; int a = 10; printf("%dn",sizeof(s = a 2));//输出为2,short占2字节,等价于printf("%dn", sizeof(s));。 printf("%dn",s);//输出为5,上面表达式没有计算 return 0; }; ‘ ’ int a = 13; a;//前置 ,先 在使用 a ;//后置 ,先使用,在 ‘&’取地址操作符,单目操作符,与按位与操作符区分 ‘*’解引用操作符或间接引用操作符 如:#include <stdio.h> int main(){ int a =13; int *p = NULL;//定义int类型的指针变量,此时 * 是定义 p = &a;//整型指针变量p中存放整型变量a的地址 printf("%dn",*p);//此句输出为13,*p与a等价。此时 * 是解引用 int a =1; char b=1; double c=1; float d=1; int *pa =&a; char *pb =&b; double *pc=&c; float *pd=&d; printf("%dn",sizeof(pa)); printf("%dn",sizeof(pb)); printf("%dn",sizeof(pc)); printf("%dn",sizeof(pd));//输出相同,为4或8(与具体系统有关),求的是指针变量的大小,不论是那种类型的指针变量,储存的地址形式都相同,内存的地址(指针常量)形式是确定的 } ‘(类型名)’, 如:#include <stdio.h> int main(){ int a = 3.14;//浮点型转换为int型会损失精度,产生警告。 int b =(int)3.14;//强制类型转换,没有警告。 return 0; } 6,关系操作符 =(赋值) ==(相等) <、>、<=、>=、!=(不等于) 字符串比较不能用==,要用字符串函数 7,逻辑操作符 &&(逻辑与) ||(逻辑或) 首先和按位与(&)、按位或(|)区分开。 逻辑与:全真为1,其它为0。 逻辑或:全0为0,其它为1。 短路现象:对于逻辑与: 如: #include <stdio.h> int main(){ int a=0,b=3,c=2,d=4; if(a && b && c && d)//先看a && b,a==0,则最终表达式结果一定为0,后面表达式不再计算 printf("111n"); else{ printf("000n");//最后输出为000 } } 对于逻辑或: 如: #include <stdio.h> int main(){ int a=5,b=3,c=2,d=4; if(a || b || c || d)//先看a || b,a == 5,则最终表达式结果一定为1,即为真,后面表达式不再计算,输出为111。 printf("111n"); else{ printf("000n"); } } 8,条件操作符 ? : (三目操作符) 如:#include <stdio.h> int main(){ int a =2; int b = 4; printf("%dn", a>b?a:b);//如果a>b表达式成立,则表达式结果为a,否则为b,输出为4。 return 0; } 9,逗号表达式 逗号表达式,从左向右依次计算,整个表达式的值是最后一个子表达式的值。 #include <stdio.h> int main(){ int a =2; int b = 4; printf("%dn", (a=a 3,b=b-2));//表达式a = a 3计算,但整个表达式(a=a 3,b=b-2)的值是表达式(b=b-2)的值,结果为2 b = 4; printf("%dn", b=b-2);//结果为2 } 10,下标引用、函数调用和结构成员访问 [ ]下标引用操作符(运算符) 操作数:一个数组名 索引值,类比二元操作符,1 2。 如: #include <stdio.h> int main(){ int a[10];//创建数组 a[0] = 10;//使用下标引用操作符为数组第一个单元赋值 } ( )函数调用操作符,接受一个或多个操作数,第一个操作数是函数名,剩余的操作数是函数的参数。 如: #include <stdio.h> int max(int a, int b){//函数定义 return a > b ? a : b; } int main(){ int a = 3; int b = 4; max(a, b);//函数调用,输出二者中较大的那个数。 printf("%dn",t); return 0; } 结构成员访问操作符:对于非指针变量使用圆点操作符,指针变量还可以使用箭头操作符 如: #include <stdio.h> struct student{ char name[20]; int age; double mathscore; }; int main(){ struct student a = { "weihe", 20, 90}; printf("%sn",a.name);//使用圆点操作符访问结构体成员name数组 struct student *p = NULL; p = &a; printf("%dn", (*p).age);//使用指针解引用访问结构体成员age printf("%dn", p->age);//使用箭头操作符访问结构体成员age return 0; } 11,表达式求值 求值顺序由操作符的优先级和结合性决定。有些表达式的操作数再求值的时候可能要转换为其他类型。 12,隐式类型转换 C的整型算术运算是以缺省(sheng)整形类型的精度来进行的。 为了达到这个缺省(sheng)整形类型的精度,表达式中的字符和短整型操作数(2字节)在使用之前被转换为普通整型(int或unsigned int),这种转换称为整形提升。 整形提升的意义: 表达式的整型运算在CPU相应的运算器件内执行,CPU内整型运算器的操作数的字节长度一般是int的字节长度,同时也是CPU的通用寄存器的长度。 即使是两个字符型变量相加,CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。 通用CPU难以直接实现两个8bit字节的直接相加运算(虽然机器指令中可能有这种字节相加指令)。 整形提升过程: 按照变量数据类型的符号位提升。 正数: char a = 1;//00000001(补码) ->(整形提升) 00000000000000000000000000000001 负数: char b = -1//11111111 (补码)-> (整形提升)11111111111111111111111111111111 如: #include <stdio.h> int main(){ char a = 3; char b = 127; char c = a b;// a: 00000011 -> 00000000000000000000000000000011 // b: 01111111 -> 00000000000000000000000001111111 c: 00000000000000000000000010000010 ->(截断) 10000010 printf("%dn", c);/ c: 10000010 -> 11111111111111111111111110000010(反码)->(求原码)10000000000000000000000001111110 即为-126 return 0;//以int型输出是也会发生整型提升,对于unsigned char,整型提升时高位均补0 } #include <stdio.h> int main(){ char c =0;//sizeof返回类型为size _t,是unsigned int,打印时要用格式符%u printf("%un",sizeof(c));结果为1 printf("%un",sizeof(-c));结果为4,sizeof运算符括号里的表达式(-c)虽然不参与运算,但有类型属性,为整形提升后的int printf("%un",sizeof( c));结果为4 printf("%un",sizeof(!c));结果为4 return 0; } **************************************************************************************************************************************************************************************************************** 字符串 相关函数 头文件#include <string.h> 求长度 char s[10] = "hello world"; strlen(s),返回字符的个数 sizeof(s),返回字符串大小,包括'
未禾的C语言总结
2023-04-27 20:53:20
浏览数 (1)