程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 指針和自由存儲空間,指針自由存儲空間

指針和自由存儲空間,指針自由存儲空間

編輯:C++入門知識

指針和自由存儲空間,指針自由存儲空間


  指針是一個變量,其存儲的是值的地址,而不是值本身。

  對變量應用地址運算符(&),就可以獲得它的位置。

  使用常規變量時,值是指定的量,而地址為派生量。下面來看看指針策略,它是C++內存管理編程理念的核心。


 

  指針與C++基本原理

  面向對象編程與傳統的過程性編程的區別在於,OPP強調的是在運行階段(而不是編譯階段)進行決策。運行階段指的是程序正在運行時,編譯階段指的是編譯器將程序組合起來時。

  運行階段決策提供了靈活性,可以根據當時的情況進行調整。在運行階段做決策並非OPP獨有的,但使用C++編寫這樣的代碼比使用C語言簡單。


 

  處理存儲數據的新策略剛好相反,將地址視為指定的量,而將值視為派生量。一種特殊類型的變量——指針用於存儲值得地址。因此,指針名表示的是地址。*運算符被稱為間接值或解除引用運算符,將其應用於指針,可以得到該地址處存儲的值(這和乘法使用的符號相同;C++根據上下文來確定所指的是乘法還是解除引用)。例如,假設manly是一個指針,則manly表示的是一個地址,而*manly表示存儲在該地址處的值。*manly與常規int變量等效。

 

聲明和初始化指針

  指針聲明必須指定指針指向的數據的類型。

int*P_updates

  這表示,*p_updates的類型為int。由於*運算符被用於指針,因此p_updates變量本身必須是指針。我們說p_updates指向int類型,我們還說p_updates的類型是指向int的指針,或int*。可以這樣說,p_updates是指針(地址),而*p_updates是int,而不是指針。

int *ptr;//傳統上,C程序員使用這種格式。這強調*ptr是一個int類型的值。
int* ptr;//很多C++程序員使用這種格式。這強調的是:int*是一種類型——指向int的指針。
/*下面的聲明創建一個指針(p1)和一個int變量(p2)*/
int* p1,p2;
/*對每個指針變量名,都需要使用一個*
在C++中,int*是一種復合類型,是指向int的指針。
*/

   可以在聲明語句中初始化指針。在這種情況下,被初始化的是指針,而不是它指向的值。也就是說,下面的語句將pt(而不是*pt)的值設置為&higgens:

int higgens=5;
int* pt=&higgens;

指針的危險

  極其重要的一點是:在C++創建指針時,計算機將反派用來存儲地址的內存,但不會分配用來存儲指針所指向的數據的內存。為數據提供空間是一個獨立的步驟,忽略這一步無疑是自找麻煩,如下所示:

long* fellow;
*fellow=223323;

  fellow確實是一個指針,但它指向哪裡呢?上述代碼沒有將地址賦給fellow。由於fellow沒有被初始化,它可能有任何值。不管值是什麼,程序都將它解釋為存儲223323的地址。如果fellow的值碰巧是1200,計算機將把數據放在地址,計算機將把數據放在地址1200上,即使這恰巧是程序代碼的地址。fellow指向的地方很可能並不是所要存儲223323的地方。這種錯誤可能會導致一些最隱匿、最難以跟蹤的bug。

  一定要在對指針應用解除引用運算符(*)之前,將指針初始化為一個確定的、適當的地址。這是關於使用指針的金科玉律。

指針和數字

  不能簡單地將整數賦給指針:

int* pt;
pt=0xB8000000;

  在這裡,左邊是指向int的指針,因此可以把它賦給地址,但右邊是一個整數。您可能知道,0xB8000000是老式計算機系統中視頻內存的組合段偏移地址,但這條語句並沒有告訴程序,這個數字就是一個地址。在C99標准發布之前,C語言允許這樣賦值。但C++在類型一致方面的要求更嚴格,編譯器將顯示一條錯誤信息,通告類型不匹配。要將數字值作為地址來使用,應通過強制類型轉換將數字轉換為適當的地址類型:

int* pt;
pt=(int*)0xB8000000;

  使用new來分配內存

 

/*use_new.cpp*/
#include<iostream>
int main()
{
    using namespace std;
    int nights = 1001;
    /*使用new為int類型的數據對象分配內存。這是在程序運行時進行的。
    有了指針,就可以像使用變量那樣使用*pt。將值賦給*pt,從而將這些值賦給新的數據對象。
    new分配的內存塊通常與常規變量聲明分配的內存塊不同。變量nights和pd的值都儲存在被稱為棧(stack)的內存區域中,而new從被稱為堆(heap)或自由存儲區(free store)的內存區域分配內存*/
    int* pt = new int;
    *pt = 1001;

    cout << "nights 的值=";
    cout << nights << ":地址" << &nights << endl;
    cout << "整型";
    cout << "值=" << *pt << ":地址=" << pt << endl;
    double*pd = new double;
    *pd = 10000001.1;

    cout << "浮點型";
    cout << "值=" << *pd << ":地址=" << pd << endl;
    cout << "指針pd的地址:" << &pd << endl;
    cout << "pt的大小=" << sizeof(pt);
    cout << "*pt的大小=" << sizeof(*pt) << endl;
    cout << "pd的大小=" << sizeof pd;
    cout << ":*pd的大小=" << sizeof(*pd) << endl;
    cin.get();
    cin.get();
    return 0;
}

 

使用new來創建動態數組

/*arranew.cpp*/
#include<iostream>
int main()
{
    using namespace std;
    /*為數組分配內存的通用格式:type_name* pointer_name=new name[num_elements];*/
    double* p3 = new double[3];
    p3[0] = 0.2;
    p3[1] = 0.5;
    p3[2] = 0.8;
    cout << "p3[1] is" << p3[1] << ".\n";
    /*不能修改數組名的值。但指針是變量,因此可以修改它的值。
    p3加1導致它指向第2個元素而不是第1個*/
    p3 = p3 + 1;
    cout << "Now p3[0] is" << p3[0] << "and";
    cout << "p3[1] is" << p3[1] << ".\n";
    /*p3減1後,指針將指向原來的值,這樣程序便可以給delete[]提供正確的地址。*/
    p3 = p3 - 1;
    /*方括號告訴程序,應釋放整個數組,而不僅僅是指針指向的元素*/
    delete[]p3;

    cin.get();
    cin.get();
    return 0;
}

輸出

p3[1] is 0.5.
Now p3[0] is 0.5 and p3[1] is 0.8.

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved