문제

이것에 대해 무엇이 유용한가요? C 구문 — 'K&R' 스타일 함수 선언을 사용합니까?

int func (p, p2)
    void* p;
    int  p2;
{
    return 0;
}

Visual Studios 2010beta에서 이것을 작성할 수 있었습니다.

// yes, the arguments are flipped
void f()
{
    void* v = 0;
    func(5, v);
}

모르겠어요.이 구문의 요점은 무엇입니까?난 쓸수있다:

int func (p, p2)
    int  p2;
{
    return 0;
}
// and write
int func (p, p2)
{
    return 0;
}

그것이 지정하는 유일한 것은 사용하는 매개변수 수와 반환 유형입니다.유형이 없는 매개변수는 꽤 멋지다고 생각합니다. 하지만 이를 허용하는 이유는 무엇입니까? int paranName 함수 선언자 뒤에요?이상해요.

또한 이것이 여전히 표준 C입니까?

도움이 되었습니까?

해결책

당신이 묻는 질문은 실제로 두 가지 질문입니다. 지금까지 대부분의 답변은 일반적인 담요 "K & R 스타일입니다"대답으로 모든 것을 다루려고 시도했지만 실제로는 작은 부분만이 K & R 스타일로 알려진 것과 관련이 있습니다 (전체 C 언어를 보지 않는 한. "K & R 스타일"으로 어떤 방식 으로든 :)

첫 번째 부분은 기능에 사용 된 이상한 구문입니다. 정의

int func(p, p2)
void *p;
int  p2; /* <- optional in C89/90, but not in C99 */
{
  return 0;
}

이것은 실제로 K & R 스타일 기능 정의입니다. 다른 대답은 이것을 꽤 잘 다루었습니다. 그리고 실제로는별로 많지 않습니다. 구문은 더 이상 사용되지 않았지만 C99에서도 여전히 완전히 지원됩니다 (C99의 "암시 적 int"규칙 제외는 C99에서는 선언을 생략 할 수 없음을 의미합니다. p2).

두 번째 부분은 K & R 스타일과 거의 관련이 없습니다. 나는 "스왑 된"인수로 함수를 호출 할 수 있다는 사실을 언급합니다. 즉, 그러한 호출에서 매개 변수 유형 검사는 발생하지 않습니다. 이것은 K & R 스타일의 정의 자체와 관련이 거의 없지만 프로토 타입이없는 기능과 관련이 있습니다. 이와 같은 기능을 선언 할 때 C에서

int foo();

실제로 함수를 선언합니다 foo 그것은 걸린다 알 수없는 유형의 지정되지 않은 수의 매개 변수. 당신은 그것을대로 부를 수 있습니다

foo(2, 3);

그리고 AS

j = foo(p, -3, "hello world");

Ans So On (당신은 아이디어를 얻습니다);

적절한 인수가있는 전화만이 "작동"(다른 사람들이 정의되지 않은 행동을 일으킨다는 의미)이지만 정확성을 보장하는 것은 전적으로 귀하에게 달려 있습니다. 컴파일러는 어쨌든 올바른 매개 변수 유형과 총 숫자를 마술처럼 알고 있더라도 잘못된 것들을 진단 할 필요가 없습니다.

실제로이 행동은 a입니다 특징 C 언어의. 위험한 것이지만 그럼에도 불구하고 기능입니다. 그것은 당신이 이런 일을 할 수 있습니다

void foo(int i);
void bar(char *a, double b);
void baz(void);

int main()
{
  void (*fn[])() = { foo, bar, baz };
  fn[0](5);
  fn[1]("abc", 1.0);
  fn[2]();
}

즉, "다형성"배열에서 다른 함수 유형을 타입 캐스트없이 혼합합니다 (여기서는 여기에서는 variadic 함수 유형을 사용할 수 없습니다). 다시 말하지만,이 기술의 내재 된 위험은 매우 분명합니다 (나는 그것을 사용하는 것을 기억하지 못하지만 그것이 어디에 유용 할 수 있는지 상상할 수 있습니다). 그러나 그것은 결국 C입니다.

