我有一个只有一个功能必须访问的结构。该函数将诸如“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输出,但我不是装配大师:)
修改
是的,我知道这种方法闻起来像脚。有些项目只有奇怪的要求(通常由奇数人强制要求)。然而,这个问题与功能的使用完全分开。
答案 0 :(得分:13)
使它成为常量并使其静态做两件事。
听起来好像你想要的是一个静态和const的结构实例,这是一个合理的事情。
性能方面,静态版本应略有优势,因为struct实例的构造只会执行一次。
答案 1 :(得分:5)
如果您声明您的数组是静态的,它将被放置在可执行文件的数据部分中并且只初始化一次(在第一次访问时)或者甚至没有(它可能已在可执行文件中初始化)。
如果没有静态,数据将位于每个函数调用的堆栈中,并在每次调用函数时初始化。
只是有点挑剔,当你说你看到struct u2type
是静态的代码时,这不是真的。尽管静态存储说明符出现在struct之前,但它确实适用于变量,在本例中是数组。即使有了
static struct foo { ... } foos [] = { ... };
然后你可以做
struct foo foo1={ ... };
和foo1
将是一个自动变量。
答案 2 :(得分:0)
如果在函数中声明变量static,则仅在第一次输入函数时初始化一次。如果您将其声明为非静态,则每次输入函数时都会初始化它。
在你的情况下,它可以略有不同。使用 static ,阵列将在静态存储中分配并初始化不超过一次。如果没有 static ,它将在堆栈上分配,并且每次调用该函数。
答案 3 :(得分:0)
在堆栈上分配局部变量或常量。它们的存在仅在函数执行期间持续,并且一旦函数返回它们的值就会丢失。每次调用函数时都会进行分配和分配。
声明局部变量或常量静态意味着它的值将从一次调用到下一次调用。这是通过全局分配而不是堆栈来实现的。分配和分配只执行一次,如果频繁调用的函数中的大数据结构可能会导致性能提升。
答案 4 :(得分:0)
Eeeww。至少将您的函数名称更改为“case_insensitive_guess_unit”。其中大多数都不是“真正的”单位,而那些('K'例如开尔文不是公斤,'b'通常是位和'B'字节)不是你要返回的单位。
如果规格是k [b] - > 1000,m [b] - > 1000000等,然后一个简单的if / else可能更快更清洁。
答案 5 :(得分:0)
...
// 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;
}