1. 程式人生 > >關於MEMSET的初始最大最小值

關於MEMSET的初始最大最小值

宣告:也是摘自網上各路大神的。

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的二進位制位000000000000000000000000000000000,-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]<d[v])d[v]=d[u]+w[u][v];

我們知道如果u,v之間沒有邊,那麼w[u][v]=INF,如果我們的INF取0x7fffffff,那麼d[u]+w[u][v]會溢位而變成負數,我們的鬆弛操作便出錯了,更一般的說,0x7fffffff不能滿足“無窮大加一個有窮的數依然是無窮大”,它變成了一個很小的負數。

除了要滿足加上一個常數依然是無窮大之外,我們的常量還應該滿足“無窮大加無窮大依然是無窮大”,至少兩個無窮大相加不應該出現災難性的錯誤,這一點上0x7fffffff依然不能滿足我們。

所以我們需要一個更好的傢伙來頂替0x7fffffff,最嚴謹的辦法當然是對無窮大進行特別處理而不是找一個很大很大的常量來代替它(或者說模擬它),但是這樣會讓我們的程式設計過程變得很麻煩。在我讀過的程式碼中,最精巧的無窮大常量取值是0x3f3f3f3f,我不知道是誰最先開始使用這個精妙的常量來做無窮大,不過我的確是從一位不認識的ACMer(ID:Staginner)的部落格上學到的,他/她的很多程式碼中都使用了這個常量,於是我自己也嘗試了一下,發現非常好用,而當我對這個常量做更深入的分析時,就發現它真的是非常精巧了。

0x3f3f3f3f的十進位制是1061109567,也就是10^9級別的(和0x7fffffff一個數量級),而一般場合下的資料都是小於10^9的,所以它可以作為無窮大使用而不致出現數據大於無窮大的情形。

另一方面,由於一般的資料都不會大於10^9,所以當我們把無窮大加上一個資料時,它並不會溢位(這就滿足了“無窮大加一個有窮的數依然是無窮大”),事實上0x3f3f3f3f+0x3f3f3f3f=2122219134,這非常大但卻沒有超過32-bitint的表示範圍,所以0x3f3f3f3f還滿足了我們“無窮大加無窮大還是無窮大”的需求。

最後,0x3f3f3f3f還能給我們帶來一個意想不到的額外好處:如果我們想要將某個陣列清零,我們通常會使用memset(a,0,sizeof(a))這樣的程式碼來實現(方便而高效),但是當我們想將某個陣列全部賦值為無窮大時(例如解決圖論問題時鄰接矩陣的初始化),就不能使用memset函式而得自己寫迴圈了(寫這些不重要的程式碼真的很痛苦),我們知道這是因為memset是按位元組操作的,它能夠對陣列清零是因為0的每個位元組都是0,現在好了,如果我們將無窮大設為0x3f3f3f3f,那麼奇蹟就發生了,0x3f3f3f3f的每個位元組都是0x3f!所以要把一段記憶體全部置為無窮大,我們只需要memset(a,0x3f,sizeof(a))。

所以在通常的場合下,0x3f3f3f3f真的是一個非常棒的選擇。

其他賦值:

memset(arr,0x7F,sizeof(arr)); //它將arr中的值全部賦為2139062143,這是用memset對int賦值所能達到的最大值

類似的還有:

memset(arr,0x80,sizeof(arr)); //set int to -2139062144

memset(arr,0x7F,sizeof(arr)); //set double to 1.38242e+306

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


相關推薦

模擬退火演算法求函式——python實現

模擬退火演算法(Simulate Anneal,SA)是一種通用概率演演算法,用來在一個大的搜尋空間內找尋命題的最優解。模擬退火是由S.Kirkpatrick, C.D.Gelatt和M.P.Vecchi在1983年所發明的。V.Černý在1985年也獨

關於MEMSET初始

宣告:也是摘自網上各路大神的。 memset的正規用法是隻能用來初始化char型別的陣列的,也就是說,它只接受0x00-0xFF的賦值。因為char是1位元組,memset是按照位元組賦值的,相當於把每個位元組都設為那個數,所以char型的陣列可賦任意值; 而對於也常

