一.基本运算符
1.赋值运算符: =
C使用可修改的左值标记那些可赋值的实体
举例: num = 2020;
说明: 1).=左侧是一个变量名,右侧是赋给该变量的值
2) 上面的语句读作: 把值2020赋给变量num
3) 赋值行为从右往左进行
4) 赋值表达式语句的目的是把值储存到内存位置上,用于储存值的数据存储区域统称为数据对象
(1) 左值
1) 左值用于标识特定数据对象的名称或表达式
2) 对象指的是实际的数据存储,左值是用于标识或定位存储位置的标签
3)赋值运算符的左侧应该是可修改的左值
(2) 右值
1)右值可以是常量、变量或其他可求值的表达式(如函数调用)
2)右值指的是能赋值给可修改左值的量,且本身不是左值
2.加法运算符: + 减法运算符: -
举例: a = b + c;
说明: 1)加法运算符用于加法运算,使其两侧的值相加;减法运算符用于减法运算,使其左侧的数减去右侧的数
2)运算对象可以是变量也可以是常量
3)a,b,c都是可修改的左值,每个变量都标识了一个可被赋值的数据对象(b+c是一个右值)
4)+和-运算符都被称为二元运算符,即这些运算符需要两个运算对象才能完成操作
3.乘法运算符: *
举例: 打印1-20的平方表
int num = 1;
while (num < 21)
{
printf("%d%6d\n", num, num*num);
num = num + 1;
}
4.除法运算法: /
举例: num = 5/3;
说明: 1) /左侧的值是被除数,右侧的值是除数
2) 在C语言中,整数除法结果的小数部分被丢弃,这一过程称为截断
printf("%d\n", 6 / 3); //输出结果为2
printf("%d\n", 6 / 4); //输出结果为1
printf("%1.2f\n", 6.5 / 4); //输出结果为1.63
3) 浮点数除以整数时,编译器将两个运算对象转换成相同的类型(整数会被转换成浮点数)
5.运算符优先级
举例: num = a+b*c/d;
说明: 1) 乘法和除法的优先级比加法和减法高,所以先执行乘法和除法(b*c->/d)
2) 运算符的优先级相同,则根据他们在语句中出现的顺序来执行(从左往右,=运算符除外)
3) 若想先进行加法运算则需要加括号即: num = (a+b*c)/d
总结:
运算符 | 结合律 |
---|---|
() | 从左往右 |
+ -(一元) | 从右往左 |
* / | 从左往右 |
+ -(二元) | 从左往右 |
= | 从右往左 |
结合律只适用于共享同一运算对象运算符
6.sizeof运算符和size_t类型
举例:
int n = 0;
size_t intSize;
intSize = sizeof(int);
printf("整数%d占%d个字节,intSize = %d", n, sizeof(n), intSize);
说明: 1) sizeof运算符以字节为单位返回运算对象的大小,运算对象可以输具体的数据对象(如变量名)或类型
2) sizeof返回size_t类型的值,size_t是一个无符号整数类型
7.求模运算符: %
举例: 把秒数换成分和秒
int sec, min, left; //声明秒,分,模后秒
printf("请输入秒数: ");
scanf("%d", &sec);
while (sec > 0)
{
min = sec / num;
left = sec % num;
printf("%d 秒换算成为: %d:%d\n", sec, min, left);
printf("请输入秒数: ");
scanf("%d", &sec);
}
printf("输入的秒数无意义!\n");
说明: 1) 求模运算符用于整数运算(不能用于浮点数),求模运算符给出其左侧整数除以右侧整数的余数
2) 负数求模: 如果第一个运算对象是负数,则求模结果为负数;
如果第一个运算对象是正数,则求模结果为正数
例: 11/5得2 11%5得1
11/-5得-2 11%-5得1
-11/-5得2 -11%-2得-1
-11/5得-2 -11%5得-1
8.递增运算符: ++
举例: 前缀++和后缀++的区别
int a = 1, b = 1;
int A = a++; //后缀递增
int B = ++b; //前缀递增
printf("a = %d,b = %d\n", a, b); //a = 2,b = 2
printf("A = %d,B = %d", A, B); //A = 1,B = 2
说明: 1) A = a++; //先将a的值赋给A,然后a = a+1
2) B = ++b; //先执行++b即b = b+1,然后将b的值赋给B
9.递减运算符: --
举例: 前缀--和后缀--的区别
int a = 5, b = 5;
int A = a--; //后缀递增
int B = --b; //前缀递增
printf("a = %d,b = %d\n", a, b); //a = 4,b = 4
printf("A = %d,B = %d", A, B); //A = 5,B = 4
说明: 1) A = a--; //先将a的值赋给A,然后a = a-1
2) B = --b; //先执行--b即b = b-1,然后将b的值赋给B
10.递增运算符和递减运算符的优先级
1) 递增运算符和递减运算符都有很高的结合优先级,只有圆括号的优先级比他们高
2) 根据优先级可以判断何时使用n的值对表达式求值,递增运算符的性质决定了何时递增n的值
3) 如果一个变量出现在一个函数的多个参数中,不要对该变量使用递增或递减运算符
4) 如果一个变量多次出现在一个表达式中,不要对该变量使用递增或递减运算符
二、表达式和语句
1.表达式
1)表达式由运算符和运算对象组成(运算对象是运算符操作的对象)
2) 举例:
表达式 | 值 |
---|---|
-4+6 | 2 |
c = 3+8 | 11 |
5>3 | 1(条件为真值为1,条件为假值为0) |
6+(c=3+8) | 17(两个子表达式的和) |
2.语句
语句是C程序的基本构件块,一条语句相当于一条完整的计算机指令
举例: 常见语句
int count,sum; //声明
count = 0; //表达式语句
sum = 0; //表达式语句
; //空语句
while(count++<20) //迭代语句
sum = sum + count;
printf("sum = %d\n",sum); //表达式语句
return 0; //跳转语句
3.复合语句(块)
复合语句是用花括号括起来的一条或多条语句,复合语句也称为块
举例:
int num = 1;
while(num<20)
{
printf("%d\n",num);
num++;
}
说明: 整个花括号括起来的实则为一条复合语句,整个复合语句被视为一条语句,每执行一条循环,复合语句就被执行一次
4.类型转换
1) 升级:由较小类型转换为较大类型(当类型转换出现在表达式时,无论unsigned还是signed的char和short都会被自动转换成int)
2) 涉及两种类型的运算:两个值会被分别转换成两种类型的更高级别
3) 类型的级别从高至低:long double>double>float>unsigned long long>long long>unsigned long>long>unsigned int>int
注:当long和int的大小相同时,unsigned int比long的级别高
4) 在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型。这个过程可能导致类型升级或降级
5) 当做为函数参数传递时,char和short被转换成int,float被转换成double
char ch;
int i;
float f;
f = i = ch = 'C'; //第四行
printf("ch = %c,i = %d,f = %2.2f\n", ch, i, f);
ch = ch + 1; //第六行
i = f + 2 * ch;
f = 2 * ch + i;
printf("ch = %c,i = %d,f = %2.2f\n", ch, i, f);
ch = 1107; //第十行
printf("ch = %c\n", ch);
ch = 80.89; //第十二行
printf("ch = %c\n", ch);
说明: 1) 第四行: 字符‘C'赋值给ch,i按4字节接受由'C'转换的整数67,f接受由67转换的浮点数67.00
2) 第六行: ch+1对应ASCII为字符‘D’赋值给ch,对应整数为68
3) 第七行: ch转换成整数68,然后*2为了和f相加,乘积整数转换为浮点数,结果为203.00转换为int类型
4) 第八行: ch转换为浮点类型68.00,然后*2为了和i相加,i的值被转换成浮点类型,结果为339.00
5) 第十行: 超出类型范围,忽略额外的位(1107%265),得到字符S的ASCII码
6) 第十二行: 将浮点类型赋值给ch,发生截断,ch的值为字符P的ASCII码
5.强制类型转换运算符
举例(num为int类型): num = 1.7+1.8;
num = (int)1.7 + (int)1.8;
说明: 1) 1.7+1.8相加得3.5,为了匹配int类型变量num,发生截断,结果为3
2) 强制类型转换将1.7和1.8都转换为1,结果为2
3) 圆括号和它括起来的类型名构成了强制类型转换运算符