静态常量字符指针及其使用方式

3
static const char* const test_script = "test_script";

你会在何时以及为什么要使用类似上面的语句?它有什么好处吗?

为什么要使用char*而不是常量字符?"常量字符指针"(const char*)已经是一个常量了,不能被改变;那么为什么要在它前面加上static这个词?这样做有什么好处吗?


相关:这两个const是什么意思?。 我更喜欢 static const char test_script[] = "test_script"; - Gyapti Jain
1个回答

7

const char *p不是常量指针,而是一个可修改的指向const char的指针,也就是指向常量字符。你可以让指针指向其他地方,但不能更改它所指向的字符或字符集合。换句话说,p = x是允许的,但*p = y是不允许的。

char * const则相反:一个指向可变字符的常量指针。*p = y是允许的,但p = x是不允许的。

const char * const则同时拥有这两个特点:一个指向常量字符的常量指针。

关于static:它给声明的变量提供了内部链接(无法从源文件外部通过名称访问)。由于您同时询问了C和C++,需要注意它们之间的区别。

在C ++中,声明为const且未显式声明为extern的变量默认具有内部链接。由于所涉及的指针是const(我指的是第二个const),因此在C ++中,static是多余的,没有任何作用。

但在C中,const变量不能用作常量表达式,并且默认情况下没有内部链接。因此,在C中,static是必要的,以给test_script提供内部链接。

上述关于static的讨论假定声明位于文件范围(C)或命名空间范围(C ++)内。如果它在函数内部,则static的含义会发生变化。如果没有static,它将成为函数中的普通局部变量,每次调用都有自己的副本。使用static,它将获得静态存储期,因此在函数调用之间保持不变-所有调用共享一个副本。由于您同时询问了C和C ++,我不打算讨论类作用域。

最后,您问“为什么使用指针而不是字符”。这样,指针就指向实际的字符串字面量(可能在进程内存的只读部分的某个位置)。这样做的一个原因是,如果需要将test_script传递到期望const char * const *(指向常量指针的指针,指向常量字符)的地方。此外,如果源代码中多次出现相同的字符串字面量,则可以共享它。

另一种选择是声明一个数组:

const char test_script[] = "test_script";

这将会将字符串文字复制到test_script中,确保它有自己的数据副本。然后,您可以通过sizeof test_script(其中包含终止的NUL)在编译时学习其长度。如果它是该字符串文字的唯一出现,则还将消耗略少的内存(不需要指针)。但是,由于它有自己的数据副本,因此无法共享字符串文字的存储空间(如果该字符串文字在代码中的其他位置也使用了)。


1
长度为 sizeof test_script - 1。如果程序中需要传递指针的地址,则将该字符串声明为指针可能会很有用。虽然不太可能,但有可能调用一个声明了参数 const char * const * 或等效参数的函数。 - chqrlie
1
假设@newb7777的test_script具有文件作用域,而您的也是如此,则该数组使用更少的内存(确切地说是sizeof(char*)字节)。 - cremno

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