문자열이 null로 종료되는 이유는 무엇입니까?또는: null-terminal vs. 문자 + 길이 저장
나는 C에서 언어 통역사를 쓰고 있고, 나의.string
유형에 a가 포함되어 있습니다.length
속성은 다음과 같습니다.
struct String
{
char* characters;
size_t length;
};
이 때문에 C에는 이런 종류의 문자열을 지원하는 기능이 내장되어 있지 않기 때문에 나는 통역사에서 많은 시간을 수동으로 처리해야 합니다.기본적인 C를 준수하기 위해 단순한 null-terminated 문자열로 전환하는 것을 고려했지만, 다음과 같이 하지 않을 이유가 많은 것 같습니다.
Null을 찾는 대신 "length"를 사용하는 경우 경계 검사가 기본 제공됩니다.
문자열의 길이를 찾기 위해 전체 문자열을 횡단해야 합니다.
null-terminated 문자열 중간에 null 문자를 처리하려면 추가 작업을 수행해야 합니다.
null-terminated 문자열은 유니코드를 잘 다루지 못합니다.
null이 아닌 문자열은 더 많은 인턴을 할 수 있습니다. 즉, "Hello, world"와 "Hello"의 문자는 길이만 다를 뿐 같은 위치에 저장할 수 있습니다.이 작업은 null-terminated 문자열로는 수행할 수 없습니다.
문자열 조각(참고: 문자열은 내 언어에서 불변입니다.분명히 두 번째는 더 느리고 오류가 발생하기 쉽습니다: 오류 검사를 추가하는 것을 생각해 보십시오.begin
그리고.end
두 가지 기능을 모두 수행합니다.
struct String slice(struct String in, size_t begin, size_t end)
{
struct String out;
out.characters = in.characters + begin;
out.length = end - begin;
return out;
}
char* slice(char* in, size_t begin, size_t end)
{
char* out = malloc(end - begin + 1);
for(int i = 0; i < end - begin; i++)
out[i] = in[i + begin];
out[end - begin] = '\0';
return out;
}
이 모든 일이 있은 후, 제 생각은 더 이상 null-terminated 문자열을 사용해야 하는지에 대한 것이 아닙니다.나는 C가 왜 그것들을 사용하는지 생각하고 있습니다!
그래서 제 질문은: 제가 놓치고 있는 null-termination의 이점이 있나요?
C 문자열은 왜 이런 식으로 작동합니까?유닉스와 C 프로그래밍 언어가 개발된 PDP-7 마이크로프로세서는 ASCIZ 문자열형이었기 때문입니다.ASCII는 "마지막에 Z(0)가 있는 ASCII"를 의미했습니다.
이것이 문자열을 저장하는 유일한 방법입니까?아니요, 사실 이것은 줄을 저장하는 최악의 방법 중 하나입니다.사소한 프로그램, API, 운영 체제, 클래스 라이브러리의 경우 페스트와 같은 ASCIZ 문자열을 피해야 합니다.
일반적인 해결책은 길이를 유지하고 널 터미네이터를 유지하는 두 가지를 모두 수행하는 것입니다.이것은 별로 추가적인 작업이 아니며, 어떤 기능에도 항상 문자열을 전달할 준비가 되어 있다는 것을 의미합니다.
null-terminated 문자열은 길이에 따라 길이가 달라지기 때문에 성능이 저하되는 경우가 많습니다.긍정적인 측면에서는 C에서 문자열을 표현하는 표준 방식이기 때문에 대부분의 C 라이브러리를 사용하려면 문자열을 지원하는 것 외에는 선택의 여지가 없습니다.
null-terminated 문자열의 한 가지 장점은 문자열을 문자 단위로 통과하는 경우 문자열을 처리하기 위해 포인터 하나만 유지하면 된다는 것입니다.
while (*s)
{
*s = toupper(*s);
s++;
}
반면 센티넬이 없는 문자열의 경우 포인터와 인덱스의 두 비트 상태를 유지해야 합니다.
while (i < s.length)
{
s.data[i] = toupper(s.data[i]);
i++;
}
...또는 현재 포인터 및 한계:
s_end = s + length;
while (s < s_end)
{
*s = toupper(*s);
s++;
}
CPU 레지스터가 부족한 리소스였을 때(컴파일러들이 이를 더 잘 할당하지 못했을 때), 이는 중요했습니다.지금은, 별로.
길이에도 문제가 있습니다.
길이는 추가 스토리지가 필요합니다(지금은 문제가 아니지만 30년 전에는 큰 문제였습니다).
문자열을 변경할 때마다 길이를 업데이트해야 하므로 전반적으로 성능이 저하됩니다.
NUL 종단 문자열을 사용하면 길이를 사용하거나 마지막 문자에 대한 포인터를 저장할 수 있으므로 문자열 조작을 많이 수행하는 경우에도 문자열 길이의 성능을 동일하게 할 수 있습니다.
NUL 종단 문자열은 훨씬 간단합니다. NUL 종단 문자열은 다음과 같은 방법으로 사용되는 규칙일 뿐입니다.
strcat
줄의 끝을 결정할 수 있습니다.따라서 구조체를 사용할 필요 없이 일반 문자 배열로 저장할 수 있습니다.
한 가지 이점은 null-termination으로 null-termination된 문자열의 꼬리도 null-termination된 문자열이라는 것입니다.만약 N번째 문자로 시작하는 부분 문자열을 어떤 문자열 처리 함수에 전달해야 한다면(버퍼 오버런이 없다면) 문제 없습니다. 그냥 거기에 오프셋된 주소를 전달하세요.다른 방법으로 크기를 저장할 때 새 문자열을 구성해야 합니다.
약간 주제가 틀리지만 설명하는 방식보다 길이 접두사가 붙은 문자열을 더 효율적으로 처리할 수 있는 방법이 있습니다.다음과 같은 구조를 만듭니다(C99 이상에서 유효).
struct String
{
size_t length;
char characters[0];
}
이렇게 하면 '문자' 요소를 현재 구조와 동일하게 문자*로 사용할 수 있는 구조가 처음에 길이를 가지는 구조는 현재 구조와 동일하게 '문자' 요소를 문자*로 사용할 수 있습니다.그러나 각 문자열에 대해 힙에 있는 항목을 두 개가 아니라 하나만 할당할 수 있다는 차이점이 있습니다.다음과 같이 문자열을 할당합니다.
mystr = malloc(sizeof(String) + strlen(cstring))
예 - 구조물의 길이(크기_t)에 실제 문자열을 넣을 수 있는 충분한 공간을 더한 값입니다.
C99를 사용하지 않으려면 "char characters[1]"을 사용하여 이 작업을 수행한 후 문자열 길이에서 1을 빼서 할당할 수도 있습니다.
몇 가지 가설들을 내던지고 있습니다.
- null terminated 문자열의 "wrong" 구현을 얻을 방법은 없습니다.그러나 표준화된 구조는 공급업체별로 구현될 수 있습니다.
- 구조물이 필요 없습니다.null terminated 문자열은 char*의 특수한 경우이기 때문에 "빌트인" 상태입니다.
대부분의 경우 array + len 방식을 선호하지만 null-terminated를 사용하는 데에는 타당한 이유가 있습니다.
32비트 시스템을 사용합니다.
7바이트 문자열을 저장하려면 다음과 같이 하십시오.
char * + size_t + 8바이트 = 19바이트
7바이트 null-term 문자열을 저장하려면 다음과 같이 하십시오.
char * + 8 = 16바이트입니다.
null-term 배열은 문자열처럼 불변일 필요가 없습니다.null char를 넣기만 하면 c-string을 즐겁게 자를 수 있습니다.코드를 작성하는 경우 메모리 할당을 포함하는 새 문자열을 작성해야 합니다.
문자열의 사용에 따라 문자열은 문자열과 반대로 c- 문자열과 가능한 성능을 비교할 수 없습니다.
0-종료는 작업의 일부에 대한 유형 확인 및 성능에 있어서 좋지 않은 방법이라는 것이 전적으로 맞습니다.이 페이지의 답변에는 이미 출처와 사용 용도가 요약되어 있습니다.
델파이가 문자열을 저장하는 방식이 마음에 들었습니다.(가변길이) 문자열 앞에 길이/최대 길이를 유지한다고 생각합니다.이렇게 하면 호환성을 위해 문자열을 null로 종료할 수 있습니다.
당신의 메커니즘에 대한 나의 관심: - 추가 포인터 - 당신의 언어의 핵심 부분에 있는 불변성 si; 보통 문자열 유형은 불변하지 않으므로 만약 당신이 다시 생각한다면 어려울 것입니다.변경 시 복사본 만들기' 메커니즘을 구현해야 합니다 - malloc(효율적이지는 않지만, 여기에 쉽게 포함될 수도 있습니까?)
행운을 빌어요; 당신만의 통역사를 쓰는 것은 주로 프로그래밍 언어의 문법과 구문을 이해하는데 매우 교육적일 수 있어요! (적어도, 그것은 저를 위한 것입니다.
제 생각에 주된 이유는 표준에 차 이외의 어떤 종류의 크기에 대해서도 구체적으로 나와 있지 않기 때문인 것 같습니다.그러나 (char) = 1의 크기는 문자열 크기로는 충분하지 않습니다.
언급URL : https://stackoverflow.com/questions/1253291/why-null-terminated-strings-or-null-terminated-vs-characters-length-storage
'programing' 카테고리의 다른 글
mysql 쿼리에서 오프셋 및 제한을 사용하여 순서 추가 (0) | 2023.11.07 |
---|---|
npm 스크립트를 사용하여 js 파일을 어떻게 실행합니까? (0) | 2023.11.07 |
새로운 WooCommerce 2.3.x에 의해 로드된 select2 스크립트/스타일을 언로드하는 방법? (0) | 2023.11.07 |
Wocommerce 카테고리 이미지 표시 - get_wocommerce_term_meta가 사용되지 않음 (0) | 2023.11.07 |
AngularJS: 양식의 모든 양식 컨트롤을 비활성화하는 방법? (0) | 2023.11.07 |