타이피프

typedef

typef프로그래밍 언어 C와 C++에서 예약키워드다. 다른 데이터 유형의 추가 이름(별칭)을 만드는 데 사용되지만, 형식 정의 한정자가 배열 요소 유형으로 전송되는 배열 유형의 정규화된 형식 정의의 모호한 경우를 제외하고는 새로운 형식을 [1]생성하지 않는다.[2] 이와 같이 구조체조합형으로 구성된 복잡한 데이터 구조를 선언하는 구문을 단순화하는 데 종종 사용되지만, 길이가 다양한 정수 데이터 유형에 대해 특정한 서술형 이름을 제공하는 것만큼이나 일반적이다.

구문

typef 선언의 구문은 다음과 같다.[3]

typedef 형식 지정;

새로운 유형의 별칭의 이름은 다른 C 식별자를 선언하는 것과 같은 구문을 따르므로, 보다 상세한 형태로 다음과 같다.

typedef 활자 화질 식별자

C 표준 라이브러리POSIX 규격에서 typeef 정의의 식별자는 종종 다음과 같이 접미사가 된다. _t, size_ttime_t와 같은. 이는 POSIX 데이터 유형에 대해 POSIX가 명시적으로 이 관행을 예약하지만 다른 코딩 시스템에서 실행된다.

타이피프 인트로 길이; 

이렇게 하면 유형이 생성됨 length 그 유형의 동의어로. int.

문서 사용

프로그래밍 컨텍스트 내에서 변수의 의미를 나타냄으로써, 예를 들어, 측정 단위나 카운트의 표현을 포함할 수 있는 타이프 선언을 문서로 사용할 수 있다. 일반 선언문,

