① 閑聊c/c++: 談內存(大/小端,高/低位元組,高/低地址)
c/c++和其他語言最大區別在於: 指針
指針就是內存地址,一旦明白了指針與內存地址相關的內容,那理解其他語言,就易如反掌。
而且你可以把其他語言用的更加好,更加有效率
例如java/js/objc中為什麼容器中只能存儲引用類型?
如果存儲基本數據類型(值類型),為什麼會發生效率很低的裝箱拆箱行為?
而c#為什麼就不會呢?
你怎麼才能讓不使用的內存盡快被垃圾收集器回收過去?
還有很多涉及內存相關的內容,例如堆分配,棧分配等........
根據經驗:
本篇目的:
是不是感覺很繞口啊,特難理解吧!
理解大小端的關鍵點是明白:
很容易理解 高低地址 了吧,就是書寫順序
高低位元組是:左高右低
高低地址是:左低右高
根據大端的定義:
數據的高位元組 保存在 內存的低地址 中,而 數據的低位元組 保存在 內存的高地址 中
則內存存儲的方式是:
DC是最高位元組[ 最左 ],放在內存的最低地址[ 最左 ]
FF是最低位元組[ 最右 ],放在內存的最高地址[ 最右 ]
按照這個規則,很容易知道,大端在內存存儲的順序是:
DC|6E|35|FF(和rgba = 0xDC6E35FF一致的順序)
根據小端的定義:
數據的高位元組 保存在 內存的高地址 中,而 數據的低位元組 保存在 內存的低地址 中
則內存存儲的方式是:
DC是最高位元組[ 最左 ],放在內存的最高地址[ 最右 ]
FF是最低位元組[ 最右 ],放在內存的最低地址[ 最左 ]
按照這個規則,很容易知道,小端在內存存儲的順序是:
FF|35|6E|DC(和rgba = 0xDC6E35FF相反的順序)
先位元組後地址:
附:今天老師帶隊一起寫生去 文章我昨天半夜寫的
② 內存中的存儲單元的地址結構是幾維
內存中的存儲單元的地址結構是16位。
大部分16位和32位的CPU不允許將字或者長字存儲到內存中的任意地址。比如Motorola68000不允許將16位的字存儲到奇數地址中,將一個16位的字寫到奇數地址將引發異常。
每一個單元的地址稱為位元組地址,任何相鄰兩個單元組成一個字地址,按編址原則約定用其中一個較小的地址來表示字地址。一個字由兩個位元組組成,則低位元組對應低地址,高位元組對應高地址。
相關應用:
在計算機中,由控制器解釋,運算器執行的指令集是一個精心定義的數目十分有限的簡單指令集合。一般可以分為四類:
1)、數據移動 (如:將一個數值從存儲單元A拷貝到存儲單元B)。
2)、數邏運算(如:計算存儲單元A與存儲單元B之和,結果返回存儲單元C)。
3)、 條件驗證(如:如果存儲單元A內數值為100,則下一條指令地址為存儲單元F)。
4)、指令序列改易(如:下一條指令地址為存儲單元F)。
③ 計算機存儲是低位在前高位在後嗎應該怎麼區分16進制中哪個是高位哪個是低
計算機存儲:最小單位是位元組,存儲順序(小端模式)為低位位元組在前、高位在後
16進制:中最右邊的是最低位,標記為第0位,向左邊一位是第1位,這樣一直到這個數據的第15位。
④ 一個佔四位元組的正整數,在內存中的存儲方式是低8位在前(第一個位元組),高8位在後(第四個位元組)嗎
位元組順序是指占內存多於一個位元組類型的數據在內存中的存放順序,通常有小端、大端兩種位元組順序。小端位元組序指低位元組數據存放在內存低地址處,高位元組數據存放在內存高地址處;大端位元組序是高位元組數據存放在低地址處,低位元組數據存放在高地址處。
你說的這張存儲方式,是小端位元組序。
⑤ C語言的內存地址是按什麼順序排列的:比如是按從大到小還是內存自動分配的,請舉例
您問的具體是什麼?
(1)是地址編號和集成電路裡面(用顯微鏡看)各個單元的位置次序之間的關系?
(2)還是問程序中各個指令代碼執行的次序和地址編號之間的關系?
(3)還是問程序中各個變數的次序和地址編號之間的關系?
如果是(1),那麼
集成電路裡面各個單元的位置次序,一般是不公開的。所以人們不知道它的次序是從左到右還是從右到左還是別的方式。據說,現在的布局大多是交叉分散排列的,因為程序中經常出現連續訪問連續地址的操作,如此分散排列,可以使功耗分散,減小局部溫升,延長器件壽命。
如果是(2),那麼
一般的指令,除了跳轉指令和調用、返回指令以外,普通指令都是按照地址連續增加的次序,連續排列的。而且,匯編語言中書寫程序清單的次序,除了使用特殊偽指令規定地址(如ORG指令)處以外,都是按照地址編號連續增加的次序書寫的。如此,除跳轉、調用、返回指令外,書寫的次序就是執行的次序。
如果是(3),那麼
用匯編語言設計程序時,你可以隨自己習慣,覺得怎麼安排方便,就怎麼安排。
如果是高級語言,那麼,不同的編譯程序,可以有所不同。
不過,如果是C語言,那麼數組內部各個下標變數的地址,必須是按照下標由小到大地址也由小到大的次序連續安排。這是因為,C語言中,對指針的運算有嚴格規定。
例如p是指向整數的指針,則p+2就應該等於指向p所指的整數變數後面第二個整數變數的指針。於是(p+2)相應的物理地址,就應該等於p相應的物理地址加上2倍int變數的長度。 而對於數組,又是按照指針的概念來規定的。例如:a[2]就和*(a+2)完全等效。
⑥ 內存的低地址和高地址
地址都是32位的,如果用整形數(16位)保存的話,就要分高低位保存,可以用整形數組 int pointer[2]來實現,高16位存在pointer[1]中,低16位存在pointer[0]中,調用時直接把pointer強制轉化成整形地址 (int *)pointer就好了。
ps不知道你為什麼一定要這樣做,地址本身就可以是一個變數,定義一個地址變數來保存不就好了么
⑦ 存儲地址由的到的,由高到高
**靜態存儲區域分配。**內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變數,static變數。
**在棧上創建。**在執行函數時,函數內局部變數的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。
從堆上分配,亦稱動態內存分配。程序在運行的時候用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋 放內存。動態內存的生存期由程序員決定,使用非常靈活,但如果在堆上分配了空間,就有責任回收它,否則運行的程序會出現內存泄漏,頻繁地分配和釋放不同大 小的堆空間將會產生堆內碎塊。
📝 2、程序的內存空間
C語言在內存中一共分為如下幾個區域,分別是:
內存棧區: 存放局部變數名;
內存堆區: 存放new或者malloc出來的對象;
常數區: 存放局部變數或者全局變數的值;
靜態區: 用於存放全局變數或者靜態變數;
代碼區:存放函數體的二進制代碼。
📝 3、區域的簡單解釋
棧區(stack)–由編譯器自動分配釋放 ,存放函數的參數值,局部變數的值等。其操作方式類似於數據結構中的棧。
堆區(heap)–般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式類似於鏈表。
全局區(靜態區)(static)–全局變數和靜態變數的存儲是放在一塊的,初始化的全局變數和靜態變數在一塊區域(RW), 未初始化的全局變數和未初始化的靜態變數在相鄰的另一塊區域(ZI)。程序結束後有系統釋放
文字常量區–常量字元串就是放在這里的。 程序結束後由系統釋放 (RO)
程序代碼區–存放函數體的二進制代碼。 (RO)
📝 4、動態內存與靜態內存
靜態分配內存:是在程序編譯和鏈接時就確定好的內存。
動態分配內存:是在程序載入、調入、執行的時候分配/回收的內存。
📝 5、堆棧
堆和棧都是動態分配內存,兩者空間大小都是可變的。
Stack: 棧,存放Automatic Variables,按內存地址由高到低方向生長,其最大大小由編譯時確定,速度快,但自由性差,最大空間不大。
通常是用於那些在編譯期間就能確定存儲大小的變數的存儲區,用於在函數作用域內創建,在離開作用域後自動銷毀的變數的存儲區。通常是局部變數,函數參數等的存儲區。他的存儲空間是連續的,兩個緊密挨著定義的局部變數,他們的存儲空間也是緊挨著的。棧的大小是有限的。
Heap: 堆,自由申請的空間,按內存地址由低到高方向生長,其大小由系統內存/虛擬內存上限決定,速度較慢,但自由性大,可用空間大。
通常是用於那些在編譯期間不能確定存儲大小的變數的存儲區,它的存儲空間是不連續的,一般由==malloc(或new)函數來分配內存塊,並且需要用free(delete)==函數釋放內存。如果程序員沒有釋放掉,那麼就會出現常說的內存泄漏問題。需要注意的是,兩個緊挨著定義的指針變數,所指向的malloc出來的兩塊內存並不一定的是緊挨著的=,所以會產生內存碎片。另外需要注意的一點是,堆的大小幾乎不受限制,理論上每個程序最大可達4GB。
每個線程都會有自己的棧,但是堆空間是共用的。