C语言小课堂:模运算

C语言小课堂:模运算
TANG JIAMEI模运算,又称模数、取模、取余数运算等,它得出一个数除以另一个数的余数。今天我们来一起了解一下在C语言中如何进行模运算。
一、知识点讲解
- 模运算是什么?
在C语言中,模运算(Modulo Operation)使用百分号 % 表示。它是一种二元运算符,用于计算两个整数相除后的余数。例如,a % b 表示 a 除以 b 的余数。
模运算的定义如下: 对于整数 a 和非零整数 b , a % b 的结果 r 满足 a = q * b + r ,其中 q 是商,r 是余数。余数 r 的符号与被除数 a 的符号相同。其绝对值小于除数 b 的绝对值,即 0 <= |r| < |b|。
示例:
10 % 3 的结果是 1 ,因为 10 = 3 * 3 + 1。
-10 % 3 的结果是 -1 ,因为 -10 = -4 * 3 + 2,但C语言中,余数的符号与被除数相同,所以 -10 = -3 * 3 - 1,或者更准确地理解为 -10 / 3 的商为 -3,余数为 -1 。
10 % -3 的结果是 1 ,因为 10 = -3 * (-3) + 1。
-10 % -3 的结果是 -1,因为 -10 = -3 * 3 - 1 。
- 何时用?
模运算在编程中具有广泛的应用,尤其是在处理周期性、循环性或需要对数据进行分组、散列的场景。
何时用:
判断奇偶性: 当一个数 n 对 2 进行模运算时,如果结果为 0 ,则 n 是偶数;如果结果为 1 或 -1(取决于 n 的符号),则 n 是奇数。
限制数值范围(循环计数): 当需要一个变量在一个固定范围内循环时,模运算非常有用。例如,一个时钟的秒数从 0 到 59 循环,可以使用 (current_second + 1) % 60 来计算下一秒。
哈希函数: 在数据结构和算法中,模运算常用于构建哈希函数,将任意大的键映射到固定大小的哈希表索引中。
数字位操作: 获取一个数字的个位数、十位数等。例如 n % 10 可以得到 n 的个位数。
周期性任务调度: 在操作系统或嵌入式系统中,周期性任务的调度常常涉及模运算,以确定任务在某个时间周期内的执行点。
加密算法: 一些加密算法(如RSA)中会用到模幂运算。
为什么用: 模运算提供了一种简洁高效的方式来处理整数除法后的余数,这对于解决上述问题至关重要。它允许我们实现周期性行为、数据分组和边界限制,而无需复杂的条件判断或循环结构。
与关联知识点的联系与区别:
与除法运算符 / 的联系: 模运算与除法运算是紧密相关的。a / b 给出的是商,而 a % b 给出的是余数。两者共同构成了整数除法的完整结果。
与位运算符的联系: 对于 2 的幂次的模运算,有时可以用位运算代替以提高效率。例如,n % 2 等价于 n & 1(对于非负数)。然而,位运算只适用于除数为 2 的幂次的情况,而模运算则适用于任意非零整数。
- 怎么用?
模运算的用法相对简单,但需要注意其操作数的类型和符号。
基本语法:result = operand1 % operand2;
其中 operand1 和 operand2 必须是整数类型(int , long , short 等)。如果操作数是浮点类型,编译器会报错。
示例代码:
1 |
|
注意事项:
除数( operand2 )不能为 0,否则会导致运行时错误(除零错误)。
模运算结果的符号与被除数(operand1)的符号相同。这是C语言标准规定的行为。
二、典型习题
- 选择题
一个整数 num 对 7 进行模运算,结果可能是以下哪个值?
A. 7
B. -7
C. 5
D. 8
- 判断题
表达式 (15 % 4) == (-15 % -4) 的结果为真(true)。
A. 对
B. 错
- 填空题
请填写 num % 10 表达式的计算结果,使其完成获取一个两位数 num 的个位数字的任务。例如,当 num 为 42 时,结果为 2 。
- 编程题
编写一个C语言程序,接收用户输入的一个正整数 n ,然后判断 n 是否为水仙花数。水仙花数是指一个三位数,其各位数字的立方和等于该数本身。例如, 153 是一个水仙花数,因为 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153。
要求:
程序应提示用户输入一个三位数。
使用模运算和除法运算分离出该三位数的百位、十位和个位。
计算各位数字的立方和。
判断并输出该数是否为水仙花数。
- 编程题
编写一个C语言程序,模拟一个简易的数字加密器。程序接收一个四位数的整数作为明文,然后对其进行加密。加密规则如下:
将明文的每个数字(个、十、百、千位)都加上 7 。
将每个数字的结果都对 10 取模,得到新的数字。
将新数字的千位和十位互换,百位和个位互换。
要求:
程序应提示用户输入一个四位数的整数。
使用模运算和除法运算分离出明文的各个数字。
按照加密规则进行计算和交换。
输出加密后的四位整数。
三、习题讲解
- 选择题
一个整数 num 对 7 进行模运算,结果可能是以下哪个值?
A. 7
B. -7
C. 5
D. 8
答案:C
解析:模运算 a % b 的结果 r 满足 0 <= |r| < |b| ,且 r 的符号与被除数 a 的符号相同。 在这里,除数是 7,所以结果的绝对值必须小于 7 。
A. 7 的绝对值不小于 7 。
B. -7 的绝对值不小于 7 。
C. 5 的绝对值小于 7,且可以是正数,符合条件。
D. 8 的绝对值不小于 7 。 因此, 5 是唯一可能的选项。
- 判断题
表达式 (15 % 4) == (-15 % -4) 的结果为真(true)。
A. 对
B. 错
答案:B
解析:首先计算 15 % 4 :15 = 3 * 4 + 3,所以 15 % 4 的结果是 3 。
然后计算 -15 % -4: C语言规定模运算结果的符号与被除数相同。-15 / -4 的商是 3 ,余数是 -3 (因为 -15 = 3 * (-4) - 3)。 所以 -15 % -4 的结果是 -3 。
比较 3 == -3,结果为假(false)。因此,原表达式的结果为 错 。
- 填空题
请填写 num % 10 表达式的计算结果,使其完成获取一个两位数 num 的个位数字的任务。例如,当 num 为 42 时,结果为 2 。
答案: num % 10
解析:任何整数对 10 进行模运算,其结果就是该整数的个位数字。 例如:
42 % 10 = 2
123 % 10 = 3
7 % 10 = 7这是因为当一个数被 10 除时,商是去掉个位数后的部分,余数就是个位数本身。
- 编程题
编写一个C语言程序,接收用户输入的一个正整数 n ,然后判断 n 是否为水仙花数。水仙花数是指一个三位数,其各位数字的立方和等于该数本身。例如, 153 是一个水仙花数,因为 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153。
代码实现:
1 |
|
解题思路:
输入与校验: 首先获取用户输入,并简单校验是否为三位数,以确保后续分离数字的逻辑正确。
分离数字:
个位: 利用 n % 10 可以直接得到 n 的个位数字。
去除个位: 利用 n = n / 10 可以将 n 的个位去除,使其变成一个两位数(或一位数)。
十位和百位: 重复上述过程,对新的 n 进行 n % 10 得到十位,再 n = n / 10 得到百位。
计算立方和: 将分离出的三个数字分别求立方,然后相加。
判断: 将计算出的立方和与原始输入的数进行比较,如果相等,则是水仙花数。
- 编程题
编写一个C语言程序,模拟一个简易的数字加密器。程序接收一个四位数的整数作为明文,然后对其进行加密。加密规则如下:
将明文的每个数字(个、十、百、千位)都加上 7 。
将每个数字的结果都对 10 取模,得到新的数字。
将新数字的千位和十位互换,百位和个位互换。
代码实现:
1 |
|
解题思路:
输入与校验: 获取用户输入,并确保其为四位数。
分离数字: 利用除法和模运算的组合,从明文中逐一提取出千位、百位、十位和个位。
plaintext % 10 得到个位。
(plaintext / 10) % 10 得到十位。
(plaintext / 100) % 10 得到百位。
plaintext / 1000 得到千位。
加密计算: 对每个分离出的数字,按照规则 (digit + 7) % 10 进行计算,得到加密后的新数字。
数字交换与重组: 根据交换规则,将新得到的四个数字重新组合成一个四位数。需要注意的是,这里是位置的交换,而不是数字本身的交换。新数字的千位是原先的十位加密结果,新数字的百位是原先的个位加密结果,以此类推。
新的千位是 e3 (原十位加密结果)
新的百位是 e4 (原个位加密结果)
新的十位是 e1 (原千位加密结果)
新的个位是 e2 (原百位加密结果) 最后将它们乘以相应的权重(1000, 100, 10, 1)并相加。
你总以为时间线是笔直向前,却不曾料想,在某个不经意的节点,一切又回到了起点,那不是停滞,而是另一种周而复始的秩序,每一次归零,都蕴含着新的可能。




