日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

編程基礎|漫淡數(shù)制、碼制、位、字節(jié)、字長及內(nèi)存對齊

 iscowang8998 2019-10-18

數(shù)制、碼制、位、字節(jié)、字長及內(nèi)存對齊等概念具有一定的相關性:

1 數(shù)制:可用符號數(shù)及模數(shù)

人類最常用的便是10進制了,然后還有計時的60進制,月份的12進制。

計算機使用的是2進制,以及輔助的16進制與8進制,16和8進制與2的乘冪相關。3個二進制位對位一個8進制位,4個二進制位對應一個16進制位。

對于n進制,有如下規(guī)則:

符號數(shù)量:n-1個;

2進制:0,1;8進制:0,1,2,3,4,5,6,7;10進制:0,1,2,3,4,5,6,7,8,9;16進制:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F(xiàn);

如何表示n呢?需要兩位,也就是10來表示n進制的n,n就是n進制的模數(shù),當某一個數(shù)m與n進行求模運算時,其結果都會小于n,如m%n的結果小于n。

我們知道,計算機采用二進制,是因為其邏輯元件最容易實現(xiàn),具有最佳的穩(wěn)定性。其理論原理來自于布爾代數(shù)和香農(nóng)提出的布爾代數(shù)在開關電路的實現(xiàn)。0和1可以用繼電器、晶體管的開關或電容電信號的有無來實現(xiàn),且通過門電路(與門、或門、非門等)實現(xiàn)布爾代數(shù)。

如果單就數(shù)字組合來說,哪一種進制的效率最高?先問一個問題:

假設a*b=N

當a取什么值時,a^b的值最大?(a,b可以是小數(shù))。

設f(x)=x^(K/x),x>0,K是大于0的常數(shù)。對f求導,即可得x=e時f取極大值,也是最大值。

e=2.71828……

與e最接近的整數(shù)不是2而是3。

二進制存儲的計算機,一個32位的的機器使用了32個1和0,也就是64個元素,可以表達2^32=4.29*10^9個精度的數(shù)字。同樣是64個元素,假設表達成3^21.3=1.45*10^10,即使是3^21也有1.05*10^10個精度,也就是說,如果用三進制,可以有更多的組合,而四進制呢?組合數(shù)又變小了(其實e進制有最多的組合數(shù))。

但3進制的硬件卻比較難以實現(xiàn),而二進制的組合效率僅次于三進制,而硬件實現(xiàn)最簡單和穩(wěn)定,所以二進制是天然的計算機最佳數(shù)制了,正如黃金是天然的貨幣一樣。

前蘇聯(lián)曾搞過的三進制計算機:在一般情況下,命題不一定為真或假,還可能為未知。在三進制邏輯學中,符號1代表真;符號-1代表假;符號0代表未知。三進制邏輯電路的電壓存在著三種狀態(tài):正電壓(1)、零電壓(0)和負電壓(-1)。

2 碼制:萬物編碼

一個以上的符號通過組合規(guī)則便可以描述和表示復雜的信息了,如摩斯密碼或電碼,英文的字母、中文的漢字。

計算中的底層不管是數(shù)據(jù)還是指令,都是二進制的0、1,硬件實現(xiàn)為晶體管的開關或電容中電信號的有無。

數(shù)的編碼:包括正整數(shù)的原碼、負整數(shù)的補碼、浮點數(shù)的IEEE754碼制(包括階碼的移碼);

字符的編碼:如ASCII碼、utf-8的unicode碼,GBK碼等,用不同長度的二進制位來表示。

位圖的編碼:位圖像素的數(shù)字化;

聲明的編碼:聲波振幅、頻率采樣的數(shù)字化;

3 數(shù)位:組合、硬件實現(xiàn)與位運算

前面說了,用晶體管或電容可以實現(xiàn)一個二進制位,或0或1。

一個二進制位包含的信息量稱為一 比特 。

從門電路到集成電路,從簡單到復雜的關鍵在于組合。

后面會提到,計算機中以8個位組合成一個字節(jié),做為基本的尋址單位,但也可以進行位層面的計算,這就是位運算。

4 字節(jié):存儲程序概念與尋址單位

計算機中以8個位組合成一個字節(jié),做為基本的尋址和運算單位。不同的數(shù)據(jù)類型使用長度不同的內(nèi)存單元(字節(jié)數(shù)不同)。

