2026/3/20 code

CPP-Primer-Chapter04

C++ Primer 数组与指针

#coding

指针

string* str1, str2; // str1是指针,str2是string对象

初始化

int ival=0;
const int ival2=0;
int *p1=ival; // error
int *p2=ival2; //ok[早期写法,现代一般不用]
int *p3=nullptr; //ok

指针与引用比较

定义时,引用必须要初始化,指针可以不用。 引用初始化后,不能改变引用对象,指针可以改变指向。

int val1=1, val2=2;
int &r1=val1; // r1是val1的别名
int &r2=val2; // r2是val2的别名
r1=r2; //并不是改变r1的引用对象,而是将r2的值赋给了r1,也就是val1=val2

指针与const

const对象的指针必须指向const对象,不能指向非const对象。 void也需要使用const修饰,表示指针指向的对象不可修改。

const int ival=0;
int *p1=&ival; // error
const int *p2=&ival; // ok

非const对象的指针可以指向const对象,但不能通过该指针修改对象的值。

int ival=0;
const int *p1=&ival; // ok
*p1=1; // error

const指针 不允许该指针指向其他对象,但可以修改指向对象的值。

int ival=0;
int *const p1=&ival; // ok
*p1=1; // ok
int ival2=2;
p1=&ival2; // error

指向const的const指针 既不允许指针指向其他对象,也不允许修改指向对象的值。

const int ival=0;
const int *const p1=&ival; // ok
*p1=1; // error
int ival2=2;
p1=&ival2; // error

typedef 和 const 的陷阱

先理解 typedef 是“类型别名”,不是文本替换。

typedef string* pstring;

这句话的意思是:pstring 是一个新类型,它的本质是 string*(指向string的指针)。

问题的核心:

const pstring cstr;

大多数人的直觉是把 pstring 展开,变成:

const string* cstr;   // 直觉上的理解(错的)

这样理解的话,cstr 是一个指向 const string 的指针(指针可以变,内容不能变)。

但实际上是这样

const 修饰的是 pstring 这个类型整体,而 pstring 是一个指针类型

const   pstring   cstr
  ↓        ↓
不可变   指针类型

所以 const 加在指针上,表示指针本身不可变,等价于:

string* const cstr;   // 正确理解:const 指针,指向 string

两种类型的对比:

const string* cstr;   // 指向const string 的指针
                      // 指针能变,但不能通过它修改内容

string* const cstr;   // 指向string 的const指针
                      // 指针不能变(不能指向别处),但内容能改

为什么不能直接文本替换?

typedef string* pstring;

// 如果是文本替换(错误思维):
const pstring -> const string* -> 指向const string的指针

// 实际上是类型替换(正确):
const pstring -> (string*) const -> const指针,指向string

typedef 创建的是一个完整的类型单元,const 只能作用在这个单元上,而不会“钻进去”修改类型内部。

多维数组与指针

int *ip[4]; // array of 4 pointers to int
int (*ip)[4]; // pointer of an array of 4 ints