0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

memset函數(shù)和calloc函數(shù)

C語言編程學習基地 ? 來源:C語言編程學習基地 ? 作者:Mr_Li_ ? 2022-10-20 16:13 ? 次閱讀

memset函數(shù)

memset(翻譯:清零)是計算機中C/C++語言初始化函數(shù)。作用是將某一塊內(nèi)存中的內(nèi)容全部設(shè)置為指定的值, 這個函數(shù)通常為新申請的內(nèi)存做初始化工作。

以前說過,定義變量時一定要進行初始化,尤其是數(shù)組和結(jié)構(gòu)體這種占用內(nèi)存大的數(shù)據(jù)結(jié)構(gòu)。在使用數(shù)組的時候經(jīng)常因為沒有初始化而產(chǎn)生“燙燙燙燙燙燙”這樣的野值,俗稱“亂碼”。

每種類型的變量都有各自的初始化方法,memset() 函數(shù)可以說是初始化內(nèi)存的“萬能函數(shù)”,通常為新申請的內(nèi)存進行初始化工作。它是直接操作內(nèi)存空間,mem即“內(nèi)存”(memory)的意思。

該函數(shù)的原型為:

## include 
void *memset(void *s, int c, unsigned long n);
將s中當前位置后面的n個字節(jié) (typedef unsigned int size_t )用 c 替換并返回 s

函數(shù)的功能是:將指針變量 s 所指向的前 n 字節(jié)的內(nèi)存單元用一個“整數(shù)” c 替換,注意 c 是 int 型。s 是 void* 型的指針變量,所以它可以為任何類型的數(shù)據(jù)進行初始化。

memset() 的作用是在一段內(nèi)存塊中填充某個給定的值。因為它只能填充一個值,所以該函數(shù)的初始化為原始初始化,無法將變量初始化為程序中需要的數(shù)據(jù)。用memset初始化完后,后面程序中再向該內(nèi)存空間中存放需要的數(shù)據(jù)。

memset 一般使用“0”初始化內(nèi)存單元,而且通常是給數(shù)組或結(jié)構(gòu)體進行初始化。一般的變量如 char、int、float、double 等類型的變量直接初始化即可,沒有必要用 memset。如果用 memset 的話反而顯得麻煩。

當然,數(shù)組也可以直接進行初始化,但 memset 是對較大的數(shù)組或結(jié)構(gòu)體進行清零初始化的最快方法,因為它是直接對內(nèi)存進行操作的。

這時有人會問:“字符串數(shù)組不是最好用''進行初始化嗎?那么可以用 memset 給字符串數(shù)組進行初始化嗎?也就是說參數(shù) c 可以賦值為''嗎?”

可以的。雖然參數(shù) c 要求是一個整數(shù),但是整型和字符型是互通的。但是賦值為 '' 和 0 是等價的,因為字符 '' 在內(nèi)存中就是 0。所以在 memset 中初始化為 0 也具有結(jié)束標志符 '' 的作用,所以通常我們就寫“0”。

memset 函數(shù)的第三個參數(shù) n 的值一般用 sizeof() 獲取,這樣比較專業(yè)。注意,如果是對指針變量所指向的內(nèi)存單元進行清零初始化,那么一定要先對這個指針變量進行初始化,即一定要先讓它指向某個有效的地址。而且用memset給指針變量如p所指向的內(nèi)存單元進行初始化時,n 千萬別寫成 sizeof(p),這是新手經(jīng)常會犯的錯誤。因為 p 是指針變量,不管 p 指向什么類型的變量,sizeof(p) 的值都是 4。 (網(wǎng)上找別人的)

#include
#include
int main(void) {
  int i;
  char str[10];
  char *p = str;


  memset(str, 1, sizeof(str));//參數(shù)1就是變量名,中間的1就是指定要初始化的值(可以是任意的值包括字符和浮點數(shù))
            //最后那個初始化是長度  (可以是填數(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表示的是一個字符變量, 只有一字節(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ù)

有時候,我們在程序中需要一段內(nèi)存來處理數(shù)據(jù),但是又不確定是要多大內(nèi)存的情況下,比如 我們申請一個數(shù)組 a[100] 但是事前我們并不知道會不會用得完這100個元素,比如我們只會用到10個,那么剩下的90個就會還在占用空間,就顯得很浪費空間,這時候使用calloc函數(shù)是用來在內(nèi)存的動態(tài)存儲區(qū)中(堆中)分配一個連續(xù)存儲空間

函數(shù)原型:

void* callocunsigned int num,unsigned int size)
在內(nèi)存的動態(tài)存儲區(qū)中分配num個長度為size的連續(xù)空間
num:對象個數(shù),size:對象占據(jù)的內(nèi)存字節(jié)數(shù),相較于malloc函數(shù),calloc函數(shù)會自動將內(nèi)存初始化為0

