Answers:
后者阻止您修改the_string
内部print_string
。在这里实际上是适当的,但是冗长的措辞推迟了开发人员。
char* the_string
:我可以改变char
哪个the_string
点,我可以修改char
在它指向。
const char* the_string
:我可以改变char
哪个the_string
点,但我不能修改char
,在它指向。
char* const the_string
:我不能改变char
哪个the_string
点,但我可以修改char
在它指向。
const char* const the_string
:我无法更改char
要the_string
指向的点,也无法修改char
其指向的点。
const char *
更好,因为const
完全相反。
指向可变字符的可变指针
char *p;
指向常量字符的可变指针
const char *p;
指向可变字符的常量指针
char * const p;
指向常量字符的常量指针
const char * const p;
const char* p; --> constant pointer to mutable character
和 char *const p; --> mutable pointer to constant character
const char * p
为:“ p是指向字符常量的指针”,或者是James正确指出的指向常量字符的可变指针。与第二个相同:)。
const char * const
表示指针以及指针指向的数据都是 const!
const char *
表示仅指针指向的数据为const。指针本身不是const。
例。
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.
(我知道这已经很老了,但我还是想分享。)
只是想详细说明托马斯·马修斯的答案。C类型声明的左右规则几乎说:当读取C类型声明时,从标识符开始,在可以的时候右移,在不能的时候左移。
最好用几个示例来解释:
从标识符开始,我们不能向右走,所以我们向左走
const char* const foo
^^^^^
foo是一个常量 ...
继续向左
const char* const foo
^
foo是指向 ...
继续向左
const char* const foo
^^^^
foo是指向char的常量指针。
继续向左
const char* const foo
^^^^^
foo是指向char 常量的常量指针(完成!)
从标识符开始,我们不能向右走,所以我们向左走
char* const foo
^^^^^
foo是一个常量 ...
继续向左
char* const foo
^
foo是指向 ...
继续向左
char* const foo
^^^^
foo是指向char的常量指针(完成!)
从标识符开始,但是现在我们可以正确了!
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个指向函数的指针组成的数组,该数组返回一个指向a常量指针的指针。
继续向左
const char* const* (*foo[8])()
^^^^
foo是一个由8个指向函数的指针组成的数组,这些函数返回一个指向常量指针的指针,该常量指针指向一个char ...
继续向左
const char* const* (*foo[8])()
^^^^^
foo是一个由8个指向函数的指针组成的数组,该函数返回一个指向常量指针的指针,该指针指向char 常量(Complete!)。
const char *
表示您不能使用指针更改所指向的内容。不过,您可以更改指针以指向其他内容。
考虑:
const char * promptTextWithDefault(const char * text)
{
if ((text == NULL) || (*text == '\0'))
text = "C>";
return text;
}
该参数是指向const char的非const指针,因此可以将其更改为另一个const char *
值(例如常量字符串)。但是,如果我们错误地编写了代码,*text = '\0'
则会出现编译错误。
可以说,如果您不打算更改参数所指向的内容,则可以更改参数const char * const text
,但这并不常见。我们通常允许函数更改传递给参数的值(因为我们按值传递参数,所以任何更改都不会影响调用者)。
顺便说一句:避免这样做是个好习惯,char const *
因为它经常被误读-含义相同const char *
,但是太多的人认为它是含义char * const
。
const char *
和签名之间的区别char const *
-您所说的BTW的方式确实有帮助!
几乎所有其他答案都是正确的,但是它们却忽略了这一方面:当const
在函数声明中的参数上使用extra 时,编译器实际上将忽略它。暂时,让我们忽略示例作为指针的复杂性,仅使用即可int
。
void foo(const int x);
声明与
void foo(int x);
仅在函数定义中const
才有意义:
void foo(const int x) {
// do something with x here, but you cannot change it
}
此定义与以上任何声明兼容。呼叫者不在乎这x
是const
与呼叫站点无关的实现细节。
如果您有数据const
指针const
,则应用相同的规则:
// these declarations are equivalent
void print_string(const char * const the_string);
void print_string(const char * the_string);
// In this definition, you cannot change the value of the pointer within the
// body of the function. It's essentially a const local variable.
void print_string(const char * const the_string) {
cout << the_string << endl;
the_string = nullptr; // COMPILER ERROR HERE
}
// In this definition, you can change the value of the pointer (but you
// still can't change the data it's pointed to). And even if you change
// the_string, that has no effect outside this function.
void print_string(const char * the_string) {
cout << the_string << endl;
the_string = nullptr; // OK, but not observable outside this func
}
很少有C ++程序员会费心地创建参数const
,即使它们可能是参数,无论这些参数是否是指针。
const
在定义中而不是在声明中向函数参数添加额外内容,Visual C ++ 2015会发出警告。