定义字符串数组

时间:2011-02-21 10:35:40

标签: c arrays string c-preprocessor

我想定义一个像这样的字符串数组:

#define sup (const char**) ("string1", "string2")

但是当我尝试打印第一个字符串时它失败了:

printf("The string: %s\n",sup[0]); 

如何以正确的方式做到这一点?

3 个答案:

答案 0 :(得分:5)

我建议不要完全使用宏来做这件事,但是如果你真的对代码的内容感兴趣 - 而不是实际应该如何处理它,这里有一个解释。

代码中存在一个简单的问题,而且更加模糊。非常简单的是声明一个数组,你不使用括号,而是使用花括号:

#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]

[*]那里有一些手工操作......编译器翻译代码,一旦插入到预处理器的宏使用位置,但翻译等同于我编写的内容,如果您要编辑手动宏。

答案 1 :(得分:2)

我认为做这种预处理器技巧,尤其是数组,并不是一个好主意。你应该有一个真正的全局字符串表,如下所示:

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

在其中一个.c文件中,并将其extern声明放在标题中,以便在需要此类字符串的地方加入:

extern const char const * sup[];

(第一个const是为了避免修改每个字符串文字 - 这是UB - ,第二个是避免替换存储在sup中的指针;如果你想允许这个最后一个动作,删除第二个const

另一种方法是将标题中的sup直接定义为static全局变量(即具有内部链接);我已经在使用整数常量之前看到了这一点,以确保它们在每个转换单元中都能立即为编译器所知(因此它可以将它们作为生成的程序集中的立即值),但我不认为使用字符串指针它可以提高性能。

答案 2 :(得分:0)

我的标题对我的所有项目都是通用的。

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

代码如下:

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

克劳德