如果整数大于256,如何在C中从整数转换为无符号字符?

如果整数大于256,如何在C中从整数转换为无符号字符?,c,casting,unsigned,integer,chars,C,Casting,Unsigned,Integer,Chars,作为CS课程的一部分,我得到了一些可以使用的函数。其中一个函数需要一个指向无符号字符的指针来将一些数据写入一个文件。我必须使用这个函数,所以我不能只创建自己的专用函数,工作方式不同。顺便说一句,我需要使用这个只接受无符号字符的函数来编写一个整数数组,其值可以高达4095 然而,我认为一个无符号字符的最大值只能是256,因为它是1字节长,这对吗?因此,我需要为每个整数使用4个无符号字符?但是,对于较大的整数值,强制转换似乎不起作用。有人知道如何最好地将整数数组转换为无符号字符吗?是的,你说得对;一

作为CS课程的一部分,我得到了一些可以使用的函数。其中一个函数需要一个指向无符号字符的指针来将一些数据写入一个文件。我必须使用这个函数,所以我不能只创建自己的专用函数,工作方式不同。顺便说一句,我需要使用这个只接受无符号字符的函数来编写一个整数数组,其值可以高达4095


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

是的,你说得对;一个字符/字节最多只允许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存储。

是的,您是对的;一个字符/字节最多只允许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,因为声明的顺序,但不管怎样。。。它更具可读性


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

听起来您真正想做的是调用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);
}

听起来您真正想要做的是调用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);
}

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

#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;
}

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

#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;
}

使用这个只接受无符号字符的函数赋值:integer(其值可以高达4095)的部分应该给您一个巨大的提示。4095无符号是12位

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


如果你关心空间,你也可以做一个位域或者一些压缩的二进制结构。更多的工作

使用这个只接受无符号字符的函数赋值:integer(其值可以高达4095)的部分应该给您一个巨大的提示。4095无符号是12位

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


如果你关心空间,你也可以做一个位域或者一些压缩的二进制结构。更多的工作

无符号字符的值通常为1字节,因此您可以将任何其他类型分解为无符号字符数组,例如,对于4字节整数,您可以使用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;
}

我希望给出的示例至少能为您提供一个起点。

无符号字符的值通常为1字节,因此您可以将任何其他类型分解为无符号字符数组,例如,对于4字节整数,您可以使用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;
}

我希望给出的示例至少为您提供了一个起点。

没有关于函数参数、返回值和语义的信息 例如,其行为的定义很难回答。一种可能性是:

鉴于:

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


所有这些都会将所有数据传递给函数,但than是否有意义将取决于函数的功能。

如果没有关于函数参数、返回值和语义的信息,即函数行为的定义,则很难回答。一种可能性是:

鉴于:

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


所有这些都会将所有数据传递给函数,但than是否有意义取决于函数的功能。

如果必须写入整数数组,则只需将数组转换为指向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将比普通整数容纳更少的位。可能是真的。因此,您可以节省空间,而不必写出每个整数的顶部位。我个人认为这是不值得的努力。如果数据的大小与国会图书馆一样大,那么编写值和处理传入数据所需的额外代码就不值得节省。规则一:尽可能少做工作,这样更容易维护。规则二:如果被问到优化,但首先要问为什么。您可能会节省空间,但会增加处理时间和维护成本。

如果必须写入整数数组,则只需将数组转换为指向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将比普通整数容纳更少的位。可能是真的。因此,您可以节省空间,而不必写出每个整数的顶部位。我个人认为这是不值得的努力。如果数据的大小与国会图书馆一样大,那么编写值和处理传入数据所需的额外代码就不值得节省。规则一:尽可能少做工作,这样更容易维护。规则二:如果被问到优化,但首先要问为什么。您可以节省空间,但这将花费处理时间和维护成本。

这取决于您是否要在文件中存储int值。如果输出文件被认为是数据的二进制存储,则不会这样做,但如果您只想将int保存为可读格式,则可以这样做。此处的sprintf要求其%s参数使用以null结尾的字符数组。如果其中任何一个字节为0,这将无法正常工作。它也不起作用,因为它将在数组末尾运行,而不会在末尾添加0。我的错误-我的意思是格式字符串为%d。已编辑以修复。这取决于是否要在文件中存储int值。如果输出文件被认为是数据的二进制存储,则不会这样做,但如果您只想将int保存为可读格式,则可以这样做。此处的sprintf要求其%s参数使用以null结尾的字符数组。如果其中任何一个字节为0,这将无法正常工作。它也不起作用,因为它将在数组末尾运行,而不会在末尾添加0。我的错误-我的意思是格式字符串为%d。编辑以修复。计算表示4095所需的位数。它不值得4个字节。在你的问题中包括函数原型;这将使它更符合您的作业要求,并为您提供更好的答案。但有时,为每个int转储sizeofint字节会更容易。这样,您可以在重新读取时在数组中运行,而无需调整每个数据项后的指针。计算需要表示4095的位数。它不值得4个字节。在你的问题中包括函数原型;这将使它更符合您的作业要求,并为您提供更好的答案。但有时更容易为每个int转储sizeofint字节。这样,在重新读取时,您可以在数组中运行,而无需调整每个数据项后的指针。这是最正式的C,即实际的标准C99。这是最正式的C,即实际的标准C99。您可以从中删除最重要的2个字节。值4095非常适合16位。无需进行任何处理即可将值放入字符数组。8位值的最大值为2^8-1,即255,而不是256。可能的总值为256,0-255。您可以从中删除最重要的2个字节。值4095非常适合16位。无需进行任何处理即可将值放入字符数组。8位值的最大值为2^8-1,即255,而不是256。可能的总值数为256,0-255。请注意,如果写入程序和读取程序具有不同的endianness或sizeofint或有关其整数表示形式的其他详细信息,则这是不安全的。很抱歉,错过了上面考虑endianness的任何解决方案!请注意,如果编写器和读取器具有不同的endianness或sizeofint或有关其整数表示的其他详细信息,则这是不安全的。很抱歉,错过了任何甚至考虑到上述endianness的解决方案!