컴퓨터는 '\ 0'(널 문자)을“unsigned int = 0”과 어떻게 구별합니까?


29

주어진 상황에서 문자 배열 (물론 null 문자로 끝남)이 있고 그 직후 메모리의 바로 다음 위치에 0부호없는 정수 로 저장하려는 경우 컴퓨터는 어떻게 이들을 구별합니까? 두?


18
당신은 정답이 맞는 일반적인 컴퓨터에 대해 묻습니다. 그러나 데이터 유형을 구별하기 위해 태그 메모리 를 사용 하는 아키텍처가 있었습니다.
grawity

12
컴퓨터가 4 바이트 플로트를 4 바이트 정수 (매우 다른 숫자를 나타냄)와 구별 할 수없는 것과 같은 방법입니다.
Hagen von Eitzen

6
0x00으로 문자열을 끝내는 것이 일반적이지만 길이 접두사 문자열을 사용하는 언어가 있습니다. 첫 번째 바이트 또는 두 번째 바이트는 문자열의 바이트 수를 포함합니다. 이러한 방식으로 끝에 0x00이 필요하지 않습니다. 파스칼과 베이직을 기억하는 것 같습니다. 아마도 코볼도 마찬가지입니다.
조명

@lit은 또한 많은 통신 프로토콜의 헤더 형식입니다. "안녕하세요. 저는 이런 종류의 메시지이고이 바이트 수입니다." 복잡한 데이터 유형을 내부에 저장해야하기 때문에 null 종료가 구문 분석하기가 훨씬 더 어려워집니다.
mathreadler

