나는 Delphi 소감과 필기를 배웠다------사용자 정의 데이터 형식(제3강)

11405 단어 Delphi
Pascal 언어의 중요한 특징은 데이터 형식을 사용자 정의할 수 있다는 것이다.각종 유형 구조기를 통해 자계 유형, 수조 유형, 기록 유형, 매거 유형, 바늘 유형, 집합 유형 등 자신의 데이터 유형을 정의할 수 있다.가장 중요한 사용자 정의 데이터 유형은 클래스(class)입니다. 클래스는 Object Pascal의 대상 확장 부분입니다. 이 부분에서는 언급하지 않습니다.
다른 프로그래밍 언어에도 이와 같은 유형의 구조기가 있다고 생각할 수 있지만, Pascal은 이 이론을 완벽하게 실현한 최초의 언어이다.지금까지도 언어가 그렇게 많은 데이터 유형을 정의할 능력이 없다.
이름 및 이름 없는 유형
변수를 후속으로 사용하거나 직접 사용하기 위해서는 사용자 정의 형식에 이름을 붙여야 합니다.명명된 유형을 사용자 정의할 경우 다음과 같이 코드를 특정 type 영역에 배치해야 합니다.
type   // subrange definition   Uppercase = 'A'..'Z';    // array definition   Temperatures = array [1..24] of Integer;    // record definition   Date = record     Month: Byte;     Day: Byte;     Year: Integer;   end;    // enumerated type definition   Colors = (Red, Yellow, Green, Cyan, Blue, Violet);    // set definition   Letters = set of Char; 

유형 정의 구조기를 사용하여 다음 코드와 같은 명명 없이 변수를 직접 정의할 수도 있습니다.
var   DecemberTemperature: array [1..31] of Byte;   ColorCode: array [Red..Violet] of Word;   Palette: set ofColors;

주의: 일반적으로 상술한 이름 없는 형식을 사용하는 것을 피해야 합니다. 왜냐하면 그것을 매개 변수로 전달할 수도 없고, 같은 유형의 다른 변수에 사용할 수도 없기 때문입니다.실제로 Pascal의 유형 호환 규칙은 유형 이름을 기반으로 하는 것이지 실제 유형 정의를 바탕으로 하는 것이 아니다.두 유형이 같은 변수는 완전히 같은 이름이 없으면 호환되지 않을 수도 있다.이름이 없는 형식은 컴파일러가 내부 이름을 할당해야 하기 때문에 데이터 구조가 복잡한 변수에 대해 이름이 있는 데이터 형식을 정의하는 데 익숙해져야 한다. 이 때문에 헛수고가 되지 않을 것이다.
그러나 상술한 사용자 정의 유형은 어떤 의미가 있습니까?만약에 Pascal 타입 구조기에 익숙하지 않다면 아래의 내용을 통해 알 수 있을 것입니다. 그리고 아래에 같은 종류의 구조기가 서로 다른 언어에서의 차이에 대해 이야기했습니다. 따라서 위에서 예시한 타입 정의를 잘 알고 있다면 아래로 읽어도 좋습니다. 그 내용에 대해 흥미를 느낄 것입니다.마지막으로, 나는 델피의 예를 보여 주고, 유형 정보에 동적 접근할 수 있는 도구를 소개할 것이다.
    
subrange)。             ,    1 10  100 1000,              ,    :
type   Ten = 1..10;   OverHundred = 100..1000;   Uppercase = 'A'..'Z'; 
       ,           ,             。           ,             。
         ,                     。        :
var   UppLetter: UpperCase; begin   UppLetter := 'F'; 
          :
var   UppLetter: UpperCase; begin   UppLetter := 'e'; // compile-time error 
             :“Constant expression violates subrange bounds”。
var   UppLetter: Uppercase;   Letter: Char; begin   Letter :='e';   UppLetter := Letter; 
Delphi      ,     ,              (               ),     Range check error (      )  。
  :                 ,            。        ,                      。                ,         ,      。                  ,          ,             。
     
                。      ,             ,            。    ,            。   :
