代碼見:登錄 - Gitee.com
1. memcpy使用和模擬實現
strcpy,strncpy是拷貝字符串的,有局限性
函數原型:
void * memcpy ( void * destination, const void * source, size_t num );
功能:
memcpy 是完成內存塊拷?的,不關注內存中存放的數據是什么
函數 memcpy 從 source 的位置開始向后復制 num 個字節的數據到 destination 指向的內存
位置。
如果 source 和 destination 有任何的重疊,復制的結果都是未定義的。
(內存重疊的情況使? memmove 就?)
memcpy 的使?需要包含 <string.h>
參數:
destination :指針,指向?標空間,拷?的數據存放在這?
source :指針,指向源空間,要拷?的數據從這?來
num :要拷?的數據占據的字節數
返回值:
拷?完成后,返回?標空間的起始地址
2. memmove使用和模擬實現
函數原型:
void * memmove ( void * destination, const void * source, size_t num );
功能:
? memmove函數也是完成內存塊拷?的
? 和memcpy的差別就是memmove函數處理的源內存塊和?標內存塊是可以重疊的。
? memmove的使?需要包含<string.h>
參數:
destination :指針,指向?標空間,拷?的數據存放在這?
source :指針,指向源空間,要拷?的數據從這?來
num :要拷?的數據占據的字節數
返回值:
拷?完成后,返回?標空間的起始地址
3. memset函數的使用
函數原型:
void * memset ( void * ptr, int value, size_t num );
功能:
? memset 函數是?來設置內存塊的內容的,將內存中指定?度的空間設置為特定的內容。
? memset 的使?需要包含 <string.h>
參數:
ptr :指針,指向要設置的內存空間,也就是存放了要設置的內存空間的起始地址。
value :要設置的值,函數將會把 value 值轉換成 unsigned char 的數據進?設置的。也就是
以字節為單位來設置內存塊的。
num :要設置的內存?度,單位是字節。
返回值:返回的是要設置的內存空間的起始地址。
4. memcmp函數的使用
函數原型:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
功能:
?較指定的兩塊內存塊的內容,?較從ptr1和ptr2指針指向的位置開始,向后的num個字節
memcmp 的使?需要包含 <string.h>
參數:
ptr1 :指針,指向?塊待?較的內存塊
ptr2 :指針,指向另外?塊待?較的內存塊
num :指定的?較?度,單位是字節
返回值:
5.整數在內存中的存儲
整數的2進制有三種表示方式:原碼,反碼和補碼
有符號整數,三種表示方法均有符號位和數值位
無符號整數始終>=0
正整數的原,反,補碼都相同,負整數三種表示方法各不相同。
對于整型:數據存放在內存中實際存放的是二進制的補碼。
因為在計算機系統中,數值?律用補碼來表示和存儲。使用補碼,可以將符號位和數值域統?處理,加法和減法也可以統?處理(CPU只有加法器)。此外,補碼與原碼相互轉換,其運算過程是 相同的,不需要額外的硬件電路。
6.大小端字節序和字節序判斷
?在a,b中的數字是按照字節為單位,倒著存儲
6.1什么是大小端
超過一個字節的數據在內存中存儲時,有存儲順序的問題,按不同的存儲順序,分為大端字節序存儲和小端字節序存儲。
大端存儲:數據的高位字節內容保存在內存的低地址處,低位字節保存在高地址處。
小端存儲:數據的高位字節內容保存在內存的高地址處,低位字節保存在低地址處。
6.2為什么有大小端?
在計算機系統中,以字節為單位,而每個地址單位都對應著一個字節,一個字節為8bit位,不過在c語言中除了8bit的char型外,還有16bit的short型,32bit的long型(看具體編譯器),另外,對于位數大于8位的處理器,由于寄存器寬度大于一個字節,那么必然存在如何將多個字節安排的問題。所以導致大端存儲模式和小端存儲模式。
我們常用的x86結構是小端模式,而KEIL C51為大端模式,很多ARM,DSP都為小端模式,有些ARM處理器還可以由硬件選擇是大端還是小端。
6.3練習
6.3.1練習1
簡述大端字節序和小端字節序的概念,設計?個小程序來判斷當前機器的字節序。
6.3.2練習2
signed char取值范圍:-123~127
unsigned char取值范圍:0~255
6.3.3練習3
6.3.4練習4
6.3.5練習5
6.3.6練習6
7.浮點數在內存中的存儲
常見的浮點數:3.14159、1E10(1.0乘以10的十次方)等,浮點數家族包括: float、double、long double 類型.
浮點數表示的范圍: float.h 中定義。
輸出結果是什么?
7.1浮點數的存儲
根據國際標準IEEE(電氣和電子工程協會)754,任意?個二進制浮點數V可以表示成下面的形式:
舉例:
IEEE 754規定:
7.1.1浮點數存的過程
IEEE 754對有效數字M和指數E,還有一些特別的規定:
由于1 ≤ M < 2 ,也就是說,M可以寫成 1.xxxxxx 的形式,其中 xxxxxx 表示小數部分。 IEEE754規定,在計算機內部保存M時,默認這個數的第?位總是1,因此可以被舍去,只保存后面xxxxxx部分。比如保存1.01的時候,只保存01,等到讀取的時候,再把第?位的1加上去。這樣做目的,是節省1位有效數字。以32位浮點數為例,留給M只有23位,將第?位的1舍去以后,等于可以保 存24位有效數字。
對于指數E:
E為?個無符號整數(unsigned int)意味著,如果E為8位,它的取值范圍為0~255;如果E為11位,它的取值范圍為0~2047。而科學計數法中的E是可以出現負數的,所以IEEE754規定,存入內存時E的真實值必須再加上 ?個中間數,對于8位的E,這個中間數是127;對于11位的E,這個中間數是1023。比如,2^10的E是10,所以保存成32位浮點數時,必須保存成10+127=137,即10001001。
7.1.2浮點數取的過程
指數E從內存中取出還可以再分成三種情況:
E不全為0或不全為1(常規情況)
浮點數采用下面的規則表示,即指數E的計算值減去127(或1023),得到真實值,再將有效數字M前加上第?位的1。比如:0.5的?進制形式為0.1,由于規定正數部分必須為1,即將小數點右移1位,則為1.0*2^(-1),其階碼為-1+127(中間值)=126,表示為01111110,尾數1.0去掉整數部分為0,補齊0到23位 00000000000000000000000,則其?進制表示形式為:
0 01111110 00000000000000000000000
E全為0
這時,浮點數的指數E等于1-127(或者1-1023)即為真實值,有效數字M不再加上第?位的1,而是還原為0.xxxxxx的小數。這樣做是為了表示±0,以及接近于0的很小的數字。
0 00000000 00100000000000000000000
E全為1
這時,如果有效數字M全為0,表示±無窮大(正負取決于符號位s)
0 11111111 00010000000000000000000
7.2題目解析
回到初始的題目
1.為什么9還原為浮點數就是0.000000?
9以整型的形式存儲在內存中,得到如下?進制序列:
0 00000000 00000000000000000001001
浮點數為:(-1)^0 * 0.00000000000000000001001*2^(-126)=1.001*2^(-146),由于恒接近0,所以表示為0.000000
2.為什么浮點數9.0,整數打印是 1091567616?
9.0? = ?(?1)^0?(1.001)? ? ?2^3
其中:s = 0,E = 3 +127 = 130,其二進制形式:
0 10000010 001 0000 0000 0000 0000 0000
上述為補碼形式,在轉換為原碼,則為1091567616
本章完。