2010-03-11 5 views
31

나는 단지 #define 몇 가지 정수를 사용할 수 있다는 것을 알고 있지만, 왜 C는 C99 전에 전용 부울 데이터 유형을 가지고 있지 않습니까?C가 C99 이전에 부울 데이터 형식을 사용하지 않은 이유는 무엇입니까?

프로그래밍과 논리에서 흔히 발생하는 것으로, 명시적인 형식과 표기법이없는 것을 이해하지 못합니다.

+5

-1 : Kernighan 's와 Ritchie의 구현 세부 사항에 대한 C의 역사를 알고 있으면 어떤 문제가 해결됩니까? –

+38

@ S.Lott - 죄송합니다, StackOverflow의 목적을 이해하지 못 했습니까? 프로그래밍과 관련이없는 질문입니까? FAQ에서 "이것은 대답 할 수있는 질문을위한 장소입니다." "귀하의 질문이 상세하고 구체적이고 분명하고 간단하게 쓰여질 경우 적어도 한 명의 다른 프로그래머에게 관심을 가져야합니다." 그 밖의 무엇을 내가 그리워 했느냐? –

+19

@ S.Lott Python 책에서 "Background and History"장을 제거해야한다고 생각합니다. –

답변

24

라이브러리에 약간의 시간을 투자한다면 추측 할 필요가 없습니다. 다음은 Dennis Ritchie's paper on the evolution of C에서 가져온 몇 가지 진술입니다. 문맥은 데니스 (Dennis)가 켄 톰슨 (Ken Thompson)의 언어 B를 구축하고 있다는 것입니다.이 언어는 단어가 지정된 컴퓨터 인 PDP-7에 구현되었습니다. 관심 증가로 인해이 그룹은 최초의 PDP-11 중 하나를 얻었습니다. 데니스

는 PDP-11의 출현

는 B의 의미 모델의 여러 부족함을 노출 씁니다. 첫째, BCPL에서 거의 변하지 않은 상속 된 문자 처리 메커니즘은 라이브러리 절차를 사용하여 압축 된 문자열을 개별 셀로 확산 한 다음 재 포장하거나 개별 문자를 액세스하고 대체하는 방식으로 어색하고 어리석은 느낌을 받기 시작했습니다. 바이트 지향 기계.

B 및 BCPL 모델은 포인터를 처리 할 때 오버 헤드를 의미합니다. 단어 규칙으로 포인터를 색인으로 정의하고 강제 포인터를 단어 색인으로 나타냅니다. 각 포인터 참조는 포인터가 하드웨어에서 예상하는 바이트 주소로 런타임 스케일 변환을 생성했습니다.

이러한 이유로 인해 문자 및 바이트 주소 지정에 대처하고 다가올 부동 소수점 하드웨어를 준비하는 데 입력 체계가 필요했습니다. 다른 문제들, 특히 유형 안전 및 인터페이스 검사는 이후에 중요하게 보이지 않았습니다.

(강조 광산.)

용지가 배열 작업을하고,이 신기한 것을 좋아하는 struct 아이디어와 조건에 와서, 새로운 포인터 의미를 발명하는 데니스의 투쟁을 설명하기 위해 계속된다. 타입 안전성에 대한 개념과 정수와 부울을 구별하는 것은 나중에는별로 중요하지 않게 보였습니다 :-)

1

왜냐하면 그들은 1을 넣지 않았기 때문입니다. 유감스럽게 들릴지 모르지만 근본적으로 그렇게 정의되지 않았습니다.

#define TRUE와 FALSE를 대부분의 사람들이 기억하십시오.

bool은 표준이라고 할 수 있지만 10 년 전에 만들어진 C99보다 분명히 표준이 아닙니다.) 누락 된 항목이 분명 해지면 추가했습니다.

+3

당신은 단지 그 말을 의역했습니다 : P –

+5

+1 : "그들은 하나를 넣지 않았기 때문에." 유일하게 가능한 대답입니다. –

+0

프로그래밍 에서뿐만 아니라 문제를 해결할 때 생각 프로세스에서도 표준입니다. – xyz

0

프로그래밍 언어에서 누락 된 데이터 유형을 포함하여 모든 것을 예측할 수 없기 때문에 아무도 알 수 없습니다.

17

C는 실제로 더 높은 수준의 어셈블리 언어입니다. 네, 컨트롤 구조와 이것 저것을 가지고 있고 어셈블러가 필요로하지 않는 타입도 있습니다.