在ASCII碼中,用一個字節(jié)來表示一個字符。不同的字符集的字符(如寬字符、多字符)需要不同數(shù)量的字節(jié)數(shù)。

5 字長:一次批量訪問和處理的字節(jié)數(shù)量

對于現(xiàn)在的電腦來時,其內(nèi)部實現(xiàn)都是串行操作的(可以利用電腦速度快和人類感官速度慢的特點,通過快速切換的串行來模擬人類表面感覺的并行),單個訪問字節(jié)效果太低了,電腦可以一次訪問多個字節(jié),如32機就是一次可以訪問32個位,4個字節(jié),64機一次可以訪問8個字節(jié)。

一次性處理事務的一個固定長度的位(bit)的位數(shù)叫字長。計算機中大多數(shù)寄存器的大小是一個字長。計算機處理的典型數(shù)值(如int)也可能是以字長為單位。CPU和內(nèi)存之間的數(shù)據(jù)傳送單位也通常是一個字長。還有而內(nèi)存中用于指明一個存儲位置的地址也經(jīng)常是以字長為單位的。現(xiàn)代計算機的字長通常為32、64位。內(nèi)部數(shù)據(jù)的表示或處理通常是字長的位數(shù)或分數(shù)。

6 內(nèi)存對齊

考慮到計算機按字長處理數(shù)據(jù)的特點,對于復合數(shù)據(jù)類型,如結構體、類、共用體,都會考慮通過內(nèi)存對齊來提供數(shù)據(jù)操作(讀寫)效率。每個特定平臺上的編譯器都有自己的默認“對齊系數(shù)”(也叫對齊模數(shù))。比如32位windows平臺下,VC默認是按照8bytes對齊的(VC->Project->settings->c/c++->Code Generation中的truct member alignment 值默認是8),程序員可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一系數(shù),其中的n就是你要指定的“對齊系數(shù)”。

編程基礎|漫淡數(shù)制、碼制、位、字節(jié)、字長及內(nèi)存對齊

內(nèi)存對齊規(guī)則:

1、數(shù)據(jù)成員對齊規(guī)則:結構(struct)(或聯(lián)合(union)或類(class))的數(shù)據(jù)成員,第一個數(shù)據(jù)成員放在offset為0的地方,以后每個數(shù)據(jù)成員的對齊按照#pragma pack(n)指定的數(shù)值和這個數(shù)據(jù)成員自身長度中,比較小的那個進行。

成員對齊系數(shù) = min(數(shù)據(jù)成員類型, n) = 4

2、結構(或聯(lián)合)的整體對齊規(guī)則:在數(shù)據(jù)成員完成各自對齊之后,結構(或聯(lián)合)本身也要進行對齊(數(shù)據(jù)成員后的內(nèi)存單元是否需要填充),對齊將按照#pragma pack指定的數(shù)值和結構(或聯(lián)合)最大數(shù)據(jù)成員長度中,比較小的那個進行。

