문자열 처리 기능 및 메모리 처리 기능의 시뮬레이션 구현

헤헤 오늘 이 시리즈가 나오네요.

목차

1. 문자열 처리 기능​

1. strlen의 세 가지 형태

1. 카운터

2. 재귀

3. 포인터 - 포인터

2. strcmp 시뮬레이션 구현

3. strcat 시뮬레이션 구현

4. strcpy 시뮬레이션 구현

5. strstr 시뮬레이션 구현

6. strtok 구현

2. 메모리 처리 기능

1. memcpy 시뮬레이션 및 구현

2. memmove 구현 시뮬레이션


1. 문자열 처리 기능

 위의 내용은 몇 가지 일반적인 문자열 처리 함수입니다. 시뮬레이션 구현의 목적은 나중에 이러한 함수를 사용할 수 없을 때 주로 수행 방법을 배우기 위해 직접 작성하는 것입니다.

1. strlen의 세 가지 형태

1. 카운터

#define _CRT_SECURE_NO_WARNINGS 1
//计数器
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	int count = 0;
	assert(dest);
	while (*dest++) {
		count++;
	}
	return count;

}
int main() {
	char arr[] = "hello";

	printf("%d",my_strlen(arr));


	return 0;
}

2. 재귀

#define _CRT_SECURE_NO_WARNINGS 1
//递归
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	assert(dest);
	if (!* dest)
		return 0;
	return 1 + my_strlen( dest + 1);
}
int main() {
	char arr[] = "hello";

	printf("%d", my_strlen(arr));


	return 0;
}

3. 포인터 - 포인터

#define _CRT_SECURE_NO_WARNINGS 1
//指针-指针
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* dest) {
	assert(dest);
	const char* p = dest;
	while (*p) {
		p++;
	}
	return p - dest;

}
int main() {
	char arr[] = "hello";

	printf("%d", my_strlen(arr));


	return 0;
}

2. strcmp 시뮬레이션 구현

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* arr1, const char* arr2) {
	assert(arr1 && arr2);
	while (*arr1 == *arr2 ) {
		arr1++;
		arr2++;
		if(*arr2=='\0')
		return 0;
	}
	return *arr1 - *arr2;
}

int main() {

	char arr1[20] = "hello ";
	char arr2[] = "world";
	int ret=my_strcmp(arr1, arr2);
	if (ret == 0) {
		printf("arr1=arr2");
	}
	if (ret < 0) {
		printf("arr1<arr2");
	}
	if (ret > 0) {
		printf("arr1>arr2");
	}

	return 0;
}

3. strcat 시뮬레이션 구현

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* res) {
	assert(dest && res);
	char* p = dest;
	while (*dest) {
		dest++;
	}
	while (*dest++=*res++) {
		;
	}

	return p;
}

int main() {
	char arr1[20] = "hello ";
	char arr2[] = "world ";

	printf("%s\n", my_strcat(arr1, arr2));

	return 0;
}

4. strcpy 시뮬레이션 구현

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest,char * src) {
	assert(dest && src);
	char* p = dest;
	while (*dest++ = *src++);
	return p;
}
int main() {
	char arr1[20] = "hello ";
	char arr2[] = "world";
	
	printf("%s\n",my_strcpy(arr1, arr2) );

	return 0;
}


5. strstr 시뮬레이션 구현

#define _CRT_SECURE_NO_WARNINGS 1
//模拟实现strstr函数
//在arr1中找是否包含arr2数组
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1, const char* str2) {
	assert(str1 && str2);
	const char* s1 = NULL;
	const char* s2 = NULL;
	//如果*str2=0;则需要返回str1的地址,所以str1的地址不能变
	char* cp = str1;

	if (*str2 == '\0') {
		//由于我定义的是const类型的,所以返回时需要强制转换为char*类型
		return (char*)str1;
	}

	while (*cp) {
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && (*s1 == *s2)) {
			s1++;
			s2++;
		}
		//这里必定是由上面的while中跳出来的,因为上面已经筛选过了,当*s2结束,返回当前cp的地址
		if (*s2 == '\0')
			return (char*)cp;
		cp++;
	}
	//要么是找不到,*s2为0,程序直接结束,要么也是找不到,直到*cp为0,返回空指针,要么因为*s1为0,返回空指针
	return NULL;
}
int main() {
	char arr1[] = "abdjkhgio";
	char arr2[] = "jk";

	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL) {
		printf("No found!");
	}
	else {
		printf("%s", ret);
	}

	return 0;
}

6. strtok 구현

#define _CRT_SECURE_NO_WARNINGS 1
//strtok函数实现
#include<stdio.h>
#include<string.h>
int main() {
	char arr[] = "[email protected]";
	char* p = "@.";

	char tmp[20] = {0};

	strcpy(tmp, arr);

	char* ret = NULL;
    //strtok的返回值是遇到标志的地址,所以之后都是从null开始,函数将标志改为了\0
	for (ret = strtok(tmp, p); ret; ret = strtok(NULL, p)) {
		printf("%s\n", ret);
	}

	return 0;
}

2. 메모리 처리 기능

1. memcpy 시뮬레이션 및 구현

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
//num指的是字节长度
void* my_memcpy(void* dest, const void* src, size_t num) {
	void* ret = dest;
	assert(dest && src);
	//这个函数是一个字节一个字节的传,为了能让多种数据都能使用该函数,强制转换为char*类型
	while (num--) {
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
		//*(char*)dest++=*(char*)src++;
		//这种方法是错的 ,解引用强制转换了之后,在进行++操作时,强制转换的作用已经不存在了
	}

	return ret;
}
int main() {
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	//arr2要够长,不然容易栈溢出。
	my_memcpy(arr2, arr1, 20);

	for(int i=0;i<5;i++)
	printf("%d\n", *(arr2+i));
	
	return 0;
}

2. memmove 구현 시뮬레이션

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t num) {
	void* ret = dest;
	assert(dest && src);
	if (dest < src) {
		while (num--) {
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else {
		while (num--) {
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main() {
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };

	my_memmove(arr1 + 2, arr1, 20);


	return 0;
}

지침:

 memcpy 함수는 겹치지 않는 메모리를 복사해야 합니다.

memmove 함수는 메모리 중복을 처리할 수 있습니다.

C 언어의 요구 사항에 따라 memcpy는 겹치지 않는 메모리만 복사할 수 있지만 VS에서는 겹치는 메모리를 복사할 수 있습니다.

추천

출처blog.csdn.net/m0_63309778/article/details/121855286