Implementing Strcpy functions - discovering the "beauty of programs" through functions | Continuous optimization, optimization, and re-optimization~


foreword

Through the self-implementation of the Strcpy library functions in the C language , explore the beauty of program optimization and explore the mystery !


1. What is the Strcpy library function?

insert image description here
The function of the Strcpy library function: realize the copying of strings

strcpy ( char * destination, const char * source );

Implementation principle: put the address of the string to be copied after the parentheses of the strcpy function, and put the destination of the copied string in front of the parentheses. They copy the string by means of address transfer .

Through the above simple understanding, it may be found that copying a string can actually be achieved by exchanging characters one by one , then we can now implement a custom function to implement the Strcpy function.


Second, the usage of Strcpy

#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char arr1[20] = "xxxxxxxxxx";
	char arr2[] = "hello";
	
	strcpy(arr1,arr2); //1.目标空间的起始地址, 2.原空间的起始地址
	
	printf("%s\n", arr1);
	
	return 0;
}

Please add image description
What is printed here is the string that has been copied over

Some students may ask: "What about the remaining x in the arr1 array?"

It can be observed here: Strcpy copies "hello" in arr2 to arr1
(and overwrites the first element one by one)

Essence: It is to cover the first few "x" in arr1 with "hello \0" in arr2

That is to say: when printing the copied arr1 , printf will print all characters before "\0" , ("\0" is the end identifier of the string) , so it will print to "\0" and stop printing

That's why the remaining "x" is not printed.

After we solve this little episode, we basically understand how Strcpy works.
Next, let's implement it in our own language!


3. Implementation of My_Strcpy


1. “Appetizer”

First prepare the program to implement My_Strcpy

#include <stdio.h>
#include <string.h>
int main()
{
    
    
	char arr1[20] = "xxxxxxxxxx";
	char arr2[] = "hello";
	
	My_Strcpy(arr1,arr2); //1.目标空间的起始地址, 2.原空间的起始地址
	
	printf("%s\n", arr1);
	
	return 0;
}

2. Implement the My_Strcpy function


Ⅰ. Optimization of "replication process"

Ignore the "appetizer" here
and start directly Custom function section

void My_Strcpy(char* dest,char* src) //dest指针接收目标数组的首元素地址;
                                     //src指针接收要复制的数组首元素地址
{
    
    
  while(*src != '\0')
  {
    
    
	*dest = *src;
	dest++;
	src++;
  } //但是这样设置循环条件的话,是不会把'\0'也给复制的
	//所以得加多一条语句
	*dest = *src; //因为上面循环已经让地址到'\0'的地方
	              //只是循环条件为假,所以不执行
	              //所以可以承接上面++后的地址,执行一次,即可把'\0'也复制
}

But is there any way to integrate '\0' into the loop as well?

If you also have such an idea
, congratulations
on starting to step into the "beauty of programs"
- optimization

Then, let's start "optimizing" ! !

In order to be able to "one step", we can try to integrate the conditions in the loop first

void My_Strcpy(char* dest,char* src) 
{
    
    
  while(*src != '\0')
  {
    
    
	*dest++ = *src++; //跟之前意思一样
	                  //先复制,然后地址++,然后解引用 复制
  } 
	*dest++ = *src++; 
}

Let's start "one step at a time"

void My_strcpy(char* dest,char* src) 
{
    
    
  while(*dest++ = *src++)
  {
    
     
	;  //上面的条件,既可以先复制
  }   //当复制'\0'后,条件判断为假,又可以退出循环
}   //这样不就能做到“一步到位”、“一石二鸟”了吗!

Seeing this
, can you feel the "enlightened" feeling brought by the "program"?
There
are even more "wonderful" ones to come! !


Ⅱ. Optimization "inside the function"

In order to ensure the feasibility of the function ,
we have to judge whether the passed is a null pointer .
This is the second point of "optimization" ~

For this judgment operation, we can use "assert()" - to assert this library function
[not detailed here]

Then we can use this to determine whether the two pointers passed in are null pointers
to ensure the executable and correctness of the function ~

