优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | |
() | 圆括号 | (表达式)/函数名(形参表) | |||
. | 成员选择(对象) | 对象.成员名 | |||
-> | 成员选择(指针) | 对象指针->成员名 | |||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
(类型) | 强制类型转换 | (数据类型)表达式 | |||
++ | 自增运算符 | ++变量名/变量名++ | 单目运算符 | ||
-- | 自减运算符 | --变量名/变量名-- | 单目运算符 | ||
* | 取值运算符 | *指针变量 | 单目运算符 | ||
& | 取地址运算符 | &变量名 | 单目运算符 | ||
! | 逻辑非运算符 | !表达式 | 单目运算符 | ||
~ | 按位取反运算符 | ~表达式 | 单目运算符 | ||
sizeof | 长度运算符 | sizeof(表达式) | |||
3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | 双目运算符 | ||
% | 余数(取模) | 整型表达式/整型表达式 | 双目运算符 | ||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | 双目运算符 | ||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | 双目运算符 | ||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | 双目运算符 | ||
< | 小于 | 表达式<表达式 | 双目运算符 | ||
<= | 小于等于 | 表达式<=表达式 | 双目运算符 | ||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!= 表达式 | 双目运算符 | ||
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | |
/= | 除后赋值 | 变量/=表达式 | |||
*= | 乘后赋值 | 变量*=表达式 | |||
%= | 取模后赋值 | 变量%=表达式 | |||
+= | 加后赋值 | 变量+=表达式 | |||
-= | 减后赋值 | 变量-=表达式 | |||
<<= | 左移后赋值 | 变量<<=表达式 | |||
>>= | 右移后赋值 | 变量>>=表达式 | |||
&= | 按位与后赋值 | 变量&=表达式 | |||
^= | 按位异或后赋值 | 变量^=表达式 | |||
|= | 按位或后赋值 | 变量|=表达式 | |||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | 从左向右顺序运算 |
注意:while(i--)和while(--i):前者是先判断i,后i再自减1;后者是先i自减1,再判断i。
6、逗号运算符的使用方法:(以下是一个经典的例子)。
在C语言中,多个表达式可以用逗号分开,其中用逗号分开的表达式的值分别结算,但整个表达式的值是最后一个表达式的值。
假设b=2,c=7,d=5,
a1=(++b,c--,d+3);
a2=++b,c--,d+3;
对于第一行代码,有三个表达式,用逗号分开,所以最终的值应该是最后一个表达式的值,也就是d+3,为8,所以a1=8,b加为3了。
对于第二行代码,那么也是有三个表达式,这时的三个表达式为a2=++b、c--、d+3,(这是因为赋值运算符比逗号运算符优先级高)所以最终表达式的值虽然也为8,但a2=4,因为第二行代码可以看成a2=++b和另外两个式子,d+3的结果会放在一个临时空间,因为未赋值给其他变量,所以无法使用这个结果。
注意:逗号运算的结合性是从左至右,完毕之后整个表达式的值是最后一个表达式的值。
例子:int a[2],x=2,y=5;
a[0]=(x+3,y++,x++);那么最终结果是:a[0]=2
为何a[0]=2:因为(x++)是运算之后再自加
a[1]=(x++,x+3,x+7);那么最终结果是:a[1]=11
第一反应,我以为a[1]=10,就是3+7;其实是错的,逗号运算是从左至右,所以先算
x++,x从而变成4了,然后a[1]=4+7=11;
不信你改成a[1]=(x++,x+3);调试一下,结果是7,就是4+3,说明经过一个逗号,x已经自加变成4了。
7、在多个条件语句判断时主要分为&&和||两种情况,编译器为了提高速度,当&&时,前一个判断语句是假,则后面的不会再去判断(但会检查有无语法错误),当||时,前一个判断语句是真,则后面的也不会再去判断。
8、非0之外的数值都认为是真。
9、printf(1)输出格式字符:d:按十进制整数输出;Hd或hd:按十进制整数输出短整型数;Ld或ld:按十进制整数输出长整型数;u:按无符号整数输出;Hu或hu:按无符号短整型输出;f:按浮点型小数输出;Lf或lf:按长精度输出浮点数;e:按科学计数法输出;o:按八进制整数输出;x:按十六进制整数输出;g:按e和f格式中较短的一种输出;c:按字符型输出;s:按字符串输出。(2)字段宽度修饰符:m(%md,%mc等等):以宽度m输出整型数,数据宽度不足m时,左补空格(宽度超过m时,也会全都输出);0m(%0md):以宽度m输出整型数,数据宽度不足m时,左补零;m,n(%m.nf):以宽度m输出实型小数,小数位为n位(整数部分宽度超过m也全都输出,小数部分则只精确到后n位,如果小数点后仅一位,则精确到n位都会写成0)。(3)注意:默认右对齐,即不足左边来补0或空格,若想左对齐,则写成%-md即可。
10、在函数中局部变量若是被定义成static型(则会存储在静态区,因此数据不会在函数调用完后被释放),如static int f = 1;它只在函数第一次被调用时初始化其值为1,假设执行完后变成10,以后调用该函数时,不再进行初始化,而是使用上一次调用的值,即10了。
11、字符数组中,初始化为char word[] = {'a','b','c'};即数组大小为3个,写成char word[3] = {'a','b','c'}也可;但初始化为char word[] = {"abc"};这时认为是字符串,而字符串以'\0'结尾,所以会有一个额外空间,即数组大小为4个,因此不能写成char word[3] = {"abc"};而应写成 char word[4]才对,否则'\0'会使用到别的数据的空间,可能造成出错。
12、scanf按%s读,遇到空格则会停止,所以若想空格一起读入,则应用gets(),读到回车符为止。同理,printf按%s输出到空格则会停止,则应用puts(),遇到空格继续输出,直到'\0'为止。
13、(1)字符串拷贝函数strcpy(数组一,数组二或字符串),左边大小一定要比右边大,会把'\0'一起拷贝到左边数组中;(2)strcat(数组一,数组二),右边数组中字符接到左边数组中,'\0'就一个,放在末尾;(3)strcmp(字符串(数组)一,字符串(数组)二),左边更大,值大于0,右边更大,值小于0,一样大,值等于0(字典序比较,一样大即到‘\0’为止);(4)strlwr(数组):小写转大写,strupr(数组):大写转小写。