C/C++ 內存與指針


內存與指針雜談

1、指針

1、數組指針
int(*ptr)[n]

()的優先級高,(*ptr)表示ptr是一個指針,指向一個int類型的一維數組,這個數組的長度為n,也可以說ptr的步長就是n。也就是說執行ptr+1時,ptr要跨過n個int的長度。

2、指針數組
int* p[n]

[]的優先級高,p和[]先結合表示一個數組,int*表示數組中元素的數據類型為int*。

3、復雜一點的指針
int* (*ptr)[n]

ptr是一個指向數組的指針,數組中的每個元素都是指向int的指針。

4、指針運算

指針運算:一個指針ptrold加(減)一個整數n后,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值加或減了n乘sizeof(ptrold所指向的類型)個字節。

5、指針變量和指針所指向的內存空間是兩個不同的概念
6、指針做函數參數,是指針存在的最大意義

*p間接賦值成立的3個條件:

  1. 2個變量(通常一個實參,一個形參)。
  2. 建立關系,實參取地址賦給形參。
  3. *p形參去間接修改實參的值。

引申:函數調用時,用n級指針(形參)修改n-1級指針(實參)的值。

7、一個指針的內容
  1. 指針的類型。

  2. 指針所指向的類型。

  3. 指針的值或者叫指針所指向的內存區或地址

    • 指針的值都是指針本身存儲的數值,這個數值將被編譯器當做一個地址,而不是一般的數值,在32位程序里所有類型的指針的值都是一個32位整數,因為32位程序里內存地址都是32位長。
    • 指針所指向的內存區就是從指針的值所代表的那個內存地址開始,長度為sizeof(指針所指向的類型)的一片內存區。
  4. 指針本身所占據的內存區。在32位平台里,指針本身占據了4個字節的長度。

2、內存

1、內存四區:
  1. 棧區(stack):由編譯器自動分配釋放,存放函數參數值,局部變量的值等。其操作方式類似於數據結構中的棧。

  2. 堆區(heap):一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。注意它與數據結構中的堆是兩個概念。分配方式倒是類似於鏈表。

  3. 數據區:主要包括靜態全局區和常量區,如果站在匯編角度細分的話還可以有很多小的區。

    • 全局區(靜態區)(static):全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,,未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域,程序結束后由系統釋放。
    • 常量區:常量字符串就是放在這里。程序結束后由系統釋放。
  4. 代碼區:存在函數體的二進制代碼。

2、變量

變量的本質:一段連續內存空間的別名。

數據類型的本質:固定大小內存空間的別名。

1、修改變量的方法
  1. 直接修改,int a = 10;
  2. 間接修改,內存有地址編號,拿到地址編號也可以修改內存,外掛的原理就是通過變量內存地址來修改變量值:&a = 1245024; ((int)(1245024)) = 10。
  3. C++中引用。
2、聲明變量的意義
  1. 建立變量符號表。
  2. 變量的數據類型指示了系統分配多少內存空間。
  3. 變量的數據類型指示了系統如何解釋內存空間中的值。
  4. 變量的數據類型確定了變量的取值范圍。
  5. 不同的數據類型有不同的操作。
3、函數內存模型
  • 主調函數可以把堆區、棧區、全局數據內存地址傳遞給被掉函數。
  • 被掉函數只能返回堆區、全局數據。
4、避免產生野指針:
  • 定義指針時,把指針變量賦值為NULL。
  • 釋放內存時,先判斷指針變量是否為NULL。
  • 釋放完內存后,把指針變量重新賦值成NULL

3、void與void*

  1. 如果函數沒有返回值,那么應聲明為void類型。
  2. 如果函數無參數,那么應聲明其參數為void。
  3. 小心使用void指針類型,ANSI標准,不能對void指針進行算法操作。
  4. 如果函數的參數可以是任何無類型指針,那么應聲明其參數為void*。

​ 例:典型的如內存操作函數memcpy,memset的函數原型:

void * memcpy(void *dest, const void *src, size_t len);
void * memset(void *buffer, int c, size_t num);

​ 這體現了內存操作函數的意思,因為它操作的對象僅僅是一片內存,而不論這片內存是什么類型。

  1. void不能代表一個真實的變量。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM