memset memcmp memcpy memmove 自己實現
阿新 • • 發佈:2018-06-15
assert for source null 方式 size_t res 取值 從後往前
memset memcmp memcpy memmove 自己實現
memset
#include <stdio.h>
#include <memory.h>
#include <assert.h>
void* my_memset(void* dest, int c, size_t cnt){
assert(NULL != dest);
char *a = (char*)dest;
while(cnt-- > 0){
*a++ = c;
}
return dest;
}
int main(){
int a[10];
for (int i = 0; i < sizeof(a) / sizeof(int); ++i){
printf("%d ", *(a+i));
}
printf("\n");
my_memset(a,0,sizeof(a));
for(int i = 0; i < sizeof(a) / sizeof(int); ++i){
printf("%d ", *(a+i));
}
printf("\n");
}
memcmp
#include <stdio.h>
#include <memory.h>
#include <assert.h>
int my_memcmp(const void* s1, const void* s2, size_t cnt){
assert(NULL != s1 && NULL != s2);
const char *t1 = s1;
const char *t2 = s2;
int res = 0;
while(cnt-- > 0){
if(*t1 > *t2){
res =1;
break;
}
else if(*t1 < *t2){
res = -1;
break;
}
else {
t1++;
t2++;
}
}
return res;
}
int main(){
char* s1 = "abcdaaa";
char *s2 = "abcdaa";
int res = my_memcmp(s1,s2,18);
if(0 == res)
printf("s1 == s2\n");
else if(res > 0)
printf("s1 > s2\n");
else
printf("s1 < s2\n");
int i1[] = {255,2,3,4,5};
int i2[] = {511,22,23,5};
int res1 = my_memcmp(i1,i2,1);
if(0 == res1)
printf("i1 == i2\n");
else if(res1 > 0)
printf("i1 > i2\n");
else
printf("i1 < i2\n");
}
memcpy
如果copy元的首地址 + copy的字節數的結果 >= copy先的首地址的話,就會出現覆蓋,得不到正確的結果。
下面的實現結果太笨了,倒過來復制是最簡單的,請看後面的memmove的實現方式。
include <stdio.h>
#include <memory.h>
#include <assert.h>
#include <malloc.h>
void* my_memcpy(void* dest, const void* src, size_t cnt){
assert(NULL != dest && NULL != src);
char *tmp = dest;
const char *st = src;
//判斷元的首地址+要copy的字節數是否大於copy先的首地址
size_t bit = st + cnt - tmp;
char *tt = NULL;
char *tm = NULL;
//為了free使用
char *ta;
//如果copy的首地址大於元的首地址,並且元的首地址+要copy的字節數是否大於copy先的首地址,覆蓋就會發生,所以要把將被覆蓋的一段內存保存下來,先開辟空間(空間大小是bit),對tt的賦值,在後面的while裏。
if(tmp > st && bit > 0){
tt = (char*)malloc(bit);
}
//由於tt被用於賦值(初始化),所以tt已經不是首地址了;當copy到被覆蓋的字節的時候,要從首地址拿值,所以從tm中拿值,不從st中拿值;ta一直指向開辟空間的首地址,最後用於釋放這個開辟的空間。
ta = tm = tt;
while(cnt-- > 0){
//tt不為NULL,就是說明了,將要發生覆蓋,所以把要被覆蓋的字節存放到tt中,但要註意不發生覆蓋的字節不需要存放進去,所以加了bit-- > 0的條件
if(NULL != tt && bit-- > 0){
*tt++ = *tmp;
}
//NULL != tt說明了,是覆蓋patten,並且到了要被覆蓋的字節,所以不從st中取值,從tm中取值。
if(st >= (char*)dest && NULL != tt){
*tmp++ = *tm++;
st++;
}
//說明不是覆蓋的patten,無腦復制就可以了。
else{
*tmp++ = *st++;
}
}
free(ta);
return dest;
}
int main(){
char s1[20] = {‘a‘,‘b‘,‘c‘,‘d‘};
char *s2 = "xyzdef";
//char *s3 = memcpy(s1+1,s1,3);
char *s3 = my_memcpy(s1+1,s1,3);
printf("s1 = [%s]\n", s1);
printf("s3 = [%s]\n", s3);
char s11[20] = {‘a‘,‘b‘,‘c‘,‘d‘};
char *s22 = "xyzdef";
char *s33 = memcpy(s11+1,s11,3);
printf("s11 = [%s]\n", s11);
printf("s33 = [%s]\n", s33);
int i1[10] = {1,2};
int i2[10] = {11,22,33,3};
int i3[10] = {1};
int *pi3 = i3;
pi3 = (int*)my_memcpy(i2+2,i2,sizeof(int) * 3);
for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
printf("i1[%d] = %d ",i, i2[i]);
}
printf("\n");
for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
printf("i3[%d] = %d ",i, pi3[i]);
}
printf("\n");
}
memmove
#include <stdio.h>
#include <memory.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t cnt){
assert(NULL != dest && NULL != src);
char* tmp = dest;
const char* st = src;
//判斷出是覆蓋的patten,所以從後往前覆蓋
if(tmp > st && st + cnt > tmp){
while(cnt-- > 0){
*(tmp + cnt) = *(st + cnt);
}
}
//判斷出不是覆蓋的patten,所以無腦從前往後覆蓋
else {
while(cnt-- > 0){
*tmp++ = *st++;
}
}
return dest;
}
int main(){
char s1[20] = {‘a‘,‘b‘,‘c‘,‘d‘};
char *s2 = "xyzdef";
char *s3 = my_memmove(s1,s1+1,3);
printf("s1 = [%s]\n", s1);
printf("s3 = [%s]\n", s3);
char s11[20] = {‘a‘,‘b‘,‘c‘,‘d‘};
char *s22 = "xyzdef";
char *s33 = memmove(s11,s11+1,3);
printf("s11 = [%s]\n", s11);
printf("s33 = [%s]\n", s33);
int i1[10] = {1,2};
int i2[10] = {11,22,33,3};
int i3[10] = {1};
int *pi3 = i3;
pi3 = (int*)my_memmove(i2+2,i2,sizeof(int) * 3);
for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
printf("i1[%d] = %d ",i, i2[i]);
}
printf("\n");
for(int i = 0; i < sizeof(i2) / sizeof(int); ++i){
printf("i3[%d] = %d ",i, pi3[i]);
}
printf("\n");
}
memset memcmp memcpy memmove 自己實現