算法查找 C 中整数的第 N 个字节

问题描述 投票:0回答:2

可以通过创建字节类型的指针(例如

int
)并初始化为
char
的地址来找到存储在
int
内存的单个字节中的值。代码应该如下所示:

#include <stdio.h>
#include <stdlib.h>

typedef char BYTE;

int main() {
    // Create an array of integers
    int num = 2147483647;
    BYTE *b = &num;
    
    // Loop over bytes
    for (int i = 0; i < sizeof(int); i++)
    {
        // Print value of i-th byte
        printf("%i\n", b[i]);
    }

    return 0;
}

虽然这适用于查找 4 字节整数内的字节值,但我正在寻找一种仅通过使用算法来查找相同值的方法。我的理解是上面的代码不能用于内存安全的语言,例如C#。

使用此算法的函数原型可能看起来像这样(假设我们定义了一个恰好是一个字节长的类型):

// n is the integer from which we are getting the byte, index is the position of that byte
BYTE get_byte_from_int(int n, int index);

我认为这个算法需要一些除法和模数,但我在实际弄清楚该怎么做方面遇到了很多困难。

arrays c byte endianness
2个回答
0
投票

是的,您可以通过利用带有移位和掩码的位操作,从 C# 或任何内存安全语言中的整数中提取特定字节。这种方法不需要指针算术或不安全的代码,而且效率很高。

byte GetByteFromInt(int n, int index)
{
    return (byte)((n >> (8 * index)) & 0xFF);
}

工作原理:

  1. 位移位 (

    >>
    ):

    • 整数
      n
      右移
      8 * index
      位。
    • 每移位 8 位,向右移动一个字节位置。
    • 这会将目标字节置于最低有效字节位置。

    移位值 = n >> (8 * 索引)

  2. 位掩码 (

    & 0xFF
    ):

    • 然后用
      0xFF
      屏蔽移位后的值(十进制为
      255
      )。
    • 此操作将除最低 8 位之外的所有位清零,从而有效隔离所需的字节。

    提取的字节 = 移位值 & 0xFF

用法示例:

假设您有整数

n = 0x12345678
并且您想要提取
index = 1
处的字节:

int n = 0x12345678;
int index = 1;

byte extractedByte = GetByteFromInt(n, index);

Console.WriteLine($"Extracted Byte: 0x{extractedByte:X2}");
// Output: Extracted Byte: 0x56

说明:

  • 整数
    0x12345678
    (以字节为单位)为
    0x12 0x34 0x56 0x78
  • 0
    (最低有效字节)开始索引,
    index = 1
    对应于
    0x56

备注:

  • 索引范围:

    • 确保
      index
      位于
      0
      sizeof(int) - 1
      之间。
    • 在 32 位整数中,有效索引为
      0
      3
  • 字节序:

    • 该方法假设采用小端系统(常见于 x86/x64 架构)。
    • 如果您正在使用大端系统,则字节顺序是相反的。

0
投票

如果您想要整数的二进制表示形式中的第 n 个字节,则可以使用

memcpy
、联合或指针双关。

typedef unsigned char BYTE;

BYTE get_byte_from_int(int n, int index)
{
    union
    {
        int i;
        BYTE b[sizeof(int)];
    }ui = {.i = n};

    return ui.b[index];
}

BYTE get_byte_from_int(int n, int index)
{
    unsigned char *pb = (unsigned char *)&n;
    return pb[index];
}

BYTE get_byte_from_int(int n, int index)
{
    unsigned char pb[sizeof(n)];

    memcpy(pb, &n, sizeof(pb));
    return pb[index];
}

如果您想要第 n 个“算术”字节,请使用位移操作:

BYTE get_byte_from_int(int n, int index)
{
    return (((unsigned)n) >> (index * 8)) & 0xff;
}
© www.soinside.com 2019 - 2024. All rights reserved.