c++ const and pointer 常量和指针
That's the million-dollar question for many C/C++ developers! It's definitely tricky at first. Here are some effective strategies to help you memorize and quickly recognize these const pointer declarations:
1. The "Right-to-Left" Rule (The Most Popular and Reliable)
This is by far the most widely taught and effective method.
-
How it works: Read the declaration starting from the variable name and moving to the left. When you hit a
const, it applies to whatever is immediately to its left. -
Example 1:
const int* p1;p1:p1is a variable.*:p1is a pointer.int: It points to anint.const: Theintit points to isconst.- Result:
p1is a pointer to aconst int. (You can changep1to point to a different int, but you can't change the value of the int it points to throughp1.)
-
Example 2:
int const* p2;p2:p2is a variable.*:p2is a pointer.const int: It points to aconst int. (Theconstapplies to theint.)- Result:
p2is a pointer to aconst int. (Same asconst int*.)
-
Example 3:
int* const p3;p3:p3is a variable.const:p3itself isconst.*:p3is a pointer.int: It points to anint.- Result:
p3is aconstpointer to anint. (You cannot change whatp3points to, but you can change the value of the int it points to.)
2. The "Const-ness" is to the Left Rule
This is a simplified version of the right-to-left rule, focusing on where the const applies.
- If
constis to the left of the*: The data pointed to is constant.const int* p;(Data is const)int const* p;(Data is const)
- If
constis to the right of the*: The pointer itself is constant.int* const p;(Pointer is const)
3. The "Analogy" Method (as used in the previous explanation)
Relating it to real-world scenarios can make it click.
- Pointer to
constdata (const int* porint const* p):- "I have a sign, and it points to a house. I can move my sign to point to another house, but I am not allowed to touch the house it's currently pointing to (no repainting, no remodeling)."
constpointer to data (int* const p):- "I have a sign, and it's stuck in the ground pointing to one specific house. I can never move this sign to point to a different house. However, since it's my sign and my house, I can repaint or remodel the house it points to."
4. Practice, Practice, Practice!
This is crucial. The more you write and read these declarations, the more intuitive they will become.
- Code examples: Write small snippets of code for each type of declaration and try to perform operations that should work and operations that should fail (and see the compiler errors). This hands-on experience solidifies your understanding.
- Quiz yourself: Create flashcards or just mentally challenge yourself when you see a declaration. "Okay,
char* const name;...constis after the*, so the pointer itself is constant. I can't reassignname, but I can change*name." - Look at existing code: When reading open-source projects or tutorials, pay attention to how
constis used with pointers.
5. Remember the "Special Case" of const char* for String Literals
This is a very common use case and can help reinforce the concept.
- When you write
const char* message = "Hello";,"Hello"is a string literal, which is stored in read-only memory. Therefore,messagemust be a pointer to a constant character. You can't modify the characters in"Hello"throughmessage. You can makemessagepoint to a different string literal.
By consistently applying the right-to-left rule and practicing with examples, you'll find that these const pointer declarations become much less intimidating over time.
要记住并识别这些 const 指针声明,确实是许多 C/C++ 开发者都会遇到的难题。不过,有一些非常有效的方法可以帮助你掌握它们:
1. 从右到左规则 (最常用且可靠的方法)
这是最广泛教学且最有效的方法。
-
工作原理: 从变量名开始,向左阅读声明。当你遇到
const时,它适用于紧挨着它左边的内容。 -
示例 1:
const int* p1;p1:p1是一个变量。*:p1是一个指针。int: 它指向一个int。const: 它所指向的int是const的。- 结果:
p1是一个指向常量整数的指针。(你可以改变p1指向另一个整数,但不能通过p1改变它所指向的整数的值。)
-
示例 2:
int const* p2;p2:p2是一个变量。*:p2是一个指针。const int: 它指向一个常量整数。(这里的const适用于int。)- 结果:
p2是一个指向常量整数的指针。(与const int*相同。)
-
示例 3:
int* const p3;p3:p3是一个变量。const:p3本身是const的。*:p3是一个指针。int: 它指向一个int。- 结果:
p3是一个指向整数的常量指针。(你不能改变p3指向哪里,但可以改变它所指向的整数的值。)
2. "Const 作用于左侧" 规则
这是从右到左规则的一个简化版本,侧重于 const 的作用对象。
- 如果
const在*的左侧: 所指向的数据是常量。const int* p;(数据是常量)int const* p;(数据是常量)
- 如果
const在*的右侧: 指针本身是常量。int* const p;(指针是常量)
3. "类比" 法 (如之前的解释中所用)
将它与现实世界的场景联系起来,可以帮助你理解。
- 指向常量数据的指针 (
const int* p或int const* p):- "我有一个指示牌,它指向一所房子。我可以移动我的指示牌去指向另一所房子,但我不允许触碰它当前指向的房子(不能重新粉刷,不能改造)。"
- 指向数据的常量指针 (
int* const p):- "我有一个指示牌,它牢牢地固定在地上,始终指向同一所房子。我永远不能移动这个指示牌去指向另一所房子。然而,既然它是我的指示牌和我的房子,我可以重新粉刷或改造它所指向的房子。"
4. 实践,实践,再实践!
这一点至关重要。你写和读这些声明越多,它们就会变得越直观。
- 代码示例: 为每种类型的声明编写小段代码,尝试执行应该成功和应该失败的操作(并查看编译器错误)。这种亲身体验会巩固你的理解。
- 自我测验: 制作抽认卡,或者当你看到一个声明时,在脑海中挑战自己。"好的,
char* const name;...const在*之后,所以指针本身是常量。我不能重新赋值name,但我可以改变*name。" - 查看现有代码: 阅读开源项目或教程时,注意
const如何与指针一起使用。
5. 记住字符串字面量的 "特殊情况" const char*
这是一个非常常见的用例,有助于巩固概念。
- 当你写
const char* message = "Hello";时,"Hello"是一个字符串字面量,它存储在只读内存中。因此,message必须是一个指向常量字符的指针。你不能通过message修改"Hello"中的字符。你可以使message指向另一个字符串字面量。
通过始终应用从右到左规则并结合实践示例,你会发现这些 const 指针声明会随着时间的推移变得不那么令人生畏。

浙公网安备 33010602011771号