考虑:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
这两个函数在所有方面都相同吗?还是有区别?
我对C语言的答案感兴趣,但如果C++语言中有什么有趣的东西,我也想知道。
考虑:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
这两个函数在所有方面都相同吗?还是有区别?
我对C语言的答案感兴趣,但如果C++语言中有什么有趣的东西,我也想知道。
技巧在于从后往前阅读声明(从右到左):
const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"
两者是同一件事情。因此:
a = 2; // Can't do because a is constant
。
const char *s; // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"
*s = 'A'; // Can't do because the char is constant
s++; // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++; // Can't do because the pointer is constant
char const *
从左往右读是:"pointer, const, char"。它是一个指向常量字符的指针。当你说 "一个指针是常量" 时,"常量" 形容词在指针上。所以,在这种情况下,你的形容词顺序应该是:"const, pointer, char"。但你是正确的,这个技巧存在歧义。这确实是一个 "技巧",而不是一个明确的 "规则"。 - Ates Goralconst T
和 T const
是相同的。但对于指针类型来说就更加复杂了:
const char*
是指向常量 char
的指针char const*
是指向常量 char
的指针char* const
是指向 (可变) char
的常量指针换句话说,(1) 和 (2) 是相同的。使指针(而不是指向的内容)成为 const
的唯一方法是使用后缀-const
。
这就是为什么许多人更喜欢始终将 const
放在类型的右侧(“东 const”风格):它使其相对于类型的位置保持一致且易于记忆(据说这也更容易教给初学者)。
它们之间没有区别。它们都声明“a”为一个无法更改的整数。
差异开始出现的地方是在使用指针时。
这两个代码片段:
const int *a
int const *a
声明 "a" 为一个指向不可变整数的指针。可以给 "a" 赋值,但不能更改 "*a" 的值。
int * const a
声明"a"为指向整数的常量指针。"*a"可以被赋值,但"a"不能。
const int * const a
声明"a"为指向常量整数的常量指针。不能对"a"或"*a"进行赋值。
static int one = 1;
int testfunc3 (const int *a)
{
*a = 1; /* Error */
a = &one;
return *a;
}
int testfunc4 (int * const a)
{
*a = 1;
a = &one; /* Error */
return *a;
}
int testfunc5 (const int * const a)
{
*a = 1; /* Error */
a = &one; /* Error */
return *a;
}
Prakash的说法是正确的,尽管关于指针情况可能需要更详细的解释。
"const int* p"是指向int类型的指针,不允许通过该指针更改int类型的值。"int* const p"是指向int类型的指针,不能被修改为指向其他int类型。
请参见https://isocpp.org/wiki/faq/const-correctness#const-ptr-vs-ptr-const。
const int
与int const
相同,这也适用于C中的所有标量类型。通常情况下,在C语言中声明标量函数参数为const
是不必要的,因为C采用按值传递的语义,意味着对变量所做的任何更改都是局部的,仅限于其封闭函数。
这两者是相同的,但在C++中,总是在右侧使用const有一个很好的理由。因为const成员函数必须这样声明,所以你会保持一致:
int getInt() const;
this
指针从Foo * const
更改为Foo const * const
。详见此处。
对于 int
类型,它们是相同的。
而对于 int*
类型,它们是不同的。
这不是一个直接的答案,而是一个相关的提示。为了保持清晰,我总是使用“把const
放在外面”的惯例,其中“外面”指的是最左边或最右边。这样就没有混淆——const
适用于最近的东西(类型或*
)。例如:
int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change
const int* cantChangeTheData;
int* const cantChangeTheAddress;