在我的嵌入式c程序中,我有一个结构:
struct var{
unsigned long value;
unsigned long length;
+ More
}
这些结构的数组用于保存变量。存储的大多数变量只是存储在'value'中,因此长度设置为1 但是,其中一些变量是数组,我试图将起始地址存储在'value'中。
unsigned long lookup[10];
variables[x].length = 10;
然后我不太确定如何存储地址......
variables[x].value = lookup;
// lookup is a pointer so I cant put it into value
OR
variables[x].value = (unsigned long)lookup;
// value reads back through sprintf+uart as '536874692'
// which couldnt be a valid memory address!
我可能只是放弃并在结构中添加一个指针变量
修改
我想避免添加指向结构的指针,因为我必须返回并重写flash读/写函数以保存指针。这些非常复杂,目前正在工作,所以我宁愿不碰它们!
答案 0 :(得分:6)
更清洁的选择是使用 union 。
struct var{
union {
unsigned long numeric;
void *ptr;
} value;
unsigned long length;
+ More
}
您也可以选择包含类型枚举,通常使用联合使用的部分。
答案 1 :(得分:5)
您可以将地址存储在value
中,然后将其转换为unsigned long
,如您所示。 (我认为你得到的值是一个有效的地址...十六进制,它出现为0x20000EC4 ......看起来你的嵌入式系统的数据段从0x20000000开始,是吗?)
然而,向int(或long)投射指针永远不会“干净”。为什么不添加
unsigned long *starting_address;
到你的结构?然后你可以避免类型转换。如果你担心这需要更多内存,你可以使用一个存储unsigned long *starting_address
或'unsigned long value`的联合,它仍然比强制转换更清晰。
答案 2 :(得分:1)
假设系统指针大小与unsigned long
的系统指针大小相同(没有gaurantee,请使用sizeof
检查),您将使用强制转换。但这很麻烦且容易出错。请考虑使用联合。
struct var{
unsigned short type;
union {
unsigned long i;
void *p;
} value;
unsigned long length;
+ More
}
您将类型存储在type
。
答案 3 :(得分:0)
我没有看到在你的结构中放置指针的缺点。你想让内存连续阻塞吗?你可以做到
struct var
{
unsigned long *value;
unsigned long length;
unsigned long othervalue1;
unsigned long othervalue2;
};
但是不要忘记使用malloc分别为值分配内存。或者,如果它需要使用固定数量的空间
unsigned long value[50];
答案 4 :(得分:0)
如果你使用sprintf + uart查找会发生什么。这给了你什么价值?
除非涉及转换或符号扩展,否则实际数据是相同的。它只是由sprintf以不同的方式解释。
您使用指针的解决方案很好。如果你真的想使用int,你应该使用intptr_t,它保证足够大以适合指针。
答案 5 :(得分:0)
当长度为1时,为什么不将值设为一个长度的数组?无论如何,你不会使用更多的空间。
答案 6 :(得分:0)
我不确定为什么你没有将值定义为无符号长*。
相反,做一些事情:
struct var{
union{
unsigned long solo_value;
unsigned long* multi_values;
}
unsigned long length;
+ More
};
此外,对齐规则在堆栈中不会像在堆中那样强制执行。虽然,如果你正在使用任何最近的编译器,他们应该是...你可能用sprintf粉碎了一些东西。使用调试器或更可靠的东西拉出值。
*技术上是malloc()等。人。强制执行8字节对齐规则,而不是语言。
答案 7 :(得分:0)
您最好的选择是使用枚举,如前所述:
typedef struct var{
union {
unsigned long numeric;
void *ptr;
} value;
unsigned long length;
// + More
} composition_t;
然后使用 lenght 成员来区分数据类型:
composition_t array[2];
unsigned long lookup[10];
// Just a plain unsigned long value
array[0].value.numeric = 100;
array[0].length= 1;
// An array of 10 long values
array[0].value.ptr= lookup;
array[x].length = 10;
答案 8 :(得分:0)
请记住,无法保证无符号长按指针,尽管它可能存在于嵌入式系统中。做标准的事情并使用联盟,正如其他答案所示。工会将在任何符合标准的实施中做正确的事,而不仅仅是你现在正在使用的。此外,它具有说出你的意思的优点,当一个没有立即修改代码的人(也许你,一年后)必须处理它时,这总是有价值的。
答案 9 :(得分:0)
你知道偏移吗? http://en.wikipedia.org/wiki/Offsetof
我不确定你真正想做什么,但是将一个结构成员的地址存储在同一个结构中似乎是不必要的。
还有一个container_of宏(google it),它是使用offsetof构建的,也可能很有用。