码迷,mamicode.com
首页 > 编程语言 > 详细

C++(5)指针

时间:2015-08-07 19:48:38      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

指针

序言:

    指针是大多数C程序的重要组成部分,而且在许多C++程序中仍然受到重视!

    与迭代器的异同:指针结构更加通用一些,指针用于指向单个对象,而迭代器只能用于访问容器内的对象。

    由于指针用于低级操作,容易产生与繁琐细节相关的额错误,因此在现代C++程序中,尽量采用vector和迭代器取代一般的数组、指针,采用string类型取代C风格字符串。【P101



正文:

指针(1)

1、每个指针都有一个与之关联的数据类型,该数据类型决定了指针所指向的对象的类型。

  1. /* 
  2. *理解指针声明语句时,请从右往左读! 
  3. *指针的书写有几种书写方式,关键是要选择一种,并坚持使用下去! 
  4. */  
  5.     vector<int> *pvec;  
  6.     int *pi;  
  7.     string *pstr;  
  8.     double *pdou;  

2、指针可能的取值

    1)类型匹配对象的地址:&对象

    2)类型匹配对象的下一个地址:&(对象+1)

    30值常量表达式:NULL,例如,在编译时可以获得0值的整型const对象或字面值常量0.

    4)同类型的另一个有效的指针

  1. //示例  
  2.     int value = 1024;  
  3.     int *pi = 0;  
  4.     int *pi1 = &value;  
  5.     int *pi2 = pi;  
  6.     int *pi3;  
  7.     pi = pi2;  
  8.     pi3 = 0;  
  9.   
  10.     int zero = 0;  
  11.     int *p = zero;      //ERROR  
  12.     const int ZERO = 0;  
  13.     int *pz = ZERO;  
  14.   
  15.     int *pnull = NULL;  
  16.   
  17.     double val = 3.14;  
  18.     int *pv = &val; //ERROR  

3、拒绝使用”野指针”!

    很多运行时错误都源于使用了未初始化的指针。因为他很难被发现。

    如果使用未初始化的指针,会将指针中存放的不确定值视为内存地址,然后操纵该内存地址中保存的内容!

建议:

   1)、除非指向的对象已经存在,否则不要先定义指针。

   2)、在使用之前初始化所有变量,尤其是指针!

  1. //这就是在找死    *_*  
  2.     int *p;  
  3.     *p = 1;  


4void*指针

    void*表明该指针与一地址相关,但不清楚存储在该地址上的对象的类型!

void*指针只支持集中有限的操作:

   1)与另一个指针进行比较

   2)向函数传递void*指针或从函数返回void*指针。

   3)给一个void*指针赋值

千万不要使用void*指针操纵他所指向的对象!!!

  1. double val = 3.14;  
  2. int obj = 3;  
  3.   
  4. double *pval = &val;  
  5. void *pvoid = pval;  
  6. pvoid = &val;  
  7. pvoid = &obj;  

5、指针提供间接操纵其所指对象的功能

    1)解引用操作符返回指定对象的左值,利用这个功能可以修改所指对象的值。

  1. string str("Hello World");  
  2. string *ps = &str;  
  3. *ps = "NiHao ShiJie";  
  4. cout << str << endl;  

    2)也可以修改指针本身:

  1. string str("Hello World");  
  2. string *ps = &str;  
  3. string obj("NiHao ShiJie");  
  4. ps = &obj;  
  5. cout << *ps << endl;  

P105:关键概念:给指针赋值或通过指针进行赋值,值得仔细品读!】


6、指针与引用的差异

   1)定义引用时没有初始化是错误的。

   2)给引用赋值修改的是该引用所关联对象的值。

  1. string str("hello world");  
  2. string &rstr1;      //ERROR  
  3. string &rstr2 = str;  
  4. rstr2 = "nihao shijie";  
  5. cout << str << endl;  

  1. int ival = 1;  
  2. int ival2 = 2;  
  3. int &r1 = ival,&r2 = ival2;  
  4. r1 = r2;  
  5. cout << r1 << endl;  
  6. cout << ival << endl;  

7、指向指针的指针

  1. int ival = 1024;  
  2. int *pi = &ival;  
  3. int **ppi = &pi;  
  4.   
  5. cout << "ival is: " << ival  
  6.      << "\n*pi is: " << *pi  
  7.      << "\n**ppi is: " << **ppi << endl;  

   对指向指针的指针获取其真正的值,需要进行两次解引用!

技术分享

  1. //P106 习题4.14  
  2. int main()  
  3. {  
  4.     int ival1 = 1024;  
  5.     int *pi = &ival1;  
  6.   
  7.     int ival2 = 2048;  
  8.     pi = &ival2;  
  9.     cout << *pi << endl;  
  10.   
  11.     *pi = 65536;  
  12.     cout << ival2 << endl;  
  13. }  

  1. //习题4.16 下列程序段实现什么功能?  
  2. int main()  
  3. {  
  4.     int i = 42,j = 1024;  
  5.   
  6.     int *pi = &i,*pj = &j;  
  7.     *pj = *pi * *pj;  
  8.     *pi *= *pi;  
  9.   
  10.     cout << "*pi = " << *pi << ", *pj = " << *pj << endl;  
  11. }  

指针(2)

