久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 學習資源 > 講師博文 > C語言的內存模型

C語言的內存模型 時間:2024-02-21      來源:華清遠見

1.內存模型

C語言程序中內存大致分為五個區域

 

 1.全局區:bss區(Block Started by Symbol)用來存放程序中未初始化的全局變量的內存區域,data區(data segment)用來存放程序中已初始化的全局變量的內存區域。

 2. 常量區: 常量區存放的是常量,如const修飾的全局變量、字符常量、字符串常量以及整型常量等

3. 代碼區(text segment): 用來存放程序執行代碼的內存區域。

 4. 堆(heap):用來存放進程運行中被動態分配的內存段,它的大小并、不固定,可動態擴張或縮減,需要程序員手動申請和釋放。當調用malloc分配內存時,新分配的內存就被動態添加到堆上,當調用free釋放堆區申請的內存。

 5. 棧(stack):存放程序中的局部變量(但不包括static聲明的變量,static變量放在數據段中)。同時,在函數被調用時,棧用來傳遞參數和返回值。由于棧先進先出特點。所以棧特別方便用來保存/恢復調用現場

 

2.代碼區

 存放 CPU 執行的機器指令。通常代碼區是可共享的(即另外的執行程序可以調用它),使其可共享的目的是對于頻繁被執行的程序,只需要在內存中有一份代碼即可。代碼區通常是只讀的,使其只讀的原因是防止程序意外地修改了它的指令。另外,代碼區還規劃了局部變量的相關信息。

總結:你所寫的所有代碼都會放入到代碼區中,代碼區的特點是共享和只讀。

 

3.全局區

全局區中主要存放的數據有:全局變量、靜態變量(被static修飾的變量)

全局區也叫靜態區

這部分可以細分為data區和bss區

3.1全局變量

定義在函數體外部的是全局變量,未初始化是初值自動為0。

存儲位置:全局區

生命周期:同整個程序共存亡

作用域:整個程序

3.2 static修飾的變量

1)變量的存放位置在全局區(靜態區)

如果靜態變量有初值,存放.data區,沒有初值存放在.bss區域

2)生命周期為整個程序

3)限制作用域

修飾局部變量: 和普通局部變量作用域沒有區別,但是生命周期被延長為整個程序。

也就是在作用函數外有生命但是不能被操作,變成了植物人。

修飾全局變量: 限制在本文件中使用,不能被extern外部引用

4)只初始化一次,初值賦值0

 

舉例對比用static和不用的局部變量在函數中自加操作

#include <stdio.h>

 

void fun()

{

static int a;

int b=0;

a++;

b++;

printf("%4d %4d\n",a,b);

}

 

int main()

{

fun();

fun();

return 0;

}

第一次調用打印:1 1

第二次調用打印:2 1

 因為被static修飾的局部變量只初始化一次,并且會保留上次調用函數結束后的值,因為存放在全局區了,但是作用域不變還是作用域當前函數內。

 

4. 常量

程序運行中不會發生變化的量,存在常量區。

4.1 字符型常量

類型為char。從ascii表中找的的字符都是字符常量,不可以改變。用單引號括起來的就是字符常量,例如'A'。

用’’括起來就是字符常量:

'a' -字符a

'\0' 空字符

' ' 空字符

'\n' 換行

例子:

printf("%c\n",'A');

printf("%c\n",97);

printf("%c\n",'\x42');

printf("%c\n",ca);

可以把字符常量賦值給字符變量

舉例子:

char a = 'A'; 

char b = '\x41';

char c = '\101';

printf("%c\n",97);

printf("%c\n",'\x41');

printf("%c\n",ca);

printf("%c\n",'A'+1);

因為C規定轉義字符'\x41'中\是轉義字符引導符,后跟一個x表示x后面的數字是十六進制表示法,用' '括起來表示一字節ASCII碼。\轉義符后面加數字代表轉義成八進制的字符,后面的數字是八進制。

