C++ const char * const 与 const char *?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4949254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
const char * const versus const char *?
提问by pict
I'm running through some example programs to refamiliarize myself with C++ and I have run into the following question. First, here is the example code:
我正在运行一些示例程序以重新熟悉 C++,我遇到了以下问题。首先,这是示例代码:
void print_string(const char * the_string)
{
cout << the_string << endl;
}
int main () {
print_string("What's up?");
}
In the above code, the parameter to print_string could have instead been const char * const the_string
. Which would be more correct for this?
在上面的代码中,print_string 的参数可以改为const char * const the_string
. 哪个更正确?
I understand that the difference is that one is a pointer to a constant character, while the other one is a constant pointer to a constant character. But why do both of these work? When would it be relevant?
我理解的区别在于,一个是指向常量字符的指针,而另一个是指向常量字符的常量指针。但是为什么这两种方法都有效呢?什么时候相关?
回答by Kent Boogaart
The latter prevents you from modifying the_string
inside print_string
. It would actually be appropriate here, but perhaps the verbosity put off the developer.
后者阻止您修改the_string
内部print_string
. 它实际上在这里是合适的,但也许冗长的内容让开发人员感到厌烦。
char* the_string
: I can change the char
to which the_string
points, and I can modify the char
at which it points.
char* the_string
: 我可以改变char
指向哪个the_string
点,我可以修改char
它指向的点。
const char* the_string
: I can change the char
to which the_string
points, but I cannot modify the char
at which it points.
const char* the_string
: 我可以改变char
指向哪个the_string
点,但我不能修改char
它指向的点。
char* const the_string
: I cannot change the char
to which the_string
points, but I can modify the char
at which it points.
char* const the_string
: 我不能改变char
指向哪个the_string
点,但我可以修改char
它指向的点。
const char* const the_string
: I cannot change the char
to which the_string
points, nor can I modify the char
at which it points.
const char* const the_string
: 我不能改变char
指向哪个the_string
点,也不能修改char
它指向的点。
回答by James Michael Hare
Mutable pointer to a mutable character
char *p;
Mutable pointer to a constant character
const char *p;
Constant pointer to a mutable character
char * const p;
Constant pointer to a constant character
const char * const p;
指向可变字符的可变指针
char *p;
指向常量字符的可变指针
const char *p;
指向可变字符的常量指针
char * const p;
指向常量字符的常量指针
const char * const p;
回答by Nawaz
const char * const
means pointer as well as the data the pointer pointed to, are bothconst!
const char * const
手段指针以及指针指向的,是数据既常量!
const char *
means onlythe data the pointer pointed to, is const. pointer itself however is not const.
const char *
意味着只有指针指向的数据是const。然而,指针本身不是常量。
Example.
例子。
const char *p = "Nawaz";
p[2] = 'S'; //error, changing the const data!
p="Sarfaraz"; //okay, changing the non-const pointer.
const char * const p = "Nawaz";
p[2] = 'S'; //error, changing the const data!
p="Sarfaraz"; //error, changing the const pointer.
回答by Garrett
(I know this is old but I wanted to share anyway.)
(我知道这是旧的,但我还是想分享。)
Just wanted to elaborate on Thomas Matthews' answer. The Right-Left Rule of C type declarations pretty much says: when reading a C type declaration start at the identifier and go right when you can and left when you can't.
只是想详细说明 Thomas Matthews 的回答。C 类型声明的右左规则几乎是这样说的:当阅读 C 类型声明时,从标识符开始,可以时向右走,不能时向左。
This is best explained with a couple examples:
这最好用几个例子来解释:
Example 1
示例 1
Start at the identifier, we can't go right so we go left
const char* const foo ^^^^^
foo is a constant...
Continue left
const char* const foo ^
foo is a constant pointer to...
Continue left
const char* const foo ^^^^
foo is a constant pointer to char...
Continue left
const char* const foo ^^^^^
foo is a constant pointer to char constant(Complete!)
从标识符开始,我们不能向右走,所以我们向左走
const char* const foo ^^^^^
foo 是一个常数...
继续向左
const char* const foo ^
foo 是一个指向...的常量指针
继续向左
const char* const foo ^^^^
foo 是一个指向char的常量指针...
继续向左
const char* const foo ^^^^^
foo 是一个指向 char常量的常量指针(完成!)
Example 2
示例 2
Start at the identifier, we can't go right so we go left
char* const foo ^^^^^
foo is a constant...
Continue left
char* const foo ^
foo is a constant pointer to...
Continue left
char* const foo ^^^^
foo is a constant pointer to char(Complete!)
从标识符开始,我们不能向右走,所以我们向左走
char* const foo ^^^^^
foo 是一个常数...
继续向左
char* const foo ^
foo 是一个指向...的常量指针
继续向左
char* const foo ^^^^
foo 是一个指向char的常量指针(完成!)
Example 1337
例 1337
Start at the identifier, but now we can go right!
const char* const* (*foo[8])() ^^^
foo is an array of 8...
Hit parenthesis so can't go right anymore, go left
const char* const* (*foo[8])() ^
foo is an array of 8 pointer to...
Finished inside parenthesis, can now go right
const char* const* (*foo[8])() ^^
foo is an array of 8 pointer to function that returns...
Nothing more to the right, go left
const char* const* (*foo[8])() ^
foo is an array of 8 pointer to function that returns a pointer to a...
Continue left
const char* const* (*foo[8])() ^^^^^
foo is an array of 8 pointer to functions that returns a pointer to a constant...
Continue left
const char* const* (*foo[8])() ^
foo is an array of 8 pointer to functions that returns a pointer to a constant pointer to a...
Continue left
const char* const* (*foo[8])() ^^^^
foo is an array of 8 pointer to functions that returns a pointer to a constant pointer to a char...
Continue left
const char* const* (*foo[8])() ^^^^^
foo is an array of 8 pointer to functions that returns a pointer to a constant pointer to a char constant(Complete!)
从标识符开始,但现在我们可以向右了!
const char* const* (*foo[8])() ^^^
foo 是一个8的数组...
打括号所以不能再向右走,向左走
const char* const* (*foo[8])() ^
foo 是一个包含 8 个指针的数组,指向...
在括号内完成,现在可以向右走
const char* const* (*foo[8])() ^^
foo 是一个包含 8 个指向函数的指针的数组,该函数返回...
没有更多的右边,向左走
const char* const* (*foo[8])() ^
foo 是一个包含 8 个指向函数的指针的数组,该函数返回一个指向...
继续向左
const char* const* (*foo[8])() ^^^^^
foo 是一个由 8 个指向函数的指针组成的数组,它返回一个指向常量的指针......
继续向左
const char* const* (*foo[8])() ^
foo 是一个由 8 个指向函数的指针组成的数组,它返回一个指向一个常量指针的指针,该指针指向一个...
继续向左
const char* const* (*foo[8])() ^^^^
foo 是一个由 8 个指向函数的指针组成的数组,它返回一个指向一个指向char的常量指针的指针......
继续向左
const char* const* (*foo[8])() ^^^^^
foo 是一个由 8 个指向函数的指针组成的数组,它返回一个指向一个指向 char常量的常量指针的指针(完整!)
Further explanation: http://www.unixwiz.net/techtips/reading-cdecl.html
回答by Thomas Matthews
Many people suggest reading the type specifier from right to left.
许多人建议从右到左阅读类型说明符。
const char * // Pointer to a `char` that is constant, it can't be changed.
const char * const // A const pointer to const data.
In both forms, the pointer is pointing to constant or read-only data.
在这两种形式中,指针都指向常量或只读数据。
In the second form, the pointer cannot be changed; the pointer will always point to the same place.
第二种形式,指针不能改变;指针将始终指向同一个地方。
回答by leonbloy
The difference is that without the extra const
the programmer could change, inside the method, where the pointer points to; for example:
不同之处在于,无需额外const
的程序员就可以在方法内部更改指针指向的位置;例如:
void print_string(const char * the_string)
{
cout << the_string << endl;
//....
the_string = another_string();
//....
}
That would be instead illegal if the signature were void print_string(const char * const the_string)
如果签名是,那将是非法的 void print_string(const char * const the_string)
Many programmers feel too verbose (in most scenarios) the extra const
keyword and omit it, even though it would be semantically correct.
许多程序员觉得额外的const
关键字太冗长(在大多数情况下)并省略它,即使它在语义上是正确的。
回答by Eglin
I think it's vary rarely relevant, because your function isn't getting called with arguments like &*the_string or **the_string. The pointer itself is a value-type argument, so even if you modify it you're not going to change the copy that was used to call your function. The version you're showing ensures that the string will not change, and I think that's sufficient in this case.
我认为它很少相关,因为你的函数没有被像 &*the_string 或 **the_string 这样的参数调用。指针本身是一个值类型参数,因此即使您修改它,您也不会更改用于调用您的函数的副本。您显示的版本确保字符串不会改变,我认为在这种情况下就足够了。
回答by TonyR
const char *
means that you can't use the pointer to change what is pointed to. You can change the pointer to point to something else, though.
const char *
意味着您不能使用指针来更改所指向的内容。不过,您可以将指针更改为指向其他内容。
Consider:
考虑:
const char * promptTextWithDefault(const char * text)
{
if ((text == NULL) || (*text == '##代码##'))
text = "C>";
return text;
}
The parameter is a non-const pointer to const char, so it can be change to another const char *
value (like a constant string). If, however, we mistakenly wrote *text = '\0'
then we'd get a compilation error.
该参数是一个指向 const char 的非常量指针,因此它可以更改为另一个const char *
值(如常量字符串)。但是,如果我们错误地写入,*text = '\0'
那么我们就会得到一个编译错误。
Arguably, if you don't intend to change what the parameter is pointing to, you could make the parameter const char * const text
, but it's not common to do so. We usually allow functions to change the values passed to parameters (because we pass parameters by value, any change does not affect the caller).
可以说,如果您不打算更改参数指向的内容,则可以创建 parameter const char * const text
,但这样做并不常见。我们通常允许函数改变传递给参数的值(因为我们是按值传递参数的,任何改变都不会影响调用者)。
BTW: it is good practice to avoid char const *
because it's often misread - it means the same as const char *
, but too many people read it as meaning char * const
.
顺便说一句:避免它是一种很好的做法,char const *
因为它经常被误读 - 它的含义与 相同const char *
,但太多人将其理解为含义char * const
。
回答by Jonathan Wood
There's no reason why either one wouldn't work. All print_string()
does is print the value. It doesn't try to modify it.
没有任何理由不工作。所有print_string()
所做的是打印的价值。它不会尝试修改它。
It's a good idea to make function that don't modify mark arguments as const. The advantage is that variables that can't change (or you don't want to change) can be passed to these functions without error.
制作不将标记参数修改为 const 的函数是个好主意。优点是不能改变(或者你不想改变)的变量可以毫无错误地传递给这些函数。
As far as the exact syntax, you want to indicate which type of arguments are "safe" to be passed to the function.
就确切的语法而言,您要指明哪种类型的参数是“安全”的,可以传递给函数。
回答by Jesus Ramos
In the latter you are guaranteeing not to modify both pointer and character in the first you only guarantee that the contents will not change but you may move the pointer around
在后者中,您保证在第一个中不会同时修改指针和字符,您只保证内容不会改变,但您可以移动指针