1

作为我的 CS 课程的一部分,我已经获得了一些可以使用的功能。其中一个函数需要一个指向无符号字符的指针来将一些数据写入文件(我必须使用这个函数,所以我不能只制作我自己专门构建的函数,它的工作方式不同)。我需要使用这个函数(只需要无符号字符)编写一个整数数组,其值可以达到 4095。

但是,我认为 unsigned char 的最大值只能为 256,因为它是 1 个字节长,这是对的吗?因此,我需要为每个整数使用 4 个无符号字符?但是转换似乎不适用于整数的较大值。有谁知道如何最好地将整数数组转换为无符号字符?

4

7 回答 7

5

通常一个 unsigned char 包含 8 位,最大值为 255。如果您想为您的特定编译器了解这一点,请从<limits.h> 您可以提取 32 位 int 的各个字节中打印出 CHAR_BIT 和 UCHAR_MAX,

#include <stdint.h>

void
pack32(uint32_t val,uint8_t *dest)
{
        dest[0] = (val & 0xff000000) >> 24;
        dest[1] = (val & 0x00ff0000) >> 16;
        dest[2] = (val & 0x0000ff00) >>  8;
        dest[3] = (val & 0x000000ff)      ;
}


uint32_t
unpack32(uint8_t *src)
{
        uint32_t val;

        val  = src[0] << 24;
        val |= src[1] << 16;
        val |= src[2] <<  8;
        val |= src[3]      ;

        return val;
}
于 2011-01-07T20:50:36.757 回答
3

Unsigned char 通常具有 1 个字节的值,因此您可以将任何其他类型分解为无符号字符数组(例如,对于 4 字节 int,您可以使用 4 个无符号字符数组)。你的练习可能是关于泛型的。您应该使用 fwrite() 函数将文件作为二进制文件写入,并在文件中逐字节写入。

以下示例应将一个数字(任何数据类型)写入文件。我不确定它是否有效,因为您将强制转换为 unsigned char * 而不是 void *。

int homework(unsigned char *foo, size_t size)
{
    int i;

    // open file for binary writing
    FILE *f = fopen("work.txt", "wb");
    if(f == NULL)
        return 1;

    // should write byte by byte the data to the file
    fwrite(foo+i, sizeof(char), size, f);

    fclose(f);
    return 0;
}

我希望给定的例子至少能给你一个起点。

于 2011-01-07T21:17:56.403 回答
0

听起来您真正想做的是调用 sprintf 来获取整数的字符串表示形式。这是从数字类型转换为其字符串表示的标准方法。类似以下内容可能会帮助您入门:

char num[5]; // Room for 4095

// Array is the array of integers, and arrayLen is its length
for (i = 0; i < arrayLen; i++)
{
    sprintf (num, "%d", array[i]);

    // Call your function that expects a pointer to chars
    printfunc (num);
}
于 2011-01-07T20:40:40.903 回答
0

如果您必须编写一个整数数组,那么只需将该数组转换为指向 char 的指针,然后遍历该数组。

int main()
{
    int    data[] = { 1, 2, 3, 4 ,5 };
    size_t size   = sizeof(data)/sizeof(data[0]); // Number of integers.

    unsigned char* out = (unsigned char*)data;
    for(size_t loop =0; loop < (size * sizeof(int)); ++loop)
    {
         MyProfSuperWrite(out + loop);  // Write 1 unsigned char
    }
}

现在人们已经提到 4096 的位数比普通整数要少。大概是真的。因此,您可以节省空间,而不是写出每个整数的最高位。我个人认为这值得努力。编写值和处理传入数据的额外代码不值得您节省(也许如果数据是国会图书馆的大小)。规则一做尽可能少的工作(它更容易维护)。规则二优化如果被问到(但先问为什么)。您可以节省空间,但会花费处理时间和维护成本。

于 2011-01-07T23:16:18.090 回答
0

如果没有有关您被指示使用的函数的参数、返回值和语义(即其行为的定义)的信息,就很难回答。一种可能性是:

鉴于:

void theFunction(unsigned char* data, int size);

然后

int array[SIZE_OF_ARRAY];
theFunction((insigned char*)array, sizeof(array));

或者

theFunction((insigned char*)array, SIZE_OF_ARRAY * sizeof(*array));

或者

theFunction((insigned char*)array, SIZE_OF_ARRAY * sizeof(int));

所有这些都会将所有数据传递给theFunction(),但是否有意义将取决于做什么theFunction()

于 2011-01-07T22:54:32.120 回答
0

作业的部分:integers whose values can be up to 4095 using this function (that only takes unsigned chars应该给你一个很大的提示。4095 无符号是 12 位。

您可以将 12 位存储在 16 位short中,但这有点浪费空间——您只使用了 16 位中的 12 位。由于您在字符转换中处理超过 1 个字节,因此您可能需要处理结果的字节顺序。最简单的。

如果您担心空间,您也可以做一个位字段或一些打包的二进制结构。更多的工作。

于 2011-01-07T20:55:56.820 回答
0

你是对的; 一个 char/byte 最多只允许 8 个不同的位,因此是 2^8 个不同的数字,从 0 到 2^8 - 1,或从 0 到 255。做这样的事情来获取字节:

int x = 0;
char* p = (char*)&x;
for (int i = 0; i < sizeof(x); i++)
{
    //Do something with p[i]
}

(由于声明的顺序,这不是正式的 C,但无论如何......它更具可读性。:))

请注意,此代码可能不可移植,因为它取决于处理器内部存储的int.

于 2011-01-07T20:23:44.163 回答