常量字符*常量与常量字符*? 我正在通过一些示例程序来重新熟悉C++,我已经遇到了下面的问题。首先,下面是示例代码: void print_string(const char * the_string) { cout << the_string << endl; } int main () { print_string("What's up?"); } void打印字符串(常量字符*字符串) { 两者之间的区别在于char*可以指向任意指针。相反,Const char*指向可执行文件数据部分中定义的常量。因此,您不能修改Const char*字符串的字符值。
在后者中,您保证不会同时修改f中的指针和字符首先,你只能保证内容不会改变,但你可以移动指针,后者可以防止你修改常量字符*常量与常量字符*? 我正在通过一些示例程序来重新熟悉C++,我已经遇到了下面的问题。首先,下面是示例代码: void print_string(const char * the_string) { cout << the_string << endl; } int main () { print_string("What's up?"); } void打印字符串(常量字符*字符串) { 两者之间的区别在于char*可以指向任意指针。相反,Const char*指向可执行文件数据部分中定义的常量。因此,您不能修改Const char*字符串的字符值。,c++,c,C++,C,在后者中,您保证不会同时修改f中的指针和字符首先,你只能保证内容不会改变,但你可以移动指针,后者可以防止你修改打印字符串中的字符串。这实际上是合适的,但可能会让开发人员感到厌烦 char*字符:我可以更改字符指向的char,也可以修改它指向的char const char*字符串:我可以更改字符串指向的字符,但我不能修改它指向的字符 char*const the_string:我无法更改该_string指向的char,但我可以修改它指向的char const char*const the_str
打印字符串中的字符串。这实际上是合适的,但可能会让开发人员感到厌烦
char*字符
:我可以更改字符
指向的char,也可以修改它指向的char
const char*字符串
:我可以更改字符串
指向的字符,但我不能修改它指向的字符
char*const the_string
:我无法更改该_string
指向的char
,但我可以修改它指向的char
const char*const the_string
:我无法更改该_string
指向的char
,也无法修改它指向的char
char *p;
const char *p;
char * const p;
const char * const p;
char *p;
const char *p;
char * const p;
const char * const p;
char *p;
const char *p;
char * const p;
const char * const p;
char *p;
const char *p;
char * const p;
const char * const p;
任何一个都不起作用是没有理由的。所有的
print\u string()
都是打印值。它不会试图修改它
让不修改的函数将参数标记为常量是一个好主意。优点是不能更改(或您不想更改)的变量可以毫无错误地传递给这些函数
至于确切的语法,您需要指出哪种类型的参数可以“安全”地传递给函数。
const char*const
表示指针以及指针指向的数据都是常量
const char*
仅表示指针指向的数据是常量。但指针本身不是常量
例如
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.
许多人建议从右到左阅读类型说明符
const char * // Pointer to a `char` that is constant, it can't be changed.
const char * const // A const pointer to const data.
在这两种形式中,指针都指向常量或只读数据
在第二种形式中,指针不能更改;指针将始终指向相同的位置。不同之处在于,如果没有额外的
常量,程序员可以在方法内部更改指针指向的位置;例如:
void print_string(const char * the_string)
{
cout << the_string << endl;
//....
the_string = another_string();
//....
}
void打印字符串(常量字符*字符串)
{
cout我认为它很少相关,因为您的函数不会使用诸如&*the_字符串或**the_字符串之类的参数调用。指针本身是一个值类型参数,因此即使您修改它,也不会更改用于调用函数的副本。您显示的版本确保字符串不会更改,我认为在这种情况下这就足够了。const char*
意味着您不能使用指针来更改指向的内容。不过,您可以将指针更改为指向其他内容
考虑:
const char * promptTextWithDefault(const char * text)
{
if ((text == NULL) || (*text == '\0'))
text = "C>";
return text;
}
该参数是指向常量字符的非常量指针,因此可以将其更改为另一个const char*
值(如常量字符串)。但是,如果我们错误地编写了*text='\0'
,则会出现编译错误
可以说,如果您不想更改参数所指向的内容,您可以将参数const char*const text
,但这样做并不常见。我们通常允许函数更改传递给参数的值(因为我们按值传递参数,任何更改都不会影响调用者)
顺便说一句:避免char*const*
是一种很好的做法,因为它经常被误读-它的意思与const*char*
相同,但太多人将其理解为char*const
几乎所有其他答案都是正确的,但他们忽略了一个方面:在参数上使用额外的const
在函数声明中,编译器基本上会忽略它。现在,让我们忽略示例作为指针的复杂性,只使用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
}
//这些声明是等效的
无效打印字符串(常量字符*常量字符串);
无效打印字符串(常量字符*字符串);
//在此定义中,您不能更改
//函数体。它本质上是一个常量局部变量。
无效打印字符串(常量字符*常量字符串){
cout(我知道这很旧,但我还是想和大家分享。)
我只是想详细说明一下Thomas Matthews的答案。C类型声明的左右规则基本上是这样的:当阅读C类型声明时,从标识符开始,可以时向右,不能时向左
最好用几个例子来解释这一点:
例1
- 从标识符开始,我们不能向右走
const char* const* (*foo[8])()
^
const char* const* (*foo[8])()
^^^^
const char* const* (*foo[8])()
^^^^^