代码之家  ›  专栏  ›  技术社区  ›  Tim Post Samir J M Araujo

在C中声明函数中的结构

  •  4
  • Tim Post Samir J M Araujo  · 技术社区  · 16 年前

    我有一个只有一个函数必须访问的结构。该函数将标记“k,k,kb,kb,m,m,mb,mb,…”转换为实际单位。这样做的目的是简化配置文件。

    static uint32_t real_unit(const char *str)
    {
        struct u2type {
          char key[3];
          uint32_t val;
        } const u2types[] = {
           { "k", KB_UNIT },
           { "K", KB_UNIT },
           { "kb", KB_UNIT },
           { "KB", KB_UNIT },
           { "m", MB_UNIT },
           { "M", MB_UNIT },
           { "mb", MB_UNIT },
           { "MB", MB_UNIT },
           { "g", GB_UNIT },
           { "G", GB_UNIT },
           { "gb", GB_UNIT },
           { "GB", GB_UNIT },
           { { 0 }, 0 }
        };
    
        ... code to look up str ...
    }
    

    我见过其他程序将struct u2type声明为静态(同样,在函数中),但我看不出这有什么用处。结构不会改变,每次输入函数时都是一样的。这就是为什么我让它成为常量。

    然而,我看到许多人在一个范围非常明显的函数中执行statc struct foo{…}const foos[]={…}。

    这样做有什么好处吗?我试图在讨论这些优化问题之前研究ASM输出,但我不是组装专家:)

    编辑:

    是的,我知道这种方法闻起来像脚。有些项目只是有一些奇怪的需求(通常是由奇怪的人授权的)。然而,问题仍然与函数的使用完全分离。

    6 回复  |  直到 16 年前
        1
  •  13
  •   anon anon    16 年前

    使其为常量和使其为静态可以做两件不同的事情。

    • 如果它是const,则每个函数调用都会获得自己的结构的不可更改实例
    • 如果是静态的,则在所有函数调用中共享一个可更改的结构实例

    听起来好像您想要的是一个结构实例,它既是静态的又是常量的,这是一件合理的事情。

    就性能而言,静态版本应该有一点优势,因为构造struct实例只需进行一次。

        2
  •  5
  •   jpalecek    16 年前

    如果将数组声明为静态,它将被放置在可执行文件的数据部分,并且只初始化一次(在第一次访问时),甚至不初始化(它可能已经在可执行文件中初始化)。

    只是有点吹毛求疵,当你说你在哪里看过代码 struct u2type

    static struct foo { ... } foos [] = { ... };
    

    然后你就可以做了

    struct foo foo1={ ... };
    

    foo1 将是一个自动变量。

        3
  •  0
  •   sharptooth    16 年前

    如果在函数中声明一个静态变量,则在首次输入函数时,该变量仅初始化一次。如果声明为非静态,则每次输入函数时都会对其进行初始化。

    静止的 阵列将在静态存储器中分配,并且初始化不超过一次。没有 静止的

        4
  •  0
  •   Pete Kirkham    16 年前

    哎哟。至少将函数名更改为“不区分大小写的猜测单元”。其中大多数不是“真实”单位,而那些('K'例如是开尔文而不是千,'b'通常是位,'b'字节)不是您要返回的单位。

    如果规格为k[b]->1000米[b]->1000000等,那么简单的if/else可能更快更干净。

        5
  •  0
  •   Mike Dunlavey    16 年前

    ...

    // so, do you want odor-free, or fast ?
    switch (str[0]){
    case 'g': case 'G':
      return GB_UNIT;
    case 'k': case 'K':
      return KB_UNIT;
    case 'm': case 'M':
      return MB_UNIT;
    }
    
        6
  •  0
  •   mouviciel    16 年前

    推荐文章