memset函數
memset(翻譯:清零)是計算機中C/C 語言初始化函數。作用是将某一塊内存中的内容全部設置為指定的值, 這個函數通常為新申請的内存做初始化工作。
以前說過,定義變量時一定要進行初始化,尤其是數組和結構體這種占用内存大的數據結構。在使用數組的時候經常因為沒有初始化而産生“燙燙燙燙燙燙”這樣的野值,俗稱“亂碼”。
每種類型的變量都有各自的初始化方法,memset() 函數可以說是初始化内存的“萬能函數”,通常為新申請的内存進行初始化工作。它是直接操作内存空間,mem即“内存”(memory)的意思。
該函數的原型為:
## include <string.h>
void *memset(void *s, int c, unsigned long n);
将s中當前位置後面的n個字節 (typedef unsigned int size_t )用 c 替換并返回 s
函數的功能是:将指針變量 s 所指向的前 n 字節的内存單元用一個“整數” c 替換,注意 c 是 int 型。s 是 void* 型的指針變量,所以它可以為任何類型的數據進行初始化。
memset() 的作用是在一段内存塊中填充某個給定的值。因為它隻能填充一個值,所以該函數的初始化為原始初始化,無法将變量初始化為程序中需要的數據。用memset初始化完後,後面程序中再向該内存空間中存放需要的數據。
memset 一般使用“0”初始化内存單元,而且通常是給數組或結構體進行初始化。一般的變量如 char、int、float、double 等類型的變量直接初始化即可,沒有必要用 memset。如果用 memset 的話反而顯得麻煩。
當然,數組也可以直接進行初始化,但 memset 是對較大的數組或結構體進行清零初始化的最快方法,因為它是直接對内存進行操作的。
這時有人會問:“字符串數組不是最好用'\0'進行初始化嗎?那麼可以用 memset 給字符串數組進行初始化嗎?也就是說參數 c 可以賦值為'\0'嗎?”
可以的。雖然參數 c 要求是一個整數,但是整型和字符型是互通的。但是賦值為 '\0' 和 0 是等價的,因為字符 '\0' 在内存中就是 0。所以在 memset 中初始化為 0 也具有結束标志符 '\0' 的作用,所以通常我們就寫“0”。
memset 函數的第三個參數 n 的值一般用 sizeof() 獲取,這樣比較專業。注意,如果是對指針變量所指向的内存單元進行清零初始化,那麼一定要先對這個指針變量進行初始化,即一定要先讓它指向某個有效的地址。而且用memset給指針變量如p所指向的内存單元進行初始化時,n 千萬别寫成 sizeof(p),這是新手經常會犯的錯誤。因為 p 是指針變量,不管 p 指向什麼類型的變量,sizeof(p) 的值都是 4。 (網上找别人的)
#include<stdio.h>
#include<string.h>
int main(void) {
int i;
char str[10];
char *p = str;
memset(str, 1, sizeof(str));//參數1就是變量名,中間的1就是指定要初始化的值(可以是任意的值包括字符和浮點數)
//最後那個初始化是長度 (可以是填數字,但沒必要)
for (i = 0; i < 10; i ) {
printf("%d\t", str[i]);
}
return 0;
}
根據memset函數的不同,輸出結果也不同,分為以下幾種情況:
memset(p, 0, sizeof(p)); //地址的大小都是4字節
0 0 0 0 -52 -52 -52 -52 -52 -52
memset(p, 0, sizeof(p)); //p表示的是一個字符變量, 隻有一字節
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也行, 但不專業
0 0 0 0 0 0 0 0 0 0
calloc函數
有時候,我們在程序中需要一段内存來處理數據,但是又不确定是要多大内存的情況下,比如 我們申請一個數組 a[100] 但是事前我們并不知道會不會用得完這100個元素,比如我們隻會用到10個,那麼剩下的90個就會還在占用空間,就顯得很浪費空間,這時候使用calloc函數是用來在内存的動态存儲區中(堆中)分配一個連續存儲空間
函數原型:
void* calloc(unsigned int num,unsigned int size)
在内存的動态存儲區中分配num個長度為size的連續空間
num:對象個數,size:對象占據的内存字節數,相較于malloc函數,calloc函數會自動将内存初始化為0
calloc在動态分配完内存後,自動初始化該内存空間為零,而malloc不做初始化,分配到的空間中的數據是随機數據。
注意:size僅僅為申請内存字節大小,與申請内存塊中存儲的數據類型無關,故編程時建議通過以下方式給出,"長度 * sizeof(數據類型)";并不需要人為的計算空間的大小,比如如果他要申請20個int類型空間,就可以int *p = (int *)calloc(20, sizeof(int))這樣就省去了人為空間計算的麻煩。
函數返回值:calloc函數返回一個指向分配起始地址的指針;如果分配不成功,返回NULL。
#include<stdio.h>
int main(void) {
int *p = (int *)calloc(10, sizeof(int));
int i;
printf("申請得的空間有:\n");
for (i = 0; i < 10; i ) {
printf("%d ", *p );
}
return 0;
}
結果:
0 0 0 0 0 0 0 0 0 0
//可以看到,使用calloc函數分配時,它最自動賦值零,而下面要介紹的malloc函數則不會
那麼會有人有疑問:既然calloc不需要計算空間并且可以直接初始化内存避免錯誤,那為什麼不直接使用calloc函數,那要malloc要什麼用呢?
實際上,任何事物都有兩面性,有好的一面,必然存在不好的地方。這就是效率。calloc函數由于給每一個空間都要初始化值,那必然效率較malloc要低,并且現實世界,很多情況的空間申請是不需要初始值的,這也就是為什麼許多初學者更多的接觸malloc函數的原因。
希望對你有幫助!
作者:Mr_Li_
另外的話為了幫助大家,輕松,高效學習C語言/C ,我給大家分享我收集的資源,從最零基礎開始的教程到C語言項目案例,幫助大家在學習C語言的道路上披荊斬棘!可以來我粉絲群領取哦~
編程學習書籍分享:
編程學習視頻分享:
整理分享(多年學習的源碼、項目實戰視頻、項目筆記,基礎入門教程)
對于C/C 感興趣可以關注小編在後台私信我:【編程交流】一起來學習哦!可以領取一些C/C 的項目學習視頻資料哦!已經設置好了關鍵詞自動回複,自動領取就好了!
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!