定义字符串数组

发布于 2024-10-18 15:21:31 字数 209 浏览 2 评论 0原文

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

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

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

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

如何以正确的方式执行它?

I would like to define an array of string like that:

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

but it fails when I try to print the first string:

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

how to do it in the proper way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ぇ气 2024-10-25 15:21:31

我建议不要完全使用宏来执行此操作,但是如果您真的对代码中发生的情况感兴趣,而不是实际应该如何解决这个问题,那么这里有一个解释。

代码中有一个简单的问题,还有一个更晦涩的问题。非常简单的是,声明数组时不使用括号,而是使用大括号:

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

[*] 那里有一些手摇...编译器翻译代码,一旦由预处理器插入到使用宏的位置,但翻译相当于我写的,如果你要编辑手动宏。

I would advice against doing this with macros altogether, but if you are really interested in what is going on with the code --more than in how this should actually be tackled, here is an explanation.

There is a simple issue in the code, and a more obscure one. The very simple is that to declare an array you don't use parenthesis but rather curly braces:

#define sup (const char**){"str1", "str2"} // still wrong!!

The less simple issue is that arrays are not pointers. The curly brace initializer can be used to initialize an array of two const char*, but that is not the same as a const char**. If you change the code to:

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

It should work.

What is going on under the hood with the previous version? Well, the compiler is seeing the declaration of a pointer (well, casting to a pointer) and the initializer. It is assuming that you want to initialize the pointer with the first element (incompatible pointer, but the cast is explicit... you must know what you want if you forced the cast), and then ignore the remainder. Basically the compiler translates your code to [*]:

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

And that will cause havoc at runtime. It is interesting to note that if you had used a proper variable and then initialized the pointer with it, it would have worked, because while arrays are not pointers (I insist, keep that in mind) arrays do decay into pointers:

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

[*] There's a bit of handwaving there... the compiler translates the code, once inserted at the place of use of the macro by the preprocessor, but the translation is equivalent to what I wrote if you were to edit the macro manually.

萌梦深 2024-10-25 15:21:31

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

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

.c 文件之一中,并将其 extern 声明放在标头中,以便在此类字符串所在的位置包含该标头需要:(

extern const char const * sup[];

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

另一种方法是直接在标头中将 sup 定义为 static 全局变量(即使用内部链接);我以前见过用整数常量完成此操作,以确保编译器在每个翻译单元中立即知道它们(因此它可以将它们作为生成的程序集中的立即值),但我不认为使用字符串指针可以显着提高性能。

I think that doing this kind of preprocessor tricks, especially with arrays, isn't such a good idea. You should instead have a real global string table, like this:

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

in one of the .c files, and put its extern declaration in a header to be included wherever such strings are needed:

extern const char const * sup[];

(the first const is to avoid modifications to each string literal - which is UB -, the second to avoid replacing the pointers stored in sup; if you want to allow this last action, remove the second const)

An alternative approach would be to define sup directly in the header as a static global variable (i.e. with internal linkage); I've seen this done before with integer constants to make sure they are immediately known to the compiler in every translation unit (so it can put them as immediate values in the generated assembly), but I don't think that with string pointers it can give any significant performance boost.

岁月流歌 2024-10-25 15:21:31

我有一个所有项目都通用的标题。

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

代码如下:

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

克劳德

I have a header that is common to all my projects.

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

The code looks like:

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

Claude

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文