这是其中之一我认为这应该有用,但最好检查问题。它在我的机器上编译并正常工作。
这是否保证能够达到我的预期(即允许我访问数组的前几个元素,并保证结构的布局,对齐,填充等与数组相同)?
struct thingStruct
{
int a;
int b;
int c;
};
void f()
{
int thingsArray[5];
struct thingStruct *thingsStruct = (struct thingStruct *)&thingsArray[0];
thingsArray[0] = 100;
thingsArray[1] = 200;
thingsArray[2] = 300;
printf("%d", thingsStruct->a);
printf("%d", thingsStruct->b);
printf("%d", thingsStruct->c);
}
编辑:为什么我想要做这样的事情呢?我有一个数组,我正在mmapping到一个文件。我将数组的第一部分视为“标题”,它存储有关数组的各种信息,其余部分我将其视为普通数组。如果我将结构指向数组的开头,我可以将结构数据作为结构成员访问,这样更易读。结构中的所有成员都与数组的类型相同。
答案 0 :(得分:3)
虽然我经常看到这种情况,但你不能(意味着它不合法,标准C)对结构的二进制布局做出假设,因为它可能在字段之间填充。
这在comp.lang.c faq:http://c-faq.com/struct/padding.htmls
中有解释答案 1 :(得分:3)
虽然可能在大多数地方工作,但它仍然有点不确定。如果要为标题的某些部分提供符号名称,为什么不这样做:
enum { HEADER_A, HEADER_B, HEADER_C };
/* ... */.
printf("%d", thingsArray[HEADER_A]);
printf("%d", thingsArray[HEADER_B]);
printf("%d", thingsArray[HEADER_C]);
答案 2 :(得分:2)
正如Evan对这个问题的评论,这可能在大多数情况下都有效(同样,如果使用#pragma pack来确保它们没有填充,则可能是最好的)假设结构中的所有类型都与数组的类型相同。根据C的规则,这是合法的。
我的问题是“为什么?”这不是一件特别安全的事情。如果一个float被抛入结构的中间,那么这一切都会崩溃。为什么不直接使用结构?在大多数情况下,这确实不是我推荐的技术。
答案 3 :(得分:0)
表示标题和其余文件数据的另一种解决方案是使用如下结构:
struct header {
long headerData1;
int headerData2;
int headerData3;
int fileData[ 1 ]; // <- data begin here
};
然后使用文件内容分配内存块并将其转换为struct header *myFileHeader
(或将内存块映射到文件上)并使用
myFileHeader->fileData[ position ]
任意大position
。该语言对索引值没有任何限制,因此您只需将任意大 posistion
保持在您分配的内存块的实际大小(或映射)中档案的大小)。
还有一个重要说明:除了关闭结构成员填充(已经被其他人描述)之外,您应该仔细选择标题成员的数据类型,以便它们适合实际文件数据布局尽管你使用了编译器(比如,int
不会从32位改为64位......)