Namespaces
Variants

Function definitions

From cppreference.net

함수 정의는 함수 본문(선언과 문장들의 시퀀스)을 함수 이름과 매개변수 목록과 연결합니다. 함수 선언 과 달리, 함수 정의는 파일 범위에서만 허용됩니다(중첩 함수는 존재하지 않습니다).

C는 두 가지 다른 형태의 함수 정의를 지원합니다:

attr-spec-seq (선택 사항) specifiers-and-qualifiers parameter-list-declarator function-body (1)
specifiers-and-qualifiers identifier-list-declarator declaration-list function-body (2) (C23 이전)

여기서

attr-spec-seq - (C23) 함수에 적용되는 속성 의 선택적 목록
specifiers-and-qualifiers - 다음의 조합
parameter-list-declarator - 함수 매개변수를 지정하기 위해 매개변수 목록 을 사용하는 함수 타입의 선언자
identifier-list-declarator - 함수 매개변수를 지정하기 위해 식별자 목록 을 사용하는 함수 타입의 선언자
declaration-list - identifier-list-declarator 의 모든 식별자를 선언하는 선언 시퀀스. 이러한 선언은 이니셜라이저를 사용할 수 없으며 허용되는 유일한 저장 클래스 지정자 register 입니다.
function-body - 이 함수가 호출될 때마다 실행되는 선언과 문의 중괄호로 묶인 시퀀스인 복합 문
1) 새로운 스타일(C89) 함수 정의. 이 정의는 함수 자체를 도입함과 동시에 이후의 모든 함수 호출 표현식 에 대한 함수 프로토타입 역할을 수행하여, 인수 표현식에서 선언된 매개변수 타입으로의 변환을 강제합니다.
int max(int a, int b)
{
    return a>b?a:b;
}
double g(void)
{
    return 0.1;
}
2) (C23 이전) 구식(K&R) 함수 정의. 이 정의는 프로토타입으로 동작하지 않으며 향후 모든 함수 호출 표현식 에서 기본 인자 승격이 수행됩니다.
int max(a, b)
int a, b;
{
    return a>b?a:b;
}
double g()
{
    return 0.1;
}

목차

설명

함수 선언 과 마찬가지로, specifiers-and-qualifiers 에 있는 타입 지정자에 의해 결정되고, 필요에 따라 declarator 에 의해 수정될 수 있는 함수의 반환 타입은 선언 에서 일반적으로 그렇듯이, 완전한 비배열 객체 타입이거나 void 타입이어야 합니다. 반환 타입이 cvr-qualified 타입일 경우, 함수 타입을 구성하기 위해 unqualified 버전으로 조정됩니다.

void f(char *s) { puts(s); } // 반환 타입은 void
int sum(int a, int b) { return a+b; } // 반환 타입은 int
int (*foo(const void *p))[3] { // 반환 타입은 3개 int 배열에 대한 포인터
    return malloc(sizeof(int[3]));
}

함수 선언 과 마찬가지로, 함수 타입을 구성하기 위해 매개변수의 타입은 함수에서 포인터로, 배열에서 포인터로 조정되며, 호환 가능한 함수 타입 을 결정하기 위한 목적으로 모든 매개변수 타입의 최상위 cvr 한정자는 무시됩니다.

함수 선언 과 달리, 이름 없는 형식 매개변수는 허용되지 않습니다 (그렇지 않으면 구형 스타일(K&R) 함수 정의에서 충돌이 발생함). 함수 내에서 사용되지 않더라도 반드시 이름을 지정해야 합니다. 유일한 예외는 특수 매개변수 목록 ( void ) 입니다.

(C23까지)

구형 스타일(K&R) 함수 정의가 제거되었으므로 함수 정의에서 형식 매개변수는 이름 없이 사용될 수 있습니다. 이름 없는 매개변수는 함수 본문 내에서 이름으로 접근할 수 없습니다.

(C23부터)
int f(int, int); // 선언
// int f(int, int) { return 7; } // C23까지는 오류, C23부터 허용
int f(int a, int b) { return 7; } // 정의
int g(void) { return 8; } // OK: void는 매개변수를 선언하지 않음

함수 본문 내에서, 모든 명명된 매개변수는 lvalue 표현식이며, 이들은 자동 storage duration block scope 를 가집니다. 매개변수들의 메모리 내 배치(또는 메모리에 저장되는지 여부)는 명시되지 않습니다: 이는 calling convention 의 일부입니다.

int main(int ac, char **av)
{
    ac = 2; // 매개변수는 lvalue입니다
    av = (char *[]){"abc", "def", NULL};
    f(ac, av);
}

함수 호출의 세부 메커니즘에 대해서는 function call operator 를 참조하고, 함수에서 반환하는 방법에 대해서는 return 을 참조하십시오.

__func__

모든 함수 본체 내에서, 특수한 사전 정의된 변수 __func__ 가 블록 범위와 정적 저장 기간을 가지고 사용 가능합니다. 마치 여는 중괄호 바로 다음에 다음과 같이 정의된 것처럼:

static const char __func__[] = "function name";

이 특수 식별자는 때때로 사전 정의된 매크로 상수 __FILE__ __LINE__ 와 결합되어 사용됩니다. 예를 들어, assert 에서 사용됩니다.

(C99부터)

참고 사항

인수 목록은 선언자에 명시적으로 존재해야 하며, typedef에서 상속될 수 없습니다

typedef int p(int q, int r); // p는 함수 타입 int(int, int)입니다
p f { return q + r; } // 오류

C89에서는, specifiers-and-qualifiers 가 선택 사항이었으며, 생략할 경우 함수의 반환 타입은 기본적으로 int 가 되었습니다( declarator 에 의해 수정될 수 있음).

또한 구식 정의에서는 declaration-list 에 모든 매개변수에 대한 선언이 필요하지 않았습니다. 선언이 누락된 매개변수는 int 타입을 가졌습니다.

max(a, b) // a and b have type int, return type is int
{
    return a>b?a:b;
}
(C99까지)

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
DR 423 C89 반환 타입이 한정될 수 있음 반환 타입은 암묵적으로 한정이 제거됨

참고문헌

  • C17 표준 (ISO/IEC 9899:2018):
  • 6.9.1 함수 정의 (p: 113-115)
  • C11 표준 (ISO/IEC 9899:2011):
  • 6.9.1 함수 정의 (p: 156-158)
  • C99 표준 (ISO/IEC 9899:1999):
  • 6.9.1 함수 정의 (p: 141-143)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 3.7.1 Function definitions

참고 항목

C++ 문서 에 대한 함수 정의