함수 선언과 프로토 타입을위한 대체 (K & R) C 구문
이 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의 "no implicit int"규칙 제외, C99에서는의 선언을 생략 할 수 없음 p2
).
두 번째 부분은 K & R 스타일과 거의 관련이 없습니다. 나는 함수가 "스왑 된"인자로 호출 될 수 있다는 사실을 언급합니다. 즉, 그러한 호출에서 매개 변수 유형 검사가 일어나지 않습니다. 이것은 K & R 스타일 정의 자체와는 거의 관련이 없지만 프로토 타입이없는 함수와 관련이 있습니다. C에서 다음과 같은 함수를 선언하면
int foo();
실제로 알 수없는 유형의 매개 변수의 지정되지 않은 수를 사용 하는 함수 foo
를 선언합니다 . 당신은 그것을 다음과 같이 부를 수 있습니다.
foo(2, 3);
그리고
j = foo(p, -3, "hello world");
ans 등등 (당신은 아이디어를 얻습니다);
Only the call with proper arguments will "work" (meaning that the others produce undefined behavior), but it is entirely up to you to ensure its correctness. The compiler is not required to diagnose the incorrect ones even if it somehow magically knows the correct parameter types and their total number.
Actually, this behavior is a feature of C language. A dangerous one, but a feature nevertheless. It allows you to do something like this
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]();
}
i.e. mix different function types in a "polymorphic" array without any typecasts (variadic function types can't be used here though). Again, inherent dangers of this technique are quite obvious (I don't remember ever using it, but I can imagine where it can be useful), but that's C after all.
Finally, the bit that links the second part of the answer to the first. When you make a K&R-style function definition, it doesn't introduce a prototype for the function. As far as function type is concerned, your func
definition declares func
as
int func();
i.e. neither the types nor the total number of parameters are declared. In your original post you say "... it seems to specify is how many params it uses ...". Formally speaking, it doesn't! After your two-parameter K&R-style func
definition you still can call func
as
func(1, 2, 3, 4, "Hi!");
and there won't be any constraint violation in it. (Normally, a quality compiler will give you a warning).
Also, a sometimes overlooked fact is that
int f()
{
return 0;
}
is also a K&R-style function definition that does not introduce a prototype. To make it "modern" you'd have to put an explicit void
in the parameter list
int f(void)
{
return 0;
}
Finally, contrary to a popular belief, both K&R-style function definitions and non-prototyped function declarations are fully supported in C99. The former has been deprecated since C89/90, if I remember correctly. C99 requires the function to be declared before the first use, but the declaration is not required to be a prototype. The confusion apparently stems from the popular terminological mix-up: many people call any function declaration "a prototype", while in fact "function declaration" is not the same thing as "prototype".
This is pretty old K&R C syntax (pre-dates ANSI/ISO C). Nowadays, you should not use it anymore (as you have already noticed its major disadvantage: the compiler won't check the types of arguments for you). The argument type actually defaults to int
in your example.
At the time, this syntax was used, one sometimes would find functions like
foo(p, q)
{
return q + p;
}
which was actually a valid definition, as the types for foo
, p
, and q
default to int
.
This is simply an old syntax, that pre-dates the "ANSI C" syntax you might be more familiar with. It's called "K&R C", typically.
Compilers support it to be complete, and to be able to handle old code bases, of course.
This is the original K&R syntax before C was standardized in 1989. C89 introduced function prototypes, borrowed from C++, and deprecated the K&R syntax. There is no reason to use it (and plenty of reasons not to) in new code.
That's a relic from when C had no prototypes for functions. Way back then, (I think) functions were assumed to return int
and all its arguments were assumed to be int
. There was no checking done on function parameters.
You're much better off using function prototypes in the current C language.
And you must use them in C99 (C89 still accepts the old syntax).
And C99 requires functions to be declared (possibly without a prototype). If you're writing a new function from scratch, you need to provide a declaration ... make it a prototype too: you lose nothing and gain extra checking from the compiler.
'developer tip' 카테고리의 다른 글
ImportError : win32com.client라는 모듈이 없습니다. (0) | 2020.11.10 |
---|---|
와일드 카드 하위 도메인 및 정적 하위 도메인 용 가상 호스트 (0) | 2020.11.10 |
두 세그먼트가 교차하는지 어떻게 확인할 수 있습니까? (0) | 2020.11.10 |
SQL Server Management Studio 2008에서 만든 트리거를 볼 수 없습니다. (0) | 2020.11.10 |
열을 null로 만들기위한 Rails 마이그레이션 => true (0) | 2020.11.10 |