區域性變數也叫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 可以宣告乙個變數代表這段記憶體,對這個變數賦值就是對這段記憶體寫入資料,在表示式中使用這個變數就是從記憶體中讀取資料 或者說 乙個變數就是特定的...