如何在C语言中初始化埃拉托斯特尼筛法所需的32位unsigned int大位数组?
用32位
unsigned int数组实现埃氏筛的批量初始化方案 1. 批量初始化数组元素为全1值
每个32位unsigned int全1的对应值是0xFFFFFFFF(十六进制),或者标准库定义的UINT_MAX(需包含<stdint.h>或<limits.h>),以下两种方法可以快速完成批量初始化:
方法一:用memset动态填充(推荐动态分配数组时使用)
memset是底层优化的内存填充函数,按字节批量赋值。每个字节填0xFF,就能让每个unsigned int元素的32位全为1:
#include <string.h> #include <stdint.h> #include <stdlib.h> #define MAX_NUM 100000 // 计算所需的数组元素个数:向上取整,确保覆盖所有位 size_t arr_len = (MAX_NUM + 31) / 32; // 动态分配内存 uint32_t *sieve = malloc(arr_len * sizeof(uint32_t)); // 批量填充:第三个参数是总字节数,必须是元素个数×单个元素字节数 memset(sieve, 0xFF, arr_len * sizeof(uint32_t));
方法二:编译时静态初始化(仅适用于静态/全局数组)
如果数组是静态分配的(全局数组或static局部数组),可以用C的指定初始化器批量赋值,注意你之前的[0-100000]写法错误,C的范围初始化格式是[起始索引 ... 结束索引],且索引是数组元素的索引,不是位索引:
#include <stdint.h> #define MAX_NUM 100000 #define ARR_LEN ((MAX_NUM + 31) / 32) // 静态数组编译时直接初始化所有元素为全1 static uint32_t sieve[ARR_LEN] = {[0 ... ARR_LEN-1] = UINT_MAX};
2. 初始化后的必要修正
埃氏筛需要先标记0和1为非质数,初始化完全1数组后,记得修改对应位:
// 标记0为非质数:对应第0位,位于sieve[0]的第0位 sieve[0] &= ~(1U << 0); // 标记1为非质数:对应第1位,位于sieve[0]的第1位 sieve[0] &= ~(1U << 1);
这里用1U是为了避免整数溢出,保证位运算在无符号规则下进行。
3. 为什么手动循环设位效率低
你之前用x = x | (1 << i)循环设位,每次都要单独计算位偏移、执行单比特修改操作,而memset是按内存块批量操作,底层由编译器或系统优化,速度远快于循环;静态初始化则是在程序加载阶段完成,运行时无额外开销。
内容的提问来源于stack exchange,提问作者user23318237
相关产品推荐
相关产品推荐

