7 記憶體變數

2021-10-18 19:35:59 字數 4321 閱讀 9863

區域性變數也叫auto自動變數,一般情況下**塊{}內部定義的變數都是自動變數,它有如下特點:

#include

void

test()

內部auto

int b =10;

}int

*main*

(void

)//a = 10; //err離開if()的復合語句,a已經不存在

return0;

}

#include

void

fun1()

void

fun2()

int*main*

(void

)

extern全域性變數宣告

extern

int a;

//宣告乙個變數,這個全域性變數在別的檔案中已經定義了,這裡只是宣告,而不是定義。

//宣告不耗費空間,定義會開闢記憶體空間

全域性函式和靜態函式

在c語言中函式預設都是全域性的,使用關鍵字static可以將函式宣告為靜態,函式定義為static就意味著這個函式只能在定義這個函式的檔案中使用,在其他檔案中不能呼叫,即使在其他檔案中宣告這個函式都沒用。

對於不同檔案中的staitc函式名字可以相同。

注意:型別作用域生命週期

auto變數

一對{}內

當前函式

static區域性變數

一對{}內

整個程式執行期

extern變數

整個程式

整個程式執行期

static全域性變數

當前檔案

整個程式執行期

extern函式

整個程式

整個程式執行期

static函式

當前檔案

整個程式執行期

register變數

一對{}內

當前函式

全域性變數

整個程式

整個程式執行期

記憶體分割槽

通過上圖可以得知,在沒有執行程式前,也就是說程式沒有載入到記憶體前,可執行程式內部已經分好3段資訊,分別為

**區(text)

資料區(data)

未初始化資料區(bss)

3個部分(有些人直接把data和bss合起來叫做靜態區或全域性區)。

存放 cpu執行的機器指令。通常**區是可共享的(即另外的執行程式可以呼叫它),使其可共享的目的是對於頻繁被執行的程式,只需要在記憶體中有乙份**即可。**區通常是唯讀的,使其唯讀的原因是防止程式意外地修改了它的指令。另外,**區還規劃了區域性變數的相關資訊。載入的是可執行檔案**段,通常是程式的函式,在記憶體中該部分不可修改

該區包含了在程式中明確 已初始化的全域性變數和靜態變數、文字常量

存入的是全域性未初始化變數和未初始化靜態變數。未初始化資料區的資料在程式開始執行之前被核心初始化為0 或者空(null)。

程式在載入到記憶體前,**區和全域性區(data和bss)的大小就是固定的,程式執行期間不能改變。然後,執行可執行程式,系統把程式載入到記憶體,除了根據可執行程式的資訊分出**區(text)、資料區(data)和未初始化資料區(bss)之外,還額外增加了棧區、堆區。

棧是一種先進後出的記憶體結構,由編譯器自動分配釋放,存放函式的引數值、返回值、區域性變數等。

在程式執行過程中實時載入和釋放,因此,區域性變數的生存週期為申請到釋放該段棧空間。

堆是的容量要遠遠大於棧,但沒有特定順序。用於動態記憶體分配。堆在記憶體中位於bss區和棧區之間。

一般由程式設計師分配和釋放,若程式設計師不釋放,程式結束時由作業系統**。

8.2.2 儲存型別總結

型別作用域生命週期儲存位置

auto變數

一對{}內

當前函式

棧區static區域性變數

一對{}內

整個程式執行期

初始化在data段,未初始化在bss段

extern變數

整個程式

整個程式執行期

初始化在data段,未初始化在bss段

static全域性變數

當前檔案

整個程式執行期

初始化在data段,未初始化在bss段

extern函式

整個程式

整個程式執行期

**區static函式

當前檔案

整個程式執行期

**區register變數

一對{}內

當前函式

執行時儲存在cpu暫存器

字串常量

當前檔案

整個程式執行期

data段

記憶體操作函式

memset()

#include

void

*memset

(void

*s,int c, size_t n)

;功能:將s的記憶體區域的前n個位元組以引數c填入

引數:c:填充的字元,c雖然引數為int,但必須是unsigned

char

, 範圍為0\~

255n:指定需要設定的大小

int a[10]

;*memset*

(a,0

,sizeof

(a))

;*memset*

(a,97

,sizeof

(a))

;int i =0;

for(i =

0; i<

10; i++

)printf

("%c\\n"

, a[i]

);

memcpy()

#include

void

*memcpy

(void

*dest,

const

void

*src, size_t n)

;引數:

n:需要拷貝的位元組數

int a[10]

=;int b[10]

;*memcpy*

(b, a,

sizeof

(a))

;int i =0;

for(i =

0; i <

10; i++

)printf

("%d, "

, b[i]);

printf

("\n");

//memcpy(&a[3], a, 5 \* sizeof(int)); //err, 記憶體重疊

memmove()

memmove()功能用法和memcpy()一樣,區別在於:dest和src所指的記憶體空間重疊時,memmove()仍然能處理,不過執行效率比memcpy()低些。

memcmp()

#include

intmemcmp

(const

void

*s1,

const

void

*s2, size_t n)

;功能:比較s1和s2所指向記憶體區域的前n個位元組

引數:n:需比較的前n個位元組

返回值:

相等:=

0大於:\>

0小於:\<

0int a[10]

=;int b[10]

=;int flag =

memcmp

(a, b,

sizeof

(a))

;printf

("flag = %d\n"

, flag)

;

堆區記憶體分配和釋放

1)malloc()

#include

void

malloc

(size_t size)

;功能:在記憶體的動態儲存區(堆區)中分配一塊長度為size位元組的連續區域,用來存放型別說明符指定的型別。分配的記憶體空間內容不確定,一般使用memset初始化。

引數:size:需要分配記憶體大小(單位:位元組)

返回值:

失敗:null

2)free()

#include

void

free

(void

*ptr)

;引數:

返回值:無

變數記憶體分配

預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中...

指標變數記憶體

1 指標不同於一般變數,存的是變數的位址,在同一架構下位址長度都是相同的 cpu的最大定址記憶體空間 所以不同型別的指標長度都一樣 你輸出的4 4 4,說明指標長度為4位元組 可以記錄的位址範圍是0x00000000 0xffffffff,這個範圍才是指標變數的值 比如說乙個char 1位元組,可以...

變數 記憶體 指標

變數 記憶體 指標 1 乙個變數需要使用一段連續的記憶體存放,記憶體中的二進位制數,就是變數值。相同的二進位制數,根據變數資料型別,表現為不同的變數值 2 可以宣告乙個變數代表這段記憶體,對這個變數賦值就是對這段記憶體寫入資料,在表示式中使用這個變數就是從記憶體中讀取資料 或者說 乙個變數就是特定的...