2009-07-29 87 views
3

在我的嵌入式C程序我有一个结构:的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

为什么536874692无法成为有效的地址? – jalf 2009-07-29 13:59:25

+0

刚刚意识到这一点。 536874692是20000EC4,它可能是有效的... – Tim 2009-07-29 14:02:35

+0

请注意,如果您的“闪存读取/写入功能”不知道查找是一个指针,他们将不知道保存它指向的数据。 – caf 2009-07-29 14:21:17

回答

5

可能将地址存储在value中,将其转换为unsigned long,如您演示的那样。 (我认为你得到一个有效的地址...十六进制,它出来作为0x20000EC4 ......看起来像你的嵌入式系统的数据段开始于0x20000000,是吧?)

然而,在浇铸整数(或长整数)指针永远不会“干净”。为什么不添加一个

unsigned long *starting_address; 

到你的结构?那么你可以避免类型转换。如果您担心这会需要更多内存,则可以使用存储unsigned long *starting_address或“无符号长整型值”的联合体,该值比转换更清晰。

0

我没有看到在你的结构中放置一个指针的缺点。你想让记忆处于连续的区块吗?你可以这样做

struct var 
{ 
    unsigned long *value; 
    unsigned long length; 

    unsigned long othervalue1; 
    unsigned long othervalue2; 
}; 

但是不要忘了分别使用malloc来分配值的内存。或者,如果它是一个固定的空间量你想使用

unsigned long value[50]; 
0

,如果你的sprintf + UART查找会发生什么。这给你什么价值?

除非涉及到投射或符号扩展,否则实际数据是相同的。 sprintf对它的解释是不同的。

你只是使用指针的解决方案是好的。如果你真的想使用int,你应该使用intptr_t,它保证足够大以适应指针。

6

清洁选项将使用工会

struct var{ 
    union { 
     unsigned long numeric; 
     void *ptr; 
    } value; 
    unsigned long length; 

    + More 
} 

你可以选择性地包含一个枚举类型,就像通常使用联合使用片段一样。

1

假设系统指针大小与unsigned long(没有gaurantee,请检查它与sizeof)的系统指针大小相同,您将使用该演员。但这是混乱和容易出错的。考虑使用联合来代替。

struct var{ 
    unsigned short type; 
    union { 
     unsigned long i; 
     void *p; 
    } value; 
    unsigned long length; 

    + More 
} 

您在哪里存储类型type

0

当长度为1时,为什么不将值设置为一个长度为1的数组?反正你不会使用更多的空间。

0

我不确定你为什么没有将值定义为unsigned long *。

相反,这样做:

struct var{ 
    union{ 
    unsigned long solo_value; 
    unsigned long* multi_values; 
    } 

    unsigned long length; 
    + More 
}; 

而且,排列规则不那么强烈*,因为它们是在堆中执行堆栈。不过,如果你使用的是最新的编译器,他们应该是无论如何......你可能用sprintf粉碎了一些东西。使用调试器或更可靠的东西拉出值。

*技术上malloc()等。人。强制执行8字节对齐规则,而不是语言。

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; 
0

熊请注意,无符号长整数不能保证指针,尽管它可能在嵌入式系统中。按照其他答案的建议,做标准的事情并使用工会。在任何符合标准的实现中,工会都会做正确的事情,而不仅仅是你现在正在使用的东西。此外,它具有说出你的意思的优点,当有人不立即诋毁代码(也许你,一年以后)必须处理它时,这是非常有价值的。

0

您是否知道胶印? http://en.wikipedia.org/wiki/Offsetof

我不确定你真的想做什么,但是将一个结构成员的地址存储在同一个结构中似乎没有必要。

还有一个container_of宏(谷歌它),它是使用offsetof构建的,也可能是有用的。