乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       iscowang8998 2019-10-18

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

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

      人類最常用的便是10進(jìn)制了,然后還有計(jì)時(shí)的60進(jìn)制,月份的12進(jìn)制。

      計(jì)算機(jī)使用的是2進(jìn)制,以及輔助的16進(jìn)制與8進(jìn)制,16和8進(jìn)制與2的乘冪相關(guān)。3個(gè)二進(jìn)制位對(duì)位一個(gè)8進(jìn)制位,4個(gè)二進(jìn)制位對(duì)應(yīng)一個(gè)16進(jìn)制位。

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

      符號(hào)數(shù)量:n-1個(gè);

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

      如何表示n呢?需要兩位,也就是10來(lái)表示n進(jìn)制的n,n就是n進(jìn)制的模數(shù),當(dāng)某一個(gè)數(shù)m與n進(jìn)行求模運(yùn)算時(shí),其結(jié)果都會(huì)小于n,如m%n的結(jié)果小于n。

      我們知道,計(jì)算機(jī)采用二進(jìn)制,是因?yàn)槠溥壿嬙钊菀讓?shí)現(xiàn),具有最佳的穩(wěn)定性。其理論原理來(lái)自于布爾代數(shù)和香農(nóng)提出的布爾代數(shù)在開關(guān)電路的實(shí)現(xiàn)。0和1可以用繼電器、晶體管的開關(guān)或電容電信號(hào)的有無(wú)來(lái)實(shí)現(xiàn),且通過(guò)門電路(與門、或門、非門等)實(shí)現(xiàn)布爾代數(shù)。

      如果單就數(shù)字組合來(lái)說(shuō),哪一種進(jìn)制的效率最高?先問(wèn)一個(gè)問(wèn)題:

      假設(shè)a*b=N

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

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

      e=2.71828……

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

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

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

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

      2 碼制:萬(wàn)物編碼

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

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

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

      字符的編碼:如ASCII碼、utf-8的unicode碼,GBK碼等,用不同長(zhǎng)度的二進(jìn)制位來(lái)表示。

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

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

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

      前面說(shuō)了,用晶體管或電容可以實(shí)現(xiàn)一個(gè)二進(jìn)制位,或0或1。

      一個(gè)二進(jìn)制位包含的信息量稱為一 比特 。

      從門電路到集成電路,從簡(jiǎn)單到復(fù)雜的關(guān)鍵在于組合。

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

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

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

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

      5 字長(zhǎng):一次批量訪問(wèn)和處理的字節(jié)數(shù)量

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

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

      6 內(nèi)存對(duì)齊

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

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

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

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

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

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

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

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

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

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

      類型 對(duì)齊方式(變量存放的起始地址相對(duì)于結(jié)構(gòu)的起始地址的偏移量)

      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ù)

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

      例1:

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

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

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

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

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

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

      例2:

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

      再來(lái)分析一下Node2,

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

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

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

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

      例3:

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

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

      例4:

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

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

      1 c1的偏移量為0;

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

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

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

      通過(guò)上面的敘述,我們可以得到一個(gè)公式:

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

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

      再來(lái)實(shí)一個(gè)整體實(shí)例:

      #include <iostream>using namespace std;//預(yù)編譯命令#pragma pack(n),n=1,2,4,8,16來(lái)改變這一系數(shù),其中的n就是你要指定的“對(duì)齊系數(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編譯器取消結(jié)構(gòu)在編譯過(guò)程中的優(yōu)化對(duì)齊void main(){	cout<<sizeof(double)<<endl; // 8	cout<<sizeof(strtSize)<<endl; // 24}

      -End-

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

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多