获取在结构中声明的元素的索引
Get the index of an element declared in a struct
我想将结构的每个元素(或其他元素,结构可能无法实现)与递增索引相关联,有点像枚举,但与值字段相关联。
假设我有这个数据结构:
typedef struct
{
int8_t value_at_index0; // start with index 0 for this field
int8_t value_at_index1; // then index = 1, etc
int8_t value_at_index2;
int8_t value_at_index3;
int8_t value_at_index4;
} data;
我想获取一个字段的索引,索引应该反映该字段在结构中声明的位置。
编辑:我的问题是我想在外部存储器中写入值,但我不想弄清楚哪个索引是值。例如我想这样做:write(index.value_at_index2, data.value_at_index2)
谢谢
好吧我假设你的代码写得不好并且不想修复它或者它是一个非常具体的问题
虽然我只会使用数组或为其分配一些内存,但我没有阅读手册但我记得一年前结构总是写成一个块(即它们不像内存那样分散分配),虽然这不是使用像这样的结构的正确行为,但我做了一个测试并且它有效
使用 __attribute__((packed, aligned(1)))
,这使得填充为 1,这意味着不会添加空白 space 字节,也就是说,如果你有一个单字节元素,它不会再添加 3 个空白来填补空白。
这并不意味着它会将所有内容缩短为一个,并且一旦您将不同大小的元素考虑在内,它就会停止工作,因为当它通过 4 字节整数时添加一个会导致意外行为
typedef struct __attribute__((packed, aligned(1))) //like so
{
int8_t value_at_index0; // start with index 0 for this field
int8_t value_at_index1; // then index = 1, etc
int8_t value_at_index2;
int8_t value_at_index3;
int8_t value_at_index4;
} data;
int main(int argc, char **argv){
data data;
int8_t *hey=NULL;
data.value_at_index0=5;
data.value_at_index1=3;
data.value_at_index2=2;
data.value_at_index3=5;
data.value_at_index4=10;
size_t i;
hey = &data;
for (i = 0; i < 5; i++){
printf("hey its working %d", *hey);
hey+=1;
}
//letsee(5, data);
return 0;
}
现在这不是正确的行为,从表面上看你的问题我只是建议你坚持内存分配,因为它允许动态大小,即使你想要静态大小,你也可以只使用数组。
如果你想在最新的 C 编译器中使用 above 的更粗略的版本,有一些技巧可以让它动态化。虽然我会告诉你你会遇到一堆内存泄漏、核心转储和意外行为
TL;DR 这是不正确的行为 我只是发布这个如果您无法更改代码并且您必须使用结构
现在是干净的版本我在问题中读到你将要编写一个结构假设该结构是基本的并且你只想在其中编写每个静态元素你可以轻松做到
FILE *fp;
if ((fp = fopen("lets.txt", "w")) == NULL){
return 1;
}
fwrite(&data, sizeof(data), 1, fp);
if (fclose(fp) != 0){
return 1;
}
因为当你在第一个参数中放置一个结构并提供它的大小时,它只会写入结构中的每个元素,这也适用于指针,尽管你必须在其中指定每个元素的大小大小参数和下一个参数中的元素数。
同样,这是假设所有元素都定义明确且是静态的,因为结构有很多标志
您应该考虑将 arrays/pointers 用于此目的。要完成这项工作,您需要确保所有值都是同一类型,并临时删除该结构的内存填充。以下代码说明了它是如何完成的。
/*Remove struct padding*/
#pragma pack(push, 1)
typedef struct
{
int8_t a;
int8_t b;
int8_t c;
int8_t d;
} data;
/*Recover struct padding, some structs from other libraries malfunction from not using struct pudding.*/
#pragma pack(pop)
int main()
{
/*Define a clean data structure*/
data tmp = { 0x00, 0x00, 0x00, 0x00 };
((int8_t *)&tmp)[0] = 0x01; /*data.a = 0x01*/
((int8_t *)&tmp)[1] = 0x03; /*data.b = 0x03*/
((int8_t *)&tmp)[2] = 0x05; /*data.c = 0x05*/
((int8_t *)&tmp)[3] = 0x07; /*data.d = 0x07*/
return 0;
}
我想将结构的每个元素(或其他元素,结构可能无法实现)与递增索引相关联,有点像枚举,但与值字段相关联。 假设我有这个数据结构:
typedef struct
{
int8_t value_at_index0; // start with index 0 for this field
int8_t value_at_index1; // then index = 1, etc
int8_t value_at_index2;
int8_t value_at_index3;
int8_t value_at_index4;
} data;
我想获取一个字段的索引,索引应该反映该字段在结构中声明的位置。
编辑:我的问题是我想在外部存储器中写入值,但我不想弄清楚哪个索引是值。例如我想这样做:write(index.value_at_index2, data.value_at_index2)
谢谢
好吧我假设你的代码写得不好并且不想修复它或者它是一个非常具体的问题
虽然我只会使用数组或为其分配一些内存,但我没有阅读手册但我记得一年前结构总是写成一个块(即它们不像内存那样分散分配),虽然这不是使用像这样的结构的正确行为,但我做了一个测试并且它有效
使用 __attribute__((packed, aligned(1)))
,这使得填充为 1,这意味着不会添加空白 space 字节,也就是说,如果你有一个单字节元素,它不会再添加 3 个空白来填补空白。
这并不意味着它会将所有内容缩短为一个,并且一旦您将不同大小的元素考虑在内,它就会停止工作,因为当它通过 4 字节整数时添加一个会导致意外行为
typedef struct __attribute__((packed, aligned(1))) //like so
{
int8_t value_at_index0; // start with index 0 for this field
int8_t value_at_index1; // then index = 1, etc
int8_t value_at_index2;
int8_t value_at_index3;
int8_t value_at_index4;
} data;
int main(int argc, char **argv){
data data;
int8_t *hey=NULL;
data.value_at_index0=5;
data.value_at_index1=3;
data.value_at_index2=2;
data.value_at_index3=5;
data.value_at_index4=10;
size_t i;
hey = &data;
for (i = 0; i < 5; i++){
printf("hey its working %d", *hey);
hey+=1;
}
//letsee(5, data);
return 0;
}
现在这不是正确的行为,从表面上看你的问题我只是建议你坚持内存分配,因为它允许动态大小,即使你想要静态大小,你也可以只使用数组。 如果你想在最新的 C 编译器中使用 above 的更粗略的版本,有一些技巧可以让它动态化。虽然我会告诉你你会遇到一堆内存泄漏、核心转储和意外行为
TL;DR 这是不正确的行为 我只是发布这个如果您无法更改代码并且您必须使用结构
现在是干净的版本我在问题中读到你将要编写一个结构假设该结构是基本的并且你只想在其中编写每个静态元素你可以轻松做到
FILE *fp;
if ((fp = fopen("lets.txt", "w")) == NULL){
return 1;
}
fwrite(&data, sizeof(data), 1, fp);
if (fclose(fp) != 0){
return 1;
}
因为当你在第一个参数中放置一个结构并提供它的大小时,它只会写入结构中的每个元素,这也适用于指针,尽管你必须在其中指定每个元素的大小大小参数和下一个参数中的元素数。 同样,这是假设所有元素都定义明确且是静态的,因为结构有很多标志
您应该考虑将 arrays/pointers 用于此目的。要完成这项工作,您需要确保所有值都是同一类型,并临时删除该结构的内存填充。以下代码说明了它是如何完成的。
/*Remove struct padding*/
#pragma pack(push, 1)
typedef struct
{
int8_t a;
int8_t b;
int8_t c;
int8_t d;
} data;
/*Recover struct padding, some structs from other libraries malfunction from not using struct pudding.*/
#pragma pack(pop)
int main()
{
/*Define a clean data structure*/
data tmp = { 0x00, 0x00, 0x00, 0x00 };
((int8_t *)&tmp)[0] = 0x01; /*data.a = 0x01*/
((int8_t *)&tmp)[1] = 0x03; /*data.b = 0x03*/
((int8_t *)&tmp)[2] = 0x05; /*data.c = 0x05*/
((int8_t *)&tmp)[3] = 0x07; /*data.d = 0x07*/
return 0;
}