"C와 포인터" 읽기 참고 사항(9장 문자열, 문자 및 바이트)

0 소개

C 언어에서는 문자열과 배열이 유사점이 많으며 호출을 위한 공식 라이브러리 함수가 많이 제공됩니다. 그렇다면 자매 문자열과 배열은 어떤 긴밀한 관계를 맺고 있나요? 이번 호의 핵심 인물인 문자열의 특징은 무엇일까요?

C 언어에는 명시적인 문자열 데이터 유형이 없습니다. 왜냐하면 문자열은 문자열 상수로 나타나거나 문자 배열에 저장되기 때문입니다. 문자열 상수는 프로그램에 의해 수정되지 않는 문자열에 적합합니다. 다른 모든 문자열은 문자 배열이나 동적으로 할당된 메모리에 저장되어야 합니다 .

이 기사에서는 문자열에 일반적으로 사용되는 라이브러리 함수를 소개하는 데 중점을 두어 모든 사람이 다양한 상황에서 가장 적합한 라이브러리 함수를 선택할 수 있도록 합니다. 다음은 이 글의 내용을 개괄적으로 정리한 것입니다

여기에 이미지 설명을 삽입하세요.

1 문자열 기본

문자열은 비트 패턴이 all 인 바이트로 끝나는 시퀀스 0个또는 문자입니다 . 예를 들어:多个0NUL

	char message[] = "hello word";

2줄 길이

문자열의 길이는 마지막 종결자를 제외하고 포함된 문자 수입니다 . 이것은 종종 인터뷰 중에 테스트됩니다.

문자열의 길이는 라이브러리 함수 strlen()을 통해 자동으로 계산될 수 있습니다.
예를 들어:

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