4.2  字符串常量

用" "括起來的是字符串

"hello" 字符串后面\0

printf("%s\n","hello");

4.3 整型常量

 整型就是類型為整數的常量,包括從負數到零到正數的所有整數。可以用二進制、八進制、十進制和十六進制表示。

例如打印15三種表達形式:

int a=15;//把整型常量賦給整型變量

printf("%d\n",0b1111);//二進制

printf("%d\n",15);//十進制

printf("%d\n",017);//八進制

printf("%d\n",0xF);//十六進制

printf("%d\n",a);

打印出來都是15

4.4 浮點型常量

 浮點型常量就是類型為浮點數的常量,包括從負數到零到正數的所有浮點數。   

float double

4.5 指數常量

用科學計數法表示

3*10^8 ->3e8

2*10^-12 ->2e-12

4.6 標識常量(宏定義)

宏定義:起標識作用

(1)只是單純的進行文本替換,在預處理的時候進行。

(2)遵循標識符的命名規則

(3)一般大寫表示

格式:#define 宏名 常量或表達式

特點:只能單純替換,不要進行手動運算(原樣替換,替換完再計算)

 

5.棧區

 棧區用來存儲函數內部的變量(包括main()函數)。它是一個FILO(First In Last Out,先進后出)的數據結構。每當一個函數聲明一個新的變量它將被壓入棧中。當一個函數運行結束后,這個函數所有在棧中相關的變量都將被刪除,而且它們所占用的內存將會被釋放。這就產生了函數內部的局部變量。棧區是一段非常特殊的內存區,它由CPU自動管理,所以你不必手動申請和釋放內存。

 內存由系統自動申請,在變量生命周期結束時由系統釋放,也就是說,在程序運行的時候,系統有多個任務,就是檢測變量是否該釋放了,簡單來說,就是cpu要抽時間去執行這部分功能。所以,如果這種變量比較多,不加節制的定義的話,那CPU的額外的工作量就會加大,綜合下來,程序的運行效率就會低下。

 

舉例:

char *p = "hello";

 //就可以說p在棧區開辟4字節空間存放字符串常量“hello”的首地址

//“hello“:存放在常量區

char buf[32]="hello";

//可以說buf:在棧區開辟32字節空間,存放"hello"字符串

5.1局部變量

定義在函數體內部的為局部變量

存儲位置:棧區

生命周期:同函數共存亡

作用域:作用域函數體內部

初值:為初始化時初值未隨機值

 

5.2如何避免棧的溢出

局部數組過大。當函數內部的數組過大時,有可能導致堆棧溢出。

 遞歸調用層次太多。遞歸函數在運行時會執行壓棧操作,當壓棧次數太多時,也會導致堆棧溢出。 

指針或數組越界。這種情況最常見,例如進行字符串拷貝,或處理用戶輸入等等。

 解決這類問題的辦法有兩個:一是增大棧空間,二是改用動態分配,使用堆(heap)而不是棧(stack)。

 

6. 堆區

 堆區由我們程序員隨時申請,由我們自己隨時釋放。一般可以用malloc()開辟,用free()釋放。

 

注意:

1)手動開辟堆區空間,要注意內存泄漏:

當指針指向開辟堆區空間后,又對指針重新賦值,則沒有指針指向開辟的堆區空間,就會造成內存泄漏。

2)使用完堆區空間后及時釋放空間

 

 為什么分這么多區域?在實際生活中,這和公司差不多,部門分的細致,工作分發的就有針對性,效率就會高。

 

上一篇:本地存儲和cookie之間的區別是什么?

下一篇:入行嵌入式,哪些技術能力是必須的

戳我查看嵌入式每月就業風云榜

點我了解華清遠見高校學霸學習秘籍

猜你關心企業是如何評價華清學員的

干貨分享
相關新聞
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2024 北京華清遠見科技發展有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部