type   Colors = (Red, Yellow, Green, Cyan, Blue, Violet);   Suit = (Club, Diamond, Heart, Spade); 
             ,   0    。  Ord   ,              。  ,Ord (Diamond)    1。
  :            。   ,Delphi  8    ;     256     ,  16    。    32    ,   C、C++       。  $Z            ,         。
    

집합 유형은 집합이 근거로 하는 질서정연한 유형에 의해 정의된 그룹 값을 나타낸다.집합을 정의하는 데 자주 사용하는 질서 유형은 많지 않으며, 일반적으로 매거 유형이나 자계 유형이다.하위 경계 유형 값이 1이면...3, 그러면 그것에 근거한 집합 유형 값은 1, 또는 2, 또는 3, 또는 1과 2, 또는 1과 3, 또는 2와 3, 또는 모든 3개의 수를 취하거나 한 개의 수를 취할 수 있다.
하나의 변수는 일반적으로 이 유형에 대응하는 값을 포함하지만, 집합 유형은 값을 포함하지 않고, 하나의 값, 두 개의 값, 세 개의 값을 포함하거나, 그 이상은 정의 범위 내의 모든 값을 포함할 수 있다.다음은 컬렉션을 정의합니다.
type   Letters = set of Uppercase; 

현재 나는 위의 형식으로 변수를 정의하고 원시 형식의 값을 변수에 부여할 수 있다.집합에서 한 조의 값을 표시하기 위해서는 쉼표로 값을 구분하고 마지막에 네모난 괄호로 끝내야 한다.다음 예제에서는 여러 값, 단일 값 및 빈 값에 대한 변수 지정을 보여 줍니다.
var   Letters1, Letters2, Letters3: Letters; begin   Letters1 := ['A', 'B', 'C'];   Letters2 := ['K'];   Letters3 := []; 

Delphi에서 컬렉션은 일반적으로 다양한 선택의 태그를 나타내는 데 사용됩니다.예를 들어 다음 두 줄 코드(Delphi 라이브러리에서 발췌)는 창 표시줄에 선택할 수 있는 아이콘을 나열하고 해당 컬렉션 유형을 선언하는 열거 유형을 나타냅니다.
type TBorderIcon = (biSystemMenu, biMinimize, biMaximize, biHelp);   TBorderIcons = set of TBorderIcon; 
     

그룹 형식은 지정한 형식의 요소 서열을 정의합니다. 네모난 괄호에 아래 값을 입력하면 그룹의 요소에 접근할 수 있습니다.배열을 정의할 때 대괄호도 가능한 아래 첨자 값을 지정하는 데 사용됩니다.예를 들어, 다음 코드에서는 24개의 정수로 구성된 배열을 정의합니다.
type   DayTemperatures = array [1..24] of Integer; 

수조를 정의할 때, 네모난 괄호에 자계 형식의 값을 입력하거나, 두 개의 질서정연한 형식의 상수로 새로운 자계 형식을 정의해야 한다. 자계 형식은 수조의 유효한 인덱스를 지정한다.하위 경계 유형이 배열 아래 첨자 값의 상계와 하계를 지정하기 때문에, 아래 첨자는 C, C++, JAVA 및 기타 언어처럼 반드시 0부터 시작해야 할 필요가 없다.
배열 아래 첨자는 하위 경계 유형을 기반으로 하므로 Delphi에서 범위 검사를 수행할 수 있습니다.비합법적인 상량자계 유형은 컴파일 시간 오류를 초래할 수 있습니다.컴파일러 범위 검사 옵션을 선택하면 범위를 초과한 하단 값이 실행 시간 오류를 일으킬 수 있습니다.
위의 배열 정의 방법을 사용하여 DayTemperatures 유형의 변수를 다음과 같이 정의합니다.
type   DayTemperatures = array [1..24] of Integer;  var     DayTemp1: DayTemperatures;    procedure AssignTemp;   begin     DayTemp1 [1] := 54;   DayTemp1 [2] := 52;   ...   DayTemp1 [24] := 66;   DayTemp1 [25] := 67; // compile-time error 

