定义字符串数组

4
我想定义一个字符串数组,像这样:
#define sup (const char**) ("string1", "string2")

但是当我尝试打印第一个字符串时,它失败了。
printf("The string: %s\n",sup[0]); 

如何以正确的方式进行操作?

3个回答

6
我建议不要完全使用宏来完成此操作,但如果您真的对代码中发生的事情感兴趣——而不是如何实际解决这个问题,那么这里有一个解释。
代码中存在一个简单的问题和一个更加隐晦的问题。非常简单的问题是,声明数组时不使用括号,而是使用花括号:
```c++ int array[] = {1, 2, 3}; ```
而不是
```c++ int array() = {1, 2, 3}; // 这是错误的 ```
更难理解的问题是,宏会在编译时展开,因此您不能将它们用于需要在运行时分配内存的操作。
#define sup (const char**){"str1", "str2"} // still wrong!!

较为复杂的问题是数组不是指针。花括号初始化程序可用于初始化两个const char*的数组,但这与const char**不同。如果更改代码如下:

#define sup (const char*[2]){"str1", "str2" }

它应该可以工作。

上一个版本的内部是怎么样的?编译器看到了一个指针的声明(其实是一个强制转换为指针),和初始化程序。它假设你想要用第一个元素来初始化指针(不兼容的指针,但是强制转换是明确的...如果你强制转换,你必须知道你想要什么),然后忽略剩余的内容。基本上,编译器将您的代码翻译成[*]:

#define sup (const char**)"str1"

这将在运行时造成混乱。需要注意的是,如果您使用了正确的变量并用它初始化指针,那么它将起作用,因为虽然数组不是指针(请记住这一点),但数组会衰变为指针:

const char* tmp[] = { "hi", "there" };
const char** sup = tmp;              // fine, tmp decays into &tmp[0]

[*] 这里有些概念性的东西......编译器会在宏被预处理器插入到使用处时翻译代码,但如果你手动编辑宏,这种翻译相当于我所写的内容。

嗨,David,感谢你的回答,它让我在这个话题上的想法更加清晰。然而,如果我使用 #define sup (const char*[2]){"str1", "str2" },当我执行 printf("String: %s\n",sup[0]); 时,会出现以下错误:"error C2059: syntax error : '{' "。 - Beppe
@Beppe 宏只是在原地展开它们的文本,所以 sup[0] 变成了 (const char*[2]){"str1", "str2" }[0],这是语法错误。因此你需要 #define sup ((const char*[2]){"str1", "str2" }) -- 注意括号。但是像这样的宏只是一个糟糕的想法。 - Jim Balter
既然大家都告诉我这是个坏主意,我会转而采用另一个解决方案,比如Matteo Italia建议的那个。 再次感谢大家宝贵的帮助。 - Beppe
请注意,在 C 语言中,字符串字面量是 char 数组,而不是 const char。因此,字符串字面量表达式通常会衰变成 char 类型指针。 - John Bode

2

我认为使用这种预处理器技巧,尤其是针对数组,不是一个很好的想法。相反,你应该有一个真正的全局字符串表,像这样:

const char const * sup[]={"String 1", "String 2", "String 3"};

在其中一个 .c 文件中定义字符串,并将其 extern 声明放在头文件中,以便在需要这些字符串的任何地方都能包含它们:
extern const char const * sup[];

(第一个const是为了避免对每个字符串字面量进行修改-这是未定义的-,第二个是为了避免替换存储在sup中的指针;如果您想允许这个最后的操作,请删除第二个const)
另一种方法是在头文件中直接定义sup作为静态全局变量(即具有内部链接);我以前看过这样做的整数常量,以确保它们在每个翻译单位中立即为编译器所知(因此它可以将它们作为生成的汇编中的立即值),但我认为对于字符串指针,它不能提供任何显着的性能提升。

0

我有一个在所有项目中都共用的标题。

#define MAX_STUDENTS 3
char STUDENT[] = { "Manny", "Joe", "Jack" };

代码看起来像:

for( int i=0; i<MAX_STUDENTS; i++ )
{ Do Something with STUDENT[i]; }

克劳德


抱歉!无法弄清楚如何操作此输入编辑器。 - Claude92105

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接