memset函數(shù)
memset(翻譯:清零)是計(jì)算機(jī)中C/C++語言初始化函數(shù)。作用是將某一塊內(nèi)存中的內(nèi)容全部設(shè)置為指定的值, 這個(gè)函數(shù)通常為新申請(qǐng)的內(nèi)存做初始化工作。
以前說過,定義變量時(shí)一定要進(jìn)行初始化,尤其是數(shù)組和結(jié)構(gòu)體這種占用內(nèi)存大的數(shù)據(jù)結(jié)構(gòu)。在使用數(shù)組的時(shí)候經(jīng)常因?yàn)闆]有初始化而產(chǎn)生“燙燙燙燙燙燙”這樣的野值,俗稱“亂碼”。
每種類型的變量都有各自的初始化方法,memset() 函數(shù)可以說是初始化內(nèi)存的“萬能函數(shù)”,通常為新申請(qǐng)的內(nèi)存進(jìn)行初始化工作。它是直接操作內(nèi)存空間,mem即“內(nèi)存”(memory)的意思。
該函數(shù)的原型為:
#
void *memset(void *s, int c, unsigned long n);
將s中當(dāng)前位置后面的n個(gè)字節(jié) (typedef unsigned int size_t )用 c 替換并返回 s
函數(shù)的功能是:將指針變量 s 所指向的前 n 字節(jié)的內(nèi)存單元用一個(gè)“整數(shù)” c 替換,注意 c 是 int 型。s 是 void* 型的指針變量,所以它可以為任何類型的數(shù)據(jù)進(jìn)行初始化。
memset() 的作用是在一段內(nèi)存塊中填充某個(gè)給定的值。因?yàn)樗荒芴畛湟粋€(gè)值,所以該函數(shù)的初始化為原始初始化,無法將變量初始化為程序中需要的數(shù)據(jù)。用memset初始化完后,后面程序中再向該內(nèi)存空間中存放需要的數(shù)據(jù)。
memset 一般使用“0”初始化內(nèi)存單元,而且通常是給數(shù)組或結(jié)構(gòu)體進(jìn)行初始化。一般的變量如 char、int、float、double 等類型的變量直接初始化即可,沒有必要用 memset。如果用 memset 的話反而顯得麻煩。
當(dāng)然,數(shù)組也可以直接進(jìn)行初始化,但 memset 是對(duì)較大的數(shù)組或結(jié)構(gòu)體進(jìn)行清零初始化的最快方法,因?yàn)樗侵苯訉?duì)內(nèi)存進(jìn)行操作的。
這時(shí)有人會(huì)問:“字符串?dāng)?shù)組不是最好用''進(jìn)行初始化嗎?那么可以用 memset 給字符串?dāng)?shù)組進(jìn)行初始化嗎?也就是說參數(shù) c 可以賦值為''嗎?”
可以的。雖然參數(shù) c 要求是一個(gè)整數(shù),但是整型和字符型是互通的。但是賦值為 '' 和 0 是等價(jià)的,因?yàn)樽址?'' 在內(nèi)存中就是 0。所以在 memset 中初始化為 0 也具有結(jié)束標(biāo)志符 '' 的作用,所以通常我們就寫“0”。
memset 函數(shù)的第三個(gè)參數(shù) n 的值一般用 sizeof() 獲取,這樣比較專業(yè)。注意,如果是對(duì)指針變量所指向的內(nèi)存單元進(jìn)行清零初始化,那么一定要先對(duì)這個(gè)指針變量進(jìn)行初始化,即一定要先讓它指向某個(gè)有效的地址。而且用memset給指針變量如p所指向的內(nèi)存單元進(jìn)行初始化時(shí),n 千萬別寫成 sizeof(p),這是新手經(jīng)常會(huì)犯的錯(cuò)誤。因?yàn)?p 是指針變量,不管 p 指向什么類型的變量,sizeof(p) 的值都是 4。 (網(wǎng)上找別人的)
int main(void) {
int i;
char str[10];
char *p = str;
memset(str, 1, sizeof(str));//參數(shù)1就是變量名,中間的1就是指定要初始化的值(可以是任意的值包括字符和浮點(diǎn)數(shù))
//最后那個(gè)初始化是長度 (可以是填數(shù)字,但沒必要)
for (i = 0; i < 10; i++) {
printf("%d ", str[i]);
}
return 0;
}
根據(jù)memset函數(shù)的不同,輸出結(jié)果也不同,分為以下幾種情況:
memset(p, 0, sizeof(p)); //地址的大小都是4字節(jié)
0 0 0 0 -52 -52 -52 -52 -52 -52
memset(p, 0, sizeof(p)); //p表示的是一個(gè)字符變量, 只有一字節(jié)
0 -52 -52 -52 -52 -52 -52 -52 -52 -52
memset(p, 0, sizeof(str));
0 0 0 0 0 0 0 0 0 0
memset(str, 0, sizeof(str));
0 0 0 0 0 0 0 0 0 0
memset(p, 0, 10); //直接寫10也行, 但不專業(yè)
0 0 0 0 0 0 0 0 0 0
calloc函數(shù)
有時(shí)候,我們?cè)诔绦蛑行枰欢蝺?nèi)存來處理數(shù)據(jù),但是又不確定是要多大內(nèi)存的情況下,比如 我們申請(qǐng)一個(gè)數(shù)組 a[100] 但是事前我們并不知道會(huì)不會(huì)用得完這100個(gè)元素,比如我們只會(huì)用到10個(gè),那么剩下的90個(gè)就會(huì)還在占用空間,就顯得很浪費(fèi)空間,這時(shí)候使用calloc函數(shù)是用來在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中(堆中)分配一個(gè)連續(xù)存儲(chǔ)空間
函數(shù)原型:
void* calloc(unsigned int num,unsigned int size)
在內(nèi)存的動(dòng)態(tài)存儲(chǔ)區(qū)中分配num個(gè)長度為size的連續(xù)空間
num:對(duì)象個(gè)數(shù),size:對(duì)象占據(jù)的內(nèi)存字節(jié)數(shù),相較于malloc函數(shù),calloc函數(shù)會(huì)自動(dòng)將內(nèi)存初始化為0
calloc在動(dòng)態(tài)分配完內(nèi)存后,自動(dòng)初始化該內(nèi)存空間為零,而malloc不做初始化,分配到的空間中的數(shù)據(jù)是隨機(jī)數(shù)據(jù)。
注意:size僅僅為申請(qǐng)內(nèi)存字節(jié)大小,與申請(qǐng)內(nèi)存塊中存儲(chǔ)的數(shù)據(jù)類型無關(guān),故編程時(shí)建議通過以下方式給出,"長度 * sizeof(數(shù)據(jù)類型)";并不需要人為的計(jì)算空間的大小,比如如果他要申請(qǐng)20個(gè)int類型空間,就可以int *p = (int *)calloc(20, sizeof(int))這樣就省去了人為空間計(jì)算的麻煩。
函數(shù)返回值:calloc函數(shù)返回一個(gè)指向分配起始地址的指針;如果分配不成功,返回NULL。
int main(void) {
int *p = (int *)calloc(10, sizeof(int));
int i;
printf("申請(qǐng)得的空間有:
");
for (i = 0; i < 10; i++) {
printf("%d ", *p++);
}
return 0;
}
結(jié)果:
0 0 0 0 0 0 0 0 0 0
//可以看到,使用calloc函數(shù)分配時(shí),它最自動(dòng)賦值零,而下面要介紹的malloc函數(shù)則不會(huì)
那么會(huì)有人有疑問:既然calloc不需要計(jì)算空間并且可以直接初始化內(nèi)存避免錯(cuò)誤,那為什么不直接使用calloc函數(shù),那要malloc要什么用呢?
實(shí)際上,任何事物都有兩面性,有好的一面,必然存在不好的地方。這就是效率。calloc函數(shù)由于給每一個(gè)空間都要初始化值,那必然效率較malloc要低,并且現(xiàn)實(shí)世界,很多情況的空間申請(qǐng)是不需要初始值的,這也就是為什么許多初學(xué)者更多的接觸malloc函數(shù)的原因。
希望對(duì)你有幫助!
審核編輯 :李倩
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4333瀏覽量
62721 -
數(shù)據(jù)結(jié)構(gòu)
+關(guān)注
關(guān)注
3文章
573瀏覽量
40149 -
變量
+關(guān)注
關(guān)注
0文章
613瀏覽量
28400
原文標(biāo)題:【零基礎(chǔ)學(xué)C語言】內(nèi)存知識(shí)總結(jié):memset函數(shù)和calloc函數(shù)
文章出處:【微信號(hào):cyuyanxuexi,微信公眾號(hào):C語言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論