今天除夕,是2013最后的一天的,,也是我們公眾課在今年的最后一講,,春節(jié)期間不再推送,過完春節(jié)后繼續(xù)推送,。所以在開講今天內容之前,,我先祝大家新年快樂,馬上發(fā)財,。 說到這馬上發(fā)財啊,,今天做了一件很糗的事,早上在QQ里面有個朋友發(fā)了一條祝福信息,,我就想今天大過年的,,也學學人家短信拜下年,于是就直接把那段信息給復制過來了,,然后找了百十來人群發(fā)出去,,后來收到大家的反饋:不要這么假吧,一點誠意都沒,,名字也不改的就拿出來發(fā)了,,我一看不對勁連忙回去看短信,有那么三秒鐘真的是石化了,,差點沒憋出一口鮮血來,,不過最后全都化成兩個——尼瑪,。 好了,該扯的也扯了,,下面我們進入今天的正題,,今天因為是除夕,所以不打算說新內容,,昨天因為時間關系匆匆把代碼敲上也沒有驗證是否能夠通過,,想來有些草率了,今天把我們昨天留下的代碼拷貝驗證了下,,還真是草率了,,編譯沒問題,但是debug運行時報錯了,,看了下,,像是操作了一塊無效內存,大家還記得昨天的代碼,?哦,,不要回復16回去看了,因為我今天已經(jīng)修改好了,,下面我就把我們昨天還沒修改過的代碼再貼出來吧,,也順便加深大家的印象: --------------------------- char* copy(char* dest, const char* src) }
char* memcopy(char* dest,const char* src,unsigned int len) ------------------------------------------------ 這是我們昨天的程序,,因為昨天沒時間驗證,今天驗證下來運行時崩潰,,大家現(xiàn)在應該看出問題出現(xiàn)在那里了吧,,就是用黑體表示的那兩句里面,說到這里,,不得不說,,編程真的不要細心啊,這個錯誤我已經(jīng)連犯兩次,,有一次是在做一個上傳下載文件的客戶端和服務器上,,在connect套接字的時候就是這樣錯將“=”當“==”使,所以導致一直無法連接服務器,。那么為什么我們上面的這個會報錯呢,?因為我們重新初始化了指針,所以導致運行時出現(xiàn)無效內存,。 還有,,這里的邏輯判斷也不對,我們的原意是要檢查參數(shù)的有效性,如果有一個為空就直接返回退出,,這樣的話用&&就極不適合了,,為什么會出現(xiàn)這個判斷符呢?因為當時沒考慮,,就直接從下面把他復制上去的。雖然我們一般不會傳無效數(shù)組指針進去,,不會碰到無效退出的情況,,但是什么時候自己傳了個無效的指針進去不是糟糕了嗎?所以上面的黑體語句應該修改為如下: if((dest == NULL) || (src == NULL)) 再調試的話發(fā)現(xiàn)完全沒問題了,,就算有重疊內存的拷貝也不會崩潰了,。下面我們來看看內存拷貝是怎么實現(xiàn)的。 首先,,我們先要判斷有沒有重疊內存的可能,,這個該怎么判斷呢?還記得我嗎上一講的那個恒等式嗎,? array[i] == *(ptr+i); &array[i] == ptr + i; 通過這兩個恒等式,,我們可以輕易的判斷出是否有內存重疊的情況: dest是要的目標地址,dest就是我們所需要用到的一塊內存的首地址,,知道首地址,,我們還知道那個len(這塊內存的長度),所以我們可以輕松的得到這塊內存的范圍:[dest,dest+len],,只要我們這塊內存的最小值小于等于在我們源地址的首地址,,或者在源地址的最大范圍外就可以肯定他們沒有重疊部分,就算有重疊部分,,這樣也不會印象到我們一般的從低到高的拷貝,,如下: if(get<= src || get > (src+len)) 當滿足該條件,我們就不用擔心內存重疊的問題,,直接從低字節(jié)向高字節(jié)依次拷貝即可,,直到將源地址里面的信息拷貝給目標內存。 ------------------------------- while(len--) { *get = *src; get++; src++; } ---------------------------------- 這就是整個拷貝過程,,當然,,如果大家喜歡用數(shù)組操作的話,可以如下循環(huán)來完成復制過來: -------------------------------- for(int i=0;i { get[i] = src[i]; } ------------------------------- 注意一點,,如果使用數(shù)組模式,,不可以使用++或--,如果使用指針的話,,可以這樣操作,。 如果不滿足上面的if條件,那么就說有內存重疊的地方,,這時我們就要考慮另一種拷貝方法了,,我們不能從低位向高位順序拷貝,,我們要從高位向低位進行拷貝,為什么呢,?就用昨天我們舉的例子吧: copy(array1+1,array1),; 從上面的原型我們可以看出,這是要把array1里面的信息拷貝到array1+1里面去,,因為他們共用了一塊內存: —————— —————— 像上面的這兩條線一樣,,array1的內存塊是上面那一段,array1+1是下面這一段,,第一個自己可以順利復制進array1+1里面來,,就簡單點說,array1這塊內存里面儲存的是abc,,那么a順利復制到array1+1的首地址里,,那么array1+1的首地址卻是array1的第二個值儲存地址,也就是b的地址,,這一來,,b便變成了a,于是array1的最終結果是aaa,,array1+1的結果也是aaa,,現(xiàn)在明白為什么要從高位到低位的拷貝了吧。 關于這個字符串的拷貝函數(shù)就說到這里了,,他到底算不算是系統(tǒng)string庫里面的strcpy()的偽碼我不知道,,有空的同學可以多加驗證,尤其是在效率方面,,因為現(xiàn)在我們就差效率沒有驗證了,,其他方面和strcpy()沒有兩樣,甚至內存重疊拷貝的情況竟然比strcpy()的要好,,我不知道這是好事還是壞事,,我想微軟不會沒有考慮我所考慮的這些,至于效率,,我也懶得去驗證,,留給大家去探索吧。最后祝大家合家歡樂,,馬上發(fā)財,,馬到成功。
==================== 回復D&d直接查看目錄,,春節(jié)過后我們接下來說復合類型——結構,。 |
|
來自: 昵稱29398856 > 《第二天》