【发布时间】:2022-01-21 23:03:49
【问题描述】:
我得到一个掩码作为我使用strtol 和strtok 检索的字符串,我想保存在unsigned int x 中,用零结尾,& 它的IP 也表示为@987654330 @ 为了只保留 MSB(最后我要将该 IP 与另一个 IP 进行比较)。
我的想法是设置x的所有位,然后关闭掩码大小之后的所有位:
#define IPV4_LENGTH 32
//subent is "123.34.45.66/31"
curr_IP->address = malloc(sizeof (struct in_addr));
token = strtok(subnet, "/");
inet_aton(token, curr_IP->address);
long mask = strtol(strtok(NULL, "/"), NULL, 10);
curr_IP->x = -1;
for(long i=mask; i<=IPV4_LENGTH; i++){
curr_IP->x &= ~(1U << i);
}
示例:如果掩码 = 31,我想以 11111111111111111111111111111110 结尾,以 unsigned int 表示 -> FFFFFFFE 以十六进制表示
PS掩码不能为0
更新:
curr_IP->x = -1;之后的内存视图
我们可以看到它确实设置了所有位
curr_IP->x &= ~(1U << i);i = 31 之后的内存视图
预计fffffffe
【问题讨论】:
-
请尝试创建一个合适的minimal reproducible example 向我们展示。对“输入”进行硬编码,并包含
IPV4_LENGTH之类的内容。 -
还可以尝试使用调试器逐条执行代码语句,同时监控变量及其值。如果您将更复杂的表达式拆分为更小更简单的表达式,并分配给临时变量,这将很有帮助。例如,
curr_IP->x &= ~(1UL << i);可以是unsigned long temp1 = 1UL << i; unsigned long temp2 = ~temp1; unsigned long temp3 = curr_IP->x & temp2; curr_IP->x = temp3;更容易查看和验证您的表达式和计算。 -
@Someprogrammerdude 希望这就够了
-
@RedYoel 请记住,类型的大小取决于编译器。例如,Microsoft 编译器仍然使用 32 位
long,即使在 64 位系统上也是如此。 -
@RedYoel
int已签名且已签名溢出是未定义的行为!所以使用unsigned int或包含<stdint.h>并使用uint32_t来获得32 位编译器
标签: c bitwise-operators bitmask