c++ 取地址運算 指標變數
一、取地址運算子&(記憶體地址)
C++編譯的程式佔用的記憶體分為以下幾個部分:
1.棧區:由編譯器自動分配釋放 ,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。與其它分割槽不同,變數的地址是按照申請順序降序排列的。
2.堆區: 由new指令申請,由delete指令釋放。申請後不釋放可能會造成記憶體資源的浪費。需要指出,對於用指標申請的對記憶體空間,指標本身存入棧,指標指向的空間則儲存在堆中。
3.全域性(靜態)變數區:全域性變數和靜態(由static修飾)變數的儲存是放在一塊的。從程式開始執行時寫入變數值,執行結束前釋放變數。
4.程式程式碼區:用於存放函式體的二進位制程式碼。
另外,還有專門用於存放常量的區域。
下面編寫程式進行測試,證明以上幾種變數分割槽不同。
?
#include
<iostream>
using namespace std;
int x,y,z;
void f1(){};
void f2(){};
void main()
{
int a,b,c;
cout<< "區域性變數的地址:" <<endl;
cout<<&a<< "
" <<&b<< "
" <<&c<<endl; //地址降序
int *m
= new int [3],
*n = new int ,
*l = new int ,
*k = new int ;
cout<< "指標所指向的記憶體的地址:" <<endl;
cout
<< &(*n) << "
" <<
&(*l) << "
" <<
&(*k) << endl; //指標本身存入棧,地址降序
cout<< "指標指向空間的地址:" <<endl;
cout
<<&(m[0])<< "
" <<&(m[1])<<
"
" <<&(m[2])<<
endl;
static int w;
cout<< "全域性(區域性)變數的地址:" <<endl;
cout<<&x<< "
" <<&y<< "
" <<&z<< /*"
"<<&w<<*/ endl;
cout<< "函式程式碼的地址:" <<endl;
cout<<&main<< "
" <<&f1<< "
" <<&f2<<endl;
}
|
程式執行結果:
由程式執行結果可以看出:
1. 四種變數的地址相互相差很大,而本身相差很小,說明被分配在了不同的記憶體空間。
2. 指標和變數的地址是降序排列的,說明被分配在了棧區。
3. 全域性變數和區域性變數的地址相鄰,說明二者被安排在了同一分割槽。
注意:不要把取地址運算子&和應用運算子&搞混,前者放在變數定義中的變數的前面,而後者放在函式原型定義中的型別名後面。
二、指標變數
我們要想更好的利用上面提到的地址,就必須設定一個變數來儲存地址。像用變數來儲存int、float等型別的值一樣,地址也可以用類似的方法儲存。
定義:用來儲存地址的變數叫做指標變數(pointer variable)或者簡稱指標。
如:int* ptr;星號表示指向誰,這個宣告定義了一個指向整型資料的指標變數。這個變數中儲存整型資料的地址:ptr=&variable;
1) 訪問指標指向的變數。
*ptr就表示了ptr中的地址上儲存的值。變數名前面的星號表示間接引用運算子(dereference operator)或者叫做取內容運算子(contents operator)。
2)void指標
指標儲存的變數必須和指標的型別保持一致,如不能將一個float型別的地址賦給一個指向int的指標。