中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言內存這個話題

發布時間:2020-07-14 23:29:08 來源:網絡 閱讀:948 作者:YPB39155 欄目:編程語言

1、計算機為什么需要編程?編程已經編了這么多年,已經寫了很多程序,為什么還需要編程?

因為我們需要(希望)通過程序,達到一定的目的或者得到一定的結果。

編寫新的程序是為了得到不同的結果。

計算機程序 = 代碼 + 數據 (經過運行后得到一個結果,就是計算機程序運行的結果)

從宏觀上理解:代碼就是動作,就是加工數據指令。

 數據就是數字,就是我們希望被代碼加工的數字。

 

結論:計算機編程不外乎兩種目的,結果或者過程;即加工數據得到結果。

可以用函數來類比:比如函數的形參就是待加工的數據(有可能函數內還需要一些臨時數據,就是局部變量),函數體就是代碼,函數體的執行就是加工過程,函數的返回值就是結果


2、程序就是有很多個函數組成的,函數是程序的重要組成部分。

程序需要運行才會得到我們需要的結果或者過程。

程序的本質就是函數,函數的本質是加工數據的動作。


3、馮諾依曼結構和哈佛結構

馮諾依曼結構是:數據和代碼放在一起。

哈佛結構是:數據和代碼分開存在。

什么是代碼:函數

什么是數據:全局變量、局部變量

譬如在S5PV210中運行的linux系統上,運行應用程序時:這時候所有的應用程序的代碼和數據都在DRAM,所以這種結構就是馮諾依曼結構;

在單片機中,我們把程序代碼燒寫到Flash(內置NorFlash,flash是只讀的)中,然后程序在Flash中原地運行,程序中所涉及到的數據(全局變量、局部變量)不能放在Flash中,必須放在RAM(SRAM)中。這種就叫哈佛結構。


4、動態內存DRAM和靜態內存SRAM

靜態內存是系統分給一定的內存后不再變化了,也就是在程序一開始運行就分配內存(不需要初始化就可以直接使用的),直到程序結束了,內存才被釋放;

動態內存是系統開始不分配內存,運行時根據需要分配(需要先進行初始化才能進行使用),也就是在程序調用在程序中定義的函數時才被分配,函數調用結束了,內存就釋放


5、為什么需要內存?

總結:內存是用來存儲可變數據的,數據在程序中表現為全局變量或局部變量等(在gcc中,常量也是存儲在內存中;但在大部分單片機中,常量存儲在flash中的,也就是代碼段中)

很多編程的關鍵都是為了內存,譬如數據結構和算法

數據結構是研究數據如何組織的,而數據是放在內存中的。

算法是研究如何更優秀的更有效的加工數據,也離不開內存。衡量一個算法優秀與否,絕大部分與這個算法所占的內存大小有關

6、如何管理內存?

內存是程序的一種資源,不能過于或隨便的浪費。所以管理內存對程序來說是一種很重要的技術。

在沒有操作系統(也就是裸機程序)中,程序需要直接操作內存,編程者需要自己計算內存的使用和安排,如果不小心把內存用錯了,后果需要自己承擔。

從語言角度來講:不同的語言提供了不同的內存操作接口;

譬如匯編:根本沒有任何內存管理,內存管理全靠程序員自己,匯編中操作內存時直接使用內存地址(如0xd0020010),非常麻煩。

譬如C語言:C語言中編譯器幫我們管理直接內存地址,我們都是通過編譯器提供的變量名等來訪問內存的。在操作系統中,如果需要大塊內存,可以通過API(malloc分配內存free釋放內存)來訪問系統內存;在裸機系統中,如果需要大塊的內存,就需要自己來定義數組等解決

總結:語言沒有好壞,只有適應不適應;譬如當我們程序對性能(如操作系統內核)非常需要時就會使用C/C++,當我們對開發程序速度非常需要時,就會使用java/C#


7、什么是內存?

內存(RAM)從硬件上講就是一個電腦配件(內存條)。

從邏輯上講內存是一種這樣的東西,可以隨機訪問,隨時進行讀寫(也可以限制只讀或者只寫)。

內存在 編程中天生就是為存放變量的(也可以說就是有了內存,才有了C語言的變量,原來受限于硬件)

