指针是"指向"另外一种类型的复合类型, 实现了对其他对象的间接访问, 然而指针与引用有很多不同点:
指针本身就是一个对象, 允许对指针赋值和拷贝在指针的声明周期内它可以先后指向几个不同的对象指针无需在定义时赋初值. 在块作用域内定义的指针如果没有被初始化, 也将拥有一个不确定的值 定义指针的方法
将声明符写成 *d 的形式, 其中 d 是变量名.如果在一条语句中定义了几个指针变量, 则每个变量前面都必须有符号*
int main(){
int *ip1, *ip2;
double dp, *dp2; // dp 是 double 型的对象, dp2 是指向double型对象的指针
return 0;
}
获取对象的地址
指针存放某个对象的地址, 要想获得该地址, 需要用到 取地址符 &.(不加取地址符会报错)
int main(){
int ival = 42;
int *p = &ival;
cout << p <
输出如下
执行完成,耗时:0 ms
0x7ffe95bfab40
42
引用不是对象, 没有实际地址, 所以不能定义指向引用的指针.指向指针的指针, 例子如下
int main(){
int ival = 42;
int *p1 = &ival;
int *p2 = p1; //正确: 初始值是指向int对象的指针
cout << *p2 << endl;
return 0;
}
输出如下
执行完成,耗时:0 ms
42
指针值
指针的值应该属于下列四种状态之一
指向一个对象指向紧邻对象所占空间的下一位置空指针, 不指向任何对象无效指针, 即除上述情况的其他值
利用指针访问对象
如果指针指向了一个对象, 则允许使用 解引用符 * 来访问该对象.
int main(){
int ival = 42;
int *p = &ival;
cout << *p << endl;
return 0;
}
输出为: 42
给解引用的结果赋值, 实际上也就是给指针所指的对象赋值.
int main(){
int ival = 42;
int *p = &ival;
*p = 30;
cout << *p << endl;
return 0;
}
输出为: 30
3. 解引用操作仅适用于那些确实指向了某个对象的有效指针
空指针
以下列出几个生成空指针的方法
int main(){
int *p1 = nullptr;
int *p2 = 0;
// 需要先 #include cstdlib
int *p3 = NULL;
return 0;
}
赋值和指针
指针和引用的区别: 引用本身并非对象, 一旦定义了引用就无法令其再绑定到另外的对象. 指针和它存放的地址之间就没有这种限制了. 给指针赋值就是令它存放一个新的地址, 从而指向一个新的对象.区分: 一条赋值语句改变了指针的值还是改变了指针所指对象的值
方法: 赋值永远改变的是等号左侧的对象
int main(){
int i1 = 42;
int i2 = 21;
int *pi = &i1;
cout << *pi << endl;
pi = &i2; // pi的值被改变, 现在pi指向i2
cout << *pi << endl;
*pi = 0; // i2 的值被改变, 指针 pi 并没有改变
cout << *pi << endl;
return 0;
}
输出为:
执行完成,耗时:0 ms
42
21
0
其他指针操作
只要指针拥有一个合法值, 就能将他用在条件表达式中.
如果指针的值是 0, 条件取 false.任何非 0 的指针对应的条件都是 true.
int main(){
int ival = 1024;
int *pi1 = 0;
int *pi2 = &ival;
if(pi1){
cout << "pi1的值不为0" << endl;
}else{
cout << "pi1的值为0" << endl;
}
if(pi2){
cout << "pi2的值不为0" << endl;
}else{
cout << "pi2的值为0" << endl;
}
}
输出如下
执行完成,耗时:0 ms
pi1的值为0
pi2的值不为0
void* 指针
void* 是一种特殊的指针类型, 可用于存放任意对象的地址不能直接操作 void* 指针所指的对象, 因为我们不知道这个对象是什么类型的.以 void* 的视角来看内存空间也就仅仅是内存空间, 没办法访问内存空间中的所存的对象.



