假设我有一个函数,我需要调用几次,它将字符串文字作为第一个也是唯一的参数。像这样:
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"
但这似乎是一件不那么伟大的事情。
感觉我错过了什么。一些建议或如何处理这个问题的一般方法将受到高度赞赏。可以使用重构来在一定程度上避免问题,但它不能解决实际问题。
答案 0 :(得分:1)
你怀疑形式
的变量是正确的const char *turtlesPath = "things_i_like/turtles/fresh_water";
隐藏了相对于将字符串文字放入内联的开销,如果您需要数千个,这将变得非常重要。但是,你对的开销是什么是不对的。它不是运行时初始化操作,也不是堆栈空间。这是一个名为动态重定位的东西,我无法简明扼要地解释,我只能指出一本书:John Levine的 Linkers and Loaders 。
事实上,最佳解决方案是在头文件中使用#define
宏
#define turtlesPath "things_i_like/turtles/fresh_water"
C预处理器宏的所有缺点都不适用于此特定用法,并且没有任何替代方案可以为编译器提供尽可能多的优化自由。
P.S。不要在括号内放置空格。当你在括号内侧放置空格时,会让小耶稣哭泣。