均值濾波,中濾波,濾波

fin proc repeat 效果 mod ava rom static 包含 http://blog.csdn.net/fastbox/article/details/7984721 討論如何使用卷積作為數學工具來處理圖像,實現圖像的濾波,其方法包含以下幾種,均值 濾波

Tingq 模糊查詢 共多少條數據 、平均、求和 升、降序

string sys post nat sender type asp idt acl 頁面代碼 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default3.aspx.cs" Inherits="

MT【61】含參數二次函數

tco pla 最大 back inline 我們 最小 但是 alt 評:此類題目在高考中作為壓軸題也曾考過,一般通性通法都如上面的做法,但是我們如果可以站在包絡的角度,很多問題將變得很清晰:MT【61】含參數二次函數最大最小值

分治算法 ------數組的

nbsp span 最大 技術分享 www images 如果 chinese 1-1 終於 找到課程鏈接了,太贊了,屈婉玲老師真的太厲害了! http://www.chinesemooc.org/kvideo.php?do=course_progress&kvid

js二叉樹,前序/中序/後序(,排序)

data nod can ole right unshift func pro node function Node(data,left,right) { this.left=left this.right=right

Java_數組的

定義變量 nbsp 出現 重載函數 一個 初始 要去 元素 urn 1 class ArrAyOperateDemo 2 { 3 public static void main(String[] args) 4 { 5 /*

判斷

min 平均值 print ret i++ return printf std n) #include "stdafx.h" int main(){   const int a = 3;   const int b = 3;   int arr[a][b] = {0};  

及比較器

寫法 color obj 核心 rto 正序 public imp ctc 一、獲取集合中的最大最小值的方法 方法一:對於已經實現了比較器的基礎類(如Integer/Date)可以用集合自帶的比較方法Collections.max(list)或者Collections.mi

JS基礎:求一組數中的,以及所在位置

們的 con style 兩個 元素 nbsp 位置 最小值 font 1 var arr = [0, 5, -3, 6, 2, -6, 10]; 2 //定義一個最大值和一個最小值,把他們的索引值賦值給固定的兩個變量 3

整數m去掉n位後剩下

sed tps sdn href stub ann blank pri 如果 題目描述 給定一個正整數(<=255位),從中刪去n位後,使得剩下的數字組成的新數最小(大); 思路:從左到右開始掃描,兩兩比較,如果是前一位比後一位大,則刪去前大的一位,直到刪完所有的n位

求傳入N個參數的

fun turn elif pri 參數 print def pre 最小值 def fun2(*args): m=args[0] m1=args[0] for l in args: if l>m: m=l

1006 Sign In and Sign Out -

 思路: 用min_element和max_element就好啦~ 程式碼如下: #include<iostream> #include<cstdio> #include<algorithm> #include<string> #

【POJ - 3273 】Monthly Expense (二分,

題幹: Farmer John is an astounding accounting wizard and has realized he might run out of money to run the farm. He has already calculated and recor

POJ 3264 線段樹求區間

很裸的線段樹,沒有什麼好說的,我把根節點所擁有的左右區間都寫在結構體裡面,這樣傳參的時候比較方便。 POJ不支援萬能頭很不習慣。 #include<iostream> #include<cstdio> using namespace std; const int

es6 陣列去重及獲取

1.陣列去重 解決方案:使用了ES6新增的set資料解構的去重特性,然後在將生成的set物件轉換成陣列。 <script type="text/javascript"> var arr = [1, 2, 3, 5, 1, 5, 7, 3];var newArray = A

C語言中求的庫函式

  最近在倒騰演算法,遇到了求三個數中最小的那個運算,自己寫了一個,發現還是大學水平,在網上發現了一個比較好的例子,這就記錄下了。 #include <stdio.h> int min_fun(int a, int b, int c) { int min;

Collection.max min 集合(list set map)

//list 用來待儲存檔案表中檔案id List<Integer> list=new ArrayList<>(); //file

java整形陣列的

int[] arr int[] arr = new int[]{56,33,51,49,102,23};                 //對元素位置進行改變  &nb