第三章 简单的算术运算和表达式
算数运算符:一元、二元、三元(条件运算符)
1/2是整型除法,1.0/2是浮点数除法
求余运算(%)限定参与运算的两个操作数必须为整数,不能对两个实型数据进行求余运算
余数的符号与被除数的符号相同
C语言中没有幂运算符!
//L3-1
#include <stdio.h>
main()
{
int x = 153, b0, b1, b2, sum;
b2 = x / 100; /* 计算百位数字 */
b1 = (x - b2 * 100) / 10; /* 计算十位数字 */
b0 = x % 10; /* 计算个位数字 */
sum = b2 + b1 + b0;
printf("b2=%d, b1=%d, b0=%d, sum=%d
", b2, b1, b0, sum);
}
//运行结果 b2=1, b1=5, b0=3, sum=9
复合的赋值运算符
- +=:a+=b; 等价于 a=a+b;
- -=
- *=
- /=
- %=
增1和减1运算符(一元运算符)
- ++x:前缀运算符,在变量使用之前对其执行加1操作
- m=++n; 等价于 n=n+1;m=n;
- x++:后缀运算符,先使用变量的当前值,然后对其进行加1操作
- m=n++; 等价于 m=n;n=n+1;
良好的程序设计风格提倡在一行语句中一个变量最多只出现一次增1或者减1运算
不建议在程序中使用复杂的增1和减1运算符,过多的增1和减1运算符会导致程序的可读性变差
宏常量和宏替换
//L3-2
#include <stdio.h>
main()
{
double r = 5.3; /* 圆的半径 */
printf("circumference = %f
", 2*3.14159*r);
printf("area = %f
", 3.14159*r*r);
}
//运行结果
circumference = 33.300854
area = 88.247263
//L3-3
#include <stdio.h>
main()
{
double r;
printf("Input r:"); /* 提示用户输入半径的值*/
scanf("%lf", &r); /* 以双精度实型格式从键盘输入半径的值 */
//scanf()函数也是C的标准输入/输出函数
//&称为取地址运算符,&r指定了用户输入数据存放的变量的地址
printf("circumference = %f
", 2*3.14159*r);
printf("area = %f
", 3.14159*r*r);
}
//运行结果
Input r:6
circumference = 37.699080
area = 113.097240
幻数:在程序中直接使用的常数
- 导致程序的可读性变差
- 容易发生书写错误
- 难以修改
把幻数定义为宏常量或const常量,用一个简单易懂的名字来代替一个长字符串
能提高程序的可读性
//L3-4
#include <stdio.h>
#define PI 3.14159 /* 定义宏常量PI */
main()
{
double r;
printf("Input r:");
scanf("%lf", &r);
printf("circumference = %f
", 2*PI*r); /*编译时PI被替换为3.14159*/
printf("area = %f
", PI*r*r); /*编译时PI被替换为3.14159*/
}
宏定义中的标识符被称为宏名
习惯上用字母全部大写的单词来命名宏常量
将程序中出现的宏名替换为字符串的过程称为宏替换
宏定义的宏名与字符串之间可有多个空白符,无需加等号
字符串后不以分号结尾
宏定义不是C语句,而是一种编译预处理命令
宏常量没有数据类型,const常量可以声明数据类型
//L3-5
#include <stdio.h>
main()
{
const double PI = 3.14159; /* 定义实型的const常量PI */
double r;
printf("Input r:");
scanf("%lf", &r);
printf("circumference = %f
", 2*PI*r);
printf("area = %f
", PI*r*r);
}
表达式中的自动类型转换:
- C编译器在对操作数进行运算之前将所有操作数都转换为取值范围较大的操作数类型,称为类型提升。
- 类型提升可以避免数据信息丢失的情况发生。
在一个赋值语句中,若赋值运算符左侧的变量的类型与右侧的表达式的类型不一致,则赋值时会发生自动类型转换
类型转换的规则是:将右侧表达式的值转换为左侧变量的类型
//L3-6
#include <stdio.h>
main()
{
int n = 256;
float f = 3.6;
double d = 2.5;
n = f;
f = n;
d = f;
printf("n = %d
", n);
printf("f = %f
", f);
printf("d = %f
", d);
}
//运行结果
n = 3
f = 3.000000
d = 3.000000
将取值范围小的类型转换为取值范围大的类型是安全的,而反之则是不安全的
尽量避免使用这种自动的类型转换,建议使用强制类型转换运算符
强制类型转换就是明确地表明程序打算执行哪种类型转换,有助于消除因隐式的自动转换而导致的程序隐患
//L3-7
#include <stdio.h>
main()
{
int m = 5;
printf("m/2=%d
", m/2);
printf("(float)(m/2) = %f
", (float)(m/2));
printf("(float)m/2 = %f
", (float)m/2);
printf("m = %d
", m);
}
//运行结果
m/2=2
(float)(m/2) = 2.000000
(float)m/2 = 2.500000
m = 5
常用的标准数学函数
//L3-8
#include <stdio.h>
#include <math.h>//C的标准数学函数库提供了丰富的数学函数
//使用这些数学函数时,只要在程序的开头加上如下的编译预处理命令即可
main()
{
float a, b, c, s, area;
printf("Input a,b,c:");
scanf("%f,%f,%f", &a, &b, &c);
s = (float)(a + b + c) / 2;
area = sqrt(s * (s - a) * (s - b) * (s - c));
printf("area = %f
", area);
}
//运行结果
Input a,b,c:3,4,5
area = 6.000000
常用的标准数学函数
sqrt(x) | 平方根 |
fabs(x) | 绝对值 |
log(x) | 自然对数 |
log10(x) | 以10为底的对数 |
exp(x) | 指数 |
pow(x,y) | x的y次方 |
sin(x) | 正弦 |
cos(x) | 余弦 |