? ? ? ? 介绍运算符时将以优先级从高到低介绍。
? ? ? ? ?[ ] 下标运算符
? ? ? ?( )括号
? ? ? ? ? .? ? 结构体成员运算符
? ? ? ? ? -> 指向结构体成员的运算符
? ? ? ? 一般使用形式 数组名[常量表达式]? ? 需要注意的是数组定义时下标运算符内必须是常量表达式不可为变量,但之后引用时可以为变量。
? ? ? ? 使用形式:(表达式) 或者 函数名(形参表)。
????????使用形式:对象 . 成员名。?
????????使用形式:对象指针 -> 成员名。?
struct Stu {
int num;
char name[20];
int score;
};
int main() {
struct Stu a = { 1,"zhangsan",87};
struct Stu* p = &a;
//分别为 . 和-> 的使用例子
printf("%d %s %d", a.num,p->name,p->score);
return 0;
}
? ? ? ? 这一类运算符的优先级最高,结合方向为:左到右。
? ? ? ??使用形式:+表达式??
????????使用形式:-表达式
? ? 注意:+和 - 操作数只有一个时为单目运算符,有两个操作数时为双目运算符。例如:+5此时的+就为单目运算符,3 - 2此时的 - 就为双目运算符。
????????使用形式:++变量名/变量名++?
? ? ? ? ?使用形式:--变量名/变量名--
? ? 作用:自增自减运算符每此都可使变量+1或者-1。
? ? 注意:++ 和 --运算符只能用于变量,不可以用于常量或者表达式。
????????使用形式:sizeof(表达式)
? ? 作用:数据类型在内存中的大小(单位是字节)。
????????使用形式:(数据类型)表达式
? ? ? 作用:运算类型不一样时可以进行数据转换,强制类型转换不会改变原变量的值和数据类型。
int a = 4;
float b = 4.5;
//b强制转换为int型,保留整数位小数位不进行四舍五入
int c = (int)b + a;
//变量c的值为8
????????使用形式:!表达式??
? ? ?有个小口诀:非真即假,非假即真。意思是 :1 值为真,前面加上!变为!1,非真就为假。相同0值为假,前面加!运算符为!0,非假值就为真。
????????使用形式:~表达式??
? ? ? C语言中整型数据在内存中由补码的形式进行储存,补码和原码的转换形式为:取反+1,要注意的是整数的原反补是一致的,只有负数在运算的时候需要转换。第一位为符号位不变。
int a = 6;
//a的补码
//000000000 00000000 00000000 00000110
a = ~a;
//按位取反
//111111111 11111111 11111111 11111001
//原码
//100000000 00000000 00000000 00000111
????????使用形式:&变量名
? ? ? 一般用来赋值给指针变量例如:int *p,a=4;p=&a;这样a的地址就赋给指针p了。
????????使用形式:*变量名
? ? ? 这个运算符可以在输出或者赋值时指针变量前加* ,可以直接取值:
int a = 4,*p;
p = &a;
//此时使用取值运算符也可以进行输出
printf("%d", *p);
? ? ? ? 第二类运算符的结合方向为:右向左。
? ? ? ? 算数运算符中有:?* / %(取余) + -? ?加减称除都是老熟人了,来说一下%运算符吧,这个运算符的作用是取余数,比如说5%2的商为2余数为1余数就是这个运算符运算的结果,一般可以判断这个数是否可以被两一个数整除。注意:取余运算符两边只能为整数。
????????使用形式:变量 << 表达式
? ? ? ? 左移右移移动的是二进制位
? ? ? ? 移动方式:向左移动,右边补0。
int a = 6;
//a的补码
//000000000 00000000 00000000 00000110
a = a << 1;
//左移
//000000000 00000000 00000000 0000110
// 补零
//000000000 00000000 00000000 00000000
//a=12
? ?左移运算符一般有*2的效果;
????????使用形式:变量 >>?表达式
? ? ? ? 右移同理,不过分为了算数右移和逻辑右移。
? ? ? ? 算数右移:右边丢弃,左边补符号位的数字(大部分编译器使用的都是算数右移)
? ? ? ? 逻辑右移:右边丢弃,左边补0
int a = 6;
//a的补码
//0000000000 00000000 00000000 00000110
a = a >> 1;
//右移,左补一个零
//0000000000 00000000 00000000 00000011
//a=3
? ? ? ? 右移运算符一般有/2的效果;
? ? ? ? 关系运算符有? >? ? >=? ? <? ? ?<=? ? ==? ?和? ?!=,? 前几个想必大家都很熟悉吧,大家重点要注意下 = 和 == 在c语言中的区别,c语言中 = 为赋值符 并非判断两个值是否相等,?判断两个值是否相等需要 == 运算符。!= 和数学中的不等于是一样的。
????????使用形式:表达式?&?表达式
? ? ? ? 按位与运算操作的同样是二进制数,两个整型的数展开32位二进制每个二进制位上对应的数(有0为零,全1为1):
int a = 6;
int b = 9;
int c = a & b;
//a 000000000 00000000 00000000 00000110 补码
//b 000000000 00000000 00000000 00001001 补码
//c 000000000 00000000 00000000 00000000 结果
//c=0 有0则0,全1为1
????????使用形式:表达式 ^ 表达式
? ? ? ? 此类操作数均为二进制数,按位异或的运算规则为:二进制位相同的为0,不同为1(相同为0,不同为1):
int a = 6 ,b = 3;
int c = a ^ b;
//a 000000000 00000000 0000000 00000110
//b 000000000 00000000 0000000 00000011
//c 000000000 00000000 0000000 00000101
//c = 5;
????????使用形式:表达式 | 表达式
? ? ? ??运算规则:有1为1,全0为0
int a = 6, b = 5;
int c = a | b;
//a补码 000000000 00000000 00000000 00000110
//b补码 000000000 00000000 00000000 00000101
//c结果 000000000 00000000 00000000 00000111
//c=7
????????使用形式:表达式 && 表达式
? ? ? ? 运算规则:两个表达式都为非0值时,运算结果为真,否则为假(有假则假,全真即真)。
? ? ? ??注意:逻辑运算存在“短路性”,短路性是指逻辑与(&&)左边的运算对象为假时,后面的运算对象不在运算。
int a =1, b = 2;
//--在前先自减,自减后为0
//a的值为假,逻辑短路不执行b++,所以b的值还是2
--a && b++;
????????使用形式:表达式 ||?表达式
????????运算规则:两个表达式都为0值时,运算结果为假,否则为真(有真则真,全假即假)。
????????需要注意的时逻辑或(||)与逻辑与一样具有“短路性”。
? ? ? ? 双目运算符的结合方向为:左向右。
? ? ? ??使用形式:表达式1 ??表达式2 : 表达式3
? ? ? ? 运算规则:先计算表达式1的值如果为真(!0),表达式2的值就为整个表达式的值,否则表达式3的值为整个表达式的值。
int a = 1, b = 2;
//a>b 这个表达式值为假,整个表达式的值为表达式3 b 赋值给d
int d = a > b ? a : b;
//d=2
????????三目运算符的结合方向为:右向左。
? ? ? ? 赋值时需要注意的是:在变量初始化时不可以出现 int a=b=5;编译器会报错。不过可以定义完成后 a=b=5 这样进行赋值。
? ? ? ? 复合符值运算符有: *=? ?/=? %=? +=? -=? ?<<=? ?>>=? &=? ?|=? ?^=?
? ? ? ? 以 *= 为例:a? * =? 表达式? ? ? 等价于? ? ?a = a * 表达式
? ? ? ? 由于优先级的问题,后面的表达式运算完毕后进行复合赋值运算。
? ? ? ??赋值运算符的结合性为:右向左。
? ? ? ??使用形式:表达式1 ,?表达式2 ,?表达式3
? ? ? ? 运算规则:从左向右依次计算,取最后一个表达式的值为整个逗号表达式的值。
int a = 3, b = 6, c;
//从左到右依次计算, a+b没有赋值号没有赋给任何变量
//a+=3 a的值变为6,b*2同理 没有赋给任何变量
//b的值没有发生过改变且为最后一项 所以c为6
c =( a + b, a+=3 , b*2, b );
? ? ? ? 结合性为:左向右。
? ? ? ? 运算符的优先级为上述从上到下,结合性小口诀:?单三赋,右向左,其余都为左向右。
? ? ? ? 那什么是结合性呢?就是表达式各操作符优先级一致,从那边结合为整体,这边以三目操作符为例:
//三目操作符 右向左
int e = a > b ? a : d > c ? d : c;
//运算时可以下向下面一样将后面看为整体
int e = a > b ? a : d > (c ? d : c);
????????注意!运算时还是从左往右运算哦!
感谢大家的观看,如有错误请指出。