首頁 > 軟體

C++中的memset用法詳解

2023-09-06 06:24:54

memset簡介

memset是一個初始化函數,作用是將某一塊記憶體中的全部設定為指定的值。

void *memset(void *s, int c, size_t n); 
  • s指向要填充的記憶體塊。
  • c是要被設定的值。
  • n是要被設定該值的字元數。
  • 返回型別是一個指向儲存區s的指標。

需要說明的幾個地方

一、不能任意賦值

memset函數是按照位元組對記憶體塊進行初始化,所以不能用它將int陣列出初始化為0和-1之外的其他值(除非該值高位元組和低位元組相同)。
其實c的實際範圍應該在0~255,因為memset函數只能取c的後八位給所輸入範圍的每個位元組。也就是說無論c多大隻有後八位二進位制是有效的

=================================================================================================
對於int a[4];
memset(a, -1, sizeof(a)) 與 memset(a, 511, sizeof(a)) 所賦值的結果一樣都為-1:
因為 -1 的二進位制碼為(11111111 11111111 11111111 11111111);511 的二進位制碼為(00000000 00000000 00000001 11111111);
後八位均為(11111111),所以陣列中的每個位元組都被賦值為(11111111)。
注意int佔四個位元組,例如a[0]的四個位元組都被賦值為(11111111),那麼a[0](11111111 11111111 11111111 11111111),即a[0] = -1。

二、注意所要賦值的陣列的元素型別

先來看兩個例子:
例一:對char型別的陣列a初始化,設定元素全為’1’

int main(){
    char a[4];
    memset(a,'1',4);
    for(int i=0; i<4; i++){
        cout<<a[i]<<" ";
    }
    return 0;
}

例二:對int型別的陣列a初始化,設定元素值全為1

int main(){
    int a[4];
    memset(a,1,sizeof(a));
    for(int i=0; i<4; i++){
        cout<<a[i]<<" ";
    }
    return 0;
}

1、首先要說明的第一點

 對於第二個程式,陣列a是整型的,一般int所佔記憶體空間為4個位元組,所以在使用memset賦值時,下面的語句是錯誤的

int a[4];
memset(a,1,4);

由於memset函數是以位元組為單位進行賦值的,所以上述程式碼是為陣列a的前4個位元組進行賦值,那麼所得到的執行結果就只能是:

正確的memset語句應為:

memset(a,1,16); //int所佔記憶體為4位元組的情況
memset(a,1,sizeof(a));

至於為什麼不是預期得到的1,將在下面的第二點進行說明。

當然,不同的機器上int的大小可能不同,所以最好用sizeof()函數

2、為什麼第一個程式可以正確賦值1而第二個不可以?

這就又回到了剛剛說的第一個問題,memset函數中只能取c的後八位賦給每個位元組

  • 第一個程式中,陣列a是字元型的,字元型佔據的記憶體大小就是1Byte,而memset函數也是以位元組為單位進行賦值的,所以輸出正確。
  • 第二個程式中,陣列a是整型的,整型佔據的記憶體大小為4Byte,而memset函數還是按照位元組為單位進行賦值,將1(00000001)賦給每一個位元組。那麼對於a[0]來說,其值為(00000001 00000001 00000001 00000001),即十進位制的16843009。

關於所要賦值的字元數的寫法

先來看一個範例:

#include<bits/stdc++.h>
using namespace std;

void fun1(int a[]){
    memset(a,-1,sizeof(a)); 
}

int main(){
    int a[6];
    fun1(a);
    for(int i=0; i<6; i++){
        cout<<a[i]<<" ";
    }
    return 0;
}

當陣列作為引數傳遞時,其傳遞的實際上是一個指標,這個指標指向陣列的首地址,如果用sizeof(a)函數得到的只是指標的長度,而不是陣列的長度。

解決方案:
在函數中加入陣列長度引數,在傳遞前先獲取陣列長度,然後將陣列長度作為引數傳遞進去。

#include<bits/stdc++.h>
using namespace std;

void fun1(int a[], int len){
    memset(a,-1,len); 
}

int main(){
    int a[6];
    int len = sizeof(a);
    fun1(a,len);
    for(int i=0; i<6; i++){
        cout<<a[i]<<" ";
    }
    return 0;
}

具體用法範例

初始化陣列

char str[100];
memset(str,0,100);

清空結構體型別的變數

typedef struct Stu{
	char name[20];
	int cno;
}Stu;
Stu stu1; 
memset(&stu1, 0 ,sizeof(Stu));

Stu stu2[10]; //陣列
memset(stu2, 0, sizeof(Stu)*10);

此外,如果結構體中有陣列的話還是需要對陣列單獨進行初始化處理的。

總結

  memset函數在初始化處理時非常方便,但也有其侷限性,比如要注意初始化數值,要注意位元組數等等。當然,直接選擇用for迴圈或while迴圈來進行初始化也是可以的,只不過memset更快捷一些。

到此這篇關於C++中的memset用法詳解的文章就介紹到這了,更多相關memset的用法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com