Table of contents
Highlights of this chapter
This article focuses on the use and precautions of library functions for characters and strings.
In-depth analysis of library functions and implementation of related library functions
1. strlen function
function prototype
size_t strlen ( const char * str );
Function introduction
- The strlen function is used to calculate the length of a string
- The string uses "\0" as the end mark. This function calculates the number of characters before "\0".
- The return value is size_t , and the prototype of size_t is typedef unsigned int. size_t is a rename of the unsigned integer type, because the strlen function calculates the length of the string and cannot be a negative number.
- Parameters are received using const char* pointers. Const cannot be modified, which increases the safety of the function.
Function simulation implementation
The following shows the simulation implementation of three strlen functions, three different ideas
Method 1: Calculate the distance between the head and tail pointers to obtain the length of the string
size_t my_strlen(const char* arr)
{
assert(arr != NULL);//断言函数,用于判断函数是否为空
const char* ret = arr;//将字符数组首地址赋值给ret指针变量
while (*ret)//当ret解引用不为\0时循环继续
{
ret++;//指针向后偏移
}
return ret - arr;//计算出指针的偏移量从而得到字符串的长度
}
Method 2: Use a marker. When the array content is not \0, add one to the marker to get the string length.
size_t my_strlen1(const char* arr)
{
assert(arr != NULL);
int sum = 0;
while (*arr)
{
arr++;
sum++;
}
return sum;
}
Method 3: Recursive implementation, recursive call when the array content is not \0
size_t my_strlen2(const char* arr)
{
assert(arr != NULL);
if (*arr)
return 1 + my_strlen2(arr+1);
else
return 0;
}
2. strcpy function
char* strcpy(char * destination, const char * source );
Function introduction
- strcpy is a function that implements string copying
- destination is the target array, source is the array used for copying, that is, the contents of the source array are copied to destination.
- The source string must end with '\0'.
- The '\0' in the source string will be copied to the target space.
- The destination space must be large enough to ensure that the source string can be stored.
- The destination space must be variable.
Function simulation implementation
char* my_strcpy(char* destination, const char* source)
{
assert(destination && source);
char* ret = destination;//用一个字符指针记录des数组的起始地址
while (*destination = *source)//当source内容为\0时循环结束
{
destination++;
source++;
}
return ret;//返回des起始地址
}
3. strcat function
function prototype
char * strcat ( char * destination, const char * source );
Function introduction
- strcat is a string append function
- Append the content of source to destination
- The source string must end with '\0'.
- The destination space must be large enough to accommodate the contents of the source string.
- The destination space must be modifiable.
Function simulation implementation
char* my_strcat(char* arr1, const char* arr2)
{
assert(arr1 && arr2);
char* ret = arr1;//使用一个字符指针记录目标数组的首地址
while (*arr1)//当目标函数内容为\0时,开始追加
{
arr1++;
}
while (*arr1 = *arr2)//开始追加字符串
{
arr1++;
arr2++;
}
return ret;
}
4. strcmp function
function prototype
int strcmp ( const char * str1, const char * str2 );
Function introduction
- strcmp function compares the size of two strings
- If the first string is greater than the second string, a number greater than 0 is returned.
- If the first string is equal to the second string, 0 is returned
- If the first string is less than the second string, a number less than 0 is returned.
Function simulation implementation
int my_strcmp(const char* arr1, const char* arr2)
{
assert(arr1 && arr2);
while (*arr1 == *arr2)//通过ascll码值依次比较每个字符的大小
{
//当字符数组内容为\0时还没有比较出大小则表示两字符串相等
if (*arr1 == '\0')
return 0;//相等则返回0
arr1++;
arr2++;
}
return *arr1 - *arr2;//不相同等返回差值
}
5. strncat function
function prototype
char * strncat ( char * destination, const char * source, size_t num );
Function introduction
- Just add a size_t num based on the original strcat
- Indicates only appending num characters
Function simulation implementation
char* my_strncat(char* arr1, const char* arr2, size_t num)
{
assert(arr1 && arr2);
char* ret = arr1;
while (*arr1)
{
arr1++;
}
while (num--)//只追加num个字符
{
*arr1 = *arr2;
arr1++;
arr2++;
}
return ret;
}
6. strncpy function
function prototype
char * strncpy ( char * destination, const char * source, size_t num );
Function introduction
- A size_t num is added to the original strncpy
- Indicates that only num characters are copied
Function simulation implementation
char* my_strncpy(char* arr1, const char* arr2, size_t num)
{
assert(arr1 && arr2);
char* ret = arr1;
while (num--)//控制复制的字符数
{
*arr1 = *arr2;
arr1++;
arr2++;
}
return ret;
}
7. strncmp function
function prototype
int strncmp ( const char * str1, const char * str2, size_t num );
Function introduction
- String comparison function, only compares num characters
- Compared with strcmp, there is only one more num
Function simulation implementation
int my_strncmp(const char* arr1, const char* arr2 ,size_t num)
{
assert(arr1 && arr2);
while (num--)
{
if (*arr1 == *arr2)//字符相等时指针后移
{
arr1++;
arr2++;
}
else
{
return *arr1 - *arr2;//只要有不相等时就返回两个字符的差
}
}
return 0;//循环结束任然相等返回0
}
8. strstr function
function prototype
char * strstr ( const char *str1, const char * str2);
Function introduction
- The strstr function is to find whether the str2 string is a substring of str1 in the str1 string.
Function simulation implementation
char* my_strstr(const char* arr1, const char* arr2)
{
const char* s1 = arr1;//利用s1指针记录被查询数组的地址
const char* s2 = arr2;//s2记录查询数组的地址
const char* p = arr1;//p指针为被查询数组的偏移量
while (*s1)
{
s1 = p;//从arr1第一个字符开始对比,不是字串就偏移一位
s2 = arr2;
while (*s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')//如果查询的数组为\0了那就证明arr2是arr1的子串
{
return p;
}
p++;
}
return NULL;
}
9. memcpy function
function prototype
void * memcpy ( void * destination, const void * source, size_t num );
Function introduction
- The function memcpy copies num bytes of data starting from the source location to the destination memory location.
- This function does not stop when it encounters '\0'.
- If there is any overlap between source and destination, the results of copying are undefined.
- You can pass any parameters, not limited to character arrays
- The num here is the number of bytes. For example, if you pass an integer array, one integer is 4 bytes, and the value of 10 integers is 40.
Function simulation implementation
void* my_memcpy(void* arr1, const void* arr2,size_t num)
{
void* ret = arr1;
assert(arr1 && arr2);
while (num--)//num为字节数,这样就保证了能够一个字节一个字节的交换
{
*(char*)arr1 = *(char*)arr2;//将传过来的地址强制类型转换为字符型
//一个字节一个字节的复制
arr1 = (char*)arr1 + 1;//强转为char*型这样指针偏移量就为1
arr2 = (char*)arr2 + 1;
}
return ret;
}
10. memmove function
function prototype
void * memmove ( void * destination, const void * source, size_t num );
Function introduction
- The difference with memcpy is that the source memory block and target memory block processed by the memmove function can overlap.
- If the source space and target space overlap, you have to use the memmove function to handle it.
Function simulation implementation
Overlap situation 1: When the source pointer is behind the destination pointer, just copy and move the number directly from front to back.
Overlap situation 2: When the source pointer is in front of the destination pointer, just copy and move the number directly from back to front.
void* my_memmove(void* arr1, const void* arr2, size_t num)
{
void* ret = arr1;
assert(arr1 && arr2);
if (arr1 <= arr2)//当目标函数指针在源函数左边时
{
while (num--)//从左向右复制
{
*(char*)arr1 = *(char*)arr2;
arr1 = (char*)arr1 + 1;
arr2 = (char*)arr2 + 1;
}
}
else//目标函数在源函数右边时
{
while (num--)//从右向左依次复制
{
*((char*)arr1 + num) = *((char*)arr2 + num);
}
}
return ret;
}
Summarize
Tall buildings rise from the ground. Without a foundation, there will be no tall buildings behind. Even if these library functions do not have any difficult algorithms, they still need us to learn.
Here is a summary of the use of 10 commonly used library functions and precautions for use. Simulation implementations of these library functions are also given.
There must still be problems here, and I hope everyone who sees them will give me some advice!