C指针问题

时间:2009-07-29 13:44:40

标签: c pointers embedded

在我的嵌入式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读/写函数以保存指针。这些非常复杂,目前正在工作,所以我宁愿不碰它们!

10 个答案:

答案 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构建的,也可能很有用。