【问题标题】:Initialize sized, static string lists in C在 C 中初始化大小的静态字符串列表
【发布时间】:2014-12-14 22:25:09
【问题描述】:

我想创建具有可发现大小的字符串列表,但不确定我是否有正确的方法/语法。这是我的尝试:

  typedef struct {
       unsigned int size;
       char** list;
  } STRLIST;

  static STRLIST listMediaType = {
      .size = 7,
      .list = {
          "Book",
          "Map",
          "Booklet",
          "Pamphlet",
          "Magazine",
          "Report",
          "Journal"
      },
  };

这是正确的方法吗?请注意,我不想将大小硬编码到结构中,因为我想使用相同的类型来定义许多不同的列表。例如,想象以下函数:

void printList( STRLIST* pList ){
   for( int x = 0; x < pList->size; x++ ) printf( "%s\n", pList->list );
}

【问题讨论】:

  • 你有没有先尝试过?
  • 如果你只做char * list[] = {"Book", "Map"...},你可以通过sizeof list / sizeof list[0] 找到它的大小,你不需要像这样将它包裹在struct 中。当你在编译时不知道你有多少元素时,这种事情只会成为一个问题,在这里你就知道了。
  • 不,我想对不同大小的不同列表使用相同的结构,因为函数将“列表”作为参数并且可以提供不同的列表。
  • 顺便说一句:为什么不能只使用一个简单的char* 数组和一个标记-NULL
  • @Deduplicator 我想我可以。我没有想到。这就是我问这个问题的原因。

标签: c string struct static initialization


【解决方案1】:

可以使用 C99 复合字面量并稍作改动:
http://coliru.stacked-crooked.com/a/4497d2645ad21b74

typedef struct STRLIST{
    unsigned int size;
    char** list;
} STRLIST;

static STRLIST listMediaType = {
    .size = 7,
    .list = (char*[]){
        "Book",
        "Map",
        "Booklet",
        "Pamphlet",
        "Magazine",
        "Report",
        "Journal"
    },
};

C90 的替代方案(因此没有复合文字和指定的初始化程序):http://coliru.stacked-crooked.com/a/5cc95d25afc18c91

static char* list[] = {
    "Book",
    "Map",
    "Booklet",
    "Pamphlet",
    "Magazine",
    "Report",
    "Journal"
};
static STRLIST listMediaType = {
    sizeof list / sizeof *list,
    // Used sizeof to avoid manually typing the lists length
    list,
};

顺便说一句,带有标记-NULL 的数组比计数数组要简单得多。
甚至不需要新类型。

static char* list[] = {
    "Book",
    "Map",
    "Booklet",
    "Pamphlet",
    "Magazine",
    "Report",
    "Journal",
    0
};
void printList(char** pList){
   while(*pList) printf( "%s\n", *pList++);
}

【讨论】:

  • +1 表示sizeof list / sizeof *list 方法。 size 与 sentinel 的优缺点似乎类似于 C 字符串和 C++ 字符串。
【解决方案2】:

您可以检查此代码:

#include <stdio.h>

typedef struct {
    unsigned int size;
    char* list[];

} STRLIST;

static STRLIST listMediaType = {
    7, 
    {
        "Book",
        "Map",
        "Booklet",
        "Pamphlet",
        "Magazine",
        "Report",
        "Journal"
    }
};

int main() {
    printf("struct size: %d\n", listMediaType.size);
    int i;
    for (i = 0; i < listMediaType.size; i++) 
        printf("struct elem[%d] = \"%s\"\n", 
                i, 
                listMediaType.list[i]);

    return 0;
}

我认为您的方法存在两个问题:

  1. TYPEDEF 在 C 中的语法是否正确?我认为你应该用小写。
  2. 如果你想初始化一个结构,只需要使用大括号并且不使用.attributes

希望这篇文章会有所帮助。

谢谢

【讨论】:

  • 使用属性可以让代码保持正确,即使字段的顺序发生变化而无需重新编码。它标记错误是在 .h 文件中删除了字段名称。它也是自我记录的。当代码只使用没有属性的大括号时,这 3 种效果不会发生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-25
  • 2011-09-26
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多