2009-07-14 5 views
32

다음 함수 시그니처를 보았습니다.이 (줄임표 또는 "...")가 일종의 다형성인지 궁금합니다.C의 인수 목록에서 의미하는 것은 무엇입니까?

#include <fcntl.h> 
int fcntl(int fd, int cmd, ...); 

미리 감사드립니다.

+4

충분한 질문. +1. 어떤 사람들은 여전히 ​​단순한 질문은 힘이라는 표시가 있음에도 불구하고 적합하지 않다고 생각합니다. – paxdiablo

+0

질문 제목을 "줄임표 (... 란 무엇입니까?") –

+0

@Hosam : 그래, 다형성에 관한 문제가 아니야 ... 제목이 바뀌 었어. –

답변

8

아니, 그건 년대 "생략"당신이 선언의 ... 부분을 참조하고 가정이보고있다.

기본적으로이 함수는 거기에 지정된 처음 두 개 이후에 알 수없는 인수를 취한다고 말합니다.

함수는 예상 할 수있는 방식으로 작성되어야하며 그렇지 않으면 이상한 결과가 발생합니다.

이 기능을 지원하는 기타 기능은 printf 기능과 그 변형을 살펴보십시오.

+1

또한 인수에도 알 수없는 유형이 있습니다. 함수에서 얻은 것은 모두 유용한 첫 번째 인수에 대한 포인터입니다. –

2

나는 당신이 줄임표 (...)를 말하고 있다고 가정합니까? 그렇다면 0 이상의 매개 변수가 따를 것임을 나타냅니다. 그것은 printf와이 기능을 사용

http://msdn.microsoft.com/en-us/library/kb57fad8.aspx

와 stdarg.h에 정의 된, 가변 인자라고합니다. 그것 없이는 함수의 마지막에 매개 변수를 계속 추가 할 수 없습니다.

+1

나는 URL의 "(VS.71)"접미사는 항상 최신 버전의 설명서에 연결됩니다. –

+0

충분히 정교합니다. ... 나는 방금 Google 검색을 통해 링크를 얻었습니다. – Goz

0

아니요, 가변 인수를 사용하는 함수입니다.

0

기술적으로 다형성이 아닙니다. fcntl은 인자가 가변적 인 숫자 인 &을 사용합니다. 그 이유는 ... printf 함수와 비슷합니다.

15

이것은 variadic function입니다. 자세한 내용은 stdarg.h을 참조하십시오.

+3

+1 내게 새로운 단어를 가르쳐주었습니다. – Gavin

11

...은 다른 의견 작성자가 이미 언급 한 것처럼이 함수에 여러 가지 인수를 전달할 수 있음을 의미합니다. 선택적 인수는 형식화되지 않으므로 컴파일러는 형식을 검사 할 수 없으며 기술적으로 모든 유형의 인수를 전달할 수 있습니다.

이렇게하면 일종의 다형 함수를 구현할 수 있습니다. 런타임에 전달 된 인수의 유형을 검사 할 수 없기 때문에 (즉, 인자의 종류에 따라 몇 가지 작업을 수행하는 함수입니다.)

번호

이 작업을 수행 할 수없는 이유이다. 변수 인수 목록에서 함수 읽기는 수신 할 선택적 인수의 유형을 이미 알고있을 것으로 예상됩니다.

실제로 모든 유형의 인수 (예 : printf)를 사용할 수있는 함수의 경우 인수 유형이 형식 문자열을 통해 전달됩니다. 즉, 호출자는 호출 할 때마다 전달할 유형을 지정해야하며 호출자가 유형을 알지 않아도되는 다형 함수의 이점을 제거합니다.

// Ideal invocation 
x = multiply(number_a, number_b) 
y = multiply(matrix_a, matrix_b) 

// Standard C invocation 
x = multiply_number(number_a, number_b) 
y = multiply_matrix(matrix_a, matrix_b) 

// Simulated "polymorphism" with varargs 
x = multiply(T_NUMBER, number_a, number_b) 
y = multiply(T_MATRIX, matrix_a, matrix_b) 

당신은 옳은 일을 할 수있는 가변 인자 함수 전에 유형을 지정해야합니다, 그래서 이것은 당신에게 아무것도 얻는하지 :

비교.

6

C는 다형성을 지원합니까? 아니요.

그러나 구조체와 포인터를 사용하여 대략적인 다형성을 구현하는 Python C API와 같은 여러 라이브러리가 있습니다. 대부분의 경우 컴파일러가 적절한 유형 검사를 수행 할 수 없다는 점에 유의하십시오.

