Is C endian-neutral? Ok, another way of asking this question. I am currently translating a lot of code from C to Matlab on the same platform (PC). Do I need to care about endianess? Both are endian-neutral languages but C (not so sure), Matlab (pretty sure). By the same token I am also translating C to Python. So my question, has anybody in his experience, (translating from C to another endian-neutral language) met an unexpected problem with big/little endianness. Obviously we are only speaking about the core language. In this case I mentionned C99.
答案 0 :(得分:2)
首先,一些背景和澄清:
正如我在对原始问题的评论中提到的,字节顺序经常与位顺序混淆。字节顺序仅指字节顺序。位顺序仅与文档相关,并且通过某些串行连接发送数据时。
在算术中,在base B (和2≤ B εℕ)中, i ' D i 具有值 D i B i 。最低有效位数对应于 i = 0,即 D 0 。对于二进制, B = 2.对于大多数人喜欢的普通十进制数, B = 10。
(这适用于所有实数,而不仅仅是整数。最重要的小数位,小数点另一侧的第一个数字,是 D -1 ,更负面的 i 表示不太有效的数字。)
因为' bit'因此,我们有一个自然标记位的方式,其中位0表示最低有效(整数)位(对应于值1),位1指的是有意义的下一个(对应于值2),依此类推。
使用big-endian字节顺序的硬件的一些文档坚持将单词中最重要的位标记为" bit 0" (位数从左到右增加 - 与大多数数字表示相反,数字从右到左变得更加显着)。这只是一个标签约定,因为该约定不遵循算术规则。实际上,你需要知道那个单词的宽度(位数),甚至可以计算出这个" bit 0" s的实际数值。
C endian-neutral?
是,C(在ISO C89,C99和C11中)在字节顺序方面是中性的。标准没有定义任何字节顺序;由实施来决定。实际上,编译器在编译时选择适合目标体系结构的字节顺序。
理论上,整数和浮点类型可能具有不同的字节顺序。
POSIX.1为C添加网络支持。网络相关结构中的某些字段定义为网络字节顺序,最重要的字节优先。 POSIX.1提供htons()
,htonl()
,ntohs()
和ntohl()
byteorder函数,以便从主机转换为网络字节顺序,反之亦然。
除了网络字节顺序(通常称为 big-endian )之外,小端字节顺序(最低有效字节优先)也很常见,例如在Intel / AMD架构上。 PDP-endian 字节顺序(其中四字节值首先存储在第二最高有效字节,然后是最高有效字节,后跟最低有效字节,后跟第二最低有效字节)现在很少见。
最后,C已经在大量架构上实现,其中字节顺序涵盖了上面提到的所有三个,没有任何字节顺序问题。这应该足够实用。
我目前正在同一平台(PC)上将大量代码从C转换为Matlab [或Python]。我需要关心结束吗?
不,在C,Matlab,Python或任何高级语言之间移植代码时,我都没有理由关心字节顺序。
然而:
语言是字节序中立的并不意味着您不需要关心程序中的字节顺序。 数据字节顺序很重要。它归结为您的程序如何传输 - 读取和写入 - 数据;通过内存结构(使用共享内存,或通过库绑定在不同的编程语言之间),文件,网络连接或通过/到其他程序的管道。
如果您的程序以某种基于文本的格式传输数据,那么您需要担心的是该格式,以及可能使用的字符集 - 我更喜欢UTF-8(请参阅utf8everywhere.org。
如果你的程序以二进制形式传输数据,那么你必须明白,在二进制中,多字节值总是具有一些特定的字节顺序。它可以是当前体系结构的网络字节顺序(或大端),小端或本机字节顺序。仅仅因为你的编程语言是字节序中立的,并不意味着你会忽略存储字节顺序。
例如,Matlab和Octave fread()
支持第五个参数,该参数指定使用的字节顺序:native
,ieee-be
(IEEE big-endian)或ieee-le
( IEEE little-endian)。 Python struct
模块打包和解包函数默认为本机字节顺序和C对齐(填充),但您可以使用<
或>
作为格式字符串中的第一个字符来表示 - 没有填充的endian或big-endian / network-endian字节顺序。
C代码以本机字节顺序存储二进制数据是很常见的。但是,有些C代码没有。我更喜欢以本机字节顺序存储,但也存储每种不同基本数字类型的已知原型值,以便读者可以轻松检测是否需要置换字节顺序以正确解释代码。还有各种库和格式,如NetCDF,可用于创建可移植的二进制数据文件。
最重要的是首先要了解C代码的作用。
我不明白为什么有人会想要将代码从C语言移植到Matlab或Python,除非C代码开头真的很差 - 在这种情况下我只是重写< / em>逻辑,而不是移植现有代码。
您是否遇到了大/小字节序的意外问题?
不,从不在高级语言之间移植代码。
是,在不同系统之间存储/检索二进制数据时。
虽然与字节序无关,但对于多维数据,重要的是要记住Fortran和Matlab(和OpenGL矩阵)使用列主要顺序(每列在内存中是连续的),而C使用行主顺序(每行在内存中连续)。