calloc在動態(tài)分配完內(nèi)存后,自動初始化該內(nèi)存空間為零,而malloc不做初始化,分配到的空間中的數(shù)據(jù)是隨機數(shù)據(jù)。

注意:size僅僅為申請內(nèi)存字節(jié)大小,與申請內(nèi)存塊中存儲的數(shù)據(jù)類型無關(guān),故編程時建議通過以下方式給出,"長度 * sizeof(數(shù)據(jù)類型)";并不需要人為的計算空間的大小,比如如果他要申請20個int類型空間,就可以int *p = (int *)calloc(20, sizeof(int))這樣就省去了人為空間計算的麻煩。

函數(shù)返回值:calloc函數(shù)返回一個指向分配起始地址的指針;如果分配不成功,返回NULL。

#include
int main(void) {
  int *p = (int *)calloc(10, sizeof(int));
  int i;


  printf("申請得的空間有:
");
  for (i = 0; i < 10; i++) {
    printf("%d ", *p++);
  }


  return 0;
}


結(jié)果:
0 0 0 0 0 0 0 0 0 0
//可以看到,使用calloc函數(shù)分配時,它最自動賦值零,而下面要介紹的malloc函數(shù)則不會

那么會有人有疑問:既然calloc不需要計算空間并且可以直接初始化內(nèi)存避免錯誤,那為什么不直接使用calloc函數(shù),那要malloc要什么用呢?

實際上,任何事物都有兩面性,有好的一面,必然存在不好的地方。這就是效率。calloc函數(shù)由于給每一個空間都要初始化值,那必然效率較malloc要低,并且現(xiàn)實世界,很多情況的空間申請是不需要初始值的,這也就是為什么許多初學者更多的接觸malloc函數(shù)的原因。

希望對你有幫助

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4260

    瀏覽量

    62228
  • 數(shù)據(jù)結(jié)構(gòu)

    關(guān)注

    3

    文章

    569

    瀏覽量

    40063
  • 變量
    +關(guān)注

    關(guān)注

    0

    文章

    609

    瀏覽量

    28288

原文標題:【零基礎(chǔ)學C語言】內(nèi)存知識總結(jié):memset函數(shù)和calloc函數(shù)

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    用malloc和calloc功能來實現(xiàn)DAQ,在調(diào)試模式下調(diào)用calloc和malloc函數(shù)時似乎卡住了,為什么?

    我正在使用 malloc 和 calloc 功能來實現(xiàn) DAQ。 我使用的是 TLE9893 系列芯片。 代碼編譯良好,但在調(diào)試模式下調(diào)用 calloc 和 malloc 函數(shù)時似乎卡住了。 我嘗試
    發(fā)表于 05-27 08:29

    回調(diào)函數(shù)(callback)是什么?回調(diào)函數(shù)的實現(xiàn)方法

    回調(diào)函數(shù)是一種特殊的函數(shù),它作為參數(shù)傳遞給另一個函數(shù),并在被調(diào)用函數(shù)執(zhí)行完畢后被調(diào)用。回調(diào)函數(shù)通常用于事件處理、異步編程和處理各種操作系統(tǒng)和
    發(fā)表于 03-12 11:46 ?2469次閱讀

    函數(shù)指針與回調(diào)函數(shù)的應(yīng)用實例

    通常我們說的指針變量是指向一個整型、字符型或數(shù)組等變量,而函數(shù)指針是指向函數(shù)函數(shù)指針可以像一般函數(shù)一樣,用于調(diào)用函數(shù)、傳遞參數(shù)。
    的頭像 發(fā)表于 03-07 11:13 ?341次閱讀
    <b class='flag-5'>函數(shù)</b>指針與回調(diào)<b class='flag-5'>函數(shù)</b>的應(yīng)用實例

    內(nèi)聯(lián)函數(shù)定義 為什么需要內(nèi)聯(lián)函數(shù)

    inline關(guān)鍵字是C99標準的型關(guān)鍵字,其作用是將函數(shù)展開,把函數(shù)的代碼復(fù)制到每一個調(diào)用處。
    的頭像 發(fā)表于 02-19 12:20 ?484次閱讀

    函數(shù)指針和指針函數(shù)是不是一個東西?

    函數(shù)指針的本質(zhì)是指針,就跟整型指針、字符指針一樣,函數(shù)指針指向的是一個函數(shù)。
    的頭像 發(fā)表于 01-03 16:35 ?470次閱讀
    <b class='flag-5'>函數(shù)</b>指針和指針<b class='flag-5'>函數(shù)</b>是不是一個東西?

    if函數(shù)多個條件怎么用

    在Excel中,如果我們需要根據(jù)多個條件來執(zhí)行不同的操作,我們可以使用IF函數(shù)的嵌套或邏輯運算符來實現(xiàn)。 IF函數(shù)是一個常用的邏輯函數(shù),它用于根據(jù)特定條件的真假來執(zhí)行不同的操作。IF函數(shù)
    的頭像 發(fā)表于 12-03 10:35 ?1998次閱讀

    vlookup函數(shù)的使用方法

    VLOOKUP函數(shù)是Excel電子表格中一種非常常用和有用的函數(shù)。它允許用戶根據(jù)一個特定的查找值,在一個給定的表格中查找匹配的值,并返回這些匹配值所在列的對應(yīng)數(shù)據(jù)。這個函數(shù)通常用于查找一個數(shù)據(jù)集中
    的頭像 發(fā)表于 11-30 17:13 ?2680次閱讀

    sumif函數(shù)的使用技巧

    SUMIF函數(shù)是Excel中非常常用的函數(shù)之一,它可以根據(jù)指定的條件對給定的范圍內(nèi)的數(shù)值進行求和操作。在日常工作和數(shù)據(jù)處理中,我們經(jīng)常需要根據(jù)某些條件來統(tǒng)計和匯總數(shù)據(jù),SUMIF函數(shù)就是一個非常方便
    的頭像 發(fā)表于 11-30 16:30 ?1134次閱讀

    c語言中函數(shù)函數(shù)體用什么符號括起來

    函數(shù) 是指將一組能完成一個功能或多個功能的語句放在一起的 代碼結(jié)構(gòu) 。 在 C語言程序 中,至少會包含一個函數(shù),及主函數(shù)main()。本文將詳細講解關(guān)于函數(shù)的相關(guān)內(nèi)容。 Part1
    的頭像 發(fā)表于 11-24 15:52 ?619次閱讀
    c語言中<b class='flag-5'>函數(shù)</b>的<b class='flag-5'>函數(shù)</b>體用什么符號括起來

    python中各種函數(shù)的用法

    Python中有很多種不同類型的函數(shù),它們在解決各種問題和完成不同任務(wù)時起著重要的作用。下面我將詳細介紹幾種常用的函數(shù),包括內(nèi)置函數(shù)、自定義函數(shù)、匿名
    的頭像 發(fā)表于 11-23 15:48 ?673次閱讀

    append()和insert()函數(shù)的區(qū)別

    在Python中, append() 和 insert() 是用于修改列表的兩個常用函數(shù)。這兩個函數(shù)的主要區(qū)別在于元素添加的位置和方式。 首先,讓我們來了解一下 append() 函數(shù)
    的頭像 發(fā)表于 11-21 14:44 ?2462次閱讀

    如何查看及更改函數(shù)/函數(shù)塊的調(diào)用環(huán)境

    模塊化設(shè)計的思想是把一些相似的功能(比如電機控制、閥控制)設(shè)計成函數(shù)函數(shù)塊,這樣就可以反復(fù)調(diào)用。其優(yōu)點是:使程序架構(gòu)更加清晰,避免重復(fù)編寫相似功能的代碼。不過可能會產(chǎn)生一個疑惑:既然PLC的程序
    的頭像 發(fā)表于 11-17 09:08 ?749次閱讀
    如何查看及更改<b class='flag-5'>函數(shù)</b>/<b class='flag-5'>函數(shù)</b>塊的調(diào)用環(huán)境

    python如何定義一個函數(shù)

    一、Python3 函數(shù) 函數(shù)是組織好的,可重復(fù)使用的,用來實現(xiàn)單一,或相關(guān)聯(lián)功能的代碼段。 函數(shù)能提高應(yīng)用的模塊性,和代碼的重復(fù)利用率。你已經(jīng)知道Python提供了許多內(nèi)建函數(shù),比如
    的頭像 發(fā)表于 11-14 11:26 ?651次閱讀

    sprintf函數(shù)耗時是strcat函數(shù)的幾倍呢?

    我們在寫代碼的時候總是被領(lǐng)導(dǎo)告知**慎用sprintf函數(shù)**,這個函數(shù)占用CPU時間較多,對于字符串拼接可以使用strcat函數(shù)替代(并未所有情形都可替代)。
    的頭像 發(fā)表于 10-26 14:28 ?1766次閱讀
    sprintf<b class='flag-5'>函數(shù)</b>耗時是strcat<b class='flag-5'>函數(shù)</b>的幾倍呢?

    函數(shù)類型和函數(shù)指針類型的區(qū)別

    平時用的更多的是函數(shù)指針類型,比如作為函數(shù)參數(shù)傳入回調(diào)函數(shù)等等。實際上函數(shù)類型也是可以作為函數(shù)的參數(shù)進行傳遞的。
    發(fā)表于 10-24 14:27 ?302次閱讀