內存操作
我們對于內存操作需要依賴于string.h
頭文件中相關的函數庫。
內存操作函數
內存填充
-
頭文件:
#include <string.h>
-
函數原型:
void* memset(void *s,int c,size_t n)
-
函數功能:將內存塊
s
的前n
個字節填充為c
,一般用于初始化或者清零操作。 -
參數說明:
s
:目標內存首地址c
:填充值(以unsigned char形式處理(0~255)))n
:填充字節數
-
返回值:
- 成功:返回s的指針
- 失敗:返回NULL
-
注意事項:
- 常用于動態化初始化,c通常設置為0(清零)
- 按字節填充,非整型初始化需要謹慎(如填充it數組時,0是安全的)
-
案例:
/*************************************************************************> File Name: demo01.c> Author: 小劉> Description: > Created Time: 2025年05月26日 星期一 10時02分49秒************************************************************************/#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(int argc,char *argv[])
{// 在堆內存中申請4個int的連續空間int *p = (int*)malloc(4 * sizeof(int));// 非空校驗if(p == NULL){perror("內存申請失敗!");//perror不需要加換行符,它可以自己換行return -1;}// 初始化堆內存,填充0memset(p,0,4 * sizeof(int));//默認初始中值為0,例如:填充后兩個memset(p + 2,0,);// 測試輸出printf("%d\n",p[1]);// p[1] 的底層實現 *(p+1) 我們可以將p[1]看作是 *(p+1) 語法糖// 內存使用完畢要,釋放free(p);// 對指針賦值NULLp = NULL;return 0;
}
內存拷貝
-
頭文件:
#include <string.h>
-
函數原型:
-
源與目標內存無重疊時使用
void* memcpy(void* dest, const void* src,size_t n);
-
安全處理內存重疊
void* memmove(void* dest, const void* src,size_t n);
-
-
函數功能:將
stc
的前n
個字拷貝到dest
-
參數說明:
dest
:目標內存首地址stc
:源內存首地址size_t n
:拷貝的字節數
-
返回值:
- 成功:返回
dest
的首地址 - 失敗:返回NULL
- 成功:返回
-
注意事項:
memmove
能正確處理內存重疊,推薦優先使用- 確保目標內存足夠大,避免溢出。
-
示例
/*************************************************************************> File Name: demo02.c> Author: 小劉> Description: > Created Time: 2025年05月26日 星期一 10時45分19秒************************************************************************/#include <stdio.h>
#include <string.h>int main(int argc,char *argv[])
{// 準備兩個數組,用來存儲和目標int src[4] = {11,22,33,44};int dest[6] = {111,222,333,444,555,666};// 進行拷貝// memcpy()memmove(dest+1,src+1,2 * sizeof(int));printf("源數組:");register int i;for(i = 0; i < 4; i++)printf("%-6d",src[i]);printf("\n目標數組:");for(i = 0; i < 4; i++)printf("%-6d",dest[i]);printf("\n");return 0;
}
思考:什么是內存重疊?
內存比較
-
頭文件:
#include <string.h>
-
函數原型:
int memcmp(const void* s1, const void* s2,size_t n);
-
函數功能:比較
s1
和s2
的前n
個字節 -
返回值:
0
:內存內容相同>0
:s1
中第一個不同字節大于s2
<0
:s1
中第一個不同字節小于s2
-
注意事項:比較按字節進行,非字符串需確保長度一致(總字節數一致)。
-
示例:
/*************************************************************************> File Name: demo03.c> Author: 劉孟丹> Description: > Created Time: 2025年05月26日 星期一 11時20分03秒************************************************************************/#include <stdio.h> #include <string.h> #include <stdlib.h>int main(int argc,char *argv[]) {// 準備比較的數據int* arr1 = (int *)malloc(3 * sizeof(int));//3個元素int* arr2 = (int *)calloc(4 , sizeof(int));//4個元素// 清零memset(arr1,0,3 * sizeof(int));// 賦值arr1[0] = 60;arr2[1] = 66;arr2[0] = 70;arr2[1] = 5;// 比較int cmp_result = memcmp(arr2,arr1,2* sizeof(int));printf("比較結果:%d-(%s)\n",cmp_result,cmp_result > 0 ?"大于":cmp_result < 0 ?"小于" :"等于");free(arr1);free(arr2);arr1 = arr2 = NULL;return 0; }
內存查找
-
頭文件:
#include <string.h>
-
函數原型:
- 正向查找:C語言標準
void* mem(void* dest, const void* src,size_t n);
-
反向查找
void* memchar(void* dest, const void* src,size_t n);
-
函數功能:在
s
的前n
個字節中查找字符c
-
返回值:
- 成功:返回找到內容對應地址
- 失敗:返回NULL
-
注意事項:
memch
- 是GNU擴展函數,需手動聲明(只要不是C語言標準提供,編譯的時候都需要手動聲明或鏈接)
- 查找單位為字節值,非整型數據需要注意內存布局
-
示例:
/*************************************************************************> File Name: demo04.c> Author: 劉孟丹> Description: > Created Time: 2025年05月26日 星期一 11時41分52秒************************************************************************/#include <stdio.h> #include <string.h> #include <stdlib.h> extern void* memchr(const void*,int,size_t); extern void* memrchr(const void*,int,size_t);int main(int argc,char *argv[]) {//準備一個測試數組char str[] = {'A','B','C','B'};// 查找字符‘B’char *first = (char*) memchr(str,'B',sizeof(str));char *last = (char*) memrchr(str,'B',sizeof(str));printf("first= %p,last=%p\n",first,last);printf("第一個B的位置,%ld\n",first - str);printf("最后一個B的位置,%ld\n",last - str);return 0; }