在C中声明函数内的结构

我有一个只有一个函数必须访问的结构。 该函数将诸如“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将被声明为静态(同样,在函数内),我看不出它是如何有用的。 结构不会改变,每次输入function时结构总是相同的。 这就是为什么我把它变成了常量。

然而,我看到很多人在范围很明显的函数中做了statc struct foo {…} const foos [] = {…}。

这样做有什么好处? 在尝试使用这些优化问题之前,我尝试研究ASM输出,但我不是组装大师:)

编辑:

是的,我知道这种方法闻起来像脚。 有些项目只有奇怪的要求(通常由奇数人强制要求)。 然而,问题仍然与function的使用完全分开。

使它成为常量并使其静态做两件事。

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

听起来好像你想要的是一个静态和const的结构实例,这是一个合理的事情。

性能方面,静态版本应该略有优势,因为struct实例的构造只会执行一次。

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

如果没有静态,数据将位于每个函数调用的堆栈中,并在每次调用函数时进行初始化。

只是有点挑剔,当你说你已经看到struct u2type是静态的代码时,这不是真的。 尽管静态存储说明符出现在struct之前,但它确实适用于变量,在本例中是数组。 即使

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

然后你可以做

 struct foo foo1={ ... }; 

foo1将是一个自动变量。

如果在函数中声明变量static,则仅在第一次输入函数时初始化一次。 如果将其声明为非静态,则每次输入函数时都会初始化它。

在你的情况下,它可以略有不同。 使用static ,数组将在静态存储中分配并初始化不超过一次。 如果没有静态 ,它将在堆栈上分配,并且每次调用该函数时。

Eeeww。 至少将您的函数名称更改为“case_insensitive_guess_unit”。 其中大多数都不是“真正的”单位,而那些(’K’例如开尔文不是公斤,’b’通常是位和’B’字节)不是你要返回的单位。

如果规格是k [b] – > 1000,m [b] – > 1000000等,那么一个简单的if / else可能更快更干净。

 // 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; } 

局部变量或常量在堆栈上分配。 它们的存在仅在函数执行期间持续,并且一旦函数返回它们的值就会丢失。 每次调用函数时都会进行分配和分配。

声明局部变量或常量静态意味着它的值将从一次调用到下一次调用。 这是通过全局分配而不是堆栈来实现的。 分配和分配仅执行一次,在经常调用的函数中的大数据结构的情况下可能导致性能改进。