【C++學習教程06】指標
阿新 • • 發佈:2021-01-02
目錄
參考資料
- 範磊C++(第8課)
- VS2015
指標
指標的基本概念
空指標
指標與型別
#include "stdafx.h" #include <stdlib.h> #include <iostream> using namespace std; int main(int argc, const char * argv[]) { double a = 3.14; cout << "double is " << sizeof(a) << "byte" << endl; int b = 6; cout << "int is " << sizeof(b) << "byte" << endl; int *p1 = &b; double *p2 = &a; cout << "double adress is:" << p2 << endl; cout << "int adress is:" << p1 << endl; p1++; p2++; cout << "after move" << endl; cout << "double adress is:" << p2 << endl; cout << "int adress is:" << p1 << endl; system("pause"); return 0; }
結果:
用指標來訪問
#include "stdafx.h" #include <stdlib.h> #include <iostream> using namespace std; int main(int argc, const char * argv[]) { double a = 3.14; cout << "double is " << sizeof(a) << "byte" << endl; int b = 6; cout << "int is " << sizeof(b) << "byte" << endl; int *p1 = &b; double *p2 = &a; cout << "double adress is:" << p2 << endl; cout << "int adress is:" << p1 << endl; cout << "double num is:" << *p2 << endl; cout << "int num is:" << *p1 << endl; p1++; p2++; cout << "after move" << endl; cout << "double adress is:" << p2 << endl; cout << "num is:" << *p2 << endl; cout << "int adress is:" << p1 << endl; cout << "num is:" << *p1 << endl; system("pause"); return 0; }
執行結果:
容易混淆的概念
#include <iostream> using namespace std; int main(int argc, const char * argv[]) { // insert code here... int i=1; int *p=NULL; cout<<"i的值:"<<i<<endl; cout<<"i的地址:"<<&i<<endl; cout<<"p的值:(P所儲存的地址)"<<p<<endl; //cout<<"p所指向地址的值"<<*p<<endl;//訪問零脂針會發生報錯“程式崩潰“ cout<<"p的地址:"<<&p<<endl; p=&i; cout<<"賦值後"<<endl; cout<<"p的值:(P所儲存的地址)"<<p<<endl; cout<<"p所指向地址的值"<<*p<<endl; cout<<"p的地址:"<<&p<<endl; return 0; }
執行後結果:
指標對數值的操作
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
// insert code here...
typedef unsigned short int ut;
cout<<sizeof(ut)<<endl;//2個位元組
ut i=5;
ut *p=NULL;
p=&i;
cout<<"i="<<i<<endl;
cout<<"*p="<<*p<<endl;
cout<<"用脂針來修改存放在i中的資料"<<endl;
*p=90;
cout<<"i="<<i<<endl;
cout<<"*p="<<*p<<endl;
cout<<"用i來修改存放在i中的資料"<<endl;
i=9;
cout<<"i="<<i<<endl;
cout<<"*p="<<*p<<endl;
return 0;
}
輸出結果:
為什麼使用指標
棧和堆
- 棧的資料壽命短但全域性區是在程式結束後才能完全釋放;
- 堆可以由程式設計師決定,自由度高,優於棧和全域性區;
- 堆是通過匿名的方式來儲存資料的,只能通過指標才能訪問到這些匿名的資料。他的安全性是最好的。
以下為詳細解釋:
⬆️合理利用記憶體空間
⬆️ 空間使用靈活
用圖來解釋棧的工作原理:
對於堆來說:
總結:
指標與堆
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
// insert code here...
int *p1;
p1=new int;//new建立堆變數
cout<<p1<<endl;
double *p2=new double;
cout<<p2<<endl;
return 0;
}
輸出:
用指標刪除堆中的空間
記憶體洩露
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
// insert code here...
int *p=new int;//new建立堆變數
*p=36000;
cout<<*p<<endl;
delete p;//釋放記憶體而不刪除指標
cout<<*p<<endl;
p=NULL;
p=new int;
*p=8;
cout<<*p<<endl;
delete p;
cout<<*p<<endl;
//delete p;//反覆delete會導致程式崩潰
return 0;
}
執行結果:
在這裡記憶體並沒有被釋放掉,值得深思。
- VS2015
#include "stdafx.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
int *p = new int;
*p = 23;
delete p;
cout << *p << endl;
system("pause");
return 0;
}
輸出結果:
參考連結: 某論壇.
記憶體洩漏
在堆中建立物件與刪除物件&訪問堆中的成員資料
#include <iostream>
using namespace std;
class Human
{
public:
Human(){cout<<"建構函式執行"<<endl; i=9999;}
~Human(){cout<<"解構函式執行"<<endl;}
int get()const{return i;}
private:
int i;
};
int main(int argc, const char * argv[]) {
Human Jack; //呼叫存放在棧中物件的方法
cout<<Jack.get()<<endl;
cout<<"************"<<endl;
//以下存放在為堆中的物件
Human *p=new Human;//此時已經建立了一個human類的物件!!他是一個匿名的!!!只能用指標找到他。
cout<<p->get()<<endl;
delete p;//刪除這個物件也可以用p
return 0;
}//棧中的物件會在遇到}自動析構掉
this指標
//
#include <iostream>
using namespace std;
class A
{
public:
int get()const{return i;}
void set(int x){i=x; cout<<"this變數儲存的記憶體:\t"<<this<<endl;}
private:
int i;
};
int main(int argc, const char * argv[]) {
A a;
a.set(9);
cout<<"物件a的記憶體地址:\t"<<&a<<endl;
cout<<a.get()<<endl;
A b;
b.set(9);
cout<<"物件b的記憶體地址:\t"<<&b<<endl;
cout<<b.get()<<endl;
return 0;
}
輸出結果:
指標的常見錯誤
#include <iostream>
using namespace std;
int main(int argc, const char * argv[]) {
int *p=new int;
*p=3;
cout<<"將3付給p的地址後,讀取指標p的值:\t"<<*p<<endl;
delete p;
//p=NULL;//用程式崩潰的代價來保證不會引起使用野指標
cout<<"刪除空間後,讀取指標p的值:\t"<<*p<<endl;
long *p1=new long;//p1指向了p所釋放的空間
cout<<"建立新空間後,指標p儲存的地址:\t"<<p<<endl;
*p1=9999;
cout<<"指向新空間的指標P1儲存的地址:\t"<<p<<endl;
*p=23;//其實是將23賦給P1指向的記憶體空間
cout<<"將23付給p的地址後,讀取指標p的值:\t"<<*p<<endl;
cout<<"將23付給p的地址後,讀取指標p1的值:\t"<<*p1<<endl;
return 0;
}
輸出結果:
常量指標和指向常量的指標
常量指標
指向常量的指標
指向常量的常指標
及上面兩個的結合,指標和指向的目標都不能改變。