提问人:Buğrahan Özcan 提问时间:11/17/2023 更新时间:11/17/2023 访问量:80
我可以创建适用于不同字节序的颜色结构吗?
Can I create color struct that works on different endians?
问:
我正在尝试创建一个联合来同时存储我的颜色值,逐个通道和 4 字节值。但是我对频道的顺序有问题。不同的字节序机器给出不同的值。有没有办法创建此结构的字节序证明版本,或者当不同的字节序更适合这项工作时使用不同的结构?我想将结构和联合用于教育目的。我正在试验,想了解 C 结构可以做什么和不能做什么。
typedef union u_color
{
struct
{
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char alpha;
};
unsigned int value;
} t_color;
答:
2赞
gulpr
11/17/2023
#1
如果您只想将其用于获取和设置(或从 ) 获取颜色,则(如果您使用最新的 gcc 系列编译器)value
value
typedef union u_color
{
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
struct
{
uint8_t blue;
uint8_t green;
uint8_t red;
uint8_t alpha;
};
#else
struct
{
uint8_t alpha;
uint8_t red;
uint8_t green;
uint8_t blue;
};
#endif
uint32_t value;
} t_color;
但是,对于表示真实屏幕数据结构的定义数组,您需要使用一个预定义的结构布局。
int main(void)
{
t_color x = {.blue = 0x11, .green = 0x22, .red = 0x33, .alpha = 0x44};
printf("%"PRIx32"\n", x.value);
}
尽管字节序,但始终会打印0x11223344。
评论
1赞
gulpr
11/17/2023
@TedLyngmo,我将为 PDP11 :)添加额外的检查。问题在于找到支持这些预定义宏的 gcc 版本:)
1赞
chux - Reinstate Monica
11/17/2023
@TedLyngmo 从 VT52 开始,您有 1 和 0。我的第一个键盘必须使用“i”和“O”。示例。;-)
1赞
chux - Reinstate Monica
11/17/2023
@TedLyngmo我仍然把我的名字写在石板上,但也在算盘上自学平方根。啊,体验技术变化的乐趣。
1赞
Ted Lyngmo
11/17/2023
@chux-恢复莫妮卡.“..你试着告诉今天的年轻人......他们不会相信你”。
1赞
Lundin
11/17/2023
据推测,我们很快就能用 C23 stdbit.h 在标准 C 中做到这一点。 等。不过,我认为还没有任何编译器支持这一点。__STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_BIG__
1赞
chux - Reinstate Monica
11/17/2023
#2
尽管可以根据字节序对 color/alpha 成员进行重新排序,但在读取和写入图形文件时,红色、绿色、蓝色的顺序是常态。我建议留下来。
代码一次可以存储 4 个字节,其中 a 为 r,g,b,a,而不是 .struct
unsigned
像素颜色不是 的好例子。union/struct
使用类型比在试验 s 时使用类型更好。(u)intN_t
unsigned
union
评论
0赞
Buğrahan Özcan
11/19/2023
感谢您的帮助。我正在尝试和试验结构和联合。你能解释为什么 (u)intN_t 比无符号值更好吗?
1赞
chux - Reinstate Monica
11/19/2023
图形文件格式通常具有指定的位宽,因此可以与 匹配。此外,某些图形数据操作是特定于位宽的。 具有最小位宽要求,但实际宽度可能因实现而异。(u)intN_t
int, long, ...
1赞
Lundin
11/17/2023
#3
KISS 解决方案只是简单地删除联合和值成员,然后始终通过函数获取值。100%便携:
#include <stdint.h>
typedef struct
{
uint8_t blue;
uint8_t green;
uint8_t red;
uint8_t alpha;
} t_color;
uint32_t t_color_value (const t_color* col)
{
return ( ((uint32_t)col->blue << 24) |
((uint32_t)col->green << 16) |
((uint32_t)col->red << 8) |
((uint32_t)col->alpha << 0) );
}
int main (void)
{
t_color col = { .blue=0x11, .green=0x22, .red=0x33, .alpha=0x44};
}
现在总是以最高有效字节结束,无论字节序如何。这是因为移位运算符与字节序无关(与联合或 memcpy 等不同)。blue
uint32_t
评论
0赞
Buğrahan Özcan
11/19/2023
感谢您的帮助,但这个问题不仅仅是解决问题。我正在尝试学习如何使用结构、联合和预处理器,以及我有多大的灵活性。
1赞
Lundin
11/20/2023
@BuğrahanÖzcan 其中一部分是要意识到他们什么时候做不好,即在表示内存映射和数据协议时。一致性和对齐性通常会使依赖于结构/联合的代码不可移植。
评论
value
unsigned int
alpha
value
red
green
blue
#if __LITTLE_ENDIAN__