首页 > 代码库 > 范磊 C++ 第8章 指针
范磊 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的值为:" << "\t" << &a << endl ; 63 cout << "a的值为:" << "\t" << a << endl ; 64 cout << "p的值为:" << "\t" << p << endl ; 65 cout << "*p的值为:" << "\t" << *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就是改变了*p106 107 cout << "i = " << i << endl ;108 cout << "*p = " << *p << endl;109 110 cout << "用指针来修改存放在i中的数据...\n" ;111 *p = 90;112 cout << "i = " << i << endl ;113 cout << "*p = " << *p << endl;114 115 cout << "用i来修改存放在i中的数据...\n" ;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:" << "\t" << i <<endl ;137 cout << "&i:" << "\t" << &i << endl ;138 cout << "j:" << "\t" << j <<endl ;139 cout << "&j:" << "\t" << &j << endl ;140 cout << "p:" << "\t" << p <<endl ;141 cout << "*p:" << "\t" << *p << endl ; //*p获得就是i的内存里面的内容.142 143 p = &j; //p存放着的是j的地址,所以p知道j里面有什么东西.144 145 cout << "更换地址后...\n" ;146 cout << "i:" << "\t" << i <<endl ;147 cout << "&i:" << "\t" << &i << endl ;148 cout << "j:" << "\t" << j <<endl ;149 cout << "&j:" << "\t" << &j << endl ;150 cout << "p:" << "\t" << p <<endl ;151 cout << "*p:" << "\t" << *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 A205 {206 private:207 int i;208 public:209 A()210 {211 cout << "构造函数执行中...\n" ;212 i = 0x999;213 }214 ~A()215 {216 cout << "析构造函数执行中...\n" ;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 A1237 {238 private:239 int i;240 public:241 int get() const242 {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 A2263 {264 private:265 int* i;266 public:267 A2();268 ~A2();269 int get() const270 {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 << "构造函数执行中... \n" ;290 i = new int(999) ;291 }292 A2::~A2()293 {294 cout << "析构函数执行中... \n" ;295 delete i ;296 }297 298 299 //-------------------------------------------------300 //8.4.6 对象在栈与堆中的不同301 class A3302 {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 << "构造函数执行中... \n" ;328 i = new int(999) ;329 }330 A3::~A3()331 {332 cout << "析构函数执行中... \n" ;333 delete i ;334 }335 336 337 //-------------------------------------------------338 //8.5 this指针339 //this指针记录每个对象的内存地址,然后通过间接引用符 -> 访问该对象的成员.340 class A4341 {342 private:343 int i;344 public:345 int get() const346 {347 return i;348 }349 void set(int x)350 {351 this-> i;352 i = x;353 cout << "this变量保存的内存地址: \t" << this << endl ;354 }355 };356 357 void fun14()358 {359 A4 a;360 a.set(99);361 cout << "对象a的内存地址: \t\t" << &a << endl;362 cout << a.get() << endl;363 364 A4 b;365 b.set(9999);366 cout << "对象b的内存地址: \t\t" << &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读取的值: \t" << *p << endl ;384 delete p;385 cout << "删除空间后,指针p读取的值: \t\t" << *p << endl ;386 387 long* p1;388 p1 = new long;389 cout << "创建新空间后,指针p中的保存地址: \t " << p << endl;390 *p1 = 99999;391 cout << "指向新空间的指针p1保存的地址: \t\t" << p1 << endl;392 *p = 23;393 cout << "将23赋值给p的地址后,指针p读取的值: \t" << *p << endl;394 cout << "将23赋值给p的地址后,指针p1读取的值: \t" << *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保存的空间地址为: \t" << 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 << "赋值后...\n" ;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的内存地址. \n" ;462 }463 else464 {465 cout << "p1大于p的内存地址. \n" ;466 }467 468 }469 470 471 //-------------------------------------------------472 //8.8.1 常量指针473 //常量指针:指针的值不能改变. 这个指针是一个常量,是一个不变量.474 class A5475 {476 private:477 int i;478 public:479 int get() const480 {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 extern497 //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 A6509 {510 private:511 int i;512 public:513 int get() const514 {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 A7535 {536 private:537 int i;538 public:539 int get() const540 {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 extern551 //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 }
范磊 C++ 第8章 指针
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。