假设我有一个需要调用几次的函数,该函数将字符串文字作为其第一个也是唯一一个参数。像这样:
func( "things_i_like\\turtles\\fresh_water" );
/* some code */
if ( turtleFred.mood == happy )
{
func( "things_i_like\\turtles\\fresh_water" );
}
/* more code */
func( "things_i_like\\turtles\\fresh_water" );
现在,如果我需要更改该字符串文字,我将不得不在 3 个不同的地方进行更改。如果我在更改其中一个字符串文字时输入错误,可能会发生一些不好的事情。为避免这种情况,我可以使用变量来存储字符串文字的位置。像这样:
const char* turtlesPath = "things_i_like\\turtles\\fresh_water";
func( turtlesPath );
/* some code */
if ( turtleFred.mood == happy )
{
func( turtlesPath );
}
/* more code */
func( turtlesPath );
这种方法有 3 个问题。让我们假设我有大约 20-30 个字符串文字而不是一个字符串文字。
问题#1: 如果所有保存字符串文字位置的指针都按照它们的定义进行了初始化,因此在范围的开头。并且程序进入了一个永远不会使用这些字符串文字的条件,这是否意味着执行的将字符串文字分配给指针(初始化)的代码是不必要的和浪费的?
问题#2: 如果在可以递归调用的回调函数中定义和初始化保存字符串文字位置的指针,这不会对堆栈的存储空间产生重大影响吗?
我的具体意思是:当只使用几个保存字符串文字位置的指针时,这可能根本不是问题,但当使用大量指针时,它可能会成为问题。因此,当添加越来越多的指针时,最终可能导致堆栈溢出。
此外,这是否意味着每次调用函数时都必须初始化指针?如果它们很多并且该函数每天被调用数千次怎么办,这不会产生大量开销吗?
问题 #3: 一种可能的解决方案是对字符串文字使用宏,如下所示:
#define TURTLES_PATH "things_i_like\\turtles\\fresh_water"
但这似乎不是一件很了不起的事情。
感觉好像错过了什么。将不胜感激关于如何处理此问题的一些建议或一般方法。重构可以在一定程度上避免问题,但它并不能解决实际问题。
最佳答案
你怀疑形式的变量是正确的
const char *turtlesPath = "things_i_like/turtles/fresh_water";
相对于将字符串文字内联而言,隐藏了开销,如果您需要数千个,这将变得很重要。不过,您对开销是多少的看法是不对的。它不是运行时初始化操作,也不是堆栈空间。这是一个叫做动态重定位的东西,我无法简明扼要地解释,我只能给你看一整本书: Linkers and Loaders 作者:约翰·莱文。
事实上,最好的解决方法是在头文件中使用 #define
宏,
#define turtlesPath "things_i_like/turtles/fresh_water"
C 预处理器宏的缺点都不适用于此特定用法,并且没有任何替代方案可以为编译器提供尽可能多的优化自由。
附言不要在括号内放置空格。当您在括号内放置空格时,它会让婴儿耶稣哭泣。
关于c - 指针初始化字符串文字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42009621/