1、使用指针访问数组元素

    在C++中,数组与指针关系密切,当在表达式中使用数组名时,会自动将数组名转换成为指向数组的第一个元素的指针!

  1. int ia[] = {0,1,2,3,4,5,5};  
  2. int *ip = ia;  
  3. ip = &ia[4];  

2、指针的算术操作

    1)通常,在指针上加上/减去一个整数n,就获得了一个新的指针,该指针指向原指针的后面/前面的第n个元素。

  1.   int ia[] = {0,1,2,3,4,5,5};  
  2.   int *ip = ia;  
  3. cout << *(ip + 4) << endl;  

    2)只要两个指针指向的是同一数组,或者指向的是该数组的末端的下一个单元,C++还支持这两个指针做减法运算,结果类型为ptrdiff_t

    ptrdiff_tcstddef头文件中定义,该保证足以存放同一数组两个指针间的距离!

  1. ptrdiff_t n = ip2 – ip1;  

3、当使用下标访问数组时,其实就是使用下标访问指针

  1. int ia[] = {0,2,4,6,8};  
  2. int *p = &ia[2];  
  3. cout << p[1] << endl;  
  4. cout << p[-1] << endl;  

4、计算数组超出末端指针

    C++虽然允许计算数组或对象的超出末端的地址,但是不允许对该地址进行解引用操作,而计算数组超出末端位置之后,或数组首地址之前的地址都是不合法的!

  1. const int arr_size = 5;  
  2. int ia[arr_size] = {0,2,4,6,8};  
  3.   
  4. int *p = ia;  
  5. /* 
  6. *对q的解引用将得到无效值,但是对于大多数编译器来说, 
  7. *会把对q解引用的结果视为一个int型数据! 
  8. */  
  9. int *q = p + arr_size;  
  10. for (; p != q; ++p)  
  11. {  
  12.     cout << *p << endl;  
  13. }  

5、输出数组元素

技术分享
  1. const size_t arr_sz = 5;  
  2. int int_arr[arr_sz] = {0,1,2,3,4};  
  3.   
  4. for (int *pbegin = int_arr,*pend = int_arr+arr_sz; pbegin != pend; ++pbegin)  
  5. {  
  6.     cout << *pbegin << endl;  
  7. }  

  1. //P110 4.18  
  2. int main()  
  3. {  
  4.     const size_t arr_sz = 5;  
  5.     int int_arr[arr_sz];  
  6.   
  7.     for (int *p = int_arr,*q = int_arr + arr_sz; p != q; ++p)  
  8.     {  
  9.         *p = 0;  
  10.         cout << *p << endl;  
  11.     }  
  12.   
  13. }  

6、指向const对象的指针

    不允许通过指针来修改其所指的const值。C++强制要求指向const对象的指针也必须具有const特性!

  1. const double *cptr;  

    const限定了cptr指针所指向的对象的类型,而并非cptr本身!

    可以把指向const的指针理解为“自以为指向const的指针”

  1. const double val = 3.14;  
  2. double *pval1 = &val;           //ERROR  
  3. const double *pval2 = &val; //OK  
  4.   
  5. double val = 3.14;  
  6. const double *pval = &val;      //OK  

  1. //示例  
  2. int main()  
  3. {  
  4.     double val = 3.14;  
  5.     const double *pval = &val;  
  6.     *pval = 2;  //ERROR  
  7.   
  8.     double *pval2 = &val;  
  9.     *pval2 = 1;  
  10.   
  11.     cout << *pval << endl;  
  12.     return 0;  
  13. }  

    在实际应用中:指向const对象的指针常用做函数的行参!


7const指针

    const指针---指针本身值不能修改,因此const指针必须在定义时初始化,而且初始化之后再也不能修改。【好专一啊(*^__^*)

    而指针所指对象的值能否修改,则完全取决于该对象的类型。

  1. int errNumb = 0;  
  2. int *const curErr = &errNumb;  
  3. *curErr = 1;        //OK  
  4. cout << errNumb << endl;  
  5.   
  6. int temp = 123;  
  7. curErr = &temp;     //ERROR  
  8. cout << *curErr << endl;  

8、指向const对象的const指针。

    既不能修改指针的值,也不能修改指针所指向对象的值。

  1. //示例  
  2.     const double val = 3.14;  
  3.     const double *const pval = &val;  
  4.   
  5.     double val = 3.14;  
  6.     const double *const pval = &val;  

9、指针和typedef

  1. //考虑下面的ERROR是为什么?  
  2.     typedef string *pstring;  
  3.     const pstring p;        //ERROR  
  4.     const string *q;        //OK  

    答疑:在C++中,const限定符既可以放在类型前面也可以放在类型后,即下面两条语句的作用是完全相同的!

  1. const string s;  
  2. string const s;  

  1. //示例  
  2.     string s;  
  3.     /* 
  4.     *下面的几条定义的作用是一样的! 
  5.     */  
  6.     typedef string *pstring;  
  7.     const pstring p1 = &s;  
  8.     pstring const p2 = &s;  
  9.     const string *p3 = &s;  
  10.     string const *p4 = &s;  

本文借鉴:http://blog.csdn.net/column/details/zjf666.html?&page=5


版权声明:欢迎转载,希望在你转载的同时,添加原文地址,谢谢配合

C++(5)指针

标签:

原文地址:http://blog.csdn.net/u011225629/article/details/47343505

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!