int main()
{
    
    
	char message[] = "hello word";
	printf("字符串的长度为:%d\n",strlen(message));
	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
이 함수는 부호 없는 숫자를 반환하므로 이 함수를 통해 두 문자열의 길이를 비교할 때 특별한 주의가 필요합니다.

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

int main()
{
    
    
	char message1[] = "hello word";
	char message2[] = "hello Shanghai";
	//比较方式1 
	if(strlen(message1) >= strlen(message2))
		printf("字符串1更长\n");
	else
		printf("字符串2更长\n");
	//比较方式2 
	if (strlen(message1) - strlen(message2) >= 0)
		printf("字符串1更长\n");
	else
		printf("字符串2更长\n");
	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
부호 없는 숫자가 반환되므로비교 방법 2, 조건부 판단의 결과는 항상 참이므로 판단 결과에 오류가 발생합니다.

3 무제한 문자열 함수

소위 무제한 문자열 함수는 사용 시 문자열의 길이(실제 매개변수)를 지정할 필요가 없으며 함수가 원활하게 실행될 수 있음을 의미합니다.

3.1 문자열 복사

문자열을 복사하는 것은 개발 시 자주 사용되지만, 새로운 문자열에 복사하면 원래 부분을 덮어쓰게 되므로 특별한 주의가 필요합니다.
예를 들어:

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

int main()
{
    
    
	char message1[] = "hello word";
	char message2[] = "hello Shanghai";

	int message2_len = strlen(message2);

	printf("字符串2的长度为:%d\n", strlen(message2));

	strcpy(message2,message1);

	printf("字符串2的长度为:%d\n",strlen(message2));
	for(int i = 0; i < message2_len; i++)
		printf("%c",message2[i]);
	system("pause");
	return 0;
}

인쇄 출력: 문자열을 에 복사한 후 실제로 길이가 다른
여기에 이미지 설명을 삽입하세요.
것을 볼 수 있는데 , 왜 그럴까요?message1message2message2

이는 문자열을 복사할 때 종결자도 복사되기 때문입니다. strlen()함수가 처리되면 반드시 를 반환할 것입니다 10. 인쇄된 결과를 보면 message2문자열의 나머지 부분은 그대로 유지됩니다.

긴 문자열을 짧은 문자열로 복사할 때 복사해야 하는 문자를 수용할 공간이 부족하기 때문에 오류가 보고되는 경우가 많습니다.

3.2 연결 문자열

문자열을 연결할 때 strcat() 함수를 사용할 수 있습니다. 그 프로토타입은 다음과 같습니다:

char *strcat(char *dst, char const *src);

예를 들어:

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

int main()
{
    
    
	char message1[] = "hello word";
	char message2[] = "hello Shanghai";

	strcat(message1,message2);
	printf("%s\n", message1);

	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
두 문자열이 직접 연결되어 있는 것을 볼 수 있습니다. 새 문자열의 길이 값은 원래 두 문자열 길이의 합입니다 .

3.3 함수의 반환값

이러한 함수의 반환 값은 때로는 첫 번째 매개변수의 복사본이므로 중첩될 수 있습니다. 문자열이 실제 매개변수로 사용될 때 첫 번째 요소의 주소도 전달되기 때문입니다. 따라서 이러한 함수는 종종 중첩이라고 부를 수 있습니다.
예를 들어:

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

int main()
{
    
    
	char message1[] = "hello ";
	char message2[] = "word ";
	char message3[] = "Shanghai";

	strcat(strcat(message1, message2), message3);
	printf("%s\n", message1);

	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
하지만 프로그램의 가독성을 위해 중첩하지 않아도 괜찮습니다.

3.4 문자열 비교

문자열 비교에는 일반적으로 사용되는 라이브러리 함수가 하나만 있습니다 strcmp. 그 프로토타입은 다음과 같습니다:

int  strcmp(char  const  *s1,  char  const  *s2);

이 함수의 비교 규칙은 매우 흥미롭습니다. 이 함수는 불일치가 발견될 때까지 두 문자열의 문자를 하나씩 비교합니다. 여기에는 두 가지 상황이 있습니다.

  1. 일치하지 않는 첫 번째 문자 중에서 ASCII 순위가 가장 높은 문자를 포함하는 문자열은 더 작은 문자열로 간주됩니다.
  2. 시작 부분의 두 문자열이 동일한 경우 더 짧은 문자열이 더 작은 문자열로 간주됩니다.

문자열에서 일치하지 않는 특정 문자가 발견되면 나머지 부분을 비교하지 않고 비교 결과를 얻을 수 있습니다.
아래와 같이
여기에 이미지 설명을 삽입하세요.
실제 코드를 살펴보세요.

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

int main()
{
    
    
	char temp1[] = "hello";
	char temp2[] = "hello world";
	char temp3[] = "hello worLd";
	//字符串temp1和temp2作比较
	if(strcmp(temp1,temp2) == 0)
	{
    
    
		printf("temp1 = temp2\n");
	}
	else if (strcmp(temp1, temp2) > 0)
	{
    
    
		printf("temp1 > temp2\n");
	}
	else if (strcmp(temp1, temp2) < 0)
	{
    
    
		printf("temp1 < temp2\n");
	}
	printf("------------------\n");
	//字符串temp2和temp3作比较
	if (strcmp(temp2, temp3) == 0)
	{
    
    
		printf("temp2 = temp3\n");
	}
	else if (strcmp(temp2, temp3) > 0)
	{
    
    
		printf("temp2 > temp3\n");
	}
	else if (strcmp(temp2, temp3) < 0)
	{
    
    
		printf("temp2 < temp3\n");
	}

	printf("\n");
	system("pause");
	return 0;
}

인쇄물:
여기에 이미지 설명을 삽입하세요.

4 제한된 길이의 문자열 함수

일부 라이브러리 함수를 호출할 때 처리할 문자열의 길이를 전달해야 하므로 이를 길이 제한 문자열 함수라고 합니다.

이러한 함수는 예측할 수 없는 긴 문자열이 대상 배열에서 오버플로되는 것을 방지하는 편리한 메커니즘을 제공합니다.
몇 가지 일반적인 기능이 있습니다:

char    *strncpy(char  *dst,  char  const  *src,  size_t  len);
char    *strncat(char  *dst,  char  const  *src,  size_t  len);
int    strncmp(char  const  *s1,  char  const  *s2,  size_t  len);

예를 들어:

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

int main()
{
    
    
	char message1[] = "hello ";
	char message2[] = "hello Beijing ";
	char message3[] = "Shanghai";
	char message_all[] = "hello Beijing Shanghai";


	if(strncmp(strncpy(strncat(message2, message3, strlen(message3)), message1, strlen(message1)), message_all,strlen(message_all)) == 0)
		printf("二者相等\n");
	else
		printf("二者不相等\n");

	system("pause");
	return 0;
}

인쇄물:
여기에 이미지 설명을 삽입하세요.
이 예는 그다지 적절하지 않습니다. 길이는 최대값에 맞춰 전달되기 때문에 문제를 설명할 수도 있습니다.

5 문자열 검색의 기본

표준 라이브러리에는 문자열을 찾기 위해 다양한 방법을 사용하는 많은 함수가 있습니다. 이러한 다양한 도구는 C 프로그래머에게 상당한 유연성을 제공합니다.

5.1 문자열 찾기

문자열에서 특정 문자를 찾는 데 사용할 수 있는 두 가지 라이브러리 함수가 있습니다.

char *strchr(char const *str, int ch);
char **strrchr(char const *str, int ch);

전자는 특정 문자를 찾는 데 사용됩니다.첫 번째문자를 찾는 데 사용되는 발생 위치(주소에 대한 포인터 반환)마지막으로이것이 발생한 위치(해당 주소에 대한 포인터를 반환).

이 두 함수는 다음과 같이 사용할 수 있습니다.

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

int main()
{
    
    
	char message1[] = "hello ";
	char message2[] = "hello Beijing ";
	char message3[] = "Shanghai";
	char message_all[] = "hello Beijing Shanghai";

	char *first_site, *last_site;

	first_site = strchr(message_all, 'h');
	last_site = strrchr(message_all, 'h');

	printf("字符串的长度是:%d\n",strlen(message_all));
	printf("h第一次出现的位置是:%d\n", first_site - message_all);
	printf("h最后一次出现的位置是:%d\n", last_site - message_all);
	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
이 함수는 대상 요소 위치의 값이 아니라 포인터를 반환하므로 결과를 얻으려면 문자열의 첫 번째 요소 포인터와 달라야 한다는 점에 유의해야 합니다.

참고: 검색은 대소문자를 구분합니다.

5.2 몇 개의 문자 찾기

strpbrk대상 문자열의 문자열에서 처음으로 나타나는 문자를 찾는 데 사용되는 보다 일반적인 함수입니다. 그 프로토타입은 다음과 같습니다:

char *strpbrk(char  const *str,   char  const  *group);

다음과 같이 사용할 수 있습니다.

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

int main()
{
    
    
	char message_all[] = "hello Beijing Shanghai";
	char *first_site;

	first_site = strpbrk(message_all, "abcde");

	printf("字符串的长度是:%d\n",strlen(message_all));
	printf("abcde第一次出现匹配字符的位置是:%d\n", first_site - message_all);
	system("pause");
	return 0;
}

인쇄 출력: 첫 번째로 일치하는 문자가 이고 위치가 임을
여기에 이미지 설명을 삽입하세요.
쉽게 알 수 있습니다 .e1

5.3 하위 문자열 찾기

문자열에서 하위 문자열을 찾으려면 strstr 함수를 사용할 수 있습니다. 해당 함수의 프로토타입은 다음과 같습니다.

char  *strstr(char  const  *s1,  char  const  *s2);

실제 사용 예를 들면 다음과 같습니다.

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

int main()
{
    
    
	char message_all[] = "hello Beijing Shanghai";
	char *first_site;

	first_site = strstr(message_all, "Beijing");

	printf("字符串的长度是:%d\n",strlen(message_all));
	printf("Beijing第一次出现的位置是:%d\n", first_site - message_all);
	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
이 검색에서는 특정 문자나 부분 문자가 아닌 모든 문자가 일치해야 함을 알 수 있습니다.

6 고급 문자열 검색

다음 함수 세트는 문자열의 시작 부분에서 부분 문자열을 찾고 추출하는 프로세스를 단순화합니다.

6.1 문자열 접두사 찾기

strspn함수 strcspn는 문자열의 시작 위치에서 문자열을 계산하는 데 사용되며 해당 프로토타입은 다음과 같습니다.

size_t  strspn(  char  const   *str,  char const  *group);
size_t  strcspn(  char  const   *str,  char const  *group);

이 두 함수는 요소 포인터가 아니라 일치하는 문자의 실제 개수를 반환한다는 점에 유의해야 합니다.

구체적인 사용법은 다음 예를 참조하세요.

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

int main()
{
    
    
	int len1, len2;
	char buffer[] = "25,142,330,smith,J,239-4123";

	len1 = strspn(buffer, "0123456789");
	len2 = strcspn(buffer, ",");

	printf("0123456789的起始匹配数是:%d\n", len1);
	printf(",的起始不匹配数是:%d\n", len2);
	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
위의 예에서 볼 수 있듯이 strspn함수는 찾을 수 없을 때까지 찾고 있는 문자열과 일치하는 문자를 처음부터 찾기 시작합니다. 이 예에서는 ,더 이상 적합하지 않으므로 연속검색의 경우 하나만 2적합합니다.

strcspn 함수는 정반대인데 찾는 내용이 일관성이 없고 처음의 2와 5는 당연히 일치하지 않지만 일관성이 있으므로 ,연속탐색의 경우 적합한 것이 있다 2.

6.2 찾기 표시

문자열에는 서로 분리된 여러 개의 개별 부분이 포함되는 경우가 많습니다. 이러한 부분을 처리할 때마다 먼저 문자열에서 해당 부분을 추출해야 합니다.
strtok 함수는 이러한 기능을 달성할 수 있습니다. 문자열에서 토큰이라는 개별 부분을 분리합니다. 구분 기호를 삭제합니다. 그 프로토타입은 다음과 같습니다:

char  *strtok(  char  *str,  char const  *sep);

알아채다:

  1. strtok 함수는 작업을 수행할 때 처리하는 문자열을 수정합니다. 소스 문자열을 수정할 수 없는 경우 복사본을 만들고 이 복사본을 strtok 함수에 전달합니다.
  2. strtok 함수의 첫 번째 매개변수가 NULL이 아닌 경우 함수는 문자열의 첫 번째 토큰을 찾습니다. strtok은 또한 문자열에 해당 위치를 저장합니다. strtok 함수의 첫 번째 매개변수가 NULL인 경우, 함수는 이전과 같이 저장된 위치부터 동일한 문자열에서 다음 토큰을 검색합니다.

예를 들어:

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

int main()
{
    
    
	int add = 0;
	char buffer[] = "25,142,330,smith,J,239-4123";
	char *token = NULL;
	for (token = strtok(buffer, ","); token != NULL; token = strtok(NULL, ","))
	{
    
    
		printf("%s\n", token);
		add++;
	}
	printf("--------------------------\n");
	printf("add的值为:%d\n",add);
	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
위의 예에서 볼 수 있듯이 경계로 찾아야 하는 표시를 사용하면 각 루프는 모든 분할이 완료될 때까지 분할된 하위 문자열을 얻습니다. 6총 시간을 나누었습니다 .

7개의 오류 메시지

C 언어 라이브러리 함수가 실행되지 않으면 오류 코드(0 1 2 3 4 5 6 7 8 9...)가 발생하며 운영 체제는 외부 정수 변수를 설정하여 errno오류 코드를 보고합니다 . 즉, 오류 코드는 오류 유형에 해당하며, strerror함수는 오류 코드 중 하나를 매개 변수로 사용하여 포인터를 반환합니다.오류를 설명하는 문자열에 대한 포인터. 이 함수의 프로토타입은 다음과 같습니다.

char  *strerror(int error_number);

예를 들어:

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

int main()
{
    
    
	for(int i = 0; i < 10; i++)
		printf("%s\n",strerror(i));
	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
서로 다른 작업 코드가 서로 다른 오류 유형에 해당하는 것을 볼 수 있으며 오류 코드는 0오류가 없음을 나타냅니다. 다른 것들은 다양한 오류를 나타냅니다. 이 부분만 이해해주세요. 마스터링이 필요하지 않습니다. 각 opcode가 어떤 오류를 나타내는지 알 필요가 없습니다.

8가지 문자 조작

표준 라이브러리에는 개별 문자를 조작하기 위한 두 가지 함수 세트가 포함되어 있으며 해당 프로토타입은 헤더 파일 ctype.h에 있습니다. 첫 번째 함수 집합은 문자열을 분류하는 데 사용되고 두 번째 함수 집합은 문자를 변환하는 데 사용됩니다.

8.1 문자 분류

각 분류 함수는 문자 값을 포함하는 정수 매개변수를 허용합니다. 함수는 이 문자를 테스트하고 참 또는 거짓을 나타내는 정수 값을 반환합니다. 아래 표에는 true를 반환하는 데 필요한 각 함수와 조건이 나열되어 있습니다.

기능 true를 반환하는 데 필요한 조건
iscntrl 제어 문자
isspace 공백 문자: 공백, 폼 피드 '\f', 줄 바꿈 '\n', 캐리지 리턴 '\r', 탭 't' 또는 세로 탭 '\v'
심지어 십진수
자기 자리 대문자와 소문자 a~f를 포함한 16진수
더 낮은 소문자
만찬 대문자
이사파 문자(대문자 또는 소문자)
아이스 홀 문자 또는 숫자
불명료한 숫자나 문자가 아닌 모든 그래픽 문자(인쇄 가능한 기호)
isgraph 모든 그래픽 문자
스프린트 그래픽 문자 및 공백 문자를 포함한 모든 인쇄 가능한 문자

따라서 이러한 함수는 문자열 요소를 결정하는 데 사용됩니다. 예를 들면 다음과 같습니다.

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

int main()
{
    
    
	char temp[] = "To carry things with great virtue";

	for (int i = 0; i < strlen(temp); i++)
	{
    
    
		if (islower(temp[i]))
			printf("temp[%d] : %c是小写字母\n", i, temp[i]);
		else if (isupper(temp[i]))
			printf("temp[%d] : %c是大写字母\n", i, temp[i]);
		else if(isspace(temp[i]))
			printf("temp[%d] : %c是空格\n", i, temp[i]);
	}

	printf("\n");
	system("pause");
	return 0;
}

인쇄 출력: 각 요소가 대문자인지, 소문자인지, 공백인지 판별된
여기에 이미지 설명을 삽입하세요.
것을 볼 수 있습니다 .temp

8.2 문자 변환

변환 함수는 대문자를 소문자로, 소문자를 대문자로 변환합니다. 호출할 수 있는 함수는 두 가지입니다. toupper함수 반환해당 매개변수의 해당 대문자 형식, tolower함수는 반환해당 매개변수에 해당하는 소문자 형식

int tolower(int  ch);
int toupper(int  ch);

실제적인 예를 들어보세요:

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

int main()
{
    
    
	char temp1[] = "To carry things with great virtue";
	char temp2[] = "To carry things with great virtue";
	//全转换为大写
	for (int i = 0; i < strlen(temp1); i++)
	{
    
    
		if (islower(temp1[i]))
			temp1[i] = toupper(temp1[i]);
		printf("%c",temp1[i]);
	}
	printf("\n-----------------------------\n");
	//全转换为小写
	for (int i = 0; i < strlen(temp2); i++)
	{
    
    
		if (isupper(temp2[i]))
			temp2[i] = tolower(temp2[i]);
		printf("%c", temp2[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}

인쇄 출력:
여기에 이미지 설명을 삽입하세요.
보시다시피 원하는 대로 문자열의 문자 대소문자를 조정할 수 있습니다.

9 메모리 작업

문자열은 일반적으로 NUL로 끝나지만, 중간에 NUL이 포함된 문자열이나 임의 길이의 바이트 시퀀스를 처리하려는 경우 이전 함수는 상대적으로 약하거나 전혀 사용할 수 없습니다. 그러나 실제 개발에서 일부 요구 사항을 완료하는 데 사용할 수 있는 또 다른 기능 세트가 있을 수 있습니다. 아래는 프로토타입입니다.

참고: 이 함수는 문자열뿐만 아니라구조또는정렬및 기타 데이터 유형 처리할 수 있는 특정 데이터 유형은 특정 기능에 따라 다릅니다.

void  *memcpy(void  *dst,  void  const  *src,  size_t  length);
void  *memmove(void  *dst,  void  const  *src,  size_t  length);
void  *memcmp(void  const  *a,  void  const  *b,  size_t  length);
void  *memchr(void  const  *a,  int  ch,  size_t  length);
void  *memset(void  *a,  int  ch,  size_t  length);

예를 들어:

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

#define SIZE 10

int main()
{
    
    

	char temp1[] = "hello world";
	char temp2[] = "hello world";
	char temp3[] = "hello world";
	char temp4[] = "hello world";
	unsigned int int_array[SIZE];
	char *p = NULL;

	//复制字符串
	memcpy(temp1 + 2, temp1, 5);
	memmove(temp2 + 2, temp2, 5);

	printf("temp1 = %s\n", temp1);
	printf("temp2 = %s\n", temp2);
	printf("---------------------------------------\n");
	//比较字符串
	if(!memcmp(temp1, temp2, 6))
		printf("temp1 = temp2\n");
	else
		printf("temp1 != temp2\n");
	printf("---------------------------------------\n");
	//查找字符
	p = (char *)memchr(temp3, 'e', strlen(temp3));
	if(p != NULL)
		printf("字符e在temp3中的位置是:%d\n", p - &temp3[0]);
	printf("---------------------------------------\n");
	//初始化数组
	memset(int_array, 0, sizeof(int_array));
	for (int i = 0; i < SIZE; i++)
		printf("int_array[%d]的值为:%d\t", i, int_array[i]);
	printf("\n", sizeof(int));
	printf("---------------------------------------\n");
	//初始化数组
	memset(temp4, 'a', sizeof(temp4) - 1);
	printf("字符串temp4为:%s\n", temp4);
	system("pause");
	return 0;
}

인쇄물:
여기에 이미지 설명을 삽입하세요.

9.1 memcpy와 memmove는 정말로 다른가요?

토론할 가치가 있는 질문이 있습니다.
memcpy와 memmove 기능이 실제로 동일한가요? "C와 포인터"와 인터넷에 있는 많은 의견은 다음과 같습니다. 둘은 다릅니다. src와 dst가 겹치면 memcpy에 문제가 있는 반면 memmove는 항상 이상적인 조건에 따라 실행될 수 있지만 우리 프로그램의 실행 결과는 그렇지 않습니다. 두 기능 모두 이상적으로 작동하는데 왜 그렇습니까?

유일한 설명은,소프트웨어의 실행 환경이 다르고 프로그램의 기본 라이브러리가 다르기 때문에 이러한 상황이 발생합니다.. 그러나 이것은 memcpy와 memmove의 이전 버전(즉, 두 버전이 다름)에 대한 우리의 연구에는 영향을 미치지 않습니다!

먼저 겹침이 무엇을 의미하는지, 겹침이 있을 때 문자열 복사로 인해 문제가 발생할 수 있는 이유를 살펴보겠습니다.
여기에 이미지 설명을 삽입하세요.
위는 우리 프로그램의 문자열 복사 작업에 대한 개략도입니다. src 부분 문자열과 dst 부분 문자열의 세 글자가 겹치는 것을 볼 수 있는데, 기존의 연산 방식을 따른다면 복사 후 다음과 같은 결과가 나올 것이다.
여기에 이미지 설명을 삽입하세요.
영역이 겹치면 복사 오류가 발생합니다. 즉, 원하는 값이 새 값으로 대체됩니다.씌우다로 인해 값을 원활하게 얻을 수 없게 되어 복사 후 temp1가 되었습니다 hehehehorld. memcpy이전에 문자열을 복사한 방법 입니다 .

그러면 이 문제를 깔끔하게 해결하는 방법을 살펴보고 memmove최적화해 보겠습니다. 보시다시피 복사 순서가 바뀌었는데 이번에는 뒤에서 앞으로 복사해 주므로 이러한 문제가 잘 방지됩니다.memcpy
여기에 이미지 설명을 삽입하세요.

그렇다면 질문이 나옵니다. 이번에는 복사할 대상이 뒤쪽입니다. 앞쪽이면 어떻게 해야 할까요? 정답은 복사 순서도 반대라는 것입니다. 실행 과정을 살펴보세요:
여기에 이미지 설명을 삽입하세요.
이때 가져오려는 값은 원래 값으로 덮어쓰이지 않고 예상한 결과에 따라 실행됩니다. 결과는 다음과 같습니다 llo w world.

9.2 memcmp: 단순 비교

memcmp메모리 영역 a와 첫 번째 length 바이트를 비교합니다. 비교방법과 반환값은 strcmp기본적으로 동일하며, 자세한 내용은 본 글 항목을 참고하시기 바랍니다 strcmp.

9.3 memchr: 단순 검색

memchr은 a의 시작 위치에서 시작하여 ch 문자가 처음 나타나는 위치를 검색하고 해당 위치에 대한 포인터를 반환합니다. 검색방법과 반환값은 strchr기본적으로 동일하며, 자세한 내용은 본 글 항목을 참고하시기 바랍니다 strchr.

9.4 memset: 초기화된 값은 0과 -1만 가능한가요?

이 함수의 도입으로 볼 때, 이 함수는 연속적인 메모리 영역에 대해 (이론적으로) 동일한 값을0 설정할 수 있지만, 실제 개발에서는 기본적으로 또는 으로 설정되어 있는데 -1, 왜 그럴까요?

이는 이 함수가 메모리에 값을 바이트 단위로 할당하기 때문인데, 문자열의 요소는 1바이트만 차지하고 배열이 다르기 때문에 문제 없이 문자열에 값을 할당하는 데 일반적으로 사용된다. 유형 배열 요소가 1바이트를 초과하므로 초기화 시 예상한 결과가 생성되지 않습니다. 0으로 설정하면 각 바이트는 0(-1이면 각 비트는 1)이므로 각 요소는 바이트 수에 관계없이 0으로 초기화되지만 다른 값의 경우 결과는 초기화되지 않습니다. 똑같아. 똑같아. 다음 절차를 참조하세요.

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

#define SIZE 10

int main()
{
    
    
	unsigned int int_array[SIZE];

	//初始化数组
	printf("--------------初始化值设为0-------------------------\n");
	memset(int_array, 0, sizeof(int_array));
	for (int i = 0; i < SIZE; i++)
		printf("int_array[%d]的值为:%d\t", i, int_array[i]);
	printf("\n");
	printf("--------------初始化值设为1-------------------------\n");
	memset(int_array, 1, sizeof(int_array));
	
	for (int i = 0; i < SIZE; i++)
		printf("int_array[%d]的值为:%d\t", i, int_array[i]);
	printf("\n");
	system("pause");
	return 0;
}

인쇄물: 여기에 이미지 설명을 삽입하세요.
왜 그렇죠?

이는 memset값이 바이트 단위로 지정되고 int유형 데이터가 4메모리에서 3바이트를 차지하므로 값은 4바이트 단위여야 합니다. 즉, 0x0101010110진수로 변환하면 정확히 입니다 16843009.

memse따라서 일반적으로 메모리 영역에 동일한 값을 설정 하려면 0또는 로 초기화하는 -1것이 최선의 선택입니다.

10 요약

문자열 자체는 그다지 복잡하지 않으며, 개발을 용이하게 하기 위해 많은 라이브러리 기능을 제공하고 있으므로 C 언어에서는 해당 라이브러리 기능만 익히면 됩니다. 특히, 일부 함수는 숫자 값이 아닌 포인터를 반환하고, 일부 함수는 사용하기에 더 특별하다는 점에 유의하세요 strtok.

------------------------------------- ----------------------끝--------------------------- ---------------------------------

추천

출처blog.csdn.net/weixin_43719763/article/details/130913227