內存實際是有無數個內存單元格組成的,每一個單元格都有一個唯一的內存地址

用大樓來類比內存很合適,內存就像是一棟無限高的大樓,一個個內存單元格就像是大樓內的一個個小房子,內存地址就像是門牌號,存進去的內容就像是住進去的人


8、位,字節,半字,字的概念和內存位寬

內存單元的大小單位:位(1bit) 字節(8bit) 半字(一般是16bit)  字(一般是32bit)

在所有計算機,所有操作系統中,位永遠是 1bit,字節永遠是 8bit

歷史上曾經出現過16位,32位,64位系統三種,而且系統還有windows,linux,ios等。半字和字等很多概念被混亂定義過

所以在工作中不要詳細區分字,半字,雙子的概念,只要知道這些單位具體占多少位是依賴于平臺的,實際工作中先去搞清楚所在平臺的定義,需要注意的是半字一定是字的一半,雙字一定是字的2倍

編程一般用不到字的概念,區分主要是我們會在文檔中用到字,如果不加區分,容易造成理解錯誤

在linux+ARM的平臺上  字是32位的

內存芯片之間可以并聯,即使是8位的內存芯片,通過并聯可以也可以做出來16位,32位的內存芯片


9、內存編址和尋址、內存對齊

內存在邏輯上就是一個一個的格子(內存單元格),里面可以存儲數據,每一個單元格都有一個內存地址,單元格與內存地址一一對應且永久綁定,這就是內存編址的方法

一個內存單元有兩個概念:地址和空間(內存單元的兩面性)

關鍵:內存編址是以字節為單位的

一個內存地址,對應的空間(內存單元)大小是一定的,就是一個字節(8bit)

內存對齊;對齊訪問和硬件匹配,所以效率高,非對齊訪問和硬件不搭配,所以效率低(因為系統兼容性的問題,非對齊訪問也可以實現)


10、數據類型和內存的關系

數據類型是用來定義變量的,變量要存儲、運算在內存中,所以內存就必須語相應的數據類型相匹配,否則就會造成效率低下或者不工作

int ×××(整數類型,整的意思就是說和cpu本身的數據位寬(32位或64位)是一樣的)

C語言的數據類型決定一個內存單元的長度和解析方法

類型只是對后面符號或者數字(代表的內存地址)所表征的內存長度規定和解析方法規定而已

指針全名是指針變量,實質上和普通變量沒有任何區別(包括內存分配)


11、內存管理之結構體

數據結構就是研究數據如何組織(在內存中分布)和加工的學問

最簡單的數據結構就是數組(可以一次定義多個數據類型相同,意義相關的變量); //int a[10];

數組的優點:數組比較簡單,可以隨機訪問,訪問時用下標

數組的缺點:數組內所有元素的類型必須相同,且在定義時數組大小就確定,而且不能改變(沒有伸縮性,靈活性差)

而在結構體中可以定義數據類型不同的變量

struct number
{
int age;
char name[20];
double high;
};


結構體可以說是數組的升級版;如果結構體中的數據類型全都相同就可以用數組來代替;

結構體內嵌指針可以實現面向對象;

總的來說C語言是面向程序的,但是C語言寫出的linux系統是面向對象的

struct s
{
int age;                //普通變量
void (*pFunc)(void);    //函數指針,指向 void func(void) 這類的函數
};


使用這樣的結構體就可以實現面向對象


12、內存管理之棧

什么是棧:棧是一種數據結構,C語言中用棧來存儲局部變量;棧是用來管理內存的

棧:先進后出;入口即出口,有一個口是堵死的,所以先進去的必須后出來

隊列:先進先出;入口和出口是分開的,必須從入口進,從出口出,所以先進去的先出來

棧內存是反復使用的,上次用完的值沒有清零,所以定義局部變量時需要顯式初始化,如果沒有顯式初始化,那么值就是隨機的。


13、復雜數據結構

鏈表:最常用也是最重要的(在嵌入式開發領域)


14、位操作運算

運算種類和運算符:

位與:符號 a&b 全一為一,有零為零 用于對關心位清零(和零作位與)

位或:符號 a|b 全零為零,有一為一 用于對關心位置位(置一,和一作位或)

位異或:符號a^b 相同為零,不同為一 用于對關心位取反(和一作異或)

