前言
嗨,我是firdawn,本章將簡單介紹,<string.h>中部分庫函數的模擬實現,如strncpy,strncat,memcpy,memmove。在本文片末,還講簡單介紹判斷機器大小端的函數實現,下面是本章的思維導圖,那么,讓我們開始吧!
一,模擬實現strncpy
1.1 strncpy的介紹
srtncpy的介紹參考cplusplus:strncpy,如下圖是該介紹的機器翻譯,有些地方可能翻譯不準。從圖中我們可以知道,strncpy用于將一個字符串拷貝到另一個字符數組中。
1.strncpy被包含在<string.h>這個頭文件中。
2.它的函數聲明為:char * strncpy ( char * destination, const char * source, size_t num );
3.其中包含三個參數,destination表示被拷貝的字符要放的目的地,source表示要拷貝到字符串的起始地址,num表示要拷貝幾個字符。
4.返回值,返回值的類型為 char*,返回的是destination的值。
1.2 strncpy的使用
具體使用如圖1.2-a
這里src數組被放入了4個字符。
1.3 實現strncpy
#include <string.h>#include <assert.h>char* my_strncpy(char* dest, const char* src, size_t num){assert(dest && src);char* p1 = dest;const char* p2 = src;//拷貝num個字符int i = 0;for (i = 0; i < num; i++){*p1++ = *p2++;}*p1 = '\0';return dest;}//模擬實現strncpyint main(){char arr1[20] = "a cute cat";char arr2[20] = { 0 };my_strncpy(arr2, arr1, 6);return 0;}
二,模擬實現strncat
2.1 strncat的介紹
srtncat的介紹參考cplusplus:strncat,同樣的,因為該網站是國外的一個網站,所以有些地方可能翻譯不準。如下圖,是該介紹的機器翻譯,從圖中我們可以知道,strncat用于將一個字符串拼接到另一個字符數組的末尾。
1.使用函數所需的頭文件:strncat 被包含在<string.h>這個頭文件中。
2.函數聲明:char * strncat ( char * destination, const char * source, size_t num );
3.參數:destination表示被拼接的字符要放的目的數組,source表示要被拼接到字符串的起始地址,num表示要拼接幾個字符。
4.返回值:返回值的類型為 char*,返回的是destination的值。
2.2 strncat的使用
如上圖,dest數組中被拼接了5個字符。
2.3 實現strncat
#include <string.h>#include <assert.h>char* my_strncat(char* dest, const char* src, size_t num){assert(dest && src);char* p1 = dest;const char* p2 = src;//讓p1指向dest數組的'\0'位置while (*p1){p1++;}//拷貝num個字符int i = 0;for (i = 0; i < num; i++){*p1++ = *p2++;}*p1 = '\0';return dest;}//模擬實現strncatint main(){char arr1[20] = "a cute cat";char arr2[20] = "I have ";my_strncat(arr2, arr1, 6);return 0;}
三,模擬實現memcpy
3.1 memcpy的介紹
memcpy的介紹參考cplusplus:memcpy,如下圖,是該介紹的機器翻譯,從圖中我們可以知道,memcpy用于拷貝內存塊的數據,拷貝大小單位是字節,不過,對于重疊內存塊的拷貝,標準是未定義的。
1.使用函數所需的頭文件:memcpy 被包含在<string.h>這個頭文件中。
2.函數聲明:void * memcpy ( void * destination, const void * source, size_t num );
3.參數:destination表示被拷貝的數據要放的目的數組,source表示要被拷貝的數據的起始地址,num表示要拷貝幾個字節。
4.返回值:返回值的類型為 void*,返回的是destination的值。
3.2 memcpy的使用
如圖,我們第一次將src數組中的數據拷貝到了dest數組中,第二次將src1數組中的數據拷貝到了dest1中。
3.3 實現memcpy
#include <assert.h>void* memcpy(void* dest, const void* src, size_t num){assert(dest && src);char* p1 = (char*)dest;char* p2 = (char*)src;int i = 0;for (i = 0; i < num; i++){*p1++ = *p2++;}return dest;}//模擬實現memcpyint main(){char arr1[20] = "beautiful girl";char arr2[20] = { 0 };memcpy(arr2, arr1, sizeof(arr1));return 0;}
四,模擬實現memmove
4.1 memmove的介紹
memmove的介紹參考cplusplus:memmove,如下圖,是該介紹的機器翻譯,從圖中我們可以知道,memmove用于拷貝內存塊的數據,拷貝大小單位是字節,不過,它支持重疊內存塊的拷貝,這在標準中是明確規定了的。
4.2 memmove的使用
在上圖中,我們將src[ 2 ]的數據拷貝到了src后面,這里拷貝到內存塊重疊了
4.3 實現memmove
#include <string.h>#include <assert.h>void* my_memmove(void* dest, const void* src, size_t num){assert(dest && src);const char* cur = (char*)src;char* p1 = NULL;if (dest > src){p1 = (char*)dest + num - 1;for (cur = (char*)src + num - 1; cur >= (char*)src; cur--){*p1-- = *cur;}}else{p1 = (char*)dest;for (cur = (char*)src; cur <= (char*)src + num - 1; cur++){*p1++ = *cur;}}return dest;}//模擬實現memmoveint main(){char arr1[30] = "a beautiful girl";my_memmove(arr1 + 2, arr1, sizeof(arr1));return 0;}
五,機器大小端的判斷
5.1 簡單介紹大小端
大小端(Endian)是計算機數據存儲的一種方式。在計算機中,數據存儲的最小單位是字節(byte),每個字節由8個二進制位組成。在一個多字節數據(如整數、浮點數等)在內存中存儲時,需要決定字節的排列順序。
大端存儲(Big Endian):字節的高位保存在低地址,字節的低位保存在高地址。即最高有效字節(Most Significant Byte)存儲在最低內存地址,最低有效字節(Least Significant Byte)存儲在最高內存地址。
小端存儲(Little Endian):字節的高位保存在高地址,字節的低位保存在低地址。即最低有效字節(Least Significant Byte)存儲在最低內存地址,最高有效字節(Most Significant Byte)存儲在最高內存地址。
不同的計算機架構和處理器可能采用不同的存儲方式。例如,x86架構的計算機通常使用小端存儲,而PowerPC架構的計算機通常使用大端存儲。為了在不同架構的計算機之間進行數據交換,通常需要進行字節序轉換操作。
5.2 大小端的函數實現
int CheckSystem(){int num = 1;return *((char*)&num);}//編寫判斷大小端程序int main(){int ret = CheckSystem();//小段返回1,大段返回0return 0;}