当前位置:网站首页>C magic skill Chapter 4 (detailed explanation of memory function)

C magic skill Chapter 4 (detailed explanation of memory function)

2022-06-12 14:24:00 Mortal programming biography

We learned about string functions in the previous chapter , But in some problems, string functions cannot be solved , But we have other functions to solve .

Question export : In the last chapter, we talked about many functions that operate on strings , such as strcpy,strlen,strcmp Such as function . Find out , This kind of function is closely related to strings , It also seems that only string type data can be processed . But our problem is not limited to string data , Usually there is int,float,double these c Language built-in type , There is even our custom struct( Structure ),union( Republic ) This type of , Can our string function handle these data ? Obviously not. !

The following is about strcpy function code :

#include<stdio.h>
#include<string.h>
int main()
{
    int arr1[]={1,2,3,4,5};
    int arr2[20]={0};
    strcpy(arr2,arr1);
    int sz=sizeof(arr1)/sizeof(arr1[0]);    // Calculation arr1 Number of array elements 
    int i=0;
    for(i=0;i<sz;i++)
    {
    printf("%d\n",arr2[i]);        // Traverse the array and print 
    }
    return 0;
}

This code is error( error ) Of ,strcpy The function copies only string type data . therefore , We need to use other functions to copy .        

memcpy function :

        explain : We all know that data is stored in memory , This function copies the data in memory , Since it is copying the data in memory , The data in memory is not only string type , This function can copy any data , Compatibility ratio strcpy The function is much more powerful .

          Parameters : Parameters 1: Destination address , Parameters 2: The copied source address , Parameters 3: How many bytes of data are copied ( Belong to unsigned int type ).

        Use :( The header file of this function is string.h)

#include<stdio.h>
#include<string.h>
int main()
{
    int arr1[]={1,2,3,4,5};
    int arr2[20]={0};
    memcpy(arr2,arr1,sizeof(arr1));
    int sz=sizeof(arr1)/sizeof(arr1[0]);    // Calculation arr1 Number of array elements 
    int i=0;
    for(i=0;i<sz;i++)
    {
    printf("%d\n",arr2[i]);        // Traverse the array and print 
    }
    return 0;
}

Realize the idea : Since we can copy any type of data , Then we will use a pointer that can receive any address , Recall one of our pointers in Section 2 , There is a kind of void* Type a pointer , The characteristic of this pointer is that it can receive any type of address , But you can't do operations , Then we will find a way to make it operational when we implement it later , His principle is simple , Follow strcpy Function similar to , however strcpy The function is to encounter \0 To stop copying ( Include \0), The third parameter of this function specifies the size and number of data bytes to be copied , So we're going to use the parameters 3 Decide whether to continue copying .

The specific implementation code is as follows :


#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = *(char*)src;		// Cast to char Revisit 
		++(char*)dest;
		++(char*)src;		// Because type conversion doesn't really change a data , Therefore, it is necessary to re convert the self increment address .
	}
	return ret;
}
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[5] = { 0 };
	my_memcpy(arr2, arr1, sizeof(arr1));
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

But this function is not omnipotent , Suppose we now see the figure 1 2 3 4 5 6 7 8 9 10, Let's say we're going to put 12345 copy to 34567 The location of , There is a problem , It's when we're right 3 Copy to 5 Location time , Because the front has put 1 copy to 3 Of memory space , What we copied this time is no longer the original 3 It is 1, The final result will be printed 1 2 1 2 1 2 1 8 9 10, At this time I our memcpy Function cannot solve this memory layout function , We're going to use another function memmeove

memmove function :

explain : This function is equivalent to memecpy Function upgrade , The processing of memory has reached another level .

Parameters : Parameters and types are the same as memmove The functions are the same .

Ideas : Back to the question we just had , Since this way of copying from front to back is not possible , Then we can change a way, such as copying from the back ? Obviously. . What memory layout should we copy from front to back , What happens when you copy from back to front ? Observe carefully , Is it just not coincident with the memory address to be copied , You can copy from front to back ? On the contrary, if the address is duplicated and overwritten, it will be copied from the back .

Specific implementation code :
​​​​​​​

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, void* src, size_t count)
{
assert(dest && src);
void* ret=dest;
char* ds=(char*)dest;
char* sc=(char*)sc;
if(ds<=sc||ds>=sc)    // Before and after 
{
    while(count--)
    {
    *ds++=*sc++;
    }
}
else            // From back to front 
{
    while(count--)
    {
    *(ds+count)=*(sc+count);    //ds+count Is the last element , Here there is no -- Because count-- Will dynamically determine their elements 
    }
}
return ret;
}
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int sz=sizeof(arr)/sizeof(arr[0]);
my_memmove(arr+2,arr,sz);
int i=0;
for(i=0;i<sz;i++)
{
printf("%d ",arr[i]);
}
return 0;
}

 

原网站

版权声明
本文为[Mortal programming biography]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203010512215064.html