tecnhique은 간단

typedef struct { 
    char * (*to_string)(); 
} Type; 

#define OBJ_HEADER Type *ob_type 

typedef struct { 
    OBJ_HEADER; 
} Object; 

typedef struct { 
    OBJ_HEADER; 
    long ival;   
} Integer; 

typedef struct { 
    OBJ_HEADER; 
    char *name; 
    char *surname; 
} Person; 

정수 및 사람이 적절한 함수 포인터 타입 오브젝트를 얻는 (예를 integer_to_string person_to_string과 같은 기능을 수행하기 위해).

지금은 단지 개체 * 받아들이는 함수를 선언 :

void print(Object *obj) { 
    printf("%s", obj->type->to_string()); 
} 

지금 당신은 정수와 사람 모두이 함수를 호출 할 수 있습니다 :

Integer *i = make_int(10); 
print((Object *) i); 

Person *p = make_person("dfa"); 
print((Object *) p); 

편집을 선택적으로

을 수행 할 수 있습니다 i와 p를 Object *로 선언하십시오. 물론 make_int 및 make_person는 정수 및 사람을위한 공간을 할당하고 적절한 캐스팅 할 것입니다 :

Object * 
make_integer(long i) { 
    Integer *ob = malloc(sizeof(Integer)); 
    ob->ob_type = &integer_type; 
    ob->ival = i; 
    return (Object *) ob; 
} 

NB : 나는 rigth 지금이 예제를 컴파일 할 수 없습니다, 그 양쪽을하시기 바랍니다.

나는 다음과 같은 함수 서명을 가로 질러 와서 나는이 (생략이, 또는 "...") 다형성의 일종 인 경우 궁금해?

예, 다형의 기본형입니다. 예 : 입니다. 하나의 함수 시그니처 만 있으면 다양한 구조를 전달할 수 있습니다. 그러나 컴파일러는 유형 오류를 감지하는 데 도움을 줄 수 없습니다. 도 여러 디스패치 (즉 런타임 타입에 기초하여 과부하) - 컴파일 타임 유형에 따라 애드혹 다형의 유형 인 -

+0

당신의 함수'print'는'void *'형의 인수를 받아 들일 필요가 있습니다. 그런 다음 당신의 예제가 작동하기 위해서는 그것을 명시 적으로'Object *'로 캐스팅해야합니다. –

+0

고침, Konrad – dfa

+0

-1에 감사드립니다. 왜냐하면 제목에서 "다형성"이라는 단어에도 불구하고 원래의 질문이 무엇인지에 대해 생각하지 않았기 때문입니다. 이 대답은 C.에 다형성을 구현할 수있는 방법에 대한 질문에 더 적절할 것입니다. –

0

는 C가 둘 함수 오버로드를 지원하지 않는다.

C에서 함수 오버로드를 시뮬레이트하려면 여러 가지 다른 이름의 함수를 만들어야합니다. 함수의 이름에는 문자에 대해서는 fputc(), 문자열의 경우에는 fputs()과 같은 유형 정보가 포함되어있는 경우가 많습니다.

가변적 인 매크로를 사용하여 다중 발송을 구현할 수 있습니다. 다시 말하지만, 유형 정보를 제공하는 것은 프로그래머의 임무이지만, 이번에는 런타임에 평가 될 추가 인수를 통해 - 위에 주어진 접근 방식의 경우 컴파일 타임 함수 이름과 대비됩니다. printf() 계열의 기능이 다중 발송의 가장 좋은 예는 아니지만 지금 당장은 더 좋은 것으로 생각할 수 없습니다.

Variadic 함수 대신 포인터를 사용하거나 형식 주석을 제공하기 위해 구조에서 값을 래핑하는 여러 가지 방법이 있습니다.

4

다른 말로 C는 다형성을 지원합니다. 예를 들어, 임의의 타입의 데이터를 정렬하는 표준 라이브러리 qsort 함수를 사용하십시오.

데이터에 대한 유형이 지정되지 않은 포인터 (void)를 사용하여 수행 할 수 있습니다. 또한 정렬 할 데이터의 크기 (sizeof을 통해 제공)와 객체의 순서를 비교하는 로직을 알아야합니다. 이것은 qsort 함수에 함수 포인터를 전달하여 수행됩니다.

이것은 런타임 다형성의 대표적인 예입니다.