void My_Strcpy(char*dest , const char*src)  
{
    
    
	//判断传过来的 是否为空指针
	assert( src != NULL);//断言----需要引头文件 <assert.h>
    // 如果 != 则 为真--则不会报错,
	//如果为假(即 指针为 空指针)--则会报错                                                             
	assert( dest != NULL);
	while (*dest++ = *src++)
	{
    
    
		;
	}
}

Another advantage of adding assert is that if it is a null pointer , the program can also quickly give the location of the error (this is what the if statement can not do )

Like the following:

insert image description here

Who wouldn't worry about using such a program?


Ⅲ. Optimization of "Function Parameters"

By looking back at the previous chapter "What is the Strcpy library function"
, it is not difficult to find that
our My_Strcpy function is "different" compared with the Strcpy library function , indicating that we still have room for "optimization" !


insert image description here
It is not difficult to find that
compared with the formal parameter part of our My_Strcpy function , the "formal parameter" part here is more " const" to modify

We have to start thinking at this moment – ​​why do we do this
[PS: To achieve this habit of diligent thinking is an excellent program standard~]

Doing so can ensure that during the copying process, the protected "copied content" will not be changed during the copying process

[PS: I will not talk about the "application of the const operator in pointers" for the time being!
If you think this article is well written and easy to understand,
you can like, repost, and favorite it!
The author will publish related content in this regard as soon as possible! !

Back to the point

Adding 'const' before *
means * source (corresponding to ' * src ' in My_Strcpy ), that is, the content corresponding to the dereferenced has a constant attribute . During the copying process, the value of source will not be change *

Only when the address of the source changes, that is , the content corresponding to the source also changes, its value will change.

This can effectively avoid the following problems

void My_Strcpy(char* dest,const char* src) ![在这里插入图片描述](https://img-blog.csdnimg.cn/66a1220bbfbe4150bb78364a367522ee.png#pic_center)

{
    
    
  while( *src++ = *dest++)
  {
    
     
	;   //复制的时候,放错位置的情况
  }   
}

When the above problems occur, the program will automatically report an error, protecting the program
insert image description here

insert image description here
Because *src has constant attributes
at this time, which is equivalent to assignment , constants cannot be placed on the left side of the equal sign.

Copy the content pointed to by src into the space pointed to by dest Essentially
, it is hoped that the content pointed to by dest will be modified, and the content pointed to by src will not be modified

This is another point of our "optimization"~


Ⅳ. Optimization of "Function Return Type"

Comparing the Strcpy library functions
again, it is not difficult to find that the return type of the Strcpy library functions is actually char * This is not "optimized" again~~

insert image description here

The library function Strcpy actually returns the starting address of the target space .

Then we can do the following "optimization"

#include <stdio.h>
#include <string.h>

char* My_Strcpy(char*dest , const char*src)  
{
    
    

	char * ret = dest; //先保存起始地址下来
	
	assert(*src != NULL)                                                           
	assert(*dest != NULL);
	while (*dest++ = *src++)
	{
    
    
		;
	}
	
	return ret; //内容改变了,但地址没变--也就依旧可以使用了

}

int main()
{
    
    
	char arr1[20] = "xxxxxxxxxx";
	char arr2[] = "hello";
	
	printf("%s\n", My_Strcpy(arr1,arr2)); //这里就可以 “链式访问”
	                            //即【函数的返回值 为 printf的参数】
	                        //这样就可以很快的查看 目标空间内容是什么
	return 0;
}

Using the char * return type , you can see what the target space content is faster ~~



Fourth, complete the My_Strcpy function

In summary,
we have successfully optimized the My_Strcpy function , and all the points that can be optimized have been optimized ~
In other words: We have successfully copied the Strcpy function. Do you feel great at once ! !

However, this is only a "little thing to see a big witch" , and it plays the role of "raising a brick and attracting jade" for the students . I hope that the students can also use this article to inspire their personal thoughts!

The world of programming is huge,
and there are more unknowns waiting for you
to explore,
discover,
and find the moment when you are suddenly enlightened~


5. Thank you for your support! ! !


[If you think this article is helpful to you, you can like and support it~]
[If you have better ideas, you can also comment below, learn from each other and make progress!

Guess you like

Origin blog.csdn.net/qq_62817113/article/details/121890169