您如何在C中声明字符串常量?


73

我知道在C中将数字常量声明为enums而不是使用#define它们是相当习惯的,或者至少是一种好的样式。

字符串常量的定义是否有等效的规则?

你喜欢哪个?如果可能,请显示这两种方法的一些缺点。

Answers:


102

还有至少一条通往罗马的路:

static—可选-是为了防止它与其他文件冲突)。我更喜欢使用它const char*,因为那样您就可以使用了sizeof(HELLO3),因此您不必将运行时推迟到编译时即可完成。

该定义具有编译时级联的优势,尽管HELLO ", World!"您也可以(请考虑)sizeof(HELLO)

但是,然后您也可以const char*在多个文件中使用它,这将为您节省很多内存。

简而言之,这取决于。


感谢您的解释。使用enums代替宏常量或const int常量整数值的原因是这样的事实,这是声明可以作为数组边界可移植的常量整数的唯一类型安全方式。好吧...编译时字符串连接几乎让我对#defines使用字符串很感兴趣,但是我会坚持const char*使用static适用的类型安全性。简而言之,我将使用enum整数常量和const变量进行其余的操作。

1
达人,我建议你不要坚持任何事情。并非所有常数都相等。如果您不打算串联,则不需要#define,如果也不需要大小,则根本不需要。我完全看不到的是,const char*然后会变得更好const char [] ,适用于静态方法的情况。但是话又说回来,如果您不需要大小,也不会更糟;-)
Michael Krelin-黑客2009年

22

定义字符串常量的一个优点(尽管很小)是可以在编译时将它们串联起来:

不确定这是否是真正的优势,但这是不能与const char *s一起使用的技术。


1
字符串连接可以通过strcat(char *s1,const char *s2)strncat()在中实现string.h
克里斯·唐

@ChrisTang有效点。我在回答中添加了“ ...在编译时”一词。
威廉·普塞尔

实际上,如果您具有char * s1 =“ HELLO WOLRD”,则不能使用strcat,因为s1是一个常量值。您可以将其用作s2,但s1必须为s2分配足够的空间。
卡梅伦僧侣

15

如果您想要一个“ const字符串”,如您的问题所述,我真的会选择您在问题中所述的版本:

特别是,我会避免:

原因:第二个版本的问题是编译器将复制整个字符串“ Howdy”,并且该字符串是可修改的(因此不是真正的const)。

另一方面,第一个版本是const指针HELLO2可访问的const字符串,任何人都无法修改它。


2
我认为此答案有两个错误:1)第二个版本创建一个常量字符串,该字符串不可修改,至少在保护其内存的系统上是这样。如果此变量是静态的,则不会进行复制。2)指针不是恒定的,只有它指向的字符。要获取只读指针,您需要编写const char * const HELLO2 = "Howdy";
繁忙的蜂

IntelliSense:this constant expression has type "const char *" instead of the required integral or enum type
亚历克西斯

9

#define方法的主要缺点是,每次使用该字符串时都会重复该字符串,因此您最终可能在可执行文件中得到很多副本,从而使其变得更大。


7
我相信编译器将优化它们,至少要在同一个文件中使用它们。因此,这并不是真正的“每次使用它”,但是是的,定义全局常数有时确实可以节省空间。
Michael Krelin-黑客

3
除非编译器或链接器将这些副本折叠为一个副本,否则这是正确的。有时也将此功能称为“字符串池”
Rom

实际上,它们都指向同一地址。尝试使用char * foo =“ HELLO WOLRD”和char * bar =“ HELLO WORLD”; 然后您会发现foo == bar为true。我相信这种设计模式称为Flyweight。
卡梅伦僧侣

0

它们之间有一些差异。

上面的语句可以与预处理器一起使用,并且只能在预处理器中进行更改。

上面的语句可以用c代码更改。现在,您不能像下面的语句那样更改每个字符,因为它是常量。

但是您可以做的是让它指向另一个字符串,例如下面的语句

这实际上取决于您希望如何更改变量。用预处理器或c代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.