整體對齊系數(shù) = min((max(最大數(shù)據(jù)成員長度), 8) = 4

3、結合1、2推斷:當#pragma pack的n值等于或超過所有數(shù)據(jù)成員長度的時候,這個n值的大小將不產(chǎn)生任何效果。

如果沒有通過pragma pack(m) 指定數(shù)值,VC規(guī)定各成員變量存放的起始地址相對于結構的起始地址的偏移量必須為該變量的類型所占用的字節(jié)數(shù)的倍數(shù)。

下面列出常用類型的對齊方式(vc6.0,32位系統(tǒng))。

類型 對齊方式(變量存放的起始地址相對于結構的起始地址的偏移量)

Char 偏移量必須為sizeof(char)即1的倍數(shù)

Short 偏移量必須為sizeof(short)即2的倍數(shù)

int 偏移量必須為sizeof(int)即4的倍數(shù)

float 偏移量必須為sizeof(float)即4的倍數(shù)

double 偏移量必須為sizeof(double)即8的倍數(shù)

各成員變量在存放的時候根據(jù)在結構中出現(xiàn)的順序依次申請空間,同時按照上面的對齊方式調整位置,空缺的字節(jié)VC會自動填充。同時VC為了確保結構的大小為結構的字節(jié)邊界數(shù)(即該結構中占用最大空間的類型所占用的字節(jié)數(shù))的倍數(shù),所以在為最后一個成員變量申請空間后,還會根據(jù)需要自動填充空缺的字節(jié),也就是說:結構體的總大小為結構體最寬基本類型成員大小的整數(shù)倍,如有需要編譯器會在最末一個成員之后加上填充字節(jié)(trailing padding)。

例1:

struct Node1{double m1;char m2;int m3;};
編程基礎|漫淡數(shù)制、碼制、位、字節(jié)、字長及內(nèi)存對齊

為上面的結構Node1分配空間的時候,VC根據(jù)成員變量出現(xiàn)的順序和對齊方式,

1 先為第一個成員m1分配空間,其起始地址跟結構的起始地址相同(剛好偏移量0剛好為sizeof(double)的倍數(shù)),該成員變量占用sizeof(double)=8個字節(jié);

2 接下來為第二個成員m2分配空間,這時下一個可以分配的地址對于結構的起始地址的偏移量為8,是sizeof(char)的倍數(shù),所以把m2存放在偏移量為8的地方滿足對齊方式,該成員變量占用 sizeof(char)=1個字節(jié);

3 接下來為第三個成員m3分配空間,這時下一個可以分配的地址對于結構的起始地址的偏移量為9,不是sizeof (int)=4的倍數(shù),為了滿足對齊方式對偏移量的約束問題,VC自動填充3個字節(jié)(這三個字節(jié)沒有放什么東西);

4 最后要考慮整體對齊規(guī)則,這時下一個可以分配的地址對于結構的起始地址的偏移量為12,剛好是sizeof(int), 由于8+4+4 = 16恰好是結構體中最大空間類型double(8)的倍數(shù),所以sizeof(Node1) =16.

例2:

struct Node2{char a;int b;char c;};
編程基礎|漫淡數(shù)制、碼制、位、字節(jié)、字長及內(nèi)存對齊

再來分析一下Node2,

1 成員a占一個字節(jié),所以a放在了第1位的位置;

2 第二個變量b占4個字節(jié),為保證起始位置是4(sizeof(b))的倍數(shù),所以需要在a后面填充3個字節(jié),也就是b放在了從第5位到第8位的位置;

3 然后就是c放在了9的位置,此時4+4+1=9。

4 接下來考慮字節(jié)邊界數(shù),9并不是最大空間類型int(4)的倍數(shù),應該取大于9且是4的的最小整數(shù)12,所以sizeof(Node2) = 12.

例3:

typedef struct{char a;char b;int c;}Node3;
編程基礎|漫淡數(shù)制、碼制、位、字節(jié)、字長及內(nèi)存對齊

同樣的方法我們要計算出sizeof(Node3) = 8;

例4:

struct node4 {char c1;Node3 n3;char c2};
編程基礎|漫淡數(shù)制、碼制、位、字節(jié)、字長及內(nèi)存對齊

n3的最寬簡單成員的類型為int,n3在考慮最寬簡單類型成員時是將Node3“打散”看的,所以n3的最寬簡單類型為int,這樣,通過n3定義的變量,其存儲空間首地址需要被4整除,整個sizeof(n3)的值也應該被4整除。

1 c1的偏移量為0;

2 n3的偏移量呢?這時n3是一個整體,它作為結構體變量也滿足前面三個準則,所以其大小為8,偏移量為4,c1與n3之間便需要3個填充字節(jié);

3 而c2與n3之間就不需要了,所以c2的偏移量為12;

4 考慮整體偏移,算上c2的大小為13,13是不能被4整除的,這樣末尾還得補上3個填充字節(jié)。最后得到sizeof(S3)的值為16。

通過上面的敘述,我們可以得到一個公式:

結構體的大小等于最后一個成員的偏移量加上其大小再加上末尾的填充字節(jié)數(shù)目,即:

sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trailing padding )

再來實一個整體實例:

#include <iostream>using namespace std;//預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一系數(shù),其中的n就是你要指定的“對齊系數(shù)”。#pragma pack(8)typedef struct people{	double weight; 	char sex; // 8 + 1 	short age; // 9 + 1+2	int money; // 12 + 4	char flag; // 16 + 1 + 7	}strtSize;//}__attribute__((packed)) strtSize;/讓GCC編譯器取消結構在編譯過程中的優(yōu)化對齊void main(){	cout<<sizeof(double)<<endl; // 8	cout<<sizeof(strtSize)<<endl; // 24}

-End-

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多