기사 디렉토리
머리말
C 언어로 된 Strcpy 라이브러리 기능 의 자체 구현을 통해 프로그램 최적화의 아름다움을 탐구하고 프로그램의 신비 !
1. Strcpy 라이브러리 기능이란 무엇입니까?
Strcpy 라이브러리 함수의 기능: 문자열 복사를 실현
strcpy ( char * destination, const char * source );
구현 원리: strcpy 함수의 괄호 뒤에 복사할 문자열의 주소를 넣고 괄호 앞에 복사된 문자열의 대상을 넣습니다. 주소 전송 을 통해 문자열을 복사합니다 .
위의 간단한 이해를 통해 실제로 문자 를 하나씩 교환하여 문자열을 복사하는 것이 가능하다는 것을 알 수 있으며 이제 Strcpy 기능 을 구현하는 사용자 정의 기능을 구현할 수 있습니다.
둘째, 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;
}
여기에 인쇄된 것은 복사된 문자열입니다.
일부 학생들은 "arr1 배열의 나머지 x는 어떻습니까?"라고 물을 수 있습니다.
여기에서 관찰할 수 있습니다. Strcpy는 arr2의 "hello"를 arr1로 복사합니다
(그리고 첫 번째 요소 를 하나씩 덮어씁니다) .
Essence: arr1 의 처음 몇 개의 "x" 를 arr2 의 "hello \0" 으로 덮는 것 입니다.
즉, 복사한 arr1을 인쇄 printf 는 "\0" 이전의 모든 문자를 인쇄합니다 ("\0" 은 문자열의 끝 식별자임) . 따라서 "\0" 으로 인쇄 하고 인쇄를 중지합니다 .
이것이 나머지 "x"가 인쇄되지 않는 이유입니다.
이 작은 에피소드를 풀고 나면 기본적으로 Strcpy가 어떻게 작동하는지 이해하고
우리 언어로 구현해 봅시다!
3. My_Strcpy의 구현
1.“전채”
먼저 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. My_Strcpy 함수 구현
Ⅰ. "복제 프로세스" 최적화
여기 에서 "전채"를 무시하고 직접
사용자 정의 기능 섹션을 시작 하십시오.
void My_Strcpy(char* dest,char* src) //dest指针接收目标数组的首元素地址;
//src指针接收要复制的数组首元素地址
{
while(*src != '\0')
{
*dest = *src;
dest++;
src++;
} //但是这样设置循环条件的话,是不会把'\0'也给复制的
//所以得加多一条语句
*dest = *src; //因为上面循环已经让地址到'\0'的地方
//只是循环条件为假,所以不执行
//所以可以承接上面++后的地址,执行一次,即可把'\0'也复制
}
그러나 '\0'을 루프에도 통합할 수 있는 방법이 있습니까?
당신도 그러한 생각을 가지고 있다면 "프로그램의 아름다움" - 최적화
를 시작하신 것을 축하 드립니다.
그럼 '최적화' 를 시작해 봅시다 ! !
"한 단계"를 수행하려면 먼저 루프의 조건을 통합하려고 시도할 수 있습니다.
void My_Strcpy(char* dest,char* src)
{
while(*src != '\0')
{
*dest++ = *src++; //跟之前意思一样
//先复制,然后地址++,然后解引用 复制
}
*dest++ = *src++;
}
'한 번에 한 걸음' 시작하자
void My_strcpy(char* dest,char* src)
{
while(*dest++ = *src++)
{
; //上面的条件,既可以先复制
} //当复制'\0'后,条件判断为假,又可以退出循环
} //这样不就能做到“一步到位”、“一石二鸟”了吗!
이것을 보면
'프로그램'이 가져다주는 '깨달음'이 느껴지시나요? 더 많은 "멋진"
것들이 있습니다! !
Ⅱ. "기능 내부" 최적화
함수의 실행 가능성을 보장하기 위해 전달된 것이 null 포인터 인지 여부 를 판단
해야 합니다. 이것이 "최적화" 의 두 번째 포인트 입니다 ~
이 판단 작업을 위해 "assert()"
를 사용할 수 있습니다.
그런 다음 이것을 사용하여 전달된 두 포인터가 함수 의 실행 및 정확성
을 보장 하기 위해 null 포인터인지 여부를 결정할 수 있습니다.
void My_Strcpy(char*dest , const char*src)
{
//判断传过来的 是否为空指针
assert( src != NULL);//断言----需要引头文件 <assert.h>
// 如果 != 则 为真--则不会报错,
//如果为假(即 指针为 空指针)--则会报错
assert( dest != NULL);
while (*dest++ = *src++)
{
;
}
}
assert 추가 의 또 다른 이점은 그것이 널 포인터 인 경우 프로그램 이 오류 위치를 신속하게 제공 할 수도 있다는 것입니다(이것은 if 문 이 할 수 없는 것 입니다)
다음과 같이:
누가 그런 프로그램을 사용하는 것에 대해 걱정하지 않겠습니까?
Ⅲ. "함수 매개변수" 최적화
이전 장 "Strcpy 라이브러리 함수란 무엇인가" 를 다시 살펴보면 My_Strcpy 함수 가 Strcpy 라이브러리 함수 와 비교하여 " 다르다"
는 것을 찾는 것이 어렵지 않습니다 . 이는 아직 "최적화" 의 여지가 있음을 나타냅니다 !
My_Strcpy 함수 의
형식 매개변수 부분과 비교하여 여기 에서 "형식 매개변수" 부분 이 수정해야 할 " const" 가 더 많다는 것을 찾는 것은 어렵지 않습니다 .
지금 이 순간부터 생각을 시작해야 한다 - 이걸 왜 할까
[PS: 이 부지런한 사고 의 습관을 들이 는 것이 프로그램의 훌륭한 기준~]
이렇게 하면 복사 프로세스 중에 보호된 "복사된 콘텐츠"가 복사 프로세스 중에 변경되지 않도록 할 수 있습니다.
[PS: "포인터에서 const 연산자의 적용"에 대해서는 당분간 이야기하지 않겠습니다! ]
이 글이 잘 쓰여지고 이해하기 쉽다고 생각
되시면 좋아요, 리포스트, 즐겨찾기 해주시면 됩니다!
저자는 이와 관련하여 가능한 한 빨리 관련 콘텐츠를 게시할 예정입니다! !
요점으로 돌아가기
* 앞에 'const' 를 붙이면
* 소스 ( My_Strcpy의 ' * src '에 해당 ) 즉, 역참조 이 상수 속성을 가 집니다. 복사 과정에서 소스 값은 변경 되지 않습니다 . *
소스의 주소가 변경되는 경우, 즉 소스에 해당하는 내용이 변경되는 경우에만 해당 값이 변경됩니다.
이것은 다음과 같은 문제를 효과적으로 피할 수 있습니다
void My_Strcpy(char* dest,const char* src) ![在这里插入图片描述](https://img-blog.csdnimg.cn/66a1220bbfbe4150bb78364a367522ee.png#pic_center)
{
while( *src++ = *dest++)
{
; //复制的时候,放错位置的情况
}
}
위의 문제가 발생하면 프로그램이 자동으로 오류를 보고하여 프로그램을 보호합니다.
이때 *src 는 assign 과 동일한 상수 속성 을 가지므로 등호 왼쪽에 상수를 배치할 수 없습니다 .
src가 가리키는 내용을 dest가 가리키는 공간에 복사한다. 본질적
으로, dest가 가리키는 내용이 수정되기를 바라며, src가 가리키는 내용은 수정되지 않기를 바란다.
이것이 우리의 "최적화"의 또 다른 포인트입니다~
Ⅳ. "함수 반환형" 최적화
다시 Strcpy 라이브러리 함수들을 비교해보면 , Strcpy 라이브러리 함수 들의 반환 타입 이 실제로 char 임을
찾는 것은 어렵지 않습니다 . * 이것은 다시 "최적화" 되지 않습니다 ~~
라이브러리 함수 Strcpy는 실제로 대상 공간 의 시작 주소 를 반환 합니다.
그런 다음 다음 "최적화" 를 수행할 수 있습니다.
#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;
}
char * return type 을 사용하면 대상 공간 내용이 더 빠른 것을 볼 수 있습니다 ~~
넷째, My_Strcpy 함수를 완성합니다.
요약하자면, My_Strcpy 함수 의 최적화 에
성공 했고 , 최적화할 수 있는 모든 포인트가 최적화되었습니다 ~ 즉 , Strcpy 함수를 성공적 으로 복사 했습니다 . !
그러나 이것은 "큰 마녀를 보는 것은 작은 일"일 뿐이며 학생들에게 " 벽돌 을 세우고 옥을 끌어들이는" 역할 을 합니다. 학생들 도이 !
프로그래밍의 세계는 넓고 , 탐험하고 발견 하고 갑자기 깨달음을 얻는 순간을 찾기
위해 더 많은 미지의 것들이 여러분을 기다리고 있습니다 ~
5. 지원해주셔서 감사합니다! ! !
[이 글이 도움이 되셨다면 좋아요와 응원 부탁드립니다~]
[더 좋은 아이디어가 있다면 아래 댓글도 함께 해주시고, 서로에게서 배우고, 발전해 나가세요! ]