C/C++ 语言系列(四)复合数据类型之指针、引用
引用
引用是一个别名,也就是说,它是某个已存在变量的另一个名字。修改引用等同于修改被引用变量自身。
一个变量可以有多个引用。
声明引用
不存在空引用。声明引用的同时,必须初始化,否则报编译错误如下:
1 | int &ref; // declaration of reference variable 'ref' requires an initializer |
引用一旦初始化,就不能再指向另一个变量。修改引用等同于修改被引用变量本身。
指针
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。
声明指针
一元运算符 *
用于声明一个指针变量:
1 | bool *bp; // 声明一个布尔型的空指针 |
- 可以声明空指针。
- 除了常指针,其它指针可以在任何时间被初始化。
- 所有指针的值的实际数据类型,不管是布尔型、字符型、整型、浮点型,还是其它的数据类型,都是一样的,其值都是一个代表内存地址的十六进制数。
- 不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同,因此执行递增或递减时的步长不同。
获取指针大小
操作系统 | 指针变量的存储大小 |
---|---|
32 bits | 4 Bytes |
64 bits | 8 Bytes |
本机为 64 位操作系统,验证如下:
1 | sizeof(bool*) // 8 |
指针的算数运算
可以对指针进行四种算术运算:++
、--
、+
、-
。运算后,指针保存新的地址。
1 | int a = 0; |
重点考点
1 | // 常指针 |
常指针
顾名思义,指针本身是个常量,不能修改。
1 | int a = 0; |
常见的常指针,例如:
- 数组名
指向常量的指针
顾名思义,指针指向的是常量,不能修改其值。
1 | int a = 0; |
指向常量的常指针
结合了上述两种特性。
常见指针
字符串指针
1 | // 字符串指针(指向一个常量字符串,它被存放在程序的静态数据区,一旦定义就不能改变) |
数组指针
1 | int arrayName[5] = {1, 2, 3, 4, 5}; // &arrayName = 0x7ffee7376620 |
结构体指针
1 | product apple; |
类指针
1 | Rectangle rect(3, 4); |
引用与指针对比
常见问题,下列代码的区别?
1 | *p |
要解决这个问题,首先需要了解这两个运算符的区别:
在赋值运算符左侧 | 在赋值运算符右侧 | |
---|---|---|
* |
表示声明指针 | 表示取值运算符 |
& |
表示声明引用 | 表示取址运算符 |
代码示例如下:
1 | int a = 10; |
输出结果如下:
1 | a = 10, &a = 0x7ffee483763c, *&a = 10 |
总结如下:
指针变量 | 结果 | 描述 |
---|---|---|
p |
0x7ffee483763c | 返回指针变量 p 保存的地址 |
*p |
10 | 返回指针变量 p 保存的地址的实际值 |
&p |
0x7ffee4837628 | 返回指针变量 p 自身的地址 |
&*p |
0x7ffee483763c | 返回指针变量 p 保存的地址的实际值的地址 |
*&p |
0x7ffee483763c | 返回指针变量 p 自身的地址的实际值 |
引用与指针的区别,如下图:
参考
http://www.cplusplus.com/doc/tutorial/pointers/