【发布时间】:2018-12-26 04:24:48
【问题描述】:
我有两个具有相同数据成员的结构。 (一个是 big_endian 结构,另一个是 little_endian )现在我必须与它们相互转换。但是当我编码时,我发现有很多重复的代码,几乎没有变化。在没有重复代码的情况下,如何将这些代码更改为更优雅? (重复代码意味着这些代码可能相似,例如mode == 1和mode == 2,它们只是赋值位置不同。看起来不优雅但有效。)
这是我的代码:
#pragma scalar_storage_order big-endian
typedef struct {
int a1;
short a2;
char a3;
int a4;
} test_B;
#pragma scalar_storage_order default
typedef struct {
int a1;
short a2;
char a3;
int a4;
} test_L;
void interconvert(test_L *little, test_B *big, int mode) {
// if mode == 1 , convert little to big
// if mode == 2 , convert big to little
// it may be difficult and redundant when the struct has lots of data member!
if(mode == 1) {
big->a1 = little->a1;
big->a2 = little->a2;
big->a3 = little->a3;
big->a4 = little->a4;
}
else if(mode == 2) {
little->a1 = big->a1;
little->a2 = big->a2;
little->a3 = big->a3;
little->a4 = big->a4;
}
else return;
}
注意:以上代码必须在gcc-7或更高版本上运行,因为#pragma scalar_storage_order
【问题讨论】:
-
我认为这没有任何问题。也许你可以创建一个单独的函数
little_to_big(test_L *little, test_B *big)和big_to_little(test_B *big, test_L *little)。我经常有超过 4 个字段的类,并且没有其他方法可以分配/初始化它们。附带说明一下,如果您的函数名称由多个单词组成,请使用蛇形或骆驼式大小写来区分它们。 -
您在这个问题中使用了奇怪的字符,例如
?和。...这是一件小事,但如果你能解决它,我认为问题会更容易一些读书。另外,也许我遗漏了一些明显的东西,但是“重复代码”是什么意思?谢谢,欢迎来到 SO! -
“重复代码”表示这些代码可能相似,例如 mode==1 & mode==2 ,只是分配位置不同。看起来不优雅但有效
-
你看过Wikipedia - Endianness——它还提供了一个用于在大/小端之间转换整数值的C函数? (您可以轻松适应
short值和char什么都不需要。) -
这个问题存在一个根本性的潜在错误:试图以可移植的方式使用结构来描述二进制数据格式。相反,您应该编写打包/解包函数来在二进制数据缓冲区和内部、本机格式数据(根本不需要类似于二进制数据存储)之间进行转换。是的,我知道很多人都这样做。我的观点是它是不可移植的,并且难以维护。和一个简单的错误来源。您是否想要编写有缺陷的代码或您可以信任的代码?
标签: c gcc optimization struct