14-求模运算符%
5.3.2 求模运算符: %
求模运算符(modulus operator)用于整数运算。求模运算符给出其左侧整数除以右侧整数的余数(remainder)。例如, 13 % 5 (读作“ 13 求模 5 ”)得 3 ,因为 13 比 5 的两倍多 3 ,即 13 除以 5 的余数是 3 。求模运算符只能用于整数,不能用于浮点数。
乍一看会认为求模运算符像是数学家使用的深奥符号,但是实际上它非常有用。求模运算符常用于控制程序流。例如,假设你正在设计一个账单预算程序,每3个月要加进一笔额外的费用。这种情况可以在程序中对月份求模3(即, month % 3 ),并检查结果是否为0。如果为0,便加进额外的费用。等学到第7章的 if 语句后,读者会更明白。
程序清单5.9演示了 % 运算符的另一种用途。同时,该程序也演示了 while 循环的另一种用法。
程序清单5.9 min_sec.c 程序
// min_sec.c -- 把秒数转换成分和秒
#include <stdio.h>
#define SEC_PER_MIN 60 // 1分钟60秒
int main(void)
{
int sec, min, left;
printf("Convert seconds to minutes and seconds!\n");
printf("Enter the number of seconds (<=0 to quit):\n");
scanf("%d", &sec); // 读取秒数
while (sec > 0)
{
min = sec / SEC_PER_MIN; // 截断分钟数
left = sec % SEC_PER_MIN; // 剩下的秒数
printf("%d seconds is %d minutes, %d seconds.\n", sec,
min, left);
printf("Enter next value (<=0 to quit):\n");
scanf("%d", &sec);
}
printf("Done!\n");
return 0;
}
该程序的输出如下:
Convert seconds to minutes and seconds!
Enter the number of seconds (<=0 to quit):
154
154 seconds is 2 minutes, 34 seconds.
Enter next value (<=0 to quit):
567
567 seconds is 9 minutes, 27 seconds.
Enter next value (<=0 to quit):
0
Done!
程序清单5.2使用一个计数器来控制 while 循环。当计数器超出给定的大小时,循环终止。而程序清单5.9则通过 scanf() 为变量 sec 获取一个新值。只要该值为正,循环就继续。当用户输入一个0或负值时,循环退出。这两种情况设计的要点是,每次循环都会修改被测试的变量值。
负数求模如何进行?C99规定“趋零截断”之前,该问题的处理方法很多。但自从有了这条规则之后,如果第1个运算对象是负数,那么求模的结果为负数;如果第1个运算对象是正数,那么求模的结果也是正数:
11 / 5得2,11 % 5得1
11 / -5得-2,11 % -2得1
-11 / -5得2,-11 % -5得-1
-11 / 5得-2,-11 % 5得-1
如果当前系统不支持C99标准,会显示不同的结果。实际上,标准规定:无论何种情况,只要 a 和 b 都是整数值,便可通过 a - (a/b) * b 来计算 a%b 。例如,可以这样计算 -11%5 :
-11 - (-11/5) * 5 = -11 -(-2)*5 = -11 -(-10) = -1