C 基礎學習 20120516

2021-09-06 10:34:30 字數 3006 閱讀 3191

1、

一下是使用strcpy_s與strcpy的安全性比較

char szbuf[2] = ;

strcpy_s(szbuf, 2, "12131");  //新的crt函式

strcpy(szbuf,  "12131");    //老的crt函式

上述**,明顯有緩衝區溢位的問題。 使用strcpy_s函式則會丟擲乙個異常。而使用strcpy函式的結果則未定,因為它錯誤地改變了程式中其他部分的記憶體的資料,可能不會丟擲異常但導致程式資料錯誤,也可能由於非法記憶體訪問丟擲異常。

使用新的增強安全的crt函式有什麼好處呢?簡單地說,新的函式加強了對引數合法性的檢查以及緩衝區邊界的檢查,如果發現錯誤,會返回errno或丟擲異常。老版本的這些crt函式則沒有那麼嚴格的檢查與校驗,如果錯誤地傳輸了引數或者緩衝區溢位,那麼錯誤並不能被立刻發現,對於定位程式錯誤也帶來更大困難。

2---------

assert斷言的使用:

1:assert是巨集,而不是函式。

void assert( int expression );   

assert的作用是先計算表示式 expression ,如果其值為假(即為0),那麼它先向stderr列印一條出錯資訊,   

然後通過呼叫 abort 來終止程式執行。

使用assert的缺點是,頻繁的呼叫會極大的影響程式的效能,增加額外的開銷。

1)在函式開始處檢驗傳入引數的合法性

2)每個assert最好只檢驗乙個條件,因為同時檢驗多個條件時,如果斷言失敗,無法直觀的判斷是哪個條件失敗

3)不能使用改變環境的語句,因為assert只在debug個生效,如果這麼做,會使用程式在真正執行時遇到問題

4)assert和後面的語句應空一行,以形成邏輯和視覺上的一致感

5)有的地方,assert不能代替條件過濾

3-----------懸掛指標

與記憶體洩露相比,c++最令人頭痛的問題是記憶體越界,而記憶體越界很多情況下是由於懸掛指標引起的。  

假設乙個指標變數: object * ptr;

使用ptr時,我們除了要判斷ptr是否為0以外,還要懷疑它指向的物件是否有效,是不是已經在別的地方被銷毀了。我們希望當它指向的物件被銷毀時,ptr被自動置為0。

所謂指標懸掛是指指標指向了一塊沒有分配給使用者使用的記憶體

4---------野指標

成因:1指標變數沒有初始化。不指向null可能指向任何位置

2被free或delete之後,沒有置為null,被認為是合法的指標

3指標操作超越了變數的作用範圍。

5------------

strcpy與memcpy的區別

void *memcpy(void *dest, const void *src, int n);與strcpy相比,memcpy並不是遇到'\0'就結束,而是一定會拷貝完n個位元組

如果目標陣列destin本身已有資料,執行memcpy()後,將覆蓋原有資料(最多覆蓋n)。如果要追加資料,則每次執行memcpy後,要將目標陣列位址增加到你要追加資料的位址

6----------

memset的使用 

void *memset(void *s, int ch, size_t n); 作用是在一段記憶體塊中填充某個給定的值,它是對較大的結構體或陣列進行清零操作的一種最快方法。

因為第乙個程式的 陣列a是字元型的,字元型佔據記憶體大小是1byte,而memset函式也是以位元組為單位進行賦值的,所以你輸出沒有問題。而第二個程式a是整型的,使用 memset還是按位元組賦值,這樣賦值完以後,每個陣列元素的值實際上是0x01010101即十進位制的16843009。你看看你輸出結果是否這樣?   

2.如果用memset(a,1,20);  a是int型的4位元組 就是對a指向的記憶體的20個位元組進行賦值,每個都用ascii為1的字元去填充,轉為二進位制後,1就是00000001,佔乙個位元組。乙個int元素是4 位元組,合一起就是00000001000000010000000100000001,就等於16843009,就完成了對乙個int元素的賦值了

memset(s,'g',6);//可以對字串給定字元值,char和int可以相互轉換啊

7------------

sprintf的用法:把資料列印到字串中

int sprintf( char *buffer, const char *format, [ argument] … ) ;

char s[100];

sprintf(s,"%d",123);把123以十進位制方式右對齊列印到字串s中

sprintf(s,"-%d",123);左對齊

sprintf(s,"%d%d",123,234);第3,4個引數個數可變

連線字串比strcat好用

sprintf(s,"%s love %s","i","wyy");

sprintf 在mfc 中也能找到他的知音:cstring::format

sprnitf 還有個不錯的表妹:strftime,專門用於格式化時間字串的

time_t t = time(0);

//產生"yyyy-mm-dd hh:mm:ss"格式的字串。   

char s[32];

strftime(s, sizeof(s), "%y-%m-%d %h:%m:%s", localtime(&t));

8----------

extern char *strcat(char *dest,char *src);

把src所指字串新增到dest結尾處(覆蓋dest結尾處的'\0')並新增'\0'

src和dest所指記憶體區域不可以重疊且dest必須有足夠的空間來容納src的字串。 返回dest指標

9-----------

字串和字元陣列的區別:

字元陣列char ch=;//必須手動指定結束符

char ch=;一維的字元陣列

char ch=;二維的陣列

字串char ch="abcdefg";預設帶有結束符\0

char ch=strlen為啥是13,vs下編譯???????????????

C 學習基礎

宣告 所謂宣告 declaration 是告訴編譯器某個東西的名稱和型別,而略去其他細節。函式的宣告揭示函式的引數型別和返回型別 定義 定義的任務是提供給編譯器宣告宣告時缺失的細節。對物件而言定義為物件分配記憶體,對函式而言提供 本體。初始化 initialization 就是為物件賦初值的過程。使...

c 基礎學習

1 size t 可以跨平台,替代int或unsigned int,擴充套件性更好 2 void bzero void s,int n 只能用於linux平台,最好使用跨系統的void memset void s,int c,size t len 如果非要在windows下用,可以加上 define...

C 基礎學習

goto 死迴圈 if else else if 猜數字 switch while bmi for 乘法口訣表 using system namespace fristlearn else 次。count switch 段位 console.writeline 您的段位是 switch count ...