位取反:符號 ~a 一變零,零變一

位左移:符號a<<

位右移:符號a>> 對于有符號數,右移時左側補符號位(如果正數就補0,負數就補1,叫算術移位)


15、邏輯操作運算

在C語言中,只有0為假,其他的全都是真

邏輯與:符號 a&&b 有假為假,全真為真

邏輯或:符號 a||b 有真為真,全假為假

邏輯取反:符號 !a 真變假,假變真


16、指針是C語言的精髓

指針變量和普通變量沒有任何本質區別

標準用法: int a = 10, b = 0; int *p; p = &a; b = *p; //結果b = 10


16、野指針問題

野指針就是指定義后沒有初始化或者賦值的指針

野指針指向的位置是隨機的,是不可預知的,在運行時容易觸發段錯誤(Sgmentation fault)

總結:指針變量和普通局部變量一樣,都是存儲在棧上,都需要在定義時,進行初始化,否則值就是隨機的


17、如何避免野指針問題

一般注意以下四點就可以避免野指針問題

第一點:在定義指針變量時就初始化為NULL

第二點:在解引用前判斷指針是否指向NULL(指向則不執行解引用,不指向則可以放心解引用)

即   if(NULL != p);

第三點:在解引用完成后,重新把指針賦值為NULL

第四點:在解引用前確保指針指向一個確定的內存地址(需要程序員自己把握)

NULL的實質就是數字0,0地址是不可訪問的


18、const關鍵字和指針結合

const和指針常見的有四種方式:

第一種:int const *p; //p是一個指針,指向一個int型數據,p所指向的是個常量

第二種:const int *p; //p是一個指針,指向一個int型數據,p所指向的是個常量

第三種:int *const p; //p是一個指針,指向一個int型數據,p本身是常量,指向的是變量

第四種:const int *const p; //p是一個指針,指向一個int型數據,p本身是常量,指向的也是常量

關于指針變量,一共涉及到兩個變量,一個是指針變量本身(p),一個是指針所指向的那個變量(*p),而一個const關鍵字只能修飾一個變量。


19、深入學習數組

從內存角度看,數組就是一次定義多個變量,而且在內存中的存儲單元的內存地址是依次連續的

從編譯器角度看,數組數組變量本質上和普通變量,指針變量沒有區別;變量的本質就是一個地址,編譯器把地址(在編譯器中表現為具體的數值)和變量名綁定,變量類型決定了這個地址的延續長度

搞清楚:變量、變量名、變量類型的三個概念的含義和區別

//左值和右值:賦值運算符左邊的就是左值,右邊的就是右值,賦值就是把右值里面的東西給左值;所以右值里面必須有東西(如常量,變量),左值必須能接收東西(如變量)


20、指針和數組的天生關系

數組就是內存地址連續的、類型相同(也就是大小相同)的一連串元素(變量)。這就決定了數組天生就適合使用指針進行訪問,數組訪問有兩種,一種是通過數組下標進行訪問(也就是 a[0];);

一種是通過指針進行訪問(也就是 *(a+2);)。

編譯器實質都是通過指針訪問數組,數組下標訪問是C語言提供給編程者的一種方便方法。

定義一個數組  int a[6];

a 表示數組首元素首地址,類型是int *類型,意義和數值等同于&a[0],兩者可以相互替換。

&a 表示整個數組的首地址,類型是數組指針。

指針變量 +1,表示指向數組的下一個元素,而不是真的數值+1;也就是加1*sizeof(數據類型);

在32位系統中,所有的指針變量所占的內存空間都是4字節


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

太和县| 伊金霍洛旗| 苏尼特右旗| 方正县| 吉木萨尔县| 格尔木市| 永和县| 封丘县| 马关县| 隆子县| 土默特左旗| 云梦县| 阿勒泰市| 丰都县| 三门县| 深州市| 昌宁县| 资溪县| 哈密市| 高邮市| 金川县| 蚌埠市| 黄石市| 道孚县| 天祝| 普洱| 京山县| 鄂州市| 彭泽县| 上饶市| 诏安县| 龙口市| 大洼县| 镶黄旗| 财经| 砚山县| 临湘市| 新沂市| 临安市| 清涧县| 神农架林区|