그러나이 언어는 수십 년 전에 설계되었습니다. 그리고 모든 불리언 결과가 프로세서의 상태 워드에서 개별 비트로 내려 가기 때문에 정수형 데이터 유형을 사용하는 것만으로도 충분했습니다. 그리고 컴파일러는 아마도 약간의 형식 검사를 생략 할 수 있기 때문에 좀 덜 복잡 할 것입니다. 나중에 언어 제어 구조에서 에 부울 값이 필요하고 C에서는 0 또는 다른 정수 값이 필요합니다.

+11

초기 C는'void *'가''*''을 사용하기 전에''char *' '가 일반 포인터 타입으로 표준화되었다는 것을 기억하십시오. 프로세서에는 '무효'라는 개념이 없으므로 언어는 하드웨어가 이해할 수있는 가장 작은 해상도의 데이터 포인터를 사용했습니다. 'void *'와 같은 "추상"개념이 나중에 나왔다. C는 매우 근접한 언어이며, 하드웨어가 유일하게 이해할 수있는 것을 반영하지 않는 새로운 데이터 유형으로 true/false를 추상화하는 것은별로 의미가 없습니다 ('bool'은 단순히 ' char'를 추가 제한 사항과 함께, 당신이 정말로 필요하다면'typedef'만큼 간단하게). – bta

7

0이 거짓이고 0이 참이 아닌 정수 유형을 가진 것으로 충분하다고 여겨집니다.

+1

이것이 최고의 대답이라고 생각합니다. 어쨌든 assemble하기 위해 컴파일 할 때 대부분의 부울은 정수로 처리됩니다. –

9

CPU에는 "부울 유형"이 없으므로 바이트와 그 배수에서만 작동하므로 부울 유형이 이점을주지 못했기 때문에 당시로서는 의미가 없었습니다 (왜 유형을 사용하면 확인할 수 있습니까? "0"또는 "null이 아님")

+2

물론 CPU에는 부울 유형이 있습니다. 플래그 레지스터는 그 (것)들로 채워진다! – xtofl

+1

네,하지만 그들은 범용이 아닙니다. – dbemerlin

10

0을 false로, 0이 아닌 값을 true로 처리하는 것이 일반적 이었지만 (여전히 경우에 따라 다름) 예를 들어, while (remaining != 0) 대신 while (remaining)을 사용할 수 있습니다.

일부 언어는 참인 경우 -1로 표준화되었습니다. 그 이유는 2 보수 표기법 (대부분의 컴퓨터가 음수를 나타 내기 위해 사용하는)에서 0이 아닌 비트가 -1 (8 비트 이진수에서는 11111111은 십진수 -1)이기 때문입니다.

시간이 지남에 따라 컴파일러가 정의한 상수를 사용하면 많은 잠재적 인 혼동을 예방할 수 있다는 것을 깨달았습니다. C++을 해본 이후로 꽤 오랜 시간이 걸렸지 만, 0이 아닌 값은 여전히 ​​"true"로 평가됩니다.

+0

+1이 가장 상세한 답변이되었습니다. –

+2

처음 발견했을 때 항상 흥미로운 0/-1 점을 발견했습니다. 특히 많은 교사/강사가 긍정적 인 1 점이 '사실'이라고 잘못 설명했기 때문에 항상 재미있었습니다. –

+4

Positive 1 **은 비교 연산자와 부울 및/또는/연산자가 각각 true 또는 false로 1 또는 0로 평가된다는 점에서 C에서 ** "true"입니다. 그러나 0이 아닌 값이 모두 참이기 때문에 값이있는 것으로 생각하지 않는 것이 가장 좋습니다. –

5

부울을 저장하는 데 사용하는 유형 (일반적으로)은 시간과 공간의 균형을 나타냅니다. 일반적으로 int (일반적으로 4 바이트)를 사용하여 가장 빠른 결과를 얻습니다 (적어도 개별 작업의 경우). 다른 한편으로, 매우 많은 것을 사용한다면, 1 바이트를 사용하는 것이 훨씬 더 합리적 일 수 있습니다. 심지어 저장하는 각 값이 하나의 비트만을 사용하도록 설정할 수 있습니다. 단일 비트를 읽거나 쓰는 것이 훨씬 더 비쌉니다.

정말로 "옳은"대답이 하나도 없었기 때문에 사용자가 작성한 프로그램의 요구 사항을 기반으로 결정을 내 렸습니다.

진정한 질문은 C99에서 부울 유형이 추가 된 이유입니다.내 생각 엔 두 가지 요소가 관련되어 있다고 생각합니다. 첫째, 그들은 프로그래머를위한 편의가 이제는 절대 최상의 성능을 제공하는 것이 더 중요하다는 것을 깨달았습니다. 둘째, 컴파일러는 이제 더 많은 글로벌 분석을 수행하므로, 적어도 누군가가 일 수도 있고,은 특정 프로그램에 가장 적합한 표현을 고르는 컴파일러를 작성할 수 있습니다. 정말로). 아마

