指针
序言:
指针是大多数C程序的重要组成部分,而且在许多C++程序中仍然受到重视!
与迭代器的异同:指针结构更加通用一些,指针用于指向单个对象,而迭代器只能用于访问容器内的对象。
由于指针用于低级操作,容易产生与繁琐细节相关的额错误,因此在现代C++程序中,尽量采用vector和迭代器取代一般的数组、指针,采用string类型取代C风格字符串。【P101】
正文:
1、每个指针都有一个与之关联的数据类型,该数据类型决定了指针所指向的对象的类型。
[cpp] view plain copy print ?
-
-
-
-
- vector<int> *pvec;
- int *pi;
- string *pstr;
- double *pdou;
/*
*理解指针声明语句时,请从右往左读!
*指针的书写有几种书写方式,关键是要选择一种,并坚持使用下去!
*/
vector<int> *pvec;
int *pi;
string *pstr;
double *pdou;
2、指针可能的取值
1)类型匹配对象的地址:&对象
2)类型匹配对象的下一个地址:&(对象+1)
3)0值常量表达式:NULL,例如,在编译时可以获得0值的整型const对象或字面值常量0.
4)同类型的另一个有效的指针
[cpp] view plain copy print ?
-
- int value = 1024;
- int *pi = 0;
- int *pi1 = &value;
- int *pi2 = pi;
- int *pi3;
- pi = pi2;
- pi3 = 0;
-
- int zero = 0;
- int *p = zero;
- const int ZERO = 0;
- int *pz = ZERO;
-
- int *pnull = NULL;
-
- double val = 3.14;
- int *pv = &val;
//示例
int value = 1024;
int *pi = 0;
int *pi1 = &value;
int *pi2 = pi;
int *pi3;
pi = pi2;
pi3 = 0;
int zero = 0;
int *p = zero; //ERROR
const int ZERO = 0;
int *pz = ZERO;
int *pnull = NULL;
double val = 3.14;
int *pv = &val; //ERROR
3、拒绝使用”野指针”!
很多运行时错误都源于使用了未初始化的指针。因为他很难被发现。
如果使用未初始化的指针,会将指针中存放的不确定值视为内存地址,然后操纵该内存地址中保存的内容!
建议:
1)、除非指向的对象已经存在,否则不要先定义指针。
2)、在使用之前初始化所有变量,尤其是指针!
[cpp] view plain copy print ?
-
- int *p;
- *p = 1;
//这就是在找死 *_*
int *p;
*p = 1;
4、void*指针
void*表明该指针与一地址相关,但不清楚存储在该地址上的对象的类型!
void*指针只支持集中有限的操作:
1)与另一个指针进行比较
2)向函数传递void*指针或从函数返回void*指针。
3)给一个void*指针赋值
千万不要使用void*指针操纵他所指向的对象!!!
[cpp] view plain copy print ?
- double val = 3.14;
- int obj = 3;
-
- double *pval = &val;
- void *pvoid = pval;
- pvoid = &val;
- pvoid = &obj;
double val = 3.14;
int obj = 3;
double *pval = &val;
void *pvoid = pval;
pvoid = &val;
pvoid = &obj;
5、指针提供间接操纵其所指对象的功能
1)解引用操作符返回指定对象的左值,利用这个功能可以修改所指对象的值。
[cpp] view plain copy print ?
- string str("Hello World");
- string *ps = &str;
- *ps = "NiHao ShiJie";
- cout << str << endl;
string str("Hello World");
string *ps = &str;
*ps = "NiHao ShiJie";
cout << str << endl;
2)也可以修改指针本身:
[cpp] view plain copy print ?
- string str("Hello World");
- string *ps = &str;
- string obj("NiHao ShiJie");
- ps = &obj;
- cout << *ps << endl;
string str("Hello World");
string *ps = &str;
string obj("NiHao ShiJie");
ps = &obj;
cout << *ps << endl;
【P105:关键概念:给指针赋值或通过指针进行赋值,值得仔细品读!】
6、指针与引用的差异
1)定义引用时没有初始化是错误的。
2)给引用赋值修改的是该引用所关联对象的值。
[cpp] view plain copy print ?
- string str("hello world");
- string &rstr1;
- string &rstr2 = str;
- rstr2 = "nihao shijie";
- cout << str << endl;
string str("hello world");
string &rstr1; //ERROR
string &rstr2 = str;
rstr2 = "nihao shijie";
cout << str << endl;
[cpp] view plain copy print ?
- int ival = 1;
- int ival2 = 2;
- int &r1 = ival,&r2 = ival2;
- r1 = r2;
- cout << r1 << endl;
- cout << ival << endl;
int ival = 1;
int ival2 = 2;
int &r1 = ival,&r2 = ival2;
r1 = r2;
cout << r1 << endl;
cout << ival << endl;
7、指向指针的指针
[cpp] view plain copy print ?
- int ival = 1024;
- int *pi = &ival;
- int **ppi = π
-
- cout << "ival is: " << ival
- << "\n*pi is: " << *pi
- << "\n**ppi is: " << **ppi << endl;
int ival = 1024;
int *pi = &ival;
int **ppi = π
cout << "ival is: " << ival
<< "\n*pi is: " << *pi
<< "\n**ppi is: " << **ppi << endl;
对指向指针的指针获取其真正的值,需要进行两次解引用!
[cpp] view plain copy print ?
-
- int main()
- {
- int ival1 = 1024;
- int *pi = &ival1;
-
- int ival2 = 2048;
- pi = &ival2;
- cout << *pi << endl;
-
- *pi = 65536;
- cout << ival2 << endl;
- }
//P106 习题4.14
int main()
{
int ival1 = 1024;
int *pi = &ival1;
int ival2 = 2048;
pi = &ival2;
cout << *pi << endl;
*pi = 65536;
cout << ival2 << endl;
}
[cpp] view plain copy print ?
-
- int main()
- {
- int i = 42,j = 1024;
-
- int *pi = &i,*pj = &j;
- *pj = *pi * *pj;
- *pi *= *pi;
-
- cout << "*pi = " << *pi << ", *pj = " << *pj << endl;
- }