【问题标题】:How to initialize void* data struct member with another struct member in C99?如何在 C99 中用另一个结构成员初始化 void* 数据结构成员?
【发布时间】:2013-04-19 12:09:17
【问题描述】:

假设我们有以下结构定义:

typedef struct {
  uint8_t a ; 
} deepest_t ;  

typedef struct {
  deepest_t* deepest_ptr ;
} deeper_t ; 

typedef struct {
  deeper_t*  deeper_ptr ;
} deep_t ; 

typedef struct {
  void* data ;
} data_container_t ; 

以及以下初始化:

deepest_t deepest = {
  .a = 5, 
} ; 

deeper_t deeper = { 
  .deepest_ptr = &deepest, 
} ;

deep_t deep = { 
  .deeper_ptr = &deeper,
} ;

现在问题,你能告诉我如何使用指定的初始化程序初始化void* data,以便void* data 将指向deepest_t deepest。我试过这样的解决方案,但编译器尖叫它不是一个 const 值:

data_container_t data_container = {
  .data = &(((deeper_t*) deep.deeper_ptr)->deepest_ptr),
} ; 

【问题讨论】:

  • 你不能。为什么你认为你应该能够?初始化程序应该是常量。对象值(在您的情况下为deep.deeper_ptr)不是常量。即使只是用一个常量初始化,还没有机会改变,它仍然不是一个常量。
  • 作为切线,这里的演员表完全是多余的,并且您的描述与您的代码不匹配(您说您想将data指向deepest,但代码试图将其指向@ 987654330@。避免强制转换和void* 将有助于减少此类事情。
  • 我真的做不到吗?但是deepest变量的地址或deepest_ptr所在的地址是已知的,它是const,这就是我想要得到的。
  • 认为((deeper_t*) deep.deeper_ptr)->deepest_ptrdeepest_t *。因此,&(((deeper_t*) deep.deeper_ptr)->deepest_ptr) 必须是 deepest_t **。根据您的问题,deepest_t ** 如何指向deepest?不要使用_t 后缀;这是为实现保留的。
  • 您指的不是deepest的地址。您指的是由隐藏在deep.deeper_ptr 中的指针指向的东西,然后获取该东西的deepest_ptr 成员,然后获取该成员的地址。如果您想要deepest 的地址,请说&deepest

标签: c pointers struct c99 designated-initializer


【解决方案1】:

在这里我相信你保留了deepest_ptr的地址..

data_container_t data_container = {
  .data = &(((deeper_t*) deep.deeper_ptr)->deepest_ptr),
} ;

所以要检索它,你可以这样做..

deepest_t * d = *((deepest_t**)(data_container.data));

printf(" %ud \n", (*d).a);

因为你不能使用void*,直到你施放它..

这是live execution

【讨论】:

  • (deeper_t*) 那个演员表是多余的,因此很危险。
  • @CacahueteFrito 是的,它的存在主要是为了便于阅读
【解决方案2】:

如果初始化器用于初始化一个static存储时长的变量,它应该是一个常量表达式,因此你不能这样做。

如果它用于初始化本地非static 变量,则可以使用此初始化程序:

data_container_t    data_container  = {
    .data   = (deep.deeper_ptr)->deepest_ptr,
};

假设您想要您在文本中所说的内容(“指向deepest_t deepest”)。

什么是常量表达式,您可以在这里阅读: Details of what constitutes a constant expression in C?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多