1.算术运算符:
算术运算符与赋值运算符,应当是所有运算符号中最简单和常用的运算符了。算术运算符除了五则运算之外,还有自增与自减总共7种运算符。
2.简单算术运算符:
在优先级相同的情况下,C语言的运算符大部分是自左向右逐一运算。如果在同一行代码中,有多个优先级不同的运算符,优先级高的先执行运算而优先级低的后运算。例如:加减运算的优先级低于乘除和取余运算的优先级。
代码 [例5-1]测试算术与赋值符号的优先级 #include <stdio.h> int main() { int a = 15; int b = a / 4 * 2; int c = a + 10*-b; a = c + b % 5 * 2; printf("a=%d,b=%d,c=%d\n",a,b,c); return 0; } |
将以上代码输入到C语言编译器中进行编译、运行并查看打印结果:
a)先用口算或笔算方式算出代码中三个变量运算后的结果,观察与程序打印的结果是否一致;
b)最好能在调试模式下单步执行,观察程序执行每一步运算之后变量内的数据变化情况;
以下为结论:
a)如果同一行代码中,同时有加减和乘除取余,乘除和取余先运算,加减后运算;
b)如果同一行代码中,只有加减或只有乘除和取余,优先级相同就正常自左向右运算。
c)如果在除法运算过程中不能完全整除,C语言不是采用四舍五入,而是去掉小数位保留整数部分。
3.除数为零的错误:
在除法或者取余运算中如果右边的值是0,程序运行时将会出现程序崩溃现象。所谓程序崩溃,就是操作系统发现某程序运行到某处代码段时遇到了致命的错误,不得不将该程序(在提示之后)强行结束。或者说,当操作系统发现某个进程将要出现严重错误时,就会立即阻断这个程序的运行,强制结束这个进程。
代码 [例5-2]测试除数为零的错误 #include <stdio.h> int main() { int a = 10; int b = a / 15 * 2; int c = a + 10 % b; a = c + b % 5 * 2; printf("a=%d,b=%d,c=%d\n",a,b,c); return 0; } |
将以上代码输入到C语言编译器中进行编译、运行并查看打印结果:
a)先用口算或笔算方式算出变量运算后的结果,预测程序执行到哪一行代码时将出现程序崩溃;
b)最好能在调试模式下单步执行,观察程序执行的每一步运算之后变量内的数据变化情况;
c)重点观察程序单步执行到哪一行代码时,出现了程序崩溃现象?
d)在控制台中输入编译生成的执行程序的路径和执行文件名,观察问题程序在控制台中运行时崩溃的现象。
4.自增自减运算符:
在程序设计中,经常遇到“i=i+1”或“i=i-1”这两种极为常见的运算。例如在循环程序中有一个变量i,变量i,在每次循环过程中都执行“i=i+1”或“i=i-1”的计算,这个变量i就被称为“计数器”。C语言为这两种类似于计数器的操作,提供了两个简化的运算符“++”和“—”,分别叫做自增运算符和自减运算符。
代码 [例5-3]测试自增自减运算符(前缀)的优先级 #include <stdio.h> int main() { int a = 5; int b = ++a; int c = ++b; a = ++b*++c; printf("a=%d,b=%d,c=%d\n",a,b,c); printf("--a=%d,--b=%d,--c=%d\n",--a,--b,--c); return 0; } |
将以上代码输入到C语言编译器中进行编译、运行并查看打印结果:
a)先用口算或笔算方式算出每个变量运算后的结果,预测程序执行两次打印输出的结果是多少;
b)最好能在调试模式下单步执行,观察程序执行每一步运算之后变量内的数据变化情况;
代码 [例5-4]将前缀的自增自减运算符拆分为两行代码 #include <stdio.h> int main() { int a = 5; a=a+1; int b =a; b=b+1; int c =b; b=b+1,c=c+1; a = b*c; printf("a=%d,b=%d,c=%d\n",a,b,c); a=a-1,b=b-1,c=c-1; printf("--a=%d,--b=%d,--c=%d\n",a,b,c); return 0; } |
将以上代码输入到C语言编译器中进行编译、运行并查看打印结果:
a)先用口算或笔算方式算出程序运算后变量内的数据变化,预测打印的结果与拆分前是否一致;
b)最好能在调试模式下单步执行每行代码,观察程序执行每一步运算之后变量内的数据变化情况;
代码 [例5-5]测试自增自减运算符(后缀)的优先级 #include <stdio.h> int main() { int a = 5; int b = a++; int c = b++; a = b++*c++; printf("a=%d,b=%d,c=%d\n",a,b,c); printf("a--=%d,b--=%d,c--=%d\n",a--,b--,c--); return 0; } |
将以上代码输入到C语言编译器中进行编译、运行并查看打印结果:
a)先用口算或笔算方式算出每个变量运算后的结果,预测程序执行两次打印输出的结果是多少;
b)最好能在调试模式下单步执行,观察程序执行每一步运算之后变量内的数据变化情况;
代码 [例5-6] 将后缀的自增自减运算符拆分为两行代码 #include <stdio.h> int main() { int a = 5; int b = a; a=a+1; int c = b; b=b+1; a = b*c; b=b+1,c=c+1; printf("a=%d,b=%d,c=%d\n",a,b,c); printf("a--=%d,b--=%d,c--=%d\n",a,b,c); a=a-1,b=b-1,c=c-1; return 0; } |
将以上代码输入到C语言编译器中进行编译、运行并查看打印结果:
a)先用口算或笔算方式算出程序运算后变量内的数据变化,预测打印的结果与拆分前是否一致;
b)最好能在调试模式下单步执行每行代码,观察程序执行每一步运算之后变量内的数据变化情况;
总结:
a)几乎所有含有前缀自增自减符号的表达式都可以拆分为,在当前表达式前一行代码中执行自增自减运算;
b)几乎所有含有后缀自增自减符号的表达式都可以拆分为,在当前表达式后一行代码中执行自增自减运算。
在实际开发的程序设计中,适当将自增自减运算符与其他表达式结合使用是可以的。但是也要注意,同一行代码中不要过多使用自增自减运算符,否则会造成程序的可读性不好甚至整个项目难于维护。