目录
普通指针
指针的定义
允许在一条语句中定义多个指针,其形式是将声明符写成 *d ,其中d是变量名
int *ip1, *ip2; //ip1和ip2指向int型对象的指针
double dp1, *dp2; //dp1是定义的double型对象,dp2是指向double型对象的指针
double d1;
double* dp3 = &d1; //正确,初始值是double型对象的地址
double* dp4 = dp3; //正确,初始值是指向double对象的指针
double* dp5 = &dp3; //错误,dp3本身就是指针类型,其初始值就是某个对象的地址,直接赋给指针dp5即可,不需要使用取地址符&
获取对象的地址
指针存放某个对象的地址。要想获取该地址,需要使用取地址符 &
int ival = 6;
//对指针p进行初始化,初始值是int型对象ival的地址
int* dp = &ival; //dp存放ival变量的地址,或者说p是指向变量ival的指针
cout << p << endl; // 000000A72BF9F8A4 每次执行内存地址都会变化
注意事项及错误示范
-
引用不是对象,没有实际的地址,所以不能定义指向引用的指针
-
不能用int型变量来初始化指针(需要加取地址符&),这与引用的初始化不同。
-
将指针的初始值指向另一个指针,不需要使用取地址符&
double* dp4 = dp3; //正确,初始值是指向double对象的指针
double* dp5 = &dp3; //错误,dp3本身就是指针类型,其初始值就是某个对象的地址,直接赋给指针dp5即可,不需要使用取地址符&
- 所有指针的类型都要与它所指向的对象的类型相匹配
double d1;
double* dp = &d1; //正确
double* dp2 = dp; //正确
// int* pi = dp; //错误,指针pi的类型与指针dp的类型不匹配
// int *pi = &d1; //错误,不能将double型对象的地址赋给int型指针
利用指针访问对象
- 使用解引用符( * ),来访问对象
int ival = 12;
int* dp = &ival;
//利用指针访问对象,使用解引用
//由解引用符*得到指针dp所指对象,输出12
cout << *dp << endl;
-
对指针解引用会得出所指的对象,可以经由这个规则,对指针所指的对象进行操作
-
由解引用符*得到指针所指对象,可经由对指针解引用(如 *dp) 来对所指对象进行赋值操作
#include <iostream>
using namespace std;
int main() {
int ival = 12;
/*
对指针dp进行初始化,三种说法:
1.指针dp存放了变量ival的地址
2.指针dp是指向int型对象ival的指针
3.指针dp的初始值是变量ival的地址
*/
int* dp = &ival;
//利用指针访问对象,使用解引用
cout << *dp << endl;
*dp = 3; //由解引用符*得到指针dp所指对象,即可经由dp为变量ival赋值
cout << "ival = " << ival << endl;
cout << "*dp(利用指针访问对象)" << *dp << endl;
return 0;
system("pause");
}
指向常量的指针
要想存放常量对象的地址,只能使用指向常量的指针,并且不能通过该指针去改变其所指对象的值,但是可以重新给该指针赋值,并且可以令其指向非常量的对象
#include <iostream>
using namespace std;
int main() {
/*
从右往左阅读,得出cptr只是一个指向常量的指针,并不是常量指针
故cptr的值(存放在指针中的地址)可以改变
*/
double pval = 4.2;
const double pi = 3.14;
// double* ptr = π//错误
const double* cptr = π //cptr只是一个指向常量的指针
//*cptr = 42;//错误
cout << "cptr指向常量pi时所存放的地址为:" << (int)cptr << endl;
cptr = &pval; //重新为指向常量的指针赋值
cout << "cptr指向非常量pval时所存放的地址为:" << (int)cptr << endl;
const double* const pip = &pval; //正确
//double* const cpip = π //错误
const double* p1 = &pval; //正确
return 0;
system("pause");
}
常量指针
-
把 * 写在const前面 用以说明指针是一个常量
-
因为指针是对象(引用不是),所以允许将指针本身定义为常量。常量指针必须初始化,一旦初始化完成,它的值(存放在指针中的那个地址)就不能改变了(注意与指向常量的指针做对比)
-
指针本身是一个常量,并不意味着不能通过指针去修改所指对象的值,常量指针可以指向常量对象,也可以指向非常量对象
-
如果常量指针指向的对象是一个常量,则常量指针的值(存放的那个地址)和所指对象的值都不能被改变
-
如果常量指针指向的对象是一个非常量对象,那么就可以通过常量指针去修改所指对象的值
-
int errNum = 0;
const double pi = 3.14159;
double pval = 4.2;
//curErr指向的是一个非常量对象
int * const curErr = &errNum; //curErr是常量指针,其值不能被改变
//pip指向的是一个常量
const double *const pip = π //pip是一个指向常量对象的常量指针(从右往左来理解)
double *const pip = π //错误,常量指针指向常量对象时,类型修饰应该是const double
const double* const cpi = &pval; //正确
-
常量指针不能用于初始化普通指针,普通指针可以用于初始化常量指针
int ival = 42; int* p1 = &ival; const int* const p3 = p1; //正确,普通指针可以用于初始化常量指针 int* p4 = p3; //错误,常量指针不能用于初始化普通指针