c語言memset詳解

void *memset(void *s, int ch, size_t n);(int ch能夠是char或int)ios

將s所指向的某一塊內存中的每一個字節的內容所有設置爲ch指定的ASCII值, 塊的大小由第三個參數指定,這個函數一般爲新申請的內存作初始化工做, 其返回值爲指向S的指針。windows

memset按字節賦值。數組

須要的頭文件
在C中 <string.h>
在C++中 <cstring>
 

void *memset(void *s, int ch, size_t n);函數

函數解釋:將s中前n個字節 (typedef unsigned int size_t)用 ch 替換並返回 s 。
memset:做用是在一段內存塊中填充某個給定的值, 它是對較大的結構體數組進行清零操做的一種最快方[1]

常見錯誤

第一: 搞反了 ch 和 n 的位置.
必定要記住若是要把一個char a[20]清零,必定是 memset(a,0,20);
而不是 memset(a,20,0);
第二: 過分使用memset,我想這些 程序員可能有某種心理陰影,他們害怕未經初始化的內存,因此他們會寫出這樣的代碼:
char buffer[20];
memset (buffer,0, sizeof ( char )*20);
strcpy (buffer, "123" );
這裏的 memset是多餘的. 由於這塊內存立刻就被覆蓋了,清零沒有意義.
第三: 其實這個錯誤嚴格來說不能算用錯memset,可是它常常在使用memset的場合出現
int some_func(struct something *a)
{
    …
    …
    memset(a,0,sizeof(a));
    …
}
這裏錯誤的 緣由是VC函數傳參過程中的指針降級,致使sizeof(a),返回的是一個 something*指針類型大小的的字節數,若是是32位,就是4字節。

常見問題

問:爲什麼要用memset置零?memset(&Address,0,sizeof(Address));常常看到這樣的用法,其實不用的話,分配數據的時候,剩餘的空間也會置零的。
答:1.若是不清空,可能會在測試當中出現野值。你作下面的試驗看看結果()
#include "iostream.h"
#include "string.h"
#include <afx.h>
int main(){
    char buf[5];
    CString str;
    CString str1;
    CString str2;
    memset(buf,0,sizeof(buf));
    for(int i = 0; i<5; i++){
        str.Format("%d",buf[i]);
        str1 +=str ;
    }
    str2.Format("%d",str1);
    cout<<str2<<endl;
    system("pause");
    return 0;
}

這樣寫,有沒有memset,輸出都是同樣測試

⒉其實否則!特別是對於字符指針類型的,剩餘的部分一般是不會爲0的,不妨做一個 試驗,定義一個字符 數組,並輸入一串字符,若是不用memset實現清零,使用MessageBox顯示出來就會有亂碼(0表示NULL,若是有,就默認字符結束,不會輸出後面的亂碼)
問:
以下demo是能夠的 ,能把數組中的元素值都設置成字符1,
include <iostream>
#include <cstring>
using namespace std;
int main(){
    char a[5];
    memset(a,'1',5);
    for(int i = 0;i < 5;i++)
        cout<<a[i]<<" ";
    system("pause");
    return 0;
}

而,以下程序想把數組中的元素值設置成1,倒是不可行的spa

#include <iostream>
#include <cstring>
#include <windows.h>
using namespace std;
int main()
{
    int a[5];
    memset(a,1,20);//若是這裏改爲memset(a,1,5*sizeof(int))也不能夠,由於memset按字節賦值
    for(int i = 0;i < 5;i++)
        cout<<a[i]<<" ";
    system("pause");
    return 0;
}
問題是:
1,第一個程序爲何能夠,而第二個不行?
由於第一個程序的數組a是字符型的,字符型佔據內存大小是1Byte,而memset函數也是以字節爲單位進行賦值的,因此你輸出沒有問題。而第二個程序a是整型的,使用 memset仍是按 字節賦值,這樣賦值完之後,每一個 數組元素的值其實是0x01010101即十進制的16843009。
2,不想要用for,或是while循環來初始化int a[5];能作到嗎?(有沒有一個像memset()這樣的函數初始化)
若是用memset(a,1,20);(實際上與memset(a,1,5*sizeof(int))結果是同樣的)就是對a指向的內存的20個 字節進行賦值,每一個都用ASCⅡ爲1的字符去填充,轉爲二進制後,1就是00000001,佔一個字節。一個INT元素是4 字節合一塊兒就是0x01010101(十六進制),就等於16843009,就完成了對一個INT元素的賦值了。 因此用memset對非字符型數組賦初值是不可取的!
 
怎麼對bool型數組賦值:
const int N = 11;
bool arr[N];
memset(&arr, 1, sizeof(bool) * N);

bool類型就是1或0.指針

例若有一個 結構體Some x,能夠這樣清零:
1
memset (&x,0, sizeof (Some));
若是是一個 結構體數組Some x[10],能夠這樣:
1
memset (x,0, sizeof (Some)*10);
 
memset能夠方便的清空一個結構類型的變量或數組。
如:

struct sample_struct
{
    char csName[16];
    int iSeq;
    int iType;
};
對於變量

struct sample_strcut stTest;
通常狀況下,清空stTest的方法:
 stTest.csName[0]={'\0'};
stTest.iSeq=0;
stTest.iType=0;
用memset就很是方便:
1 memset(&stTest,0,sizeof(struct sample_struct));
若是是數組:

struct sample_struct TEST[10];
則

memset(TEST,0,sizeof(struct sample_struct)*10);
另外:
若是結構體中有數組的話仍是須要對數組單獨進行初始化處理的。

來自百度百科。http://baike.baidu.com/view/982208.htmcode

相關文章
相關標籤/搜索