首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >const char * VS char const * const (不是关于const是什么)

const char * VS char const * const (不是关于const是什么)
EN

Stack Overflow用户
提问于 2012-07-23 11:24:19
回答 5查看 9.2K关注 0票数 12

所以,我知道char const *,char * const和char const * const之间的区别。即:

char* the_string :我可以将the_string所指向的字符更改为哪个字符,并且可以修改它所指向的字符。 const * the_string :我可以将the_string所指向的字符更改为哪个字符,但不能修改它所指向的字符。 char* const the_string :我不能将the_string所指向的字符更改为哪个字符,但我可以修改它所指向的字符。 const * const the_string :我不能更改the_string所指向的字符,也不能修改它所指向的字符。

(来自?)

现在,我的问题是:假设我正在编写一个不修改传递给它的C字符串的函数,例如:

代码语言:javascript
复制
int countA(??? string) {
    int count = 0;
    int i;
    for (i=0; i<strlen(string); i++) {
         if (string[i] == 'A') count++;
    }
    return count;
}

现在,标题应该是什么?

代码语言:javascript
复制
int countA(char const * string); 
int countA(char const * const string);

我的感觉是我应该使用第二个,因为我不会修改指针本身,也不会修改数组的内容。但是,当我查看标准函数的头时,它们使用第一个函数。示例

代码语言:javascript
复制
char * strcpy ( char * destination, const char * source );

为什么?

(事实上,char const *对我来说并没有什么意义,因为如果您考虑的是抽象字符串,您不是在修改字符串(所以,char const * const是因为您没有修改指针,也不是修改内容),或者您将修改字符串(因此,只需要修改char *,因为您可能需要修改内容,可能需要分配更多内存,因此可能需要修改指针)。

我希望有人能把这一切都告诉我。谢谢。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-07-23 11:27:27

在这种情况下,指针本身是否是const并不重要,因为它无论如何都是通过值传递的:strcpysource所做的任何操作都不会影响调用者的变量,因为strcpy将操作堆栈上调用方的source的副本,而不是原始的。注意,我讨论的是指针值,而不是指针指向的值,显然不应该更改它,因为它是源参数。

代码语言:javascript
复制
char dest[10];
char const * source = "Hello";
strcpy( dest, source );
// no matter what strcpy does, the value of source will be unchanged

strcpy中,您需要在destinationsource所指向的数组上迭代指针。不将参数声明为const允许函数直接使用堆栈中的值,而无需首先复制/转换它们。

票数 6
EN

Stack Overflow用户

发布于 2012-07-23 11:27:41

拥有const char * 代表一个契约。这是一个承诺,该函数将不会使用该指针修改用户传递的内容。指针本身是否是常量就不那么有价值了。

因此,对于调用者来说,指针本身是否是const没有任何区别。

在许多实现中,"string“函数定期修改传递的指针而不修改内容。如果规范(C标准)要求指针本身为常数,则将成为所有实现的限制因素,而不会为调用方提供任何好处。

顺便提一句,我认为你不应该把所有的事情都做const,然后用你的方式解决它。如果它觉得函数不应该改变它,就做一些const吧。简而言之,不要疯狂,,这不是一个银弹,可能是一个令人沮丧的处方。

票数 5
EN

Stack Overflow用户

发布于 2012-07-23 11:32:02

非限定性声明:

代码语言:javascript
复制
int countA(char const * string);
int countA(char const * const string);
int countA(char const * foobar);
int countA(char const *);

都是等价的。string参数名称(实际上)是countA实现中的局部变量。实现是否修改该变量与调用方无关,也不影响函数的签名。

函数是否修改string的引用是调用者的事,所以第一个const很重要。变量的名称稍微取决于调用方的事务,但仅仅是因为约定是将声明中的参数命名为提示它们的用途。文档是完全表达每个参数的含义的方法,而不是它的名称。

如果您想要一条规则:省略第二个const,因为它混淆了声明,同时告诉调用者没有任何有用的东西。

您可以将它包含在函数定义中,但是这样做有一些问题。您要么需要保持标头与定义的同步(在这种情况下,您会发现由于不影响调用者的实现细节的更改,有时会更改标头)。否则,您必须接受标题与定义不匹配的事实,这有时会让看到以下内容的人感到不安:

代码语言:javascript
复制
int countA(char const * const string) {
    return 0; 
}

并搜索int countA(char const * const string)的标头,反之亦然,查看标头并搜索源。他们需要一个更聪明的搜索词。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11611564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档