Detailed explanation of commonly used character functions and string functions

     Table of contents

Highlights of this chapter

1. strlen function

2. strcpy function

3. strcat function

4. strcmp function

5. strncat function

6. strncpy function

7. strncmp function

8. strstr function

9. memcpy function

10. memmove function


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

function prototype

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!

Guess you like

Origin blog.csdn.net/x2656271356/article/details/128680681#comments_24893034