C 作为结构访问数组*

C 作为结构访问数组*,c,arrays,memory,struct,C,Arrays,Memory,Struct,这是我认为应该有效的方法之一,但最好检查问题。它在我的机器上编译并运行良好 这是否保证了我所期望的(即允许我访问数组的前几个元素,并保证结构的布局、对齐、填充等与数组相同) 编辑:我到底为什么要做这样的事?我有一个数组,我正在映射到一个文件。我将数组的第一部分视为“头”,它存储有关数组的各种信息,其余部分则视为普通数组。如果我将结构指向数组的开头,我就可以以结构成员的形式访问头数据片段,这样可读性更强。结构中的所有成员都将与数组的类型相同。正如Evan在这个问题上所评论的,这可能在大多数情况下都

这是我认为应该有效的方法之一,但最好检查问题。它在我的机器上编译并运行良好

这是否保证了我所期望的(即允许我访问数组的前几个元素,并保证结构的布局、对齐、填充等与数组相同)


编辑:我到底为什么要做这样的事?我有一个数组,我正在映射到一个文件。我将数组的第一部分视为“头”,它存储有关数组的各种信息,其余部分则视为普通数组。如果我将结构指向数组的开头,我就可以以结构成员的形式访问头数据片段,这样可读性更强。结构中的所有成员都将与数组的类型相同。

正如Evan在这个问题上所评论的,这可能在大多数情况下都有效(同样,如果您使用#pragma pack来确保它们没有填充,可能最好),假设结构中的所有类型都与数组的类型相同。根据C的规则,这是合法的


我的问题是“为什么?”这不是一件特别安全的事情。如果一个浮点数被抛出到结构的中间,这一切都会崩溃。为什么不直接使用struct呢?在大多数情况下,这并不是我推荐的一种技术。

虽然我经常看到这样做,但您不能(这意味着它不合法,标准C)对结构的二进制布局做出假设,因为它可能在字段之间有填充

这在comp.lang.c常见问题解答中进行了解释:

尽管它可能在大多数地方都有效,但仍然有点不确定。如果要为标题的某些部分指定符号名称,为什么不:

enum { HEADER_A, HEADER_B, HEADER_C };

/* ... */.

printf("%d", thingsArray[HEADER_A]);
printf("%d", thingsArray[HEADER_B]);
printf("%d", thingsArray[HEADER_C]);

表示头和其余文件数据的另一种解决方案是使用如下结构:

struct header {
    long  headerData1;
    int   headerData2;
    int   headerData3;
    int   fileData[ 1 ];  // <- data begin here
};
对于任意大的
位置
。该语言对索引值没有任何限制,因此您只需负责将任意的big
posistion
保持在分配的内存块的实际大小(或映射文件的大小)内


还有一个重要提示:除了关闭其他人已经描述过的结构成员填充之外,您应该仔细选择头成员的数据类型,以便它们适合实际的文件数据布局,尽管您使用的是编译器(例如,
int
不会从32位更改为64位…)

我认为,只要使用
#pragma
或其他东西来禁用结构上的填充,就可以了。请注意,使用GCC可以通过在结构定义结尾的大括号后添加
#属性(packed)
来实现这一点。对于Windows编译器(也受GCC支持),我相信您可以使用
#pragma pack(0)
在结构定义之前和
#pragma pack()
之后。“给定C的规则,这是合法的。”这是否违反了严格的别名规则?Hrm。。。你可能会想,但是GCC4.4.3并没有抱怨,不管我对它有什么选择。可能是因为结构的第一个成员是正确的类型,因此不存在冲突?我已经看过很多次这样的代码,其中一个较大的值被一个较小的类型指向,每次都让我不寒而栗。为什么?我正在将数组映射到文件。我在开始时存储了一些头信息,其余的作为数组处理。所有的值都是相同的类型(我做梦也想不到混合类型!)。我只是觉得在标题部分添加描述性支柱成员比添加索引更具可读性。@Joe关于较大/较小类型的注释,它与您的问题没有直接关系,只是在讨论字符串别名时用作一个常见的示例。@Joe抱歉,大脑抽筋,您回答了我的“为什么”在原始答案中。在你描述的情况下,这听起来很合理。我可能会有点畏缩,但我可能会在代码审查中放弃它,只要有一些注释解释发生了什么。也许您可以更新原始问题,以描述如何以及为什么要对阵列进行MMA,这将使其他人更容易提供更具建设性的响应。您是对的。。。但我认为,除非编译器有理由在相同类型的项之间添加填充,否则它在大多数情况下都应该有效。
struct header {
    long  headerData1;
    int   headerData2;
    int   headerData3;
    int   fileData[ 1 ];  // <- data begin here
};
myFileHeader->fileData[ position ]