问题来由
在C\C++里的有一个老生常谈的问题:关于const限定符与指针符号 * 之间位置关系的不同组合,在代码中所代表的语义的差异。在理解这些不同概念时,发现有两个对应的中文翻译:指针常量和常量指针,大家的理解居然不一致,甚至是刚好相反。有意思的是,到现在为止,从网上的博客文章、搜索词条,好像也没有因为这种理解上的差异,生出额外的沟通、代码成本,大家各自用的都还挺顺,实在“诡异”。今天我本着无聊的精神,来分析下为什么会出现这种现象,及(建议)应该如何统一沟通表述与代码语义,减少不必要的沟通语义差异所带来的成本。
const与*的不同位置关系的语义差异
const限定符与解引用符 * 之间不同位置关系所代表的语义,本身并不难理解。具体如下表:
const 与 * 组合语法:
组合 | 含义 |
---|---|
const int * p | p(变量)可变,p指向的对象内容不可变 |
int const * p | p(变量)可变,p指向的对象内容不可变 |
int * const p | p(常量)不可变,p指向的对象内容可变 |
const int * const p | p(常量)不可变,p指向的对象内容不可变 |
由上表可知:
1. const int * p与 int const * p是同义的。
2. const 在 * 左边时,表示指针所指的对象是常量,不可通过*p解引用方式去更改p所指对象的值。
3. const 在 * 右边时,表示指针p 是常量,定义时就要赋初始地址,且指针p一直指向该初始地址,不可改变。
常量与指针不同位置关系的表述差异
指针常量与常量指针常常出现理解与表述上混乱,在网上梳理了一下,对指定组合的语义的本质理解应该是一致的,但在表述时却存在两种方式,且刚好相反:
组合一
int a = , b = , c = ;
int * const p = &a;
p = &b; //编译错误, 不能对p再进行赋值(地址)操作
*p = c; //编译通过,可以对p所指的非常量对象a进行赋值操作
表述一
此为指针常量,本质是常量,属偏正短语,指针(的)为形容词修饰中心名词常量,因此其完整表述为“指针的常量”, 表示该常量的类型为指针,以此表述来说明该常量的值是一个地址(指针)。
表述二 (推荐)
此为常量指针1(const pointer), 本质是指针,属偏正短语, 常量(的)为形容词修饰中心名词指针, 因此其完整表述为”常量的指针“,以此表述来说明该指针本身为常量。一旦(必须)初始化完成,则它的值(存放在指针中的地址)就不能发生改变了。
组合二
const int a = , b = , c = ;
const int * p = &a; //或写成“int const * p = &a;” 语义相同
p = &b; //编译正确, 可以对变量p再进行赋值(地址)操作
*p = c; //编译错误,不能对p所指的常量对象a 进行赋值操作
表述一
此为常量指针,本质是指针,用前缀常量来补充说明指针类型,应属”名+名“的并列短语, 表示一种所属关系,完整表述为”常量的指针“。以说明该指针指向一个常量,而该指针本身是一个变量,可以对指针重新赋地址。
表述二 (推荐)
此为指向常量的指针2 (pointer to const) , 即组合二的的字面语义表述,简单直接。该表述偏正短语,由”指向常量的“修饰中心词”指针“
组合三
const int a = , b = , c = ;
const int * const p = &a;
p = &b; //编译错误, 不能对常量p再进行赋值(地址)操作
*p = c; //编译错误,不能对p所指的常量对象a 进行赋值操作
表述
此为指向常量的常量指针, 大家对此组合表述差异不大,不做进一步说明。
总结
上述针对典型的几种组合进行了表述列举,这其中对同一概念理解的表述混乱,个人理解,这其实应该归结到使用中文短语时,未按照统一的短语结构来表述各组合对应语义,对同一类词组是属并列短语还是偏正短语所引起的理解二义性问题。个人推荐上述各组合的表述二,原因有三:
- 按照短语结构统一的标准,两中组合的表述二均为”偏正短语“,满足标准。
- Bjarne在他的The C++ Programming Language里面给出过一个助记的方法: 把一个声明从右向左读。 而Stanley B. Lippman在他的C++ Primer中同样给出从右向左读的建议3。各组中表述二均符合这样的阅读顺序。
- 组合一的表述一“指针常量”的表述,几大大部头C\C++经典书籍均未翻译出现(实际上英文也未发现有pointer const这类表达,不合语法,更正确的应该是pointer to const,表示“指向常量的指针”)。有讹用之嫌,因此并不建议使用。
以上总结,实为愚见,如有纰漏,欢迎指正。
目录
-
- 问题来由
- const与*的不同位置关系的语义差异
- 常量与指针不同位置关系的表述差异
- 组合一
- 表述一
- 表述二 (推荐)
- 组合二
- 表述一
- 表述二 (推荐)
- 组合三
- 表述
- 组合一
- 总结
- 以上总结,实为愚见,如有纰漏,欢迎指正。
- 目录
- C++ Primer 5th edition, chapter 02, 2.4.2 ↩
- C++ Primer 5th edition, chapter 02, 2.4.2 ↩
- C++ Primer 5th edition, chapter 02, 2.4.2 ↩