배열은 다음과 같은 다차원일 수 있습니다.
type   MonthTemps = array [1..24, 1..31] of Integer;   YearTemps = array [1..24, 1..31, Jan..Dec] of Integer; 

이 두 그룹은 같은 핵심 유형에 세워져 있기 때문에 앞에서 정의한 데이터 형식으로 다음 코드와 같이 설명할 수 있습니다.
type   MonthTemps = array [1..31] of DayTemperatures;   YearTemps = array [Jan..Dec] of MonthTemps; 

상례의 성명은 색인의 순서를 앞뒤로 바꾸었지만, 변수 사이의 전체 블록 값을 허용합니다.예를 들어 1월의 온도치를 2월에 부여한다.
var   ThisYear: YearTemps; begin ... ThisYear[Feb] := ThisYear[Jan]; 

너도 0에서 시작하는 그룹을 정의할 수 있지만, 이것은 논리에 맞지 않는 것 같다. 왜냐하면 세 번째 항목에 접근하기 위해 아래 2를 사용해야 하기 때문이다.그러나 Windows는 항상 0에서 시작하는 그룹을 사용하고 있으며, Delphi 컨트롤 라이브러리도 이 방향으로 접근합니다.
그룹을 사용할 때, 표준 함수인 Low와 High로 경계를 측정하고, Low와 High는 아래 표시된 하계와 상계를 되돌려줍니다.특히 순환 중에는 Low와 High를 사용하는 것을 강력히 권장합니다. 이렇게 하면 코드가 그룹 범위와 무관하기 때문에, 만약 그룹 아래에 표시된 범위 성명을 바꾸면 Low와 High 코드는 영향을 받지 않습니다.그렇지 않으면, 코드에 수조 하위 순환체가 있다면, 수조의 크기가 바뀔 때, 순환체의 코드를 업데이트해야 한다.Low와 High는 당신의 코드를 더욱 쉽게 유지하고 안정적으로 할 것입니다.
참고: Low와 High를 사용하면 시스템 운영에 추가 비용이 들지 않습니다.컴파일할 때, 그들은 실제 함수 호출이 아니라 상수 표현식으로 변환되었기 때문이다.다른 간단한 시스템 함수도 마찬가지다.
    

기록 형식은 서로 다른 형식의 데이터 항목의 고정 집합을 정의하는 데 사용됩니다.기록에 있는 모든 원소, 또는 필드는 그 자체의 유형이 있다.레코드 유형 정의에는 도메인 이름별로 액세스할 수 있는 도메인이 모두 나열됩니다.
다음은 기록 유형의 정의, 유형 변수의 성명과 이런 변수의 사용을 간단하게 열거했다.
type   Date = record     Year: Integer;     Month: Byte;     Day: Byte;   end;    var   BirthDay: Date;    begin   BirthDay.Year := 1997;   BirthDay.Month := 2;   BirthDay.Day := 14; 

