1. 判断奇偶性
求余运算常用于判断一个整数是否为偶数或奇数:
- 偶数:
n % 2 == 0
- 奇数:
n % 2 != 0
#include <stdio.h>
int main() {
int num = 5;
if (num % 2 == 0) {
printf("%d 是偶数\n", num);
} else {
printf("%d 是奇数\n", num);
}
return 0;
}
判断3的倍数:
#include <stdio.h>
int is_multiple_of_3(int n) {
return n % 3 == 0;
}
int main() {
int num;
printf("请输入一个整数: ");
scanf("%d", &num);
if (is_multiple_of_3(num)) {
printf("%d 是 3 的倍数\n", num);
} else {
printf("%d 不是 3 的倍数\n", num);
}
return 0;
}
判断7的倍数:
#include <stdio.h>
int is_multiple_of_7(int n) {
return n % 7 == 0;
}
int main() {
int num;
printf("请输入一个整数: ");
scanf("%d", &num);
if (is_multiple_of_7(num)) {
printf("%d 是 7 的倍数\n", num);
} else {
printf("%d 不是 7 的倍数\n", num);
}
return 0;
}
2. 循环和约束范围
通过取模运算可以将一个数限制在一个特定范围内,常用于循环索引或数组处理。
例如,假设有一个数组 arr
,需要按循环方式访问:
int arr[] = {10, 20, 30};
int size = 3;
for (int i = 0; i < 10; i++) {
printf("%d\n", arr[i % size]); // 保证索引始终在 0 ~ size-1 范围内
}
3. 解决周期性问题
在某些数学或编程问题中,取模可以用来处理周期性问题,比如:
- 圆周上的点循环。
- 时钟问题:如
hours % 12
将 24 小时制转换为 12 小时制。
4. 哈希函数
在哈希表或哈希算法中,取模运算常用来将哈希值压缩到数组的合法索引范围内。
示例:
int hash = key % table_size; // 将键值映射到 [0, table_size-1] 的范围
5. 对齐操作
在某些低级编程中,取模可以用于对齐内存地址或判断是否为某种倍数。
示例:
if (address % 4 == 0) {
printf("内存地址对齐到 4 字节边界\n");
}
示例,假设我们有一块内存区域,要求它的起始地址是 4 字节对齐,可以使用求余检查:
#include <stdio.h>
void check_alignment(void* ptr, int alignment) {
if ((size_t)ptr % alignment == 0) {
printf("地址 %p 是 %d 字节对齐的\n", ptr, alignment);
} else {
printf("地址 %p 不是 %d 字节对齐的\n", ptr, alignment);
}
}
int main() {
int a;
check_alignment(&a, 4);
return 0;
}
6. 分组或分片
通过取模将数据分配到不同的组或块中。例如,将一组数字分成 3 组:
int group = num % 3; // 分成组 0, 1, 2
6.1 按索引分组
通过 i % n
(n
为组数),可以将数组中索引为 i
的元素分配到第 (i % n)
组。
用途:均匀分配数组中的元素,例如任务分配、循环排班等。
代码示例:
#include <stdio.h>
void group_by_index(int arr[], int size, int groups[][100], int group_size[], int n) {
for (int i = 0; i < n; i++) {
group_size[i] = 0; // 初始化每组大小
}
for (int i = 0; i < size; i++) {
int group_index = i % n; // 计算组号
groups[group_index][group_size[group_index]++] = arr[i];
}
}
int main() {
int arr[] = {10, 20, 30, 40, 50, 60, 70, 80, 90};
int size = sizeof(arr) / sizeof(arr[0]);
int n = 4; // 分成 4 组
int groups[4][100], group_size[4];
group_by_index(arr, size, groups, group_size, n);
for (int i = 0; i < n; i++) {
printf("组 %d: ", i);
for (int j = 0; j < group_size[i]; j++) {
printf("%d ", groups[i][j]);
}
printf("\n");
}
return 0;
}
组 0: 10 50 90
组 1: 20 60
组 2: 30 70
组 3: 40 80
6.2 按值分组
通过对数组元素值 value % n
求余,可以将值分到特定的组。
用途:将数据分类到不同的组,例如分桶、散列存储等。
代码示例:
#include <stdio.h>
void group_by_value(int arr[], int size, int groups[][100], int group_size[], int n) {
for (int i = 0; i < n; i++) {
group_size[i] = 0; // 初始化每组大小
}
for (int i = 0; i < size; i++) {
int group_index = arr[i] % n; // 根据值计算组号
groups[group_index][group_size[group_index]++] = arr[i];
}
}
int main() {
int arr[] = {15, 23, 36, 44, 52, 67, 71, 85, 91};
int size = sizeof(arr) / sizeof(arr[0]);
int n = 3; // 分成 3 组
int groups[3][100], group_size[3];
group_by_value(arr, size, groups, group_size, n);
for (int i = 0; i < n; i++) {
printf("组 %d: ", i);
for (int j = 0; j < group_size[i]; j++) {
printf("%d ", groups[i][j]);
}
printf("\n");
}
return 0;
}
组 0: 15 36 52
组 1: 44 67 85
组 2: 23 71 91
注意事项
- 如果操作数为负数,取模结果的符号取决于编译器的实现,通常与被除数(左操作数)保持一致。
- 如果右操作数为 0,会导致运行时错误(除以零错误)。