首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言字符串初始化函數 memset 詳解與手寫實現

     編輯:關於C語言

C語言字符串初始化函數 memset 詳解與手寫實現

在定義局部字符數組時,未初始化會包含隨機垃圾值。標準庫提供 memset 高效完成內存填充。本文深入解析其用法、常見誤區,並從零手寫實現對比源碼。

一、memset 標準庫函數

函數原型

#include 
void *memset(void *s, int c, size_t n);

參數說明

  • s:目標內存起始地址(void* 通用指針)
  • c:填充字節值(取低 8 位,unsigned char)
  • n:填充字節數
  • 返回值:s,支持鏈式調用

經典用法:字符數組初始化

#include 
#include 

#define SIZE 16

int main() {
    char str[SIZE];  // 未初始化,內容不定
    printf("舊字符串: %s\n", str);  // 輸出亂碼
    
    memset(str, 'a', SIZE * sizeof(char)); // 填充 'a'
    printf("新字符串: %s\n", str);  // 輸出 aaaaaaaaaaaaaaaa
    
    return 0;
}

關鍵點:sizeof(char) 保證可移植性

雖然 sizeof(char) == 1 恆成立,但寫成 SIZE * sizeof(char) 語義更清晰,擴展到其他類型(如 int arr[10]; memset(arr, 0, 10 * sizeof(int)))時不易出錯。

二、DIY 實現 memset

算法邏輯

  1. 將 void* 轉為 char* 逐字節操作
  2. 檢查空指針,防御性編程
  3. 循環 n 次,每次賦值 c 並移動指針
  4. 返回原始指針

手寫代碼

void *diy_memset(void *s, char c, int n) {
    if (s == NULL) return NULL;  // 防御性檢查
    
    char *p = (char *)s;
    while (n > 0) {
        *p = c;
        p++;
        n--;
    }
    return s;
}

三、對比 Linux 內核源碼實現

void *memset(void *s, int c, size_t count) {
    char *xs = (char *)s;
    while (count--)
        *xs++ = c;
    return s;
}

異同分析

維度DIY 版本內核版本
空指針檢查有無(調用者保證)
參數類型char c, int nint c, size_t count
循環寫法while(n>0) {n--;}while(count--) 更簡潔
指針遞增分兩句*xs++ = c 單句完成
核心邏輯完全一致完全一致

四、常見誤區與最佳實踐

❌ 錯誤:用 memset 初始化非字節型數組為非零值

int arr[10];
memset(arr, 1, sizeof(arr)); // 錯誤!每個 int 變成 0x01010101 = 16843009

memset 按字節填充,只適用於:

  • 字符數組填充字符
  • 任意類型數組清零(全位模式 0 對應整數 0、浮點 0.0、空指針 NULL)
  • 結構體清零

✅ 正確:清零初始化

struct Student { int id; char name[20]; double score; };
struct Student stu;
memset(&stu, 0, sizeof(stu)); // 所有成員歸零

✅ 正確:字符串填充

char buf[100];
memset(buf, '*', 50); // 前 50 字節填 '*'
buf[50] = '\0';       // 手動添加結束符

五、總結

  • memset 是按字節填充內存的高效工具,核心場景是清零和字符填充
  • 手寫實現有助於理解指針算術、類型轉換、循環邊界控制
  • 生產代碼直接使用標準庫,經過優化(如向量化指令、對齊優化)
  • 切記:不要用 memset 給整型/浮點型數組賦非零值
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved