파스칼과 C의 비교
Comparison of Pascal and C![]() |
비교 프로그래밍 언어 |
---|
|
컴퓨터 프로그래밍 언어 C와 Pascal은 기원, 영향 및 목적이 유사합니다.둘 다 생애 초기에 자체 컴파일러를 설계(및 컴파일)하는 데 사용되었습니다.최초의 파스칼 정의는 1969년에, 최초의 컴파일러는 1970년에 등장했습니다.C의 첫 버전은 1972년에 등장했다.
둘 다 ALGOL 언어 시리즈의 후손입니다.ALGOL은 프로그램이 if, while, for 및 case와 같은 단일 엔트리 및 단일 출구 구성으로 구성되는 구조화된 프로그래밍을 위한 프로그래밍 언어 지원을 도입했습니다.파스칼은 ALGOL W에서 직접 유래했으며, ALGOL 68과 몇 가지 새로운 아이디어를 공유했습니다.C언어는 ALGOL에 간접적으로 관련되어 있습니다.원래는 B, BCPL, CPL을 경유하고, 나중에는 ALGOL 68을 경유합니다(예를 들어,struct
그리고.union
또한 Pascal(예: 열거의 경우)도 있습니다.const
,typedef
및 부울란)을 클릭합니다.일부 파스칼 방언은 또한 C의 특징을 포함했다.
여기서 문서화된 언어는 1982년에 ISO 7185로 표준화된 Niklaus Worth의 Pascal과 1989년에 표준화된 Brian Kernighan과 Dennis Ritchie의 C입니다.그 이유는 이 두 버전이 모두 언어의 성숙한 버전을 나타내며, 또한 시간이 비교적 가깝기 때문입니다.ANSI C 및 C99(나중의 C 표준)의 특징과 Pascal(터보 파스칼, 프리 파스칼)의 향후 구현의 특징은 그들이 부여한 견고성과 기능의 향상에도 불구하고 비교에 포함되지 않습니다.
구문
이 섹션은 어떠한 출처도 인용하지 않습니다.(2013년 6월 (이 및 ) |
구문론적으로 파스칼은 C보다 훨씬 더 ALGOL과 유사합니다.C가 구두점 기호를 사용하는 경우 영어 키워드는 유지됩니다 – Pascal은and
,or
,그리고.mod
여기서 C는&&
,
,그리고.%
예를들면.단, C는 (단순한) 선언에 관해서는 Pascal보다 ALGOL에 가깝고 type-namevariable-name 구문을 유지합니다.예를 들어, C는 함수의 외부 블록뿐만 아니라 모든 블록의 시작 부분에서 선언을 받아들일 수 있습니다.
세미콜론 사용
또 다른 미묘한 차이점은 세미콜론의 역할입니다.Pascal에서는 세미콜론은 복합문 내에서 개별문을 구분합니다.C에서는 대신 문을 종료합니다.C에서는 구문적으로도 문장의 일부입니다(표현을 문장으로 변환합니다).이 차이는 주로 다음 두 가지 상황에서 나타납니다.
- 파스칼에서 세미콜론은 절대 바로 앞에 있을 수 없다.
else
단, C에서는 block 문이 사용되지 않는 한 필수입니다. - 앞의 마지막 진술
end
또는until
세미콜론 뒤에 붙일 필요는 없습니다.
마지막 줄에 불필요한 세미콜론을 삽입하여 빈 문을 정식으로 삽입할 수 있습니다.
평.
전통적인 C에서는 다음과 같은 기능만 있습니다./* block comments */
이것은 MIDletPascal과 같은 특정 Pascal 방언에서만 지원됩니다.
전통적인 파스칼에는,{ block comments }
그리고.(* block comments *)
오브젝트 파스칼(Delphi, FPC)과 같은 최신 Pascal 및 최신 C 구현에서는 C++ 스타일의 코멘트가 가능합니다.// line comments
식별자 및 키워드
C와 파스칼은 대소문자의 해석이 다르다.C는 대소문자를 구분하지만 Pascal은 대소문자를 구분하지 않습니다.MyLabel
그리고.mylabel
C에서는 구별되는 이름이지만 Pascal에서는 동일합니다.양쪽 언어에서 식별자는 문자와 숫자로 구성되며 첫 번째 문자는 숫자가 될 수 없습니다.C에서는 밑줄은 문자로 간주되므로 _abc조차 유효한 이름입니다.C의 특수 시스템 식별자를 구별하기 위해 선행 언더스코어가 있는 이름이 자주 사용됩니다.
C와 Pascal은 모두 키워드(언어용으로 예약된 단어)를 사용합니다.예를 들어, if while const, for 및 goto가 두 언어에 공통되는 키워드입니다.C에서는 기본 내장형 이름은 키워드(예: int, char) 또는 키워드 조합(예: 부호 없는 문자)이지만 Pascal에서는 내장형 이름이 미리 정의된 일반 식별자입니다.
정의, 선언 및 블록
Pascal에서 프로시저 정의는 키워드 프로시저 또는 함수로 시작하고 유형이 있는 형식 정의로 시작합니다.C에서 함수 정의는 구문 컨텍스트에 따라 결정되며 유형 정의에서는 키워드를 사용합니다.typedef
두 언어 모두 복잡한 유형의 정의에 키워드와 구두점을 혼합하여 사용합니다.예를 들어 배열은 Pascal에서는 키워드 배열로, C에서는 구두점으로 정의되며 열거는 키워드로 정의됩니다.enum
Pascal 구두점을 사용하여 C로 표기합니다.
Pascal 함수에서는 시작과 끝을 문 블록(적절)으로 구분하고, C 함수에서는 "{"와 "}"을 사용하여 선언이 선택적으로 선행되는 문 블록을 구분합니다.C(C99 이전)에서는 특정 블록 내의 스테이트먼트보다 선언이 먼저 이루어지도록 엄밀하게 정의하지만 블록 내에 블록을 표시할 수 있습니다.이것이 이 문제를 회피하는 방법입니다.Pascal은 선언이 문 앞에 발생해야 한다는 엄격한 기준을 가지고 있지만, 변수 선언뿐만 아니라 유형 및 함수의 정의를 함수 정의로 캡슐화할 수 있습니다.
실행
두 언어의 문법은 크기가 비슷하다.구현의 관점에서 두 언어의 주요 차이점은 C를 해석하기 위해서는 유형을 위한 기호 테이블에 접근할 필요가 있는 반면 Pascal에는 이러한 구성, 즉 할당이 하나뿐이라는 것입니다.예를 들어 C fragment는X * Y;
선언일 수 있다Y
(물건이) 포인터이다X
, 또는 곱셈하는 문장의 표현X
그리고.Y
이와는 대조적으로 대응하는 파스칼 조각은var Y:^X;
는 본질적으로 모호하지 않습니다.올바른 해석에는 기호 테이블이 필요하지 않습니다.
심플한
이 섹션은 어떠한 출처도 인용하지 않습니다.(2013년 6월 (이 및 ) |
정수
Pascal은 모든 변수 및 함수 선언을 명시적으로 지정해야 합니다.기존 C에서는 대부분의 컨텍스트에서 타입명이 생략되어 디폴트타입이 될 수 있습니다.int
(이는integer
Pascal에서)가 암묵적으로 가정됩니다(단, 이러한 기본값은 C에서 잘못된 관행으로 간주되며 종종 경고에 의해 플래그가 지정됩니다).
C는 다음과 같은 수식어를 사용하여 정수에 대해 다양한 크기와 부호 있는 모드 및 부호 없는 모드를 수용합니다.long
,short
,signed
,unsigned
결과 정수형의 정확한 의미는 머신에 의존합니다.보증할 수 있는 것은 다음과 같습니다.long int
보다 짧지 않다int
그리고.int
보다 짧지 않다short int
그러나 C 표준에서는 최소 크기의 유형이 지정되어 있으며, 이는 다음을 보증합니다.char
1바이트가 되는 것int
최소 2바이트여야 합니다.
서브 레인지
Pascal 에서는, 정수의 서브 레인지를 선언하는 것으로, 같은 엔드가 실행됩니다(그러면 컴파일러는 선언된 변수에 대해 더 적은 양의 스토리지를 할당하는 것을 선택할 수 있습니다).
유형 a = 1..100; b = -20..20; c = 0..100000;
이 서브레인지 기능은 C에서는 지원되지 않습니다.
C와 Pascal의 주요 차이점은 정수 연산을 촉진하는 방법입니다.Pascal에서는 중간 결과가 정수에 맞지 않더라도 모든 정수/하위 범위에 대해 연산 결과가 정의됩니다.결과는 할당 왼쪽에 있는 정수/하위 범위에 맞지 않는 경우에만 정의되지 않습니다.이는 정수형 범위에 대한 인위적인 제한을 의미하거나 중간 결과를 처리하기 위해 느린 실행이 필요할 수 있습니다.그러나 컴파일러는 제한된 서브 범위를 이용하여 보다 효율적인 코드를 생성할 수 있습니다.
C에서 오퍼랜드는 우선 필요한 결과의 크기로 승격해야 합니다.프로모션된 오퍼랜드의 범위에 맞지 않으면 중간 결과는 정의되지 않습니다.필요한 결과의 범위가 오퍼랜드의 범위보다 클 경우, 이것은 일반적으로 적절한 최적화 컴파일러에서도 느린 비효율적인 코드를 생성합니다.단, C 컴파일러는 중간 결과를 처리할 필요가 없거나 범위 밖의 결과를 처리할 것으로 예상되지 않습니다.모든 중간 결과가 오퍼랜드 범위에 맞는지 확인하는 것은 프로그래머의 책임입니다.
Small-C 등뿐만 아니라 C의 선행 표준 구현에서는 정수와 포인터 유형을 비교적 자유롭게 혼재시킬 수 있었다.
문자 유형
C의 문자 유형은 다음과 같습니다.char
이 정수는 더 이상 이 정수가 아닌short int
, . 다음과 같은 표현'x'+1
따라서 다음과 같은 선언이 있는 것처럼 완전히 합법적이다.int i='i';
그리고.char c=74;
.
이 정수적 성질char
(1바이트)는 다음과 같은 선언으로 명확하게 설명됩니다.
서명되어 있지 않다 차 uc = 255; /* 공통 제한 */ 서명된 차 sc = -128; /* 공통 음수 한계 */
그 유무char
유형으로 간주해야 한다signed
또는unsigned
디폴트로는 구현에 달려 있습니다.
파스칼에서는 문자와 정수는 구별되는 유형입니다.내장된 컴파일러 기능ord()
그리고.chr()
는 단일 문자를 사용 중인 문자 세트의 해당 정수 값으로 타이프캐스트하기 위해 사용할 수 있으며, 그 반대도 마찬가지입니다. 예를 들어 ASCII 문자 세트를 사용하는 시스템에서 사용할 수 있습니다.ord('1') = 49
그리고.chr(9)
는 TAB 문자입니다.
부울형
Pascal에서 boolean은 열거형입니다.가능한 부울 값은 false 및 true이며, 서수 값은 false = 0 및 true = 1입니다.정수로 변환하는 경우 ord가 사용됩니다.
i := 주문하다(b);
정수에서 부울로 변환하는 표준 함수는 없지만 실제로는 변환이 간단합니다.
b := i << 고객명 >>님 0;
C에는 2진수 값 관계 연산자(<, >, ==, !=, <=, >=)가 있으며, 이는 항상 0 또는 1의 결과를 제공한다는 점에서 부울로 간주될 수 있다.모든 테스트(&, ?:, if, while 등)가 제로 체크에 의해 실행되므로 false는 0으로 표시되고 true는 기타 값으로 표시됩니다.
비트 연산
C를 사용하면 비트 연산자를 사용하여 부울 연산을 수행할 수 있습니다.오퍼랜드가 값을 나타내기 위해 여러 비트를 사용하는 경우 의미가 다르기 때문에 주의해야 합니다.
파스칼은 비트 단위로 데이터를 처리하는 더 추상적이고 높은 수준의 방법을 가지고 있습니다.세트를 사용하면 프로그래머가 직접 비트 연산자(현대 Pascal에서도 사용 가능)를 사용하는 대신 비트 데이터 값을 설정, 삭제, 교차 및 통합할 수 있습니다.예:
파스칼:
상황 := 상황 + [스틱 플래그]; 상황 := 상황 - [스틱 플래그]; 한다면 (스틱 플래그 에 상황) 그리고나서 ... (* 또는 비트 연산자 사용: *) 상황 := 상황 또는 스틱 플래그; 상황 := 상황 그리고. 것은 아니다. 스틱 플래그; 한다면 스틱 플래그 그리고. 상황 = 스틱 플래그 그리고나서 ...
C:
상황 = 스틱 플래그; 상황 &= ~스틱 플래그; 한다면 (상황 & 스틱 플래그) { ...
정수에서의 비트 연산과 세트에서의 연산은 비트를 사용하여 구현되는 경우 유사하다고 간주할 수 있지만 정수와 세트 간의 비표준 변환이 가능하지 않는 한 이들 사용 사이에 직접적인 병렬은 없습니다.
구현에 관한 주의사항
표현식 평가 중 및 두 언어 모두에서 부울 값은 기계, 컴파일러 및 상황에 따라 단일 비트, 단일 바이트, 풀 머신 워드, 생성된 코드 내의 위치 또는 상태 레지스터 내의 조건 코드로 내부적으로 저장될 수 있습니다.이러한 요소는 보통 컴파일된 언어보다 더 중요합니다.
부동 소수점 유형
C는 Pascal보다 덜 엄격한 부동소수점 유형을 가지고 있습니다.C에서는 정수를 부동소수점 숫자로 암묵적으로 변환할 수 있으며, 그 반대의 경우도 마찬가지입니다(정밀 손실은 경고에 의해 플래그가 지정될 수 있습니다).파스칼에서 정수는 암묵적으로 다음과 같이 변환될 수 있다.real
, 단, 의 변환real
로.integer
(정보가 손실될 수 있는 경우) 기능을 통해 명시적으로 수행해야 합니다.trunc()
그리고.round()
이 값은 각각 분수를 잘라내거나 반올림합니다.
열거형
C와 Pascal 모두 열거 유형을 포함합니다.Pascal의 예:
유형 색. = (빨간., 초록의, 파랑색); 변화하다 a: 색.;
A의 예:
열거하다 색. {빨간., 초록의, 파랑색}; 열거하다 색. a;
그러나 두 언어의 유형별 동작은 매우 다릅니다.주식회사,red
0의 동의어가 됩니다.green
1의 경우,blue
이 범위를 벗어난 값이 변수에 할당되는 것을 막을 수 없습니다.a
게다가, 다음과 같은 조작은,a = a + 1;
Pascal에서는 엄격하게 금지되어 있습니다.대신,a := succ(a);
C에서는 Enum을 int로 자유롭게 변환할 수 있지만 Pascal에서는 열거형에서 정수로 변환하기 위해 함수 ord()를 사용해야 합니다.반대 변환에서는 다음과 같은 typecast 연산을 사용해야 합니다.a := color(1)
위해서green
가치수익률
구조화형
이 섹션은 어떠한 출처도 인용하지 않습니다.(2013년 6월 (이 및 ) |
어레이 타입
C와 Pascal은 모두 다른 어레이를 포함한 다른 복잡한 유형의 어레이를 허용합니다.그러나 언어간의 유사성은 거기서 끝이 난다.C 어레이는 기본 유형과 요소 수로 정의됩니다.
인트 a[크기];
항상 0부터 SIZE-1까지 색인화됩니다(즉, 모듈로 SIZE).
Pascal에서 인덱스의 범위는 종종 하위 범위로 지정됩니다(위의 간단한 유형에서 소개됨).의 10가지 요소
변화하다 a : 배열[0..9] 의 정수;
(이 경우 C와 마찬가지로) 0.9까지 인덱스가 작성됩니다.배열 인덱스는 범위뿐만 아니라 모든 서수 데이터 유형일 수 있습니다.
유형 TCollor = (빨간., 초록의, 파랑색); (* 열거*) RGB = 배열[TCollor] 의 0..255; 변화하다 사진. : 배열[1..640, 1..480] 의 RGB 변화하다 팔레트 : 배열[바이트, 0..2] 의 바이트
n(>1)자로 구성된 문자열은 범위 1..n의 패킹된 배열로 정의됩니다.
어레이 및 포인터
C 식에서 어레이를 나타내는 식별자는 어레이의 첫 번째 요소에 대한 상수 포인터로 취급되며, 따라서 선언이 주어지면int a[10]
그리고.int *p;
임무p = a
는 유효하며 p와 a가 같은 어레이를 가리키게 됩니다.식별자로서a
상수 주소를 나타냅니다.a = p
그러나 유효하지 않습니다.
C의 배열은 고정되어 있지만 포인터는 서로 교환할 수 있습니다.이 유연성을 통해 C는 동일한 코드를 사용하여 임의의 길이의 배열을 조작할 수 있습니다.또, 언어에 체크가 짜넣어져 있지 않기 때문에, 할당된 어레이 밖에 기입하지 않는 것도 프로그래머에게 맡겨집니다.
Pascal에서 배열은 포인터와 다른 유형입니다.이것에 의해, 컴파일러의 관점에서 어레이의 경계를 체크할 수 있게 됩니다.실질적으로 모든 Pascal 컴파일러는 컴파일 옵션으로 범위 체크를 지원합니다.런타임에 길이가 변경되는 어레이와 언어 제어 하에 이들을 체크할 수 있는 어레이를 모두 갖추고 있는 것을 「다이나믹 어레이」라고 부릅니다.Pascal에서는 각 배열 유형의 요소 수는 컴파일 시 결정되며 프로그램 실행 중에는 변경할 수 없습니다.따라서 프로그램 데이터에 따라 길이가 달라지는 배열을 정의할 수 없습니다.
C는 임의의 길이의 배열을 초기화할 수 있습니다.그sizeof
연산자는 C 코드에서 정적으로 초기화된 배열의 크기를 얻기 위해 사용할 수 있습니다.예를 들어 다음 코드에서는 문자열 목록이 변경되면 루프의 종단 인덱스가 자동으로 조정됩니다.
정적인 차 *워드 리스트[] = { 인쇄, 아웃, "the" (the), "텍스트", "메시지 }; 정적인 인트 리스트 사이즈 = (크기(워드 리스트)/크기(워드 리스트[0])); 인트 i; 위해서 (i=0; i< >리스트 사이즈; i++) 놓다(워드 리스트[i]); 위해서 (i=리스트 사이즈-1; i>=0; i--) 놓다(워드 리스트[i]);
오리지널 Pascal은 배열 초기화(문자열 이외)도 컴파일 시 임의의 배열 크기를 결정하는 수단도 없습니다.
Pascal에서 위의 예를 구현하는 방법 중 하나는 자동 크기 조정 없이 다음과 같습니다.
컨스턴트 미니 리스트 = 1; 최대 리스트 = 5; 최대어 = 7; 유형 리스트 레인지 = 미니 리스트 .. 최대 리스트; 단어 범위 = 1..최대어; 단어 = 기록. 내용물: 포장된 배열 [단어 범위] 의 차; 길이: 단어 범위 끝.; 워드 리스트 = 배열[리스트 레인지] 의 단어; 변화하다 i: 정수; 단어: 워드 리스트; 절차. 리스트 작성(변화하다 w: 워드 리스트); 시작한다. w[1].내용물 := '인쇄'; w[1].길이 := 5; w[2].내용물 := '아웃; w[2].길이 := 3; w[3].내용물 := " "; w[3].길이 := 3; w[4].내용물 := '텍스트'; w[4].길이 := 4; w[5].내용물 := '메시지; w[5].길이 := 7; 끝.; 시작한다. 리스트 작성(단어); 위해서 i := 미니 리스트 로. 최대 리스트 하다 와 함께 단어[i] 하다 기입(내용물: 길이); 위해서 i := 최대 리스트 까지 미니 리스트 하다 와 함께 단어[i] 하다 기입(내용물: 길이) 끝..
줄들
두 언어에서 문자열은 원시적인 배열의 문자입니다.
파스칼에서 길이 n의 문자열 리터럴은 다음 유형과 호환됩니다.packed array [1..n] of char
C에서 문자열은 일반적으로 다음과 같은 유형을 가집니다.char[n]
.
Pascal은 가변 길이 배열을 지원하지 않으므로 문자열 작업을 수행하는 루틴 집합은 특정 문자열 크기에 따라 달라집니다.이제 표준화된 Pascal "적합 배열 매개 변수" 확장은 이 문제를 크게 해결하며, Pascal의 많은 또는 대부분의 구현에서 언어에 고유한 문자열을 지원합니다.
C 문자열 리터럴은 늘 종단됩니다.즉, 문자열 끝의 센티널로서의 말미의 늘 문자입니다.
컨스턴트 차 *p; p = 스페인의 비; /* null-terminated */
배열에 저장된 문자열 변수에 대해서는 늘 종단을 수동으로 유지해야 합니다(이는 라이브러리 루틴에 의해 부분적으로 처리되는 경우가 많습니다).
C에는 삽입 문자열 또는 배열 할당이 없기 때문에 문자열이 p로 전송되는 것이 아니라 p가 메모리 내의 일정한 문자열을 가리키도록 되어 있습니다.
Pascal에서는 C와 달리 문자열의 첫 번째 문자 요소는 0이 아니라 인덱스 1에 있습니다(길이 프리픽스로 지정됩니다).이는 Pascal이 문자열의 길이를 문자 배열의 0번째 요소에 저장하기 때문입니다.이 차이를 잘 이해하지 못하면 두 언어에서 생성된 객체 코드를 이식하거나 인터페이스하려고 할 때 오류가 발생할 수 있습니다.
FreeBSD 개발자인 Poul-Henning Kamp는 ACM 큐에 기술되어 있습니다.나중에 길이 프리픽스 문자열에 대한 늘 종단 문자열의 승리를 [1]"가장 비싼 1바이트 오류"라고 부릅니다.
레코드 타입
C와 Pascal은 모두 "레코드" 유형을 선언할 수 있습니다.C에서는 이들을 '구조'라고 한다.
구조 a { 인트 b; 차 c; };
유형 a = 기록. b: 정수; c: 차; 끝.;
Pascal에서는 name_of_record.name_of_field를 쓰는 대신 로컬 변수와 같이 해당 레코드의 필드를 직접 사용하기 위해 "with name_of_record do"라는 문장을 사용할 수 있습니다.다음은 예를 제시하겠습니다.
유형 r = 기록. s: 스트링; c: 차; 끝.; 변화하다 r1 : r; 시작한다. 와 함께 r1 하다 시작한다. s := '푸'; c := 'b'; 끝.;
C의 와 동등한 기능은 없습니다.
C에서는 필드의 정확한 비트 길이를 지정할 수 있습니다.
구조 a { 서명되어 있지 않다 인트 b:3; 서명되어 있지 않다 인트 c:1; };
사용되는 스토리지 용량은 대상 시스템의 특성(예: 워드 정렬)에 따라 달라집니다.
이 기능은 Pascal에서 packed 키워드와 관련하여 서브범위 구성(3비트의 범위는 0 ~7)을 사용하여 사용할 수 있습니다.
유형 a = 포장된 기록. b: 0..7; c: 0..1; 끝.;
C와 Pascal은 서로 겹치는 서로 다른 필드를 포함할 수 있는 레코드를 지원합니다.
조합 a { 인트 a; 흘러가다 b; };
유형 a = 기록. 사례. 부울 의 거짓의: (a: 정수); 진실의: (b: 진짜) 끝.;
양쪽 언어 프로세서는 유니언/레코드에서 가장 큰 유형을 포함하는 데 필요한 만큼의 공간만 할당할 수 있습니다.
C와 Pascal의 가장 큰 차이점은 Pascal이 언어 프로세서에 "태그필드"를 명시적으로 사용하여 변종 레코드의 유효한 컴포넌트에 액세스하고 있는지 여부를 판별할 수 있다는 것입니다.
유형 a = 기록. 사례. q: 부울 의 거짓의: (a: 정수); 진실의: (b: 진짜) 끝.;
이 경우 태그필드q를 올바른 상태로 설정하여 레코드의 적절한 부분에 액세스해야 합니다.
포인터
C에서 포인터는 객체 또는 함수를 포함한 대부분의 프로그램 엔티티를 가리킬 수 있습니다.
인트 a; 인트 *b; 인트 (*비교하다)(인트 c, 인트 d); 인트 My Compare(인트 c, 인트 d); b = &a; 비교하다 = &My Compare;
C에서는 배열과 포인터가 거의 동등하기 때문에 다음과 같습니다.
a = b[5]; a = *(b+5); a = *(5+b); a = 5[b];
따라서 포인터는 배열에 액세스하기 위한 다른 방법으로 C에서 자주 사용됩니다.
동적 데이터를 생성하기 위해 라이브러리가 기능합니다.malloc()
그리고.free()
는 동적 데이터 블록을 가져오고 해제하는 데 사용됩니다.따라서 동적 메모리 할당은 언어 프로세서에 내장되어 있지 않습니다.이는 특히 C가 운영체제 커널 또는 임베디드 타깃에서 사용되는 경우 유용합니다.이는 플랫폼(아키텍처뿐 아니라)에 따라 매우 고유하며 사용하는 플랫폼(또는 운영체제)별로 C 컴파일러를 변경해야 하기 때문입니다.
파스칼은 C와 같은 종류의 포인터를 가지고 있지 않지만, C 포인터의 가장 일반적인 사용을 다루는 간접 연산자를 가지고 있다.각 포인터는 단일 동적 데이터 항목에 바인딩되어 있으며 할당에 의해서만 이동할 수 있습니다.
유형 a = ^정수; 변화하다 b, c: a; 신규(b); c := b;
Pascal의 포인터는 안전한 타입입니다.즉, 하나의 데이터 타입에 대한 포인터는 같은 데이터 타입의 포인터에만 할당할 수 있습니다.또한 포인터는 포인터가 아닌 변수에는 할당할 수 없습니다.포인터 산술(특히 엔디안성 문제 및 플랫폼에 의존하지 않는 유형 크기와 결합될 경우 C에서 프로그래밍 오류의 일반적인 소스)은 Pascal에서 허용되지 않습니다.이러한 모든 제한은 C에 비해 Pascal에서 포인터 관련 오류가 발생할 가능성을 줄여주지만 Pascal에서 잘못된 포인터 참조를 모두 방지하지는 않습니다.예를 들어 포인터가 초기화되기 전 또는 폐기된 후에 참조되면 런타임 오류가 발생합니다.
표현.
이 섹션은 어떠한 출처도 인용하지 않습니다.(2013년 6월 (이 및 ) |
우선 순위 수준
표현평가에 있어서는 언어가 크게 다르지만 종합적으로 비교가 됩니다.
파스칼
- 논리적 부정:
not
- 승수:
* / div mod and
- 추가:
+ - or
- 관계형:
= <> < > <= >= in
C
- 단항 포스트픽스:
[] () . -> ++ --
- 단항 접두사:
& * + - ! ~ ++ -- (type) sizeof
- 승수:
* / %
- 추가:
+ -
- 시프트:
<< >>
- 관계형:
< > <= >=
- 동등성:
== !=
- 비트 및:
&
- 비트 단위 xor:
^
- 비트 단위 또는:
- 논리적 및:
&&
- 논리 또는:
- 조건:
? :
- 할당:
= += -= *= /= %= <<= >>= &= ^= =
- 쉼표 연산자:
,
타자 치기
대부분의 연산자는 파스칼에서 여러 가지 목적을 수행하는데, 예를 들어 마이너스 부호는 부정, 감산 또는 설정 차이에 사용될 수 있습니다(유형과 구문적 맥락에 따라 다름).>=
연산자를 사용하여 숫자, 문자열 또는 집합 등을 비교할 수 있습니다.C는 전용 연산자 기호를 더 많이 사용한다.
할당 및 동등성 테스트
두 언어는 할당에 서로 다른 연산자를 사용합니다.파스칼은 ALGOL과 마찬가지로 수학적 등식 연산자를 사용한다.=
동등성 검정과 기호를 위해:=
반면 C는 B와 마찬가지로 할당에 수학적 동등 연산자를 사용합니다.C(및 B)의 경우,==
따라서 등식 테스트를 위해 기호가 도입되었습니다.
C에서는 경험 부족 또는 단순한 입력 오류로 인해 실수로 다음과 같은 조건문에 할당 식을 넣는 것이 일반적인 실수입니다.if (a = 10) { ... }
. 할당식이 있기 때문에 대괄호 안의 코드는 항상 실행됩니다.a = 10
값 10은 0이 아니므로 C에서 "참"으로 간주됩니다.이는 부분적으로 C(및 ALGOL)가 형식에서 여러 개의 할당을 허용하기 때문입니다.a = b = c = 10;
Pascal에서는 지원되지 않습니다.또, 주의해 주세요.a
이제 가치가 있다10
다음 코드에 영향을 줄 수 있습니다.최근의 C 컴파일러는 이러한 케이스를 검출하여 사용자에게 경고하고 다음과 같은 애매한 구문을 요구합니다.if ((a=10) != 0 ) { ... }
.
Pascal에서 이러한 종류의 실수는 발생할 수 없습니다. 할당은 표현식이 아니며 값이 없기 때문입니다. 잘못된 연산자를 사용하면 명백한 컴파일 오류가 발생할 수 있으며, 또한 누군가가 실수를 할 가능성이 낮습니다.:=
동등성 검정의 기호입니다.
ALGOL의 조건식이 다음과 같은 형태로 나타난 것은 주목할 만하다.a := if a > b then a else b;
C에는 등가물이 있지만 Pascal에는 없습니다.
구현 문제
Niklaus Worth가 파스칼을 설계했을 때, 그 욕구는 우선순위 수준을 제한하는 것이었다(결국 구문 분석 루틴이 더 적기 때문이다).따라서 OR 연산자와 배타적 OR 연산자는 Addop과 동일하게 처리되며 산술식 수준에서 처리됩니다.마찬가지로 AND는 Mulop처럼 처리되며 Term으로 처리됩니다.precedence 레벨은 다음과 같습니다.
수준 구문 요소 연산자 0 요인 리터럴, 변수 1 부호 있는 요인 1차 빼기, NOT 2 항 *, / 및 AND 3 식 +, - 또는 OR
구문 규칙 세트는 두 종류의 연산자에 모두 적용되는1개뿐이에요이 문법에 따르면 다음과 같은 표현들이 있습니다.
x + (y AND NOT z) / 3
완벽하게 합법적이야그리고 사실, 파서에 관한 한, 그들은 그렇다.파스칼은 산술변수와 부울변수의 혼합을 허용하지 않습니다.이러한 변수들은 구문 레벨이 아닌 의미 수준에서 코드를 생성할 수 있습니다.
C의 저자는 정반대의 접근방식을 취했다. 즉, 그들은 측정 시스템을 다른 것으로 취급하며, 실제로 C에는 15개 이상의 레벨이 있다.왜냐하면 C에는 연산자 '=', '+='와 그 친족인 '<', '>', '+', '--' 등도 있기 때문이다.C에서는 산술 연산자와 부울 연산자가 별도로 처리되지만 변수는 그렇지 않습니다. 즉, 임의의 정수 값에 대해 부울 테스트를 수행할 수 있습니다.
논리 접속
파스칼에서 특정 평가 순서에 의존하는 부울식은 (함수 호출의 부작용을 통해) 어느 정도 오류로 간주됩니다.파스칼 컴파일러는 원하는 순서를 자유롭게 사용할 수 있으며, 결과가 부분 평가에 의해 결정되더라도 항상 전체 식을 평가해야 합니다.
C에서, 부울 평가 순서에 대한 의존은 완전히 합법적이며 종종 시스템적으로 사용됩니다.&&
그리고.
연산자와 다음과 같은 연산자와 함께++
,+=
, 콤마 연산자 등그&&
그리고.
연산자는 논리 연산자와 조건문의 조합으로 기능합니다.
단락 표현 평가는 일반적으로 "평가 문제" 때문에 C의 장점으로 간주되어 왔다.
변화하다 i: 정수; a: 포장된 배열 [1..10] 의 차; ... i := 1; 하는 동안에 (i <=> 10) 그리고. (a[i] << 고객명 >>님 'x') 하다 i := i+1; ...
이 간단한 검색은 Pascal에서 문제가 됩니다.배열 액세스 a[i]는 i가 11일 경우 유효하지 않기 때문입니다.이 문제를 회피하는 방법은 여러 가지가 있습니다.다음 예제에서는 타깃 문자가 검출되었는지 여부를 나타내는 부울 변수를 도입합니다.
컨스턴트 스트렌 = 10; 변화하다 i: 정수; a: 포장된 배열 [1..스트렌] 의 차; 찾았다: 부울; ... i := 1; 찾았다 := 거짓의; 하는 동안에 것은 아니다. 찾았다 그리고. (i <=> 스트렌) 하다 한다면 (a[i] = 'x') 그리고나서 찾았다 := 진실의 또 다른 i := i+1; ...
제어 구조
빌딩 제어 구조에 대한 문장은 대략 유사하고 비교적 유사하다(최소한 처음 세 개).
Pascal의 특징:
- 한다면 견디다 그리고나서 스탑 또 다른 스탑
- 하는 동안에 견디다 하다 스탑
- 따라하다 스탑 까지 견디다
- id : = expr to expr do stmt 및 id : = expr do stmt의 경우
- expr의 대소문자 expr : stmt;...expr : stmt; other : stmt; end
C에는 다음이 있습니다.
- if ( cond ) stmt else stmt
- (초) stmt 동안
- (초) 동안 stmt 실행;
- (expr; cond; expr) stmt의 경우
- 스위치(expr) {case expr : stmt ;...case expr : stmt ;기본값 : stmt }
파스칼은 원래 형태에서 기본값과 동등한 것이 없었지만 동등한 else 절이 일반적인 확장자입니다.그렇지 않으면 파스칼 프로그래머는 다음과 같은 식으로 대소문자를 보호해야 했습니다. expr이 [A]에 없는 경우.B] 디폴트 케이스입니다.
C는 이른바 얼리아웃 스테이트먼트를 중단하고 계속하며, 일부 파스칼도 가지고 있습니다.
C와 Pascal 둘 다 goto 스테이트먼트를 가지고 있습니다.그러나 Pascal에는 중첩된 프로시저/함수가 있기 때문에 내부 프로시저 또는 함수에서 포함된 프로시저로 점프할 수 있습니다. 이는 오류 복구를 구현하기 위해 일반적으로 사용되었습니다.C에는 ANSI C setjmp 및 longjmp를 통해 이 기능이 있습니다.이것은 프로그래머가 접근할 수 있는 구조로 점프 주소나 스택 프레임과 같은 프로그램 고유의 정보를 저장하기 때문에 동등하지만 안전성은 거의 없습니다.
기능 및 절차
값을 반환하는 파스칼 루틴을 함수라고 하며 값을 반환하지 않는 루틴을 프로시저라고 합니다.C의 모든 루틴을 함수라고 합니다.값을 반환하지 않는 C 함수는 반환 타입의 보이드로 선언됩니다.
파스칼 프로시저는 C "void" 함수와 동등하며, 파스칼 함수는 값을 반환하는 C 함수와 동등합니다.
C에서는 다음 2개의 선언이 있습니다.
인트 f(인트 x, 인트 y); 무효 k(인트 q);
는 Pascal의 다음 선언과 동일합니다.
기능. f(x, y: 정수): 정수; 절차. k(q: 정수);
Pascal에는 값별 매개 변수와 참조별 매개 변수(VAR)의 두 가지 유형이 있습니다.
기능. f(변화하다 k: 정수): 정수; x := f(t);
C에서는 모든 파라미터가 값으로 전달되지만 포인터를 사용하여 pass-by-reference를 시뮬레이션할 수 있습니다.다음 세그먼트는 위의 Pascal 세그먼트와 유사합니다.
인트 f(인트 *k); //함수에서 포인터를 파라미터로 받아들임 x = f(&t);
C를 사용하면 함수가 변수 함수라고 하는 변수 개수를 수신할 수 있습니다.
인트 f(인트 a, ...); f(1, 2, 3, 4, 5);
함수f()
는 각 파라미터에 차례로 액세스 할 수 있는 특수한 기능 세트를 사용합니다.
또한 Pascal은 I/O 문을 언어에 내장하여 다음과 같은 다양한 양의 매개 변수를 처리합니다.Writeln
Pascal은 프로시저와 함수를 중첩할 수 있도록 합니다.이는 절차 그룹에 로컬이지만 전역 변수가 아닌 변수를 허용하기에 편리합니다.C에는 이 기능이 없기 때문에 변수 또는 함수의 현지화는 변수 또는 함수가 스태틱하다고 선언된 컴파일모듈에서만 실행할 수 있습니다.
C를 사용하면 함수 포인터를 통해 함수를 간접적으로 호출할 수 있습니다.다음 예제에서는 이 스테이트먼트가(*cmpar)(s1, s2)
와 동등하다strcmp(s1, s2)
:
#실패하다 <문자열>h> 인트 (*cmpar)(컨스턴트 차 *a, 컨스턴트 차 *b); 컨스턴트 차 *s1 = "안녕하세요"; 컨스턴트 차 *s2 = "세계"; cmpar = &스트램프; b = (*cmpar)(s1, s2);
또한 Pascal은 함수 및 프로시저를 함수 또는 프로시저에 매개 변수로 전달할 수 있습니다.
절차. 쇼헥스(i: 정수); ... 끝.; 절차. ShowInt(i: 정수); ... 끝.; 절차. 데모(절차. 표시(i: 정수)); 변화하다 j: 정수; 시작한다. 표시(j) 끝.; ... 데모(쇼헥스); 데모(ShowInt); ...
프리프로세서
초기 C에는 일정한 선언도 타입 선언도 없었습니다.C 언어는 원래 메모리 사용량을 줄이기 위해 상수, 포함 및 매크로 정의를 처리하는 별도의 프로그램 및 패스인 "프리프로세서"가 필요하다고 정의되어 있었습니다.이후 ANSI C에서는 상수 정의 기능과 유형 정의 기능을 얻었으며 프리프로세서도 언어의 일부가 되어 오늘날 우리가 볼 수 있는 구문이 되었습니다.
파스칼 상수 및 유형 정의가 내장되어 있지만, Pascal에서도 프리프로세서를 사용하는 프로그래머가 있었습니다(때로는 C에서 사용되는 것과 동일). 확실히 C에서처럼 흔하지는 않습니다.Pascal의 "부족"으로 자주 지적되지만 C에는 프로그램 모듈러나 매크로가 내장되어 있지 않습니다.단순하고 낮은 수준의 개별 컴파일 기능이 있지만(기존 어셈블리 언어에 사용되는 일반 링커를 사용), Pascal은 그렇지 않습니다.
유형 이스케이프
C에서 프로그래머는 어떤 오브젝트의 바이트 레벨 표현을 포인팅함으로써 검사할 수 있습니다.char
포인터:
인트 a; 차 *p = (차 *)(&a); 차 c = *p; // 의 첫 번째 바이트
구별되지 않은 변종 레코드를 사용하여 Pascal에서 유사한 작업을 수행할 수 있습니다.
변화하다 a: 정수; b: 진짜; a2c: 기록. 사례. 부울 의 거짓의: (a: 정수); 진실의: (b: 진짜); 끝.; 끝.; 시작한다. a2c.b := b; a := a2c.a; 끝.;
대부분의 파스칼 컴파일러와 인터프리터에서는 캐스팅이 가능하지만 a2c.a와 a2c.b 위의 코드에서도 동일한 주소 공간을 공유하는 파스칼 표준화가 필요하지 않습니다.Pascal의 설계자인 Niklaus Wirth는 다음과 같은 접근방식을 사용하여 활자 탈출을 시도하는 문제의 본질에 대해 썼다.
"Pascal의 대부분의 구현자들은 이 검사 비용이 너무 많이 들고 코드가 확대되고 프로그램 효율이 저하된다고 판단했습니다.그 결과, 변형 레코드는 보통 함정과 재앙으로 변하는 트릭을 좋아하는 모든 프로그래머들이 타입 시스템을 깨는 데 가장 선호하는 특징이 되었습니다."
현재 자바, C#, 워스의 오베론 등 여러 언어에서 이러한 유형의 이스케이프는 제외되어 있습니다.
파일
C 파일은 내장형(시스템헤더에 정의되어 있음)으로 존재하지 않으며 모든 I/O는 라이브러리 콜을 통해 이루어집니다.파스칼은 언어에 파일 처리 기능이 내장되어 있습니다.
각 언어로 I/O를 수행할 때 사용되는 일반적인 문장은 다음과 같습니다.
인쇄물("합계는: %d\n", x);
기입하다("합계는 다음과 같습니다.', x);
주요 차이점은 C는 printf 함수에 대한 인수를 찾아 변환하기 위해 해석되는 "포맷 문자열"을 사용하는 반면 Pascal은 언어 프로세서의 제어 하에 그것을 수행한다는 것입니다.해석이 이루어지지 않기 때문에 Pascal 방법이 더 빠르지만 C 방법은 확장성이 매우 높습니다.
이후 Pascal 구현 및 확장
일부 인기 있는 파스칼 구현은 거의 모든 C구조를 파스칼에 통합했습니다.예를 들어 유형 캐스트, 변수 주소, 로컬 또는 전역, 특수 승격 속성을 가진 다양한 유형의 정수 가져오기 등이 있습니다.
단, 타입과 타입 변환에 대한 C의 관대한 태도를 도입하면 타입의 보안의 일부 또는 전부를 잃게 될 가능성이 있습니다.예를 들어 Java 및 C#은 C의 인식된 유형의 보안 문제에 대처하기 위해 부분적으로 작성되었으며 비활성 참조 작성에 사용할 수 없는 "관리된" 포인터를 가지고 있습니다.(Niklaus Wirth에 의해 기술된) 원래 형태에서 파스칼은 Java 또는 C#보다 약 30년 전에 관리 대상 포인터 언어로 인정됩니다.그러나 C와 결합된 Pascal은 정의상 그러한 보호를 잃게 됩니다.일반적으로 기본 태스크에 대한 포인터에 대한 의존도가 낮기 때문에 실제로는 C보다 안전합니다.
확장 파스칼 표준은 원래 표준인 파스칼이 지원하지 않았던 많은 것들을 보다 안전한 방식으로 지원하기 위해 파스칼을 확장합니다.예를 들어 스키마 유형은 어레이와 함께 어레이 치수를 필수적으로 전송하는 유형의 안전성을 유지하면서 가변 길이 어레이를 지원하므로 동적 크기 어레이에 대해서도 범위 밖의 인덱스를 자동으로 런타임 체크할 수 있습니다.
「 」를 참조해 주세요.
메모들
- ^ Kamp, Poul-Henning (25 July 2011), "The Most Expensive One-byte Mistake", ACM Queue, 9 (7), ISSN 1542-7730, retrieved 2 August 2011
추가 정보
- Kathleen Jensen과 Niklaus Worth: PASCAL - 사용자 매뉴얼 및 보고서Springer-Verlag, 1974, 1985, 1991, ISBN 3-540-97649-3 https://web.archive.org/web/20050314152247/http ~ warts / books / Pascal / ]
- 브라이언 커니건, 데니스 리치:C 프로그래밍 언어K&R이라고도 불리며, C에 관한 오리지널 서적입니다.
- 1번, 프렌티스 홀 1978; ISBN 0-13-110163-3.ANSI C 이전
- 2번, 프렌티스 홀 1988; ISBN 0-13-110362-8.ANSI C.
- Niklaus Worth: PASCAL 37-38, ACM SIGPLAN Notice, Volume 11, 제1호, 1976년 1월호 동적 어레이에 대한 코멘트.
- Niklaus Worth: Pascal 개발에 관한 추억. 333-342, ACM SIGPLAN Notice, Volume 28, 제3호, 1993년 3월.
- ISO/IEC 9899공식 C:1999 표준과 결함 보고서 및 근거.
- C를 파스칼로 변환하는 상세 분석
- Alan R. Feuer, Narain H. Gehani: 프로그래밍 언어 C와 Pascal 73-92의 비교, ACM Computing Surveies, Volume 14, 제1호, 1982년 3월.
- 프로그래밍 언어 비교 및 평가: 에이다, C, 파스칼, 편집자 앨런 R.프렌티스 홀, 1984년, Feuer와 Narain Gehani.ISBN 0-13-154840-9
- Scott Meyers: 유효 C++, Eddison-Wesley, 1998, ISBN 0-201-92488-9
- 빈센트 헤이워드:프로그래밍 언어 Pascal과 C 50-60의 해부도 비교, ACM SIGPLAN Notice, Volume 21, 제5호, 1986년 5월.
- FreePascal 컴파일러 Wiki의 C 사용자용 Pascal