마지막으로, 답의 두 번째 부분을 첫 번째 부분과 연결하는 비트. K & R 스타일 기능 정의를 만들면 기능에 대한 프로토 타입을 소개하지 않습니다. 함수 유형에 관한 한, 당신의 func 정의 선언 func ~처럼

int func();

즉, 유형이나 총 매개 변수 수가 선언되지 않습니다. 원래 게시물에서 "... 얼마나 많은 매개 변수가 사용하는지 ..."라고 말합니다. 공식적으로 말하면, 그렇지 않습니다! 2 파라미터 K & R 스타일 후 func 정의는 여전히 전화 할 수 있습니다 func ~처럼

func(1, 2, 3, 4, "Hi!");

그리고 그 안에 제약 위반이 없습니다. (일반적으로 품질 컴파일러는 경고를 제공합니다).

또한 때때로 간과되는 사실은 그 것입니다

int f()
{
  return 0;
}

또한 프로토 타입을 소개하지 않는 K & R 스타일 기능 정의입니다. "현대"로 만들려면 명시 적을 넣어야합니다 void 매개 변수 목록에서

int f(void)
{
  return 0;
}

마지막으로, 대중적인 신념과는 반대로, K & R 스타일 기능 정의와 비 프로토 타입 기능 선언은 C99에서 완전히 지원됩니다. 전자는 내가 정확하게 기억한다면 C89/90 이후 더 이상 사용되지 않았다. C99는 첫 번째 사용 전에 기능을 선언해야하지만 선언은 프로토 타입이 될 필요는 없습니다. 혼란은 분명히 인기있는 용어 혼합에서 비롯된 것 같습니다. 많은 사람들이 모든 기능 선언을 "프로토 타입"이라고 부르는 반면 실제로 "기능 선언"은 "프로토 타입"과 동일하지 않습니다.

다른 팁

이것은 꽤 오래된 K & R C 구문 (사전 날짜 ANSI/ISO C)입니다. 요즘에는 더 이상 사용해서는 안됩니다 (이미 큰 단점을 발견 한 것처럼 컴파일러는 귀하의 인수 유형을 확인하지 않습니다). 인수 유형은 실제로 기본값입니다 int 당신의 예에서.

당시이 구문이 사용되었으며 때로는 다음과 같은 기능을 찾을 수 있습니다.

foo(p, q) 
{
    return q + p;
}

실제로 유효한 정의였습니다. foo, p, 그리고 q 기본값 int.

이것은 여러분에게 더 친숙할 수 있는 "ANSI C" 구문보다 이전의 오래된 구문일 뿐입니다.그것은 ~라고 불린다 "K&R C", 일반적으로.

물론 컴파일러는 이를 완전하게 지원하고 이전 코드 기반을 처리할 수 있도록 지원합니다.

이것은 C가 1989 년에 표준화되기 전에 원래 K & R 구문입니다. C89는 C ++에서 빌린 기능 프로토 타입을 도입하고 K & R 구문을 더 이상 사용하지 못했습니다. 새 코드에서 그것을 사용할 이유가 없습니다 (그리고 많은 이유가 없음).

C가 기능에 대한 프로토 타입이 없었을 때의 유물입니다. 그 당시에는 (내 생각에) 기능은 돌아 왔다고 가정했습니다. int 그리고 그 모든 주장은 그 것으로 추정되었습니다 int. 함수 매개 변수에 대한 점검이 수행되지 않았습니다.

현재 C 언어에서 기능 프로토 타입을 사용하는 것이 훨씬 좋습니다.
당신은요 ~ 해야 하다 C99에서 사용하십시오 (C89는 여전히 이전 구문을 허용합니다).

C99는 기능을 선언해야한다 (아마도 프로토 타입없이). 새로운 기능을 처음부터 작성하는 경우 선언을 제공해야합니다. 프로토 타입으로 만들면 아무것도 잃지 않고 컴파일러에서 추가 점검을받습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top