클래스와 대상은 기록 형식의 확장이라고 볼 수 있습니다.Delphi 라이브러리는 레코드 유형을 클래스로 대체하는 경향이 있지만 Windows API에는 많은 레코드 유형이 정의되어 있습니다.
기록 형식에variant 필드를 포함할 수 있습니다. 이것은 여러 개의 필드가 같은 메모리 영역을 공용할 수 있고, 필드는 서로 다른 종류가 될 수 있음을 나타냅니다. (이것은 C 언어의 연합union에 해당합니다.)다시 말하면,variant역이나 한 그룹의 방문 기록에서 같은 메모리 위치를 사용할 수 있지만, 각 값은 구별해야 한다.variant 유형은 주로 비슷하지만 다른 데이터를 저장하고 유형 매핑(typecasting)과 비슷한 유형 변환을 하는 데 사용된다. (typecasting이Pascal에 도입된 이후 이런 방법은 거의 사용되지 않는다).델피는 일부 특수한 상황에서variant 기록 유형을 사용하고 있지만 현재는 대상을 대상으로 하는 기술이나 다른 현대 기술로 대체되었다.
variant 기록 유형의 응용은 유형 안전 원칙에 부합되지 않기 때문에 프로그래밍에서 사용하는 것을 제창하지 않기 때문에 초보자는 더욱 그렇다.실제로 전문가급 프로그래머는variant 기록 유형을 사용해야 하는데 Delphi 라이브러리의 핵심 부분에서 이 유형을 사용했다.어쨌든, Delphi 전문가가 아니라면,variant 기록 형식을 사용하는 것을 피해야 한다.
  

포인터는 지정된 유형(또는 정의되지 않은 유형) 변수의 메모리 주소를 저장하는 변수이기 때문에 포인터가 간접적으로 값을 참조합니다.특정 키워드가 아닌 특수 문자를 사용하여 포인터를 정의합니다. 이 특수 문자는 탈자 기호(^)입니다. 다음 예제를 참조하십시오.
type   PointerToInt = ^Integer; 

포인터 변수를 정의하면 @ 기호로 같은 형식의 다른 변수의 주소를 부여할 수 있습니다.다음 예제를 참조하십시오.
var   P: ^Integer;   X: Integer; begin   P := @X;   // change the value in two different ways   X := 10;   P^ := 20;   

포인터 P를 정의하면 P는 포인터가 가리키는 메모리 주소를 표시하고 P^는 메모리에 저장된 실제 내용을 표시합니다.따라서 위 코드에서 P^는 X와 같습니다.
할당된 메모리의 주소를 표시하는 것 외에, 바늘은 뉴 루틴을 통해 무더기에서 메모리를 동적으로 분배할 수 있지만, 이 바늘이 필요하지 않을 때, Dispose 루틴을 호출해서 동적 할당된 메모리를 방출해야 한다.
Delphi는 또한 포인터 데이터 형식을 정의했는데, 포인터는 형식이 없는 포인터를 나타낸다. (C 언어의void*와 같다.)만약 형식이 없는 포인터를 사용한다면, 메모리 분배 크기가 확실하지 않은 경우에 GetMem 루틴이 아니라 GetMem 루틴을 사용해야 합니다.
실제로 델파이에서 바늘을 사용해야 하는 경우는 드물다. 이것은 델파이 개발 환경의 매력적인 장점이다.그럼에도 불구하고 고급 프로그래밍을 하고 Delphi 대상 모델을 완전히 이해하려면 지침을 이해하는 것이 중요하다. 왜냐하면 Delphi 대상 모델이 배후에서 지침을 사용했기 때문이다.
주의:Delphi에서는 포인터를 자주 사용하지 않지만, 아주 비슷한 구조인 인용 (references) 을 자주 사용합니다.모든 대상의 실례는 실제적으로 은밀한 지침이나 실제 데이터에 대한 인용이다. 인용을 이용하면 다른 데이터 형식처럼 대상 변수를 사용할 수 있다.
    

또 다른 Pascal별 유형 작성기는 파일 유형(file)입니다.파일 유형은 Pascal 언어의 특수한 유형인 물리적 디스크 파일을 나타냅니다.다음 방법으로 새 데이터 유형을 정의할 수 있습니다.
type   IntFile = file of Integer; 

그리고 이 구조에 해당하는 물리 파일을 열거나 파일에 정수를 쓰거나 파일에서 현재 값을 읽을 수 있습니다.
Pascal 파일 형식의 사용은 매우 직관적이며 Delphi에서도 파일 저장과 마운트, 데이터 흐름과 데이터베이스에 대한 지원을 위한 컨트롤을 정의했다.

좋은 웹페이지 즐겨찾기