You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言位编程:ipv4_to_bit_string()传参1234的移位逻辑解析

问题描述

我是C语言位编程的初学者,目前难以理解代码中ipv4_to_bit_string()函数的工作原理,核心疑问如下:

  • 向该函数传入整数1234时具体会执行什么操作?
  • 函数中为何要对传入的整数分别执行右移24位、16位、8位、4位的操作?
参考代码
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct BIT_STRING_s {
    uint8_t *buf;       /* BIT STRING body */
    size_t size;        /* Size of the above buffer */
    int bits_unused;    /* Unused trailing bits in the last octet (0..7) */
} BIT_STRING_t;

BIT_STRING_t     tnlAddress;


void ipv4_to_bit_string(int i, BIT_STRING_t *p)
{
    do {
        (p)->buf = calloc(4, sizeof(uint8_t));              
        (p)->buf[0] = (i) >> 24 & 0xFF;                  
        (p)->buf[1] = (i) >> 16 & 0xFF;                  
        (p)->buf[2] = (i) >> 8 & 0xFF;                   
        (p)->buf[3] = (i) >> 4 & 0xFF;                   
        (p)->size = 4;
        (p)->bits_unused = 0;
    } while(0);
}


int main()
{
    BIT_STRING_t *p = (BIT_STRING_t*)calloc(1, sizeof(BIT_STRING_t));
    ipv4_to_bit_string(1234, p);
}
解答

传入1234时的执行流程

传入参数i=1234时,函数按顺序执行以下操作:

  1. 为p->buf分配4字节的堆内存,calloc会自动将这4字节初始化为0
  2. 逐字节计算并填充buf数组的4个元素:
    1234作为32位int存储时的二进制为00000000 00000000 00000100 11010010,所有高于12位的比特位全为0:
    • 计算buf[0]:将1234右移24位后,所有有效比特位都被移出,结果为0,和0xFF按位与后仍为0,因此buf[0] = 0
    • 计算buf[1]:将1234右移16位后,有效比特位同样被全部移出,结果为0,因此buf[1] = 0
    • 计算buf[2]:将1234右移8位后,剩余值为二进制00000100也就是十进制4,和0xFF按位与后为4,因此buf[2] =4
    • 计算buf[3]:将1234右移4位后,剩余值为二进制01001101也就是十进制77,和0xFF按位与后为77,因此buf[3] =77
  3. 给结构体其他成员赋值:设置p->size =4表示缓冲区长度为4字节,设置p->bits_unused=0表示最后一个字节没有闲置比特位
  4. 代码里的do{...}while(0)是C语言常见的单段代码包裹写法,没有循环逻辑,只会执行一次包裹内的代码。

移位操作的设计逻辑

IPv4地址本质是一个32位无符号整数,我们平时用的点分十进制格式(比如192.168.1.1),本质是把32位整数拆成4个独立的8位段(每个段取值0-255),从高位到低位依次对应四个十进制数。
正常的IPv4拆分为字节数组的逻辑,就是通过移位把每个8位段移动到最低位,再通过&0xFF保留最低8位、清除高位多余值,对应关系是:

  • 右移24位:取32位整数的最高8位,对应点分十进制的第一个段
  • 右移16位:取32位整数的次高8位,对应点分十进制的第二个段
  • 右移8位:取32位整数的第三个8位,对应点分十进制的第三个段
  • 右移0位(即不做移位直接&0xFF):取32位整数的最低8位,对应点分十进制的第四个段

你贴出的代码最后一步写的是右移4位,这是代码编写错误,会导致最后一个字节取值错误,无法正确解析出IPv4地址的第四段。


内容的提问来源于stack exchange,提问作者myquest4 sh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:42:31