인트로 current_speed; 인트로 high_beauth;  공허하게 하다 축하하다(인트로 your_properties) {     만일 (your_properties > high_beauth) {         // ...     } } 

컨텍스트별 유형을 선언하여 표시할 수 있다.

타이피프 인트로 km_per_hour; 타이피프 인트로 포인트;  // 'km_per_hour'는 여기서 'int'와 동의어여서 컴파일러가 취급한다. // 정수로서의 새로운 변수. km_per_hour current_speed; 포인트 high_beauth;  공허하게 하다 축하하다(포인트 your_properties) {     만일 (your_properties > high_beauth) {         // ...     } } 

코드의 두 섹션 모두 동일하게 실행된다. 그러나 두 번째 코드 블록에서 typedef 선언을 사용하면 동일한 데이터 유형을 나타내면서도 두 변수가 명확하게 나타난다. int, 서로 다르거나 호환되지 않는 데이터 저장. 정의: congratulate()your_score 라고 프로그래머에게 지시한다. current_speed (또는 a로 선언되지 않은 다른 변수) points)는 논거로 전가해서는 안 된다. 만약 두 가지가 모두 다음과 같은 변수로 선언되었다면 이는 명백하지 않을 것이다. int 데이터 타입 단, 표시는 프로그래머만을 위한 것이다. C/C++ 컴파일러는 두 변수 모두 유형으로 간주한다. int 다음 항목에 대해 "불완전한" 인수 유형에 대한 유형 불일치 경고 또는 오류 플래그 지정 안 함 congratulate(points your_score) 아래 코드 조각에서:

공허하게 하다 foo() {     km_per_hour km100 = 100;     축하하다(km100); } 

유형간소화

복합형(구조, 조합) 또는 포인터형식의 선언을 단순화하기 위해 typeef를 사용할 수 있다.[4] 예를 들어,

구조상의 마이스트락트 {     인트로 data1;     마를 뜨다 data2; }; 

이것은 데이터 유형을 정의한다. struct MyStructC에서 이러한 유형의 변수 선언은 또한 키워드를 필요로 한다. struct, 그러나 C++에서는 생략할 수 있다.

구조상의 마이스트락트 a; 

typef 선언으로 지정하지 않아도 됨 struct 예를 들어, 선언문은

타이피프 구조상의 마이스트락트 뉴타입의; 

다음 항목으로 축소됨

뉴타입의 a; 

구조 선언과 타이핑에프도 단일 문장으로 결합할 수 있다.

타이피프 구조상의 마이스트락트 {     인트로 data1;     마를 뜨다 data2; } 뉴타입의; 

또는 다음과 같이 사용할 수 있다.

타이피프 구조상의 {     인트로 data1;     마를 뜨다 data2; } 뉴타입의; 

C++에서는 C와 대조적으로 키워드 struct, class그리고 enum 다른 식별자에 대한 모호성이 없는 한, 정의와 분리된 변수 선언에서 선택 사항이다.

구조상의 마이스트락트 x; 마이스트락트 y; 

그런 만큼 MyStruct 어디에나 쓸 수 있다 newtype 사용할 수 있다. 그러나, 그 반대는 사실이 아니다. 예를 들어, 시공자 방법은 다음과 같다. MyStruct 이름을 붙일 수 없다 newtype.

C++가 필요한 악명 높은 예 struct 키워드는 POSIXstat 시스템 호출로, 인수에서 동일한 이름의 구조체를 사용한다.

인트로 스타트를 끊다(경시하다 마를 뜨다 *파일 이름, 구조상의 스타트를 끊다 *뷔프) {     // ... } 

여기C와 C++는 모두 struct 매개 변수 정의의 키워드.

포인터

새 포인터 유형을 정의하는 데 typef를 사용할 수 있다.

타이피프 인트로 *삽시간에;  삽시간에 삐걱삐걱거리다;  // 다음 항목과 동일: // int *ptr; 

intptr 포인터 유형이 있는 새 별칭 int *정의는, intptr ptr;, 변수를 정의함 ptr 같은 타입으로 int *그래서. ptr 유형의 변수를 가리킬 수 있는 포인터 int.

새 포인터 유형을 정의하기 위해 typef를 사용하면 혼동을 초래할 수 있다. 예를 들면 다음과 같다.

타이피프 인트로 *삽시간에;  // '클리프'와 '알렌'은 모두 int*형이다. 삽시간에 벼랑을 치다, 알렌;  // 'cliff2'는 int*형이지만, '22'는 int**형이다. 삽시간에 절벽2, *앨런2;  // 다음 항목과 동일: // inptr cliff2; // intptr *belf2; 

위에. intptr cliff, allen; 평균: 두 변수 정의 int* 둘 다 타이핑하다 왜냐하면 typeef가 정의한 유형은 확장이 아니라 유형이기 때문이다. 바꾸어 말하면, 환언하면 intptr, 어느 것이 더 좋은가? int* 활자, 장식 둘 다 cliff 그리고 allen.을 위해 intptr cliff2, *allen2;intptr 활자를 장식하다 cliff2 그리고 *allen2그래서. intptr cliff2, *allen2; 2개의 별도 정의에 해당한다. intptr cliff2; 그리고 intptr *allen2. intptr *allen2 라는 뜻이다. allen2 에 대한 기억을 가리키는 포인터 입니다. int* 타이핑. 곧, allen2 그런 타입이 있어 int**.

상수 포인터

다시 말하지만, typedef는 확장이 아닌 유형을 정의하기 때문에, const 한정자를 사용하는 선언은 예기치 않은 또는 비양심적인 결과를 산출할 수 있다. 다음 예제는 정수에 대한 포인터가 아니라 인터거 유형에 대한 상수 포인터를 선언한다.

타이피프 인트로 *삽시간에;  경시하다 삽시간에 삐걱삐걱거리다 = NULL;  // 다음 항목과 동일: // int *constant ptr = NULL; 

상수 포인터인 만큼 선언문에 초기화해야 한다.

구조물 및 구조물 포인터

타이핑에프도 구조물 포인터 유형에 대한 정의나 선언을 단순화할 수 있다. 다음을 고려하십시오.

구조상의 노드 {     인트로 자료;     구조상의 노드 *다음 단계의; }; 

typef를 사용하여 위의 코드를 다음과 같이 다시 쓸 수 있다.

타이피프 구조상의 노드 노드;  구조상의 노드 {     인트로 자료;     노드 *다음 단계의; }; 

C에서는 포인터나 비점자와 구조를 섞어서라도 같은 유형의 여러 변수를 단일 문장으로 선언할 수 있다. 그러나 각 변수에 별표를 붙여야 포인터로 지정할 수 있다. 다음에서 프로그래머는 다음과 같이 가정할 수 있다. errptr 정말로 Node *, 그러나 인쇄상의 오류는 다음을 의미한다. errptr 이사하다 Node. 이것은 미묘한 구문 오류를 초래할 수 있다.

구조상의 노드 *스타트렉, *종말론자, *커프터, *우세하다, 실수하다, *재흡수하다; 

typedef 정의 Node *, 모든 변수는 구조 포인터 유형, 즉 각 변수가 구조 유형을 가리키는 포인터 유형이라는 것이 확실하다.

타이피프 구조상의 노드* 노드Ptr;  노드Ptr 스타트렉, 종말론자, 커프터, 우세하다, 실수하다, 재흡수하다; 

함수 포인터

인트로 do_math(둥둥 뜨다 arg1, 인트로 arg2) {     돌아오다 arg2; }  인트로 call_a_funk(인트로 (*call_this)(둥둥 뜨다, 인트로)) {     인트로 생산량 = call_this(5.5, 7);      돌아오다 생산량; }  인트로 final_properties = call_a_funk(&do_math); 

앞의 코드는 다음과 같이 타이핑된 ef 사양으로 다시 작성할 수 있다.

타이피프 인트로 (*매트릭펑크)(둥둥 뜨다, 인트로);  인트로 do_math(둥둥 뜨다 arg1, 인트로 arg2) {     돌아오다 arg2; }  인트로 call_a_funk(매트릭펑크 call_this) {     인트로 생산량 = call_this(5.5, 7);      돌아오다 생산량; }  인트로 final_properties = call_a_funk(&do_math); 

여기, MathFunc 형식에 대한 새 별칭입니다. a MathFunc 정수를 반환하고 플로트와 정수를 차례로 인수하는 함수에 대한 포인터입니다.

함수가 함수 포인터를 반환할 때, 타이프 없이 더 혼란스러울 수 있다. 다음은 FreeB 신호(3)의 기능 프로토타입이다.SD:

공허하게 하다 (*신호를 보내다(인트로 시그널, 공허하게 하다 (*펑크)(인트로)))(인트로); 

위의 함수 선언은 함수가 인수로 받아들이는 것, 또는 반환하는 유형을 명확하게 나타내지 않기 때문에 암호화된 것이다. 초보 프로그래머는 심지어 함수가 싱글을 받아들인다고 가정할 수도 있다. int 그것의 주장으로서 그리고 아무것도 반환하지 않지만, 실제로는 그것은 또한 기능 포인터를 필요로 하고 또 다른 기능 포인터를 반환한다. 다음과 같이 더욱 깨끗하게 쓸 수 있다.

타이피프 공허하게 하다 (*한숨 돌리기_t)(인트로);  한숨 돌리기_t 신호를 보내다(인트로 시그널, 한숨 돌리기_t 펑크); 

배열

또한 배열 유형의 정의를 단순화하는 데 typef를 사용할 수 있다. 예를 들어,

타이피프 마를 뜨다 arrType[6];  arrType arr = {1, 2, 3, 4, 5, 6}; arrType *파르;  // 다음 항목과 동일: // char arr[6] = {1, 2, 3, 4, 5, 6}; // char(*pArr)[6]; 

여기, arrType 에 대한 새로운 별칭이다. char[6] 형식, 이것은 6개의 요소를 가진 배열 형식이다. 을 위해 arrType *pArr;, pArr 에 대한 기억을 가리키는 포인터 입니다. char[6] 타자를 치다

유형 캐스트

typeef는 type definition 구문을 사용하여 생성되지만 type cast 구문을 사용하여 생성된 것처럼 사용할 수 있다.(type casting은 데이터 유형을 변경). 예를 들어, 첫 번째 줄 뒤의 각 줄에서:

// funcptr은 'double'을 취하고 'int'를 반환하는 함수에 대한 포인터다. 타이피프 인트로 (*펑크프터)(곱절로 하다);  // C와 C++ 모두에서 유효함. 펑크프터 x = (펑크프터) NULL;  // C++에서만 유효함. 펑크프터 y = 펑크프터(NULL); 펑크프터 z = 정적_캐스트<펑크프터>(NULL); 

funcptr 왼쪽에는 변수를 선언하는 데 사용되며 오른쪽에는 값을 캐스팅하는 데 사용된다. 따라서 정의 구문을 유형 캐스트 구문으로 변환하는 방법을 알아내기를 원하지 않는 프로그래머가 타이핑에프를 사용할 수 있다.

typef가 없으면 일반적으로 정의 구문과 캐스트 구문을 서로 교환하여 사용할 수 없다. 예를 들면 다음과 같다.

공허하게 하다 *p = NULL;  // 이것은 합법이다. 인트로 (*x)(곱절로 하다) = (인트로 (*)(곱절로 하다)) p;  // 왼쪽은 합법적이지 않다. 인트로 (*)(곱절로 하다) y = (인트로 (*)(곱절로 하다)) p;  // 오른쪽은 합법적이지 않다. 인트로 (*z)(곱절로 하다) = (인트로 (*p)(곱절로 하다)); 

C++에서의 사용

C++에서 형식 이름은 복잡할 수 있으며, 형식 정의는 형식에 간단한 이름을 할당하는 메커니즘을 제공한다.

찌꺼기::벡터<찌꺼기::짝을 짓다<찌꺼기::끈을 매다, 인트로>> 가치;  을 위해 (찌꺼기::벡터<찌꺼기::짝을 짓다<찌꺼기::끈을 매다, 인트로>>::const_iterator i = 가치.시작되다(); i != 가치.종지부를 찍다(); ++i) {     찌꺼기::짝을 짓다<찌꺼기::끈을 매다, 인트로> 경시하다 & t = *i;      // ... } 

그리고

타이피프 찌꺼기::짝을 짓다<찌꺼기::끈을 매다, 인트로> value_t; 타이피프 찌꺼기::벡터<value_t> values_t;  values_t 가치;  을 위해 (values_t::const_iterator i = 가치.시작되다(); i != 가치.종지부를 찍다(); ++i) {     value_t 경시하다 & t = *i;      // ... } 

C++11은 다음과 같이 타이핑된 ef를 표현할 수 있는 가능성을 소개했다. using 대신에 typedef. 예를 들어, 위의 두 개의 타이핑된 ef는 동등하게 다음과 같이 기록될 수 있다.

사용. value_t = 찌꺼기::짝을 짓다<찌꺼기::끈을 매다, 인트로>; 사용. values_t = 찌꺼기::벡터<value_t>; 

템플릿과 함께 사용

C++03은 템플리트화된 타이핑을 제공하지 않는다. 예를 들어, 을 갖는 것 stringpair<T> 대표하다 std::pair<std::string, T> 모든 종류에 대하여 T 사용할 수 없음:

템플릿<타이프 이름 T> 타이피프 찌꺼기::짝을 짓다<찌꺼기::끈을 매다, T> 현악기<T>; // 작동하지 않음 

그러나, 기꺼이 받아들이려 한다면. stringpair<T>::type 대신에 stringpair<T>다른 방법으로 사용되지 않는 템플리트 클래스 또는 구조체 내의 타이핑을 통해 원하는 결과를 얻을 수 있다.

템플릿<타이프 이름 T> 계급 현악기 { 사유의:     // '스트링페어'의 인스턴스화 방지T>"라고 말했다.     현악기(); 공중의:     // '스트링페어'를 만드세요.T>::타입은 std:pair를 나타낸다.     타이피프 찌꺼기::짝을 짓다<찌꺼기::끈을 매다, T> 타자를 치다; };  // "std:pair" 유형의 변수를 선언하십시오. 현악기<인트로>::타자를 치다 my_my_my_of_string_and_int; 

C++11에서는 다음과 같은 구문과 함께 템플리트화된 타이핑이 추가되는데, 이 구문은 다음과 같다. using 보다 키워드 typedef 키워드 (템플릿 별칭을 참조하십시오.)[5]

템플릿 <타이프 이름 T> 사용. 현악기 = 찌꺼기::짝을 짓다<찌꺼기::끈을 매다, T>;  // "std:pair" 유형의 변수를 선언하십시오. 현악기<인트로> my_my_my_of_string_and_int; 

다른 언어

SystemVerilog에서 typedef는 C와 C++[6]에서와 똑같이 동작한다.

하스켈, 미란다, OCaml 등과 같이 정적으로 타이핑된 많은 기능 언어에서는 C의 타이핑과 같은 타입의 동의어를 정의할 수 있다. 하스켈의 예:

타자를 치다 페어오핀츠 = (인트, 인트) 

이 예에서는 유형 동의어를 정의함 PairOfInts 정수 활자로

Seed7에서 상수 유형의 정의는 형식에 대한 동의어를 도입하는 데 사용된다.

const type: myVector는 배열 정수; 

Swift에서, typealias 키워드: 입력된 ef를 만드는 방법:

타이팔리아스 페어오핀츠 = (인트, 인트) 

C#에는 typedef 또는 의 기능과 유사한 기능이 포함되어 있다. using C++[7][5]의 구문

사용. newType = 전지구적::시스템.런타임.인터롭.보안관; 사용. otherType = 에넘스.MyEnumType; 사용. StringListMap = 시스템.컬렉션.포괄적인.사전<끈을 매다, 시스템.컬렉션.포괄적인.리스트<끈을 매다>>; 

D에서 키워드 alias[8] 형식 또는 부분 형식 동의어를 작성할 수 있음.

구조상의 (T){} 가명 푸인트 = !인트로; 가명 재미 = 인트로 위임하다(인트로); 

사용 우려 사항

Kernighan과 Ritchie는 타이페프를 사용하는 두 가지 이유를 말했다.[1] 첫째, 프로그램을 보다 휴대성이 높거나 유지관리가 용이하도록 하는 수단을 제공한다. 프로그램의 소스 파일 전체에 걸쳐 모든 외형에서 타입을 변경해야 하는 대신, <stdlib>의 size_tptrdiff_t 하나만 변경하면 된다.h>는 그렇게 타이프된 이름들이다. 둘째로, 타이페프는 복잡한 정의나 선언문을 이해하기 쉽게 만들 수 있다.

일부 프로그래머들은 타자기의 광범위한 사용에 반대한다. 대부분의 논쟁은 typeefs가 변수의 실제 데이터 유형을 숨긴다는 생각에 초점을 맞춘다. 를 들어, 리눅스 커널 해커이자 문서 작성자인 그렉 크로아 하르트만은 기능 프로토타입 선언을 제외한 어떤 것에 대해서도 사용이 금지된다. 그는 이러한 관행이 불필요하게 코드를 난독화시킬 뿐만 아니라, 프로그래머들이 단순한 유형이라고 생각하는 대형 구조물을 실수로 오용하게 할 수도 있다고 주장한다.[9]

참고 항목

참조

  1. ^ a b Kernighan, Brian W.; Ritchie, Dennis M. (1988). The C Programming Language (2nd ed.). Englewood Cliffs, New Jersey.: Prentice Hall. p. 147. ISBN 0-13-110362-8. Retrieved 18 June 2016. C provides a facility called typedef for creating new data type names. … It must be emphasized that a typedef declaration does not create a new type in any sense; it merely adds a new name for some existing type.
  2. ^ "const type qualifier". cppreference.com. Retrieved 2020-10-20.
  3. ^ "typedef specifier". cppreference.com. Retrieved 18 June 2016.
  4. ^ Deitel, Paul J.; Deitel, H. M. (2007). C how to program (5th ed.). Upper Saddle River, N.J.: Pearson Prentice Hall. ISBN 9780132404167. Retrieved 12 September 2012. Names for structure types are often defined with typedef to create shorter type names.
  5. ^ a b "Type alias, alias template (since C++11) - cppreference.com". en.cppreference.com. Retrieved 2018-09-25.
  6. ^ Tala, Deepak Kumar. "SystemVerilog Data Types Part-V". www.asic-world.com. ASIC World. Retrieved 25 September 2018.
  7. ^ http://msdn.microsoft.com/en-us/library/aa664765(VS.71).aspx
  8. ^ "Declarations - D Programming Language". dlang.org. Retrieved 2017-05-28.
  9. ^ Kroah-Hartman, Greg (2002-07-01). "Proper Linux Kernel Coding Style". Linux Journal. Retrieved 2007-09-23. Using a typedef only hides the real type of a variable.