2

我遇到了一个问题:基于无符号整数形成一个字符数组。数组将以十六进制表示法表示该 int。使用按位运算符执行此操作。

所以,我的想法如下:我创建了一个掩码,它的 4 个最低值位为 1。我将给定 int 的位向右推 4 并在该 int 和掩码上使用 & 。我重复直到(int!= 0)。我的问题是:当我得到单独的十六进制数字(4 位包)时,如何将它们转换为字符?例如,我得到:

x & mask = 1101(2) = 13(10) = D(16)

是否有将 int 转换为十六进制表示的函数,或者我是否必须对 switch 语句或其他任何东西使用蛮力?

我差点忘记了,我是在 C 中做的 :)

这就是我的意思:

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

#define BLOCK 4

    int main() {
        unsigned int x, y, i, mask;
        char a[4];

        printf("Enter a positive number: ");
        scanf("%u", &x);
        for (i = sizeof(usnsigned int), mask = ~(~0 << 4); x; i--, x >>= BLOCK) {
            y = x & mask;
            a[i] = FICTIVE_NUM_TO_HEX_DIGIT(y);
        }

        print_array(a);

        return EXIT_SUCCESS;
    }
4

5 回答 5

1

You are almost there. The simplest method to convert an integer in the range from 0 to 15 to a hexadecimal digit is to use a lookup table,

char hex_digits[] = "0123456789ABCDEF";

and index into that,

a[i] = hex_digits[y];

in your code.

Remarks:

char a[4];

is probably too small. One hexadecimal digit corresponds to four bits, so with CHAR_BIT == 8, you need up to 2*sizeof(unsigned) chars to represent the number, generally, (CHAR_BIT * sizeof(unsigned int) + 3) / 4. Depending on what print_array does, you may need to 0-terminate a.

for (i = sizeof(usnsigned int), mask = ~(~0 << 4); x; i--, x >>= BLOCK)

initialising i to sizeof(unsigned int) skips the most significant bits, i should be initialised to the last valid index into a (except for possibly the 0-terminator, then the penultimate valid index).

The mask can more simply be defined as mask = 0xF, that has the added benefit of not invoking undefined behaviour, which

mask = ~(~0 << 4)

probably does. 0 is an int, and thus ~0 is one too. On two's complement machines (that is almost everything nowadays), the value is -1, and shifting negative integers left is undefined behaviour.

于 2013-04-12T16:23:17.183 回答
0

尝试这样的事情:

char hex_digits[] = "0123456789ABCDEF";

for (i = 0; i < ((sizeof(unsigned int) * CHAR_BIT + 3) / 4); i++) {
    digit = (x >> (sizeof(unsigned int) * CHAR_BIT - 4)) & 0x0F;
    x = x << 4;
    a[i] = hex_digits[digit];
}
于 2013-04-12T16:21:29.283 回答
0

好的,这就是我得到的地方:

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

#define BLOCK 4

void printArray(char*, int);

int main() {
    unsigned int x, mask;
    int size = sizeof(unsigned int) * 2, i;
    char a[size], hexDigits[] = "0123456789ABCDEF";

    for (i = 0; i < size; i++)
        a[i] = 0;

    printf("Enter a positive number: ");
    scanf("%u", &x);
    for (i = size - 1, mask = ~(~0 << 4); x; i--, x >>= BLOCK) {
        a[i] = hexDigits[x & mask];
    }

    printArray(a, size);

    return EXIT_SUCCESS;
}

void printArray(char a[], int n) {
    int i;

    for (i = 0; i < n; i++)
        printf("%c", a[i]);

    putchar('\n');
}

我已经编译,它运行并且正确地完成了工作。我不知道...我应该担心这个问题对我来说有点难吗?在教师,考试期间,我们必须在一张纸上手写我们的代码......我不认为我会这样做。有没有更好(不太复杂)的方法来解决这个问题?谢谢大家的帮助:)

于 2013-04-12T16:56:06.410 回答
0
char buffer[10] = {0};
int h = 17;
sprintf(buffer, "%02X", h);
于 2013-04-12T15:53:46.463 回答
0

我会考虑移位时潜在填充位的影响,因为移位等于或大于整数类型中存在的值位的数量是未定义的行为。

也许您可以先使用: 终止字符串array[--size] = '\0';,使用 写入最小的半字节(十六进制数字)array[--size] = "0123456789ABCDEF"[value & 0x0f],使用 : 移动到下一个半字节value >>= 4,然后重复 while value > 0。完成后,返回array + sizeor&array[size]以便调用者知道十六进制序列的开始位置。

于 2013-04-12T16:07:05.183 回答