1. 指针的四种状态
指针p本身地址 &p = 0x28ff40,保持 i 对象的地址 p = 0x28ff44, i 对象的值为 *p = 123
- 指向一个对象
- 指向紧邻对象所占空间的下一个位置
- 空指针,意味着指针没有指向任何对象
- 无效指针,上述三种情况的其他值
#include <iostream>
using namespace std;
/**
* 指针
*/
int main() {
int *p; // 指向 int 型对象的指针
std::cout << "*p 默认值 = " << *p << ", 指针地址 &p = " << &p << ", p = " << p << std::endl;
int iVal = 123;
p = &iVal; // iP 存放变量 iVal 的地址, *iP 是指向 iVal 对应的值
std::cout << "*p 是指向 iVal 对应的值 = " << *p << ", p 存放变量 iVal 的地址 = " << p << std::endl;
return 0;
}
运行结果
*p 默认值 = 0, 指针地址 &p = 0x28ff44, p = 0x7efde000
*p 是指向 iVal 对应的值 = 123, p 存放变量 iVal 的地址 = 0x28ff40
运行结果:*p 再次指向,其地址 (指向紧邻对象所占空间的下一个位置)
2. 利用指针访问对象
- 操作符 (*)又称解应用符,作用又符号得到指针所指的对象值
int iVal = 123;
p = &iVal; // iP 存放变量 iVal 的地址, *iP 是指向 iVal 对应的值
std::cout << "*p 是指向 iVal 对应的值 = " << *p << ", p 存放变量 iVal 的地址 = " << p << std::endl;
*p 是指向 iVal 对应的值 = 123, p 存放变量 iVal 的地址 = 0x28ff40
- 给解应用赋值,实际上是给指针所指的对象赋值
#include <iostream>
using namespace std;
/**
* 指针
*/
int main() {
int *p; // 指向 int 型对象的指针
std::cout << "*p 默认值 = " << *p << ", 指针地址 &p = " << &p << ", p = " << p << std::endl;
int iVal = 123;
p = &iVal; // iP 存放变量 iVal 的地址, *iP 是指向 iVal 对应的值
std::cout << "*p 是指向 iVal 对应的值 = " << *p << ", p 存放变量 iVal 的地址 = " << p << std::endl;
*p = 456;
std::cout << "*p 是指向 iVal 对应的值 = " << *p << ", p 存放变量 iVal 的地址 = " << p << ", iVal = " << iVal << std::endl;
return 0;
}
运行结果
*p 默认值 = 0, 指针地址 &p = 0x28ff44, p = 0x7efde000
*p 是指向 iVal 对应的值 = 123, p 存放变量 iVal 的地址 = 0x28ff40
*p 是指向 iVal 对应的值 = 456, p 存放变量 iVal 的地址 = 0x28ff40, iVal = 456
上述 解应用重新赋值 *p = 456,*p 和 iVal 的对象都被重新赋值了
int i = 123;
int *p = &i;
// 指针p本身地址 &p = p0x28ff40,保持i对象的地址 p = 0x28ff44, i对象的值为 *p = 123
std::cout<<"指针p本身地址 &p = "<< &p<<",保持i对象的地址 p = "<<p<<", i对象的值为 *p = "<<*p<<std::endl;
3.空指针
int *p = nullptr; // 定义空指针,等价于 int *p1 = 0
error: `nullptr' was not declared in this scope
这里指针需要初始化,否则编译不过
4.指针和引用区别
- 相同点
指针和引用都能提供对其他对象的访问 - 不同点
引用本身并非一个对象,一旦定义了引用,就无法令其在绑定到另外的对象,之后每次使用这个引用都是访问它之前绑定的对象
5.Void* 指针
特殊的指针类型,可用于存放任意对象地址