• 范磊 C++ 第8章 指针


      1 // section_8.cpp : Defines the entry point for the console application.
      2 //范磊 C++ 第8章 指针
      3 //指针本质也是一个变量,只是这个变量存放的数据比较特殊,怎么特殊?
      4 //里面存放的是别人家的地址. 其他变量的内存编号而已.
      5 
      6 #include "stdafx.h"
      7 #include "iostream"
      8 
      9 using namespace std;
     10 
     11 //--------------------------------------------------
     12 //8.1 地址
     13 //地址,可以理解为:每一个内存都有自己的空间编号,这个编号称为"地址"
     14 void fun1()
     15 {
     16     int i;
     17 
     18     i = 1;
     19     cout << &i << endl ;    // &是取地址符号,在变量名字前面 +&,表示获得这个变量 i 的内存编号.
     20 }                            //c++直接回输出一个16进制的数字.不向c那样,前面要 %x 表示16进制.
     21 
     22 
     23 //--------------------------------------------------
     24 //8.2 用指针来保存地址
     25 //用一个特别的变量(指针)去存放其他变量的内存地址.
     26 void fun2()
     27 {
     28     int a;
     29     int* p;
     30 
     31     p = &a;
     32     cout << &a << endl;        //打印出变量a的地址 0018ffe0
     33     cout << p << endl;        //打印出变量a的地址 0018ffe0,所以说指针p 保存了变量a的地址.
     34 }
     35 
     36 
     37 //-------------------------------------------------
     38 //8.21 空指针(好像不是很适合叫空指针)
     39 //当我们定义了一个指针后,如果不初始化,这个"迷途指针"里面的内容是一个随机数
     40 //所以我们要给指针赋值,赋个0给他.
     41 void fun3()
     42 {
     43     int* p;
     44     p = 0;
     45     cout << "p: " << p << endl;
     46 }
     47 
     48 
     49 //-------------------------------------------------
     50 //8.2.3 用指针来访问值
     51 // 符号 * 称为指针运算符. 意思是取出指针里面的地址的内容.
     52 //例如 指针p = 1234567 ,*p 的意思就是 取出内存地址单元编号为1234567 里面的内容.
     53 //汇编理解:  mov Exr, ds:[1234567]
     54 void fun4()
     55 {
     56     int a;
     57     int* p;
     58 
     59     a = 1;
     60     p = &a;
     61 
     62     cout << "&a的值为:" << "	" << &a << endl ;
     63     cout << "a的值为:" << "	"  << a << endl ;
     64     cout << "p的值为:" << "	"  << p << endl ;
     65     cout << "*p的值为:" << "	"  << *p << endl;
     66 }
     67 //打印的结构是 a == 1 , *p == 1.  
     68 
     69 
     70 //-------------------------------------------------
     71 //8.2.4 指针地址,指针保存的地址和该地址的值
     72 //指针的地址: 因为指针的本质其实也是一个变量,这个变量肯定占用内存空间,肯定有内存单元编号
     73 //指针保存的地址:指针里面存放的数据,这个数据不是一般普通数据,这个数据是其他内存的单元编号(地址).
     74 //该地址的值:可以通过指针里面的地址,按照地址去找到那个内存,看看里面放的是什么数据.
     75 void fun5()
     76 {
     77     int i;
     78     int* p;
     79 
     80     cout << "i的地址为: " << &i << endl ;
     81     cout << "p的值为: " << p << endl ;        //此时p还没赋值,属于一个"迷途指针"
     82     cout << "p的地址为: " << &p << endl ;    //p虽然是迷途指针,但前面已经进行int* p 声明了.
     83                                             //所以p也有自己的地址.
     84     i = 3;
     85     cout << "i赋值后的地址为: " << &i << endl ;
     86 
     87     p = &i;                                        //把 i 的地址告诉了p.
     88     cout << "p赋值后的值为: " << p << endl ;    //p里面存放就是i的地址.
     89     cout << "p赋值后的地址为: " << &p << endl ;
     90 
     91 }
     92 
     93 
     94 //-------------------------------------------------
     95 //8.2.5 指针对数值的操作
     96 //可以通过 * 号,间接访问或读取指针的保存的地址里面的数据
     97 typedef unsigned short int ut;    //因为unsigned short int 这个类型名字很长,另外起了个小名 ut
     98 void fun6()
     99 {
    100     //cout << sizeof(ut) << endl ;    //测试一下ut是占用了多大内存空间
    101     ut i;
    102     ut* p = 0;
    103     
    104     i = 5;
    105     p = &i;        //自从当执行p = &i以后, 改变了*p就是改变了i,改变了i就是改变了*p
    106 
    107     cout << "i = " << i << endl ;
    108     cout << "*p = " << *p << endl;
    109 
    110     cout << "用指针来修改存放在i中的数据...
    "  ;
    111     *p = 90;
    112     cout << "i = " << i << endl ;
    113     cout << "*p = " << *p << endl;
    114 
    115     cout << "用i来修改存放在i中的数据...
    "  ;
    116     i = 9;
    117     cout << "i = " << i << endl ;
    118     cout << "*p = " << *p << endl;
    119 }
    120 
    121 
    122 //-------------------------------------------------
    123 //8.2.6 更换指针保存的地址
    124 //平时,小明口袋里放着怎么去小芳家的地图,所以他只知道小芳家有什么东西.
    125 //今天他口袋了放的是去小李家的地图,所以他只知道小李家有什么东西.不知道小芳家有什么东西.
    126 void fun7()
    127 {
    128     int i;
    129     int j;
    130     int* p;
    131     
    132     i = 10;
    133     j = 20;
    134     p = &i;        //p存放着的是i的地址,所以p知道i里面有什么东西.
    135 
    136     cout << "i:" << "	" << i <<endl ;
    137     cout << "&i:" << "	" << &i << endl ;
    138     cout << "j:" << "	" << j <<endl ;
    139     cout << "&j:" << "	" << &j << endl ;
    140     cout << "p:" << "	" << p <<endl ;
    141     cout << "*p:" << "	" << *p << endl ;    //*p获得就是i的内存里面的内容.
    142 
    143     p = &j;        //p存放着的是j的地址,所以p知道j里面有什么东西.
    144 
    145     cout << "更换地址后...
    " ;
    146     cout << "i:" << "	" << i <<endl ;
    147     cout << "&i:" << "	" << &i << endl ;
    148     cout << "j:" << "	" << j <<endl ;
    149     cout << "&j:" << "	" << &j << endl ;
    150     cout << "p:" << "	" << p <<endl ;
    151     cout << "*p:" << "	" << *p << endl ;    //*p获得就是j的内存里面的内容.
    152 }
    153 
    154 
    155 //-------------------------------------------------
    156 //8.3.2 用指针创建堆中空间
    157 //什么叫堆?(3个特点):1.堆是一大堆不连续的内存区域;2.堆生存的时间要比栈长;3.堆要手动申请,手动释放;
    158 //C++中,用关键字 new 创建一个堆,并分配内存.
    159 void fun8()
    160 {
    161     int* p;
    162     p = new int; //这里如果直接写 new int 是不会报错的,但不能运行.为什么?
    163                  //堆是一大堆大小不连续的内存区域,在系统中由链表串接起来使用,堆中的每个内存单元都是
    164                  //匿名的,因此必须先在对堆中申请一个内存单元地址,然后保存在一个指针中,只有使用该指针
    165                  //才能访问到该内存单元的数据.
    166     *p = 4;
    167     cout << *p << endl ;            //堆的内容
    168     cout << "p: " << p << endl;        //堆的地址
    169     cout << "&p: " << &p << endl;   
    170 }
    171 //函数的框架是esp-48h,多了的8个字节是怎么来?
    172 //int* p 这里多了4个字节. 另外是 new int 这里也多了4个字节.
    173 
    174 
    175 //-------------------------------------------------
    176 //8.3.3 用指针删除堆中空间(成也萧何败也萧何)
    177 //C++中,用关键字 delete 释放堆的空间.否则的话,会造成内存泄露.
    178 //什么叫内存泄露?
    179 //堆的地址一定是在指针里面的,只有指针才知道怎么去找到堆.如果指针丢了,那么其他任何途径都找不到这个堆了.
    180 //一个宝藏地图只有小明知道,但是小明死了,其他人永远也别想找到宝藏的位置了.
    181 void fun9()
    182 {
    183     int* p;
    184     p = new int;
    185     *p = 3600;
    186 
    187     cout << *p << endl ;
    188 
    189     delete p;
    190     cout << *p << endl ;    //p已经变成了迷途指针了.
    191 
    192     p = 0;
    193     p = new int;
    194     *p = 8;
    195     cout << *p << endl ;
    196     
    197     delete p;
    198     cout << *p << endl ;
    199 }
    200 
    201 
    202 //-------------------------------------------------
    203 //8.4.2 在堆中删除对象
    204 class A
    205 {
    206 private:
    207     int i;
    208 public:
    209     A()
    210     {
    211         cout << "构造函数执行中...
    " ;
    212         i = 0x999;
    213     }
    214     ~A()
    215     {
    216         cout << "析构造函数执行中...
    " ;
    217     }
    218     int get()
    219     {
    220         return i;
    221     }
    222 };
    223 void fun10()
    224 {
    225     A* p;
    226     p = new A;
    227     delete p;
    228 }
    229 //函数框架不明白.
    230 
    231 
    232 
    233 //-------------------------------------------------
    234 //8.4.4 访问对中的数据成员
    235 //必须要通过指针才能访问堆.
    236 class A1
    237 {
    238 private:
    239     int i;
    240 public:
    241     int get() const
    242     {
    243         return i;
    244     }
    245     void set(int x)
    246     {
    247         i = x;
    248     }
    249 };
    250 void fun11()
    251 {
    252     A1* a;
    253     a = new A1;
    254     a->set(66);        //通过 -> 符号来访问堆.
    255     cout << a->get() << endl ;
    256     delete a;
    257 }
    258 
    259 
    260 //-------------------------------------------------
    261 //8.4.5 在构造函数中开辟内存空间
    262 class A2
    263 {
    264 private:
    265     int* i;
    266 public:
    267     A2();
    268     ~A2();
    269     int get() const
    270     {
    271         return *i;
    272     }
    273     void set(int x)
    274     {
    275         *i = x;
    276     }
    277 };
    278 void fun12()
    279 {
    280     A2* p;
    281     p = new A2;
    282     cout << p->get() << endl ;
    283     p->set(0) ;
    284     cout << p->get() << endl ;
    285     delete p ;
    286 }
    287 A2::A2()
    288 {
    289     cout << "构造函数执行中... 
    " ;
    290     i = new int(999) ;
    291 }
    292 A2::~A2()
    293 {
    294     cout << "析构函数执行中... 
    " ;
    295     delete i ;
    296 }
    297 
    298 
    299 //-------------------------------------------------
    300 //8.4.6 对象在栈与堆中的不同
    301 class A3
    302 {
    303 private:
    304     int* i;
    305 public:
    306     A3();
    307     ~A3();
    308     int get() const    //const加在这里什么意思?
    309     {
    310         return *i;
    311     }
    312     void set(int x)
    313     {
    314         *i = x;
    315     }
    316 };
    317 void fun13()
    318 {
    319     A3* p;
    320     p = new A3;        //开辟新的内存空间,空间的首地址放到了p里面.?
    321     cout << p->get() << endl ;
    322     p->set(123);
    323     cout << p->get() << endl ; 
    324 }
    325 A3::A3()
    326 {
    327     cout << "构造函数执行中... 
    " ;
    328     i = new int(999) ;
    329 }
    330 A3::~A3()
    331 {
    332     cout << "析构函数执行中... 
    " ;
    333     delete i ;
    334 }
    335 
    336 
    337 //-------------------------------------------------
    338 //8.5 this指针
    339 //this指针记录每个对象的内存地址,然后通过间接引用符 -> 访问该对象的成员.
    340 class A4
    341 {
    342 private:
    343     int i;
    344 public:
    345     int get() const
    346     {
    347         return i;
    348     }
    349     void set(int x)
    350     {
    351         this-> i;
    352         i = x;
    353         cout << "this变量保存的内存地址: 	" << this << endl ;
    354     }
    355 };
    356 
    357 void fun14()
    358 {
    359     A4 a;
    360     a.set(99);
    361     cout << "对象a的内存地址: 		" << &a << endl;
    362     cout << a.get() << endl;
    363 
    364     A4 b;
    365     b.set(9999);
    366     cout << "对象b的内存地址: 		" << &b << endl;
    367     cout << b.get() << endl;
    368 
    369 }
    370 
    371 
    372 
    373 //-------------------------------------------------
    374 //8.6 指针的常见错误
    375 //删除一个指针后,一定要将该指针设定为赋值为0.因为删除该指针只会释放它指向的内存空间,不会删除指针.
    376 //因此这个指针还存在,并且仍会指向原来的内存空间,这时如果再次尝试使用该指针,将导致程序出错.
    377 void fun15()
    378 {
    379     int* p;
    380     p = new int;
    381     *p =3;
    382 
    383     cout << "将3赋值给p的地址后,指针p读取的值: 	" << *p << endl ;
    384     delete p;
    385     cout << "删除空间后,指针p读取的值: 		" << *p << endl ;
    386 
    387     long* p1;
    388     p1 = new long;
    389     cout << "创建新空间后,指针p中的保存地址: 	 " << p << endl;
    390     *p1 = 99999;
    391     cout << "指向新空间的指针p1保存的地址: 		" << p1 << endl;
    392     *p = 23;
    393     cout << "将23赋值给p的地址后,指针p读取的值: 	" << *p << endl;
    394     cout << "将23赋值给p的地址后,指针p1读取的值: 	" << *p1 << endl;
    395     delete p1;
    396 }
    397 
    398 
    399 //-------------------------------------------------
    400 //8.7.1 指针的加减运算
    401 void fun16()
    402 {
    403     int* p;
    404     p = new int;
    405     cout << "指针p保存的空间地址为: 	" << p << endl ;
    406     p++;
    407     cout << "自加后,指针p保存的空间地址为: " << p << endl ;
    408     p--;
    409     cout << "自减后,指针p保存的空间地址为: " << p << endl ;
    410     p -= 2;
    411     cout << "减2后,指针p保存的空间地址为: " << p << endl ;    
    412 }
    413 
    414 
    415 
    416 //-------------------------------------------------
    417 //8.7.2 指针的赋值运算
    418 void fun17()
    419 {
    420     int* p;
    421     p = new int;
    422     cout << "p:" << p << endl;
    423     int* p1;
    424     p1 = new int;
    425     cout << "p1:" << p1 << endl;
    426     p = p1;
    427     cout << "赋值后...
    " ;
    428     cout << "p:" << p << endl;
    429 }
    430 
    431 
    432 //-------------------------------------------------
    433 //8.7.3 指针的相减运算
    434 void fun18()
    435 {
    436     int* p;
    437     p = new int;
    438     cout << "p:" << p << endl;
    439     int* p1;
    440     p1 = new int;
    441     cout << "p1:" << p1 << endl ;
    442     *p = p - p1;    //两个地址相减,得出的是一个数字.
    443     cout << "两个内存的地址差: " ;
    444     cout << *p << endl;
    445 }
    446 
    447 
    448 
    449 //-------------------------------------------------
    450 //8.7.4 指针的比较运算
    451 void fun19()
    452 {
    453     int* p;
    454     p = new int;
    455     cout << "p:" << p << endl ;
    456     int *p1;
    457     p1 = new int;
    458     cout << "p1:" << p1 << endl ;
    459     if(p > p1)
    460     {
    461         cout << "p大于p1的内存地址. 
    " ;
    462     }
    463     else
    464     {
    465         cout << "p1大于p的内存地址. 
    " ;
    466     }
    467 
    468 }
    469 
    470 
    471 //-------------------------------------------------
    472 //8.8.1 常量指针
    473 //常量指针:指针的值不能改变. 这个指针是一个常量,是一个不变量.
    474 class A5
    475 {
    476 private:
    477     int i;
    478 public:
    479     int get() const
    480     {
    481         return i;
    482     }
    483     void set(int x)
    484     {
    485         i = x;
    486     }
    487 };
    488 void fun20()
    489 {
    490     A5* p;
    491     p = new A5;
    492     cout << "p:" << p << endl ;
    493     p += 1;
    494     cout << "p:" << p << endl ;
    495 
    496     A5* const p1 = new A5;    //error C2734: 'p1' : const object must be initialized if not extern
    497     //p1 = new A5;   不能再这样写了.报上面的错.
    498     //p1 += 1;        //因为前面const p1说明了p1是不能改变的.如果非要执行这句的话,编译出错.
    499     p1->set(6);
    500     cout << p1->get() << endl;
    501 
    502 }
    503 
    504 
    505 
    506 //-------------------------------------------------
    507 //8.8.2 指向常量的指针
    508 class A6
    509 {
    510 private:
    511     int i;
    512 public:
    513     int get() const
    514     {
    515         return i;
    516     }
    517     void set(int x)
    518     {
    519         i = x;
    520     }
    521 };
    522 void fun21()
    523 {
    524     const A6* p;    // const(A6* p) ,说明这个(A6* p)的值是一个常量.
    525     p = new A6;
    526     p += 1;            
    527     //p->set(11);
    528     cout << p->get() << endl ;
    529 }
    530 
    531 
    532 //-------------------------------------------------
    533 //8.8.3 指向常量的常指针
    534 class A7
    535 {
    536 private:
    537     int i;
    538 public:
    539     int get() const
    540     {
    541         return i;
    542     }
    543     void set(int x)
    544     {
    545         i = x;
    546     }
    547 };
    548 void fun22()
    549 {
    550     const A7*  const p = new A7;      //'p' : const object must be initialized if not extern
    551     //p = new A7;          //不能这样写了.
    552     //p += 1;              //因为指针是常量,所以这里要进行指针改变,不能通过编译.
    553     //p->set(11);          //因为指针指向的内容页是常量,所以这里要进行修改,也不能通过编译.
    554     cout << p->get() << endl ;
    555 }
    556 
    557 
    558 //////////////////////第8章主要例子完毕///////////////////////
    559 
    560 
    561 int main(int argc, char* argv[])
    562 {
    563     //fun1();        //8.1 地址
    564     //fun2();        //8.2 用指针来保存地址
    565     //fun3();        //8.2.1 空指针
    566     //fun4();        //8.2.3 用指针来访问值
    567     //fun5();        //8.2.4 指针地址,指针保存的地址和该地址的值
    568     //fun6();        //8.2.5 指针对数值的操作
    569     //fun7();        //8.2.6 更换指针保存的地址
    570     //fun8();        //8.3.2 用指针创建堆中空间
    571     //fun9();        //8.3.3 用指针删除堆中空间
    572     //fun10();        //8.4.2 在堆中删除对象
    573     //fun11();        //8.4.4 访问对中的数据成员
    574     //fun12();        //8.4.5 在构造函数中开辟内存空间(不明白)
    575     //fun13();        //8.4.6 对象在栈与堆中的不同(不明白)
    576     //fun14();        //8.5 this指针                
    577     //fun15();        //8.6 指针的常见错误
    578     //fun16();        //8.7.1 指针的加减运算
    579     //fun17();        //8.7.2 指针的赋值运算
    580     //fun18();        //8.7.3 指针的相减运算
    581     //fun19();        //8.7.4 指针的比较运算
    582     //fun20();        //8.8.1 常量指针
    583     //fun21();        //8.8.2 指向常量的指针
    584     //fun22();        //8.8.3 指向常量的常指针
    585 
    586     return 0;
    587 }
  • 相关阅读:
    python urllib urllib2
    python 标准库获取网络信息
    dell N1500 安全配置
    python jinjia2模板使用
    flask-admin
    github使用
    python中文处理
    C++输入和输出中进制问题
    hdu1708(C++)
    hdu1017(C++)
  • 原文地址:https://www.cnblogs.com/adalovelace/p/4018101.html
Copyright © 2020-2023  润新知