+0

+1 : 나는 공간 - 시간 교환에 대한 언급을 좋아했다. 그게 아주 중요한 포인트 야. – Arun

+0

일부 컴파일러에서 'int'는 부울 값을 저장하는 가장 빠른 형식입니다. 그러나 (전부는 아니지만) 많은 경우에,'char'도 마찬가지로 빠릅니다. 일부 임베디드 시스템 프로세서는 더 빠른 속도의 특수한 '비트'타입을 가지고 있습니다 (일반적으로 다른 시스템에서는 '비트'타입을 포함 할 수 없습니다). 'char'도 마찬가지로 빠르다는 플랫폼에서'int'에 불린 (Boolean)을 저장하는 것은 어리석은 일입니다. – supercat

+0

supercat이 말했듯이, c의 초기 목표는 일반적으로 매우 제한된 기계 였기 때문에 거의 항상 수동으로 비트 포장을 관리하는 것이 더 낫습니다. 부울 유형을 다시 추가하면 끔찍한 기계 코드 출력으로 간주 될 수있는 것을 장려했을 것입니다. –

4

역사적 이유 : 크게 ALGOL에 의해 영향을 받았다

CPL은 대부분 부울 유형을했다,하지만 내 구글 - Fu는 이것에 대한 참조를 찾을 충분하지 않았다. 그러나 CPL은 그 당시에는 너무 야심 찬 것으로서, BCPL이라고 불리는 차별화 된 버전을 만들었습니다.이 버전은 사용 가능한 하드웨어에 실제로 구현할 수있는 이점이있었습니다. '단어'- -

BCPL은 하나의 유형이 있었다 부울 상황에서 거짓으로 해석 한 경우 0과 같은 경우는 true ~0 (서명 twos-으로 해석하면 값 -1을 나타내는 것 0의 보수를 의미 보체 정수). 다른 값의 해석은 구현에 따라 다릅니다.

여전히 타입이없는 후속 B 이후 C는 유형 시스템을 다시 도입했지만 여전히 전임자의 유형이없는 특성에 크게 영향을 받았습니다.

5

올드 C는 부울 타입을 실제로 "빠뜨린"것이 아니 었습니다 - 모든 필수 유형 또한 적합하다고 생각했습니다 부울을 저장하는 이중 의무를 수행합니다.나는이 두 가지 이유 볼 수 있습니다

  • 비트 어드레싱 프로세서는 전혀 일반적이었다 (그리고 아직도있다)를, 그래서 컴파일러는 정말 "부울 true"를 사용 할 수 없을 것입니다 어떤 공간을 절약하기 위해 타입을 입력하십시오. 어쨌든 (최소한 효율적으로 접근하기를 원한다면) 부울은 적어도 char만큼 커야합니다. int보다 좁은

  • 유형 어쨌든 표현에 int로 확대된다 - 그래서 부울 연산자는 여전히 int 피연산자에서 작동합니다.

.. 전용 부울 유형이 실제적인 이점을 실제로 전달할만큼 충분한 경우는없는 것처럼 보입니다. !&&, ||, !=, ==, <, <=, >>= - - 그래서 그것은 단지의

C 언어는 부울 결과를 연산자 세트가 않음을 기억합니다 (0 또는 1로 정의) 거기에없는 전용 부울 유형.

1

정수와 호환되지 않는 별도의 "부울"유형을 추가하면 단순히 정수를 사용하는 것보다 컴파일러가 복잡해집니다. 정수와 호환되는 별도의 부울 유형을 사용하면 0 또는 1 이외의 값을 부울 객체에 저장하거나 부울 객체에 숫자 계산을 수행 할 때 발생할 수있는 결과를 지정해야합니다 "0"또는 "1". 을 감안할 때 : intFunction이 0이 아닌 값은 일반적으로보다 위의 더 비싼 만들 것 반환하는 경우 someInt는 값 1을 받아야한다는 요구

someBool = intFunction(); 
someInt = someBool; 

전자의 의미가 요구 될 경우
someChar = intFunction(); 
someInt = someChar; 

, 또한 그들없이 수행 할 수 있습니다 부울 유형을 사용하여 수행 할 수있는 일 때문에

someChar = !!intFunction(); 
someInt = someChar; 

, 많은 경우 C에서 : 그들은을 통해, 부울 타입을 사용하지 않고 달성 할 수 문자 유형을 사용하는 ode는 부울 유형보다 더 효율적일 수 있습니다. 나는 그 (것)들을위한 실제적인 필요성이 결코 존재하지 않았다고 제안합니다.

관련 문제