acm中用memset給陣列初始化
標頭檔案:cstring 或 memory
話說剛開始使用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。這樣就可以將陣列初始化為一個很小的數了。
下面談談無窮大的用法:
0x3f3f3f3f的十進位制是1061109567,也就是10^9級別的(和0x7fffffff一個數量級),而一般場合下的資料都是小於10^9的,所以它可以作為無窮大使用而不致出現數據大於無窮大的情形。
另一方面,由於一般的資料都不會大於10^9,所以當我們把無窮大加上一個資料時,它並不會溢位(這就滿足了“無窮大加一個有窮的數依然是無窮大”),事實上0x3f3f3f3f+0x3f3f3f3f=2122219134,這非常大但卻沒有超過32-bit int的表示範圍,所以0x3f3f3f3f還滿足了我們“無窮大加無窮大還是無窮大”的需求。
最後,0x3f3f3f3f還能給我們帶來一個意想不到的額外好處:如果我們想要將某個陣列清零,我們通常會使用memset(a,0,sizeof(a))這樣的程式碼來實現(方便而高效),但是當我們想將某個陣列全部賦值為無窮大時(例如解決圖論問題時鄰接矩陣的初始化),就不能使用memset函式而得自己寫迴圈了(寫這些不重要的程式碼真的很痛苦),我們知道這是因為memset是按位元組操作的,它能夠對陣列清零是因為0的每個位元組都是0,現在好了,如果我們將無窮大設為0x3f3f3f3f,那麼奇蹟就發生了,0x3f3f3f3f的每個位元組都是0x3f!所以要把一段記憶體全部置為無窮大,我們只需要memset(a,0x3f,sizeof(a))。
所以在通常的場合下,0x3f3f3f3f真的是一個非常棒的選擇。
因為char是1位元組,memset是按照位元組賦值的,相當於把每個位元組都設為那個數,所以char型的陣列可賦任意值,int是4個位元組,當memset(,1,sizeof()); 1相當於ASSCII碼的1,1轉為二進位制00000001,當做一位元組,一位元組8位,int為4位元組,所以初始化完每個數為00000001000000010000000100000001 = 16843009;
初始化最大值的方法:
如果你想初始最大化,第一位為符號位,不能為1,剩下全是1,也就是7個1,1111111化為
十六進位制正好為0x7f,所以memset(a,0x7f,sizeof(a);就可以了
就相當於memset(a,127,sizeof(a))
但是這樣容易溢位所以初始化最大用memset(a,0x3f,sizeof(a)) 更好
--------------------- 作者:fr0der1c 來源:CSDN 原文:https://blog.csdn.net/vencent7/article/details/40890993 版權宣告:本文為博主原創文章,轉載請附上博文連結!