1
@lit : 대부분은 파스칼과 BASIC 예, 및 PL / I와 에이다의 변형 - 및 하위 문자열 공유가 7u6에서 떨어 된 이후 자바에 효과적으로 배열의 길이 접두사를 사용합니다 -하지만 COBOL은 정렬의 : 당신은 수 읽기 에서 데이터를 pic X occurs m to n depending on v( 카운트는 직전이 아니라 어디에서나 가능하지만 저장 하는 것이 더 복잡합니다.
dave_thompson_085

답변:


86

그렇지 않습니다.

문자열 종결자는 모든 0 비트를 포함하는 바이트입니다.

부호없는 int는 각각 0 비트를 포함하는 2 또는 4 바이트 (환경에 따라 다름)입니다.

두 항목은 서로 다른 주소에 저장됩니다. 컴파일 된 코드는 이전 위치의 문자열에 적합한 연산과 후자의 부호없는 이진수에 적합한 연산을 수행합니다. (코드에 버그가 있거나 위험한 영리한 코드가 아닌 한!)

그러나이 모든 바이트는 CPU와 동일하게 보입니다. 메모리에있는 데이터 (가장 일반적으로 사용되는 명령어 세트 아키텍처에서)와 관련된 데이터 유형이 없습니다. 그것은 소스 코드에만 존재하며 컴파일러에만 해당되는 추상화입니다.

편집 추가 : 예를 들어 : 문자열을 구성하는 바이트에 대해 산술을 수행하는 것이 가능합니다. 8 비트 ASCII 문자 문자열이있는 경우 32 (10 진수)를 더하거나 빼서 문자열의 문자를 대문자와 소문자로 변환 할 수 있습니다. 또는 다른 문자 코드로 변환하는 경우 해당 요소의 값을 다른 코드에서 동등한 비트 코딩을 제공하는 배열에 인덱스로 사용할 수 있습니다.

CPU에서 문자는 실제로 매우 짧은 정수입니다. (16, 32 또는 64 대신 각각 8 비트) 인간에게는 값이 읽을 수있는 문자와 관련이 있지만 CPU는 그 사실을 알지 못합니다. 또한 "널 바이트는 문자열을 끝냅니다"의 "C"규칙에 대해 아무것도 알지 못합니다 (많은 답변과 의견에서 언급했듯이 그 규칙이 전혀 사용되지 않는 프로그래밍 환경이 있습니다) .

확실히, x86 / x64에는 REP 접두사와 같은 문자열과 함께 많이 사용되는 몇 가지 명령어가 있지만 원하는 결과를 얻으면 정수 배열에서도 사용할 수 있습니다.


14
따라서 개발자는 문자열에주의해야합니다. 연속 된 100 바이트가있는 경우 최대 99 개의 1 바이트 문자와 마지막 바이트의 종결자를 더할 수 있습니다. 100 바이트 문자열을 거기에 쓰면 프로그램은 문자열이 끝나는 것을 알 수 없으며 우연의 0 바이트까지 연속 바이트를 계속 읽습니다. 문자열의 길이가 100 바이트를 초과하면 인접한 데이터를 덮어 씁니다. 고수준 프로그래밍 언어 (Java, C #, JS 등)는이를 스스로 처리하지만 C, C ++, 어셈블리와 같은 저수준 언어에서는 개발자의 책임입니다.
gronostaj

18
@gronostaj 귀하의 의견은 약간 혼동됩니다. C와 달리 C ++ 문자열도이를 자동으로 처리합니다. C ++은 일반적으로 저수준 언어로 분류되지도 않으며 C조차도 그렇지 않습니다.
Konrad Rudolph

5
데이터 값에 타입 마커가있는 (오래된) CPU 아키텍처가 있으므로 정수를 포인터로 역 참조하면 예외가 발생합니다.
Simon Richter

8
@JamieHanrahan IA64 프로세서 에는 값이 설정되어 있으면 예외를 throw 할 수있는 NaT (또는 "Not a Thing") 라는 비트 가 있습니다.
ErikF

4
@KonradRudolph "자동"은 C ++에서 확실히 "무방비"를 의미하지 않습니다
rackandboneman

5

간단히 말해서 차이는 없습니다 (int는 2 또는 4 바이트 너비이고 char은 1입니다).

문제는 모든 최신 라이브러리가 null 종료 자 기술을 사용하거나 문자열 길이를 저장한다는 것입니다. 그리고 두 경우 모두 프로그램 / 컴퓨터는 널 문자를 읽거나 크기에 지시 된만큼의 문자를 읽을 때 문자열 끝에 도달했음을 알고 있습니다.

널 터미네이터가 없거나 길이가 잘못된 경우 프로그램이 메모리에서 읽지 않기 시작하면이 문제가 시작됩니다.


3
단, 실제로는 매우 기계에 의존하는 데이터 유형 : 것에 대해 일종의 악명입니다 - 아, 거기 짧은에 차이가있다
rackandboneman을

2

다른 점이 없다. 머신 코드 (어셈블러)에는 변수 유형이 없으며 대신 데이터 유형이 명령어에 의해 결정됩니다.

더 좋은 예로들 수 intfloat메모리에 4 바이트가 있다면, 그것이인지 전혀 정보가 없다, int또는을 float, 그러나 정수 추가 및 플로트 또한 2 개 가지 지침, 그렇다면 정수 또한이 있습니다 (또는 완전히 뭔가 다른) 명령은 데이터에 사용 된 다음 정수이며 그 반대도 마찬가지입니다.

문자열과 마찬가지로 주소를보고 바이트에 도달 할 때까지 바이트를 계산하는 코드가 있으면 \0문자열의 길이를 계산하는 함수로 생각할 수 있습니다.

물론 이와 같은 프로그래밍은 완전한 광기 일 것이므로 기계 코드로 컴파일하고 어셈블러에서 거의 아무도 프로그램을 직접 컴파일하지 않는 고급 언어를 사용하는 이유입니다.


2

과학적인 단일 단어 답변은 메타 데이터입니다.

메타 데이터는 컴퓨터에 특정 위치의 일부 데이터가 정수, 문자열, 프로그램 코드 또는 기타 데이터인지를 알려줍니다. 이 메타 데이터는 프로그램 코드의 일부이거나 (Jamie Hanrahan이 언급했듯이) 어딘가에 명시 적으로 저장 될 수 있습니다.

최신 CPU는 종종 프로그램 코드에 할당 된 메모리 영역과 데이터 영역 (예 : NX Bit https://en.wikipedia.org/wiki/NX_bit )을 구별 할 수 있습니다 . 일부 이국적인 하드웨어는 문자열과 숫자를 구별 할 수도 있습니다. 그러나 일반적인 경우는 코드에서 암시 적 메타 데이터 또는 명시 적 메타 데이터 (객체 지향 VM이 종종 메타 데이터 (유형 / 클래스 정보)를 데이터 (객체)의 일부로 저장함)를 통해 소프트웨어가이 문제를 처리하는 것입니다. .

서로 다른 종류의 데이터를 구별하지 않는 이점은 일부 작업이 매우 단순해진다는 것입니다. I / O 하위 시스템은 디스크에서 읽거나 디스크에 쓰는 데이터가 실제로 프로그램 코드, 사람이 읽을 수있는 텍스트 또는 숫자인지 알 필요가 없습니다. 그것은 기계를 통해 운송되는 모든 비트입니다. 프로그램 코드가 멋진 타이핑 문제를 처리하게하십시오.


0

그렇지 않습니다. 당신은 그것을 할!

또는 컴파일러 / 통역사.

컴퓨터에 지시에 0따라 숫자 를 추가하도록 지시하면 됩니다. 컴퓨터가 0'에 도달 한 후 데이터 인쇄를 중지하도록 지시 하면' \0'문자 '로 표시됩니다.

언어에는 데이터 처리 방법을 보장하는 메커니즘이 있습니다. C는 변수 타입 등이 int, float그리고 char, 컴파일러가 각각의 데이터 타입에 대한 권리의 지시를 생성한다. 그러나 C를 사용하면 변수에서 다른 유형의 다른 변수로 데이터를 캐스트 할 수 있으며 심지어 포인터를 숫자로 사용할 수도 있습니다. 컴퓨터에는 다른 것과 비슷합니다.


0

널 문자는 1 바이트이고 부호없는 int는 2 바이트입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.