memset 函式初始化問題

2021-08-20 08:37:08 字數 2399 閱讀 2744

話說剛開始使用memset的時候一直以為memset是對每乙個int賦值的,心裡想有了memset還要for迴圈對陣列進行初始化幹嘛。但其實memset這個函式的作用是將數字以單個位元組逐個拷貝的方式放到指定的記憶體中去

memset(dp,0,sizeof(dp));
int型別的變數一般占用4個位元組,對每乙個位元組賦值0的話就變成了「00000000 00000000 000000000 00000000」 (即10進製數中的0)

賦值為-1的話,放的是 「11111111 11111111 11111111 11111111 」(十進位制的-1)

這樣你可能以為如果你賦值1的話會讓整個dp陣列裡的每乙個int變成1,其實不然。

memset(dp,1,sizeof(dp));
以上**執行後,dp陣列的內容為 00000001 00000001 00000001 00000001 轉化為十進位制後不為1

我們在很多程式中都會看到memset(a,127,sizeof(a));這樣的**,127是什麼特別的數字呢?通過基礎的進製轉換可以得知127的二進位制表示是01111111,那麼在dp陣列裡放的內容就是「01111111 01111111 01111111 01111111」,(10進製的2139062143),這樣就實現了將陣列裡的全部元素初始化為乙個很大的數的目的了,在最短路徑問題以及其他很多演算法中都是需要用到的。值得注意的是,int型別的範圍為2^31-1,大約是2147483647的樣子(如果我沒有記錯的話),所以初始化int型別的陣列也可以使用127這個數值。

如果是128呢?因為128的二進位制是10000000,那麼放的內容就是10000000 10000000 10000000 10000000,經過計算可得這個數是-2139062144。這樣就可以將陣列初始化為乙個很小的數了。

memset的正規用法是只能用來初始化char型別的陣列的,也就是說,它只接受0x00-0xff的賦值。

因為char是1位元組,memset是按照位元組賦值的,相當於把每個位元組都設為那個數,所以char型的陣列可賦任意值;

而對於也常用的int型別,int是4個位元組,當memset(,1,sizeof());時,1相當於asscii碼的1,1轉為二進位制00000001,當做一位元組,一位元組8位,int為4位元組,所以初始化完每個數為00000001000000010000000100000001 = 16843009;

memset(,0xff,sizeof()),0xff轉為二進位制11111111,int為4位元組所以最後為11111111111111111111111111111111為-1。(化為二進位製補位,然後再賦值)。

可以全賦值為0,0的二進位制位000000000000000000000000000000000,還可以是-1,-1的二進位制就是11111111111111111111111111111111,所以memset可以直接初始化(0,-1);

例如:0xff轉為二進位制位11111111,正好是一位,0x1f小於0xff,而0x59也小於0xff,所以這些都可以用來初始化,只要能填滿8位的二進位制,就可以了。

如果你想初始最大化,第一位為符號位,不能為1,剩下全是1,也就是7個1,1111111化為十六進製制正好為0x7f,所以memset(,0x7f,sizeof());就可以了

memset中無窮大常量的設定技巧

如果問題中各資料的範圍明確,那麼無窮大的設定不是問題,在不明確的情況下,很多程式設計師都取0x7fffffff作為無窮大,因為這是32-bit int的最大值。如果這個無窮大只用於一般的比較(比如求最小值時min變數的初值),那麼0x7fffffff確實是乙個完美的選擇,但是在更多的情況下,0x7fffffff並不是乙個好的選擇。

很多時候我們並不只是單純拿無窮大來作比較,而是會運算後再做比較,例如在大部分最短路徑演算法中都會使用的鬆弛操作:

if (d[u]+w[u][v]

memset(arr,0xfe,sizeof(arr)); //set double to -5.31401e+303

大佬們講了這麼多,我來說說自己學到的小知識:

1.首先明白memset()函式是按位元組進行儲存的,也就是八位一儲存。(多餘八位取後八位,例如:比如int a[5]賦值memset(a,-1,sizeof(int )*5)與memset(a,511,sizeof(int )*5) 所賦值的結果是一樣的都為-1;因為-1的二進位製碼為(11111111 11111111 11111111 11111111)而511的二進位製碼為(00000000 00000000 00000001 11111111)後八位都為(11111111))

2.1大部分情況下是只能初始化為0或者-1,因為對0初始化是00000000 00000000 000000000 00000000,不管多少位數,結果都是一樣的。對-1初始化也是如此(11111111 11111111 11111111 11111111 )。

2.2對於無窮初始化,如上。

memset函式初始化

對於絕大多數編譯器來講,char namekey 15 與memset namekey,0x0,sizeof namekey 或memset namekey,0 sizeof namekey 這三個是一樣的。但是有的編譯器,char namekey 15 只將namekey 0 給賦值為 0 其他成...

memset函式初始化

標頭檔案 incldue 靜態陣列 int num 10 memset num,0,sizeof num 初始化為 0 memset num,1 sizeof num 初始化為 1 memset num,0x3f sizeof num 初始化為無窮大 memset num,0x3f sizeof n...

memset 函式初始化

memset 函式標頭檔案及原型 include void memset void s,int c,unsigned long n 功能 對一段申請的記憶體進行初始化,mem即memory 記憶體 memset即給記憶體設定 初值 引數說明 將 指標變數 s所指向的記憶體單元中的前n個位元組用 整型...