가상 함수 테이블을 수동으로 관리하여 개체 지향 동작 (특히 가상 함수 호출)을 구현하는 다른 방법이 있습니다. 구조체에 함수 포인터를 저장하고 전달할 수 있습니다. 많은 API가 그렇게합니다. WinAPI는 객체 지향의 고급 측면을 사용합니다. 기본 클래스 호출 디스패치 (기본 클래스의 가상 메서드 호출을 시뮬레이트하기 위해 DefWindowProc).

+0

-1 : Konrad, 저는 그것이 다형성의 표준 정의의 주요한 부분이라고 생각합니다. 타입이 지정되지 않은 데이터를 처리하는 방법 이상의 것은 아닙니다. 우리의 어둡고 유형이없는 과거에 대한 회귀입니다. 예전에 우리가 OO를하기 전에해야했던 일이었습니다. –

+2

John, 미안하지만 당신이 틀렸어. 거기에는 스트레칭이 없으며 "표준"정의와 같은 것은 없으며 다형성의 일반적인 정의는 구현에 사용 된 기술과 관련하여 완전히 명확하지 않습니다. –

+0

상속을 가진 하위 유형 다형성뿐만 아니라 다양한 형태의 다형성이 있습니다. 파라 메트릭 다형성 (예 : 템플릿)과 나는 함수형 포인터를 전달하는 것이 매개 변수형 다형성 (parametric polymorphism)이라고 말합니다. 그렇다면 과부하 기능을 가진 정적 다형성이 있습니다. 나는 콘라드가 이것으로 옳다고 생각한다. –

1

표준 라이브러리의 printf와 선언은

int printf(const char*, ...); 

그것에 대해 생각합니다.

0

C에서 다형성 동작을 지원하는 코드를 작성할 수 있지만 ... (줄임표)는별로 도움이되지 않습니다. 그것은 함수에 대한 가변 인수를위한 것입니다.

다형성 비헤이비어를 사용하려는 경우 유니온 및 구조체를 사용하여 "유형"섹션과 유형에 따라 가변 필드가있는 데이터 구조를 구성 할 수 있습니다. 구조에 함수 포인터 테이블을 포함 할 수도 있습니다. 똥! 당신은 C++을 발명했습니다.

1

c는 조질 형태의 다형성을지지한다. 나는. 다른 유형으로 표시되고 작동 할 수있는 유형입니다. 그것은 C + +에서 후드 (메모리 정렬에 의존)에서와 유사하지만 캐스팅을 통해 컴파일러를 도와야했습니다. 예 :

typedef struct { 
    char forename[20]; 
    char surname[20]; 
    } Person; 

그리고 또 다른 구조체 :

typedef struct { 
      char forename[20]; 
      char surname[20]; 
      float salary; 
      char managername[20]; 
      } Employee; 

그런

int main (int argc, int *argv) 
{ 
    Employee Ben; 
    setpersonname((Person *) &Ben); 
} 

void setpersonname(Person *person) 
{ 
    strcpy((*person).Name,"Ben"); 
} 

위의 예는 직원 한 사람으로 사용되고 보여줍니다 당신은 구조체를 정의 할 수 있습니다.

+0

나는 아직도 이것이 용어를 늘리고 있다고 말한다. _Yes_ Employee는 Person과 유사하게 동작합니다. C의 _everything_는 일련의 작은 의미 집합이 맨 위에 매핑 된 바이트 시퀀스와 같은 역할을하기 때문입니다. FORTRAN의 COMMON 블록은 다형성을 나타내거나 어셈블러가 액세스하는 시스템의 완전히 유형이없는 주소 공간을 나타냅니다. –

+0

예. 컴파일러가 '유형 다형성 (Polymorphism)'을 지원하지 않았으며, 컴퓨터 사이언스 사전 정의에 따라 어떤 방식 으로든 주장 될 수 있습니다. 나는 C가 할 수있는 최선을 보여주고 있었다고 생각합니다. –

+0

이런 식으로해야 할 경우 Employee를 공용 구조체를 사용하여 정의 할 수 있음을 잊지 마십시오. 이것은 일반적인 바이트 순서를 강제합니다! – maxwellb

-4

예 C는 (하나의 세부 here을 찾을 수 있습니다) 우리가 처음 컴파일러에 의해 C 코드로 변환하면 다형성 을 구현하는 가상 사용하여 C++에 쓰기 다형성

코드를 지원합니까.

C++의 가상 기능은 함수 포인터를 사용하여 구현되는 것으로 잘 알려져 있습니다.

관련 문제