C 함수 구문, 파라미터 목록 뒤에 선언된 파라미터 유형
저는 C는 비교적 처음입니다.지금까지 본 적이 없는 함수 구문의 형태로 파라미터 타입이 파라미터 리스트 뒤에 정의되어 있습니다.일반적인 C 함수 구문과 어떻게 다른지 누가 설명해 줄 수 있나요?
예:
int main (argc, argv)
int argc;
char *argv[];
{
return(0);
}
이는 파라미터 리스트의 구식 구문이며, 지금도 지원됩니다.K&R C에서는 타입 선언을 생략할 수도 있습니다.디폴트로는 int. 즉,
main(argc, argv)
char *argv[];
{
return 0;
}
같은 기능이 될 것입니다.
차이는 없습니다.그것은 C의 함수 선언에 대한 오래된 구문일 뿐입니다.이것은 ANSI 이전에 사용되었습니다.80년대 친구들에게 줄 계획이 아니라면 절대 그런 코드를 작성하지 마세요.또한 암묵적인 유형의 전제조건에 의존하지 마십시오(다른 답변이 시사하는 것처럼).
또한 흥미로운 점은 시제품이 있는 함수와 없는 함수의 호출 규칙 차이입니다.오래된 스타일의 정의를 고려합니다.
void f(a)
float a; {
/* ... */
}
이 경우 모든 인수는 함수에 전달되기 전에 승격됩니다(예를 들어,float
의론이 최초로 추진되다double
(합격 전).그래서 만약에f
수신하다double
단, 파라미터에는 타입이 있습니다.float
(완벽하게 유효한) 컴파일러는 함수 본문을 실행하기 전에 더블을 플로트로 변환하는 코드를 내보내야 합니다.
프로토타입을 포함하면 컴파일러는 더 이상 이러한 자동 프로모션을 수행하지 않으며 전달된 데이터는 할당에 의한 것처럼 프로토타입을 매개 변수 유형으로 변환됩니다.따라서 다음 사항은 합법적이지 않으며 정의되지 않은 동작이 발생합니다.
void f(float a);
void f(a)
float a; {
}
이 경우 함수의 정의에 의해 전송된 파라미터가 변환됩니다.double
(프로모션 폼)으로float
정의가 구식이기 때문입니다.그러나 함수에는 시제품이 있기 때문에 매개변수는 플로트로 제출되었습니다.예를 들어, clang은
main.c:3:9: 경고: K&R 함수 매개 변수의 승격된 형식 'double'이 이전 프로토타입에서 선언된 매개 변수 유형 'float'과 호환되지 않습니다. [-Wknr-promitted-parameter]
모순을 해결하기 위한 옵션은 다음 두 가지입니다.
// option 1
void f(double a);
void f(a)
float a; {
}
// option 2
// this declaration can be put in a header, but is redundant in this case,
// since the definition exposes a prototype already if both appear in a
// translation unit prior to the call.
void f(float a);
void f(float a) {
}
때문에 큰 소리가 오래 된 스타일의 정의 앞을 없앤다면 선택할 수 있는 옵션 2우선되어야 한다.기능에 대한 모순적인 기능 형식은 같은 번역 단위에서 나타나면, 컴파일러 보통( 하지만 필요하지 않다)너에게 말할 것이다.만약 그러한 모순을 여러개의 번역 단위에 걸쳐 나타나면 해당 오류 가능성은 묻히지 않고 버그를 예측하기 힘든 결과를 초래할 수 있을 것입니다.이 오래 된 스타일의 정의를 피하는 것이 가장 좋다.
이것은 그렇게 호출자 K&, R스타일이나 구식의 선언이다.
참고, 이 선언은 현대 선언과는 다르다.K&, R선언이 외부에 코드를 매개 변수의 형식을 노출시키지 않을 기능에 대한 프로토 타입을 도입하지 않다.
반면 기능 정의의 옛 구문 여전히(경고로, 너의 컴파일러 물어보) 일한다, 그것들을 사용하고 기능 프로토 타입을 제공하지 않는다.
없이 기능 prototypes이 기능이 정확히 불린다는 컴파일러를 확인하지 않습니다.
#include <stdio.h>
int foo(c)
int c;
{ return printf("%d\n", c); }
int bar(x)
double x;
{ return printf("%f\n", x); }
int main(void)
{
foo(42); /* ok */
bar(42); /* oops ... 42 here is an `int`, but `bar()` "expects" a `double` */
return 0;
}
프로그램이 운영된다, 내 컴퓨터의 출력이다.
$ gcc proto.c
$ gcc -Wstrict-prototypes proto.c
proto.c:4: warning: function declaration isn’t a prototype
proto.c:10: warning: function declaration isn’t a prototype
$ ./a.out
42
0.000000
단지는 되지만 같은 패션.당신은 아마도 그것은 오래 되어 유산 코드를 발견했다.
안 오래 되고 나는 무엇 그리곤다고는 오래 된 것이라고 주장할 것이다.피라미드처럼, 그러나 오늘날 소위 과학자들이 전혀 단서를 어떻게 만들어졌다 고대의 것입니다.돌이켜 보면 오래 된 프로그램은 여전히 오늘날 메모리 누수 없이지만, 이" 새로운"계획은 종종 실패하는 경향이 있다.나는 경향을 참조하십시오.
아마도 그들은 함수를 실행 가능한 본문을 가진 구조물로 간주했을 것이다.이 미스터리를 풀기 위해서는 ASM에 대한 지식이 필요합니다.
편집 중 인수 이름을 입력할 필요가 없음을 나타내는 매크로가 발견되었습니다.
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
#ifndef Z_ARG /* function prototypes for stdarg */
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
# define Z_ARG(args) args
# else
# define Z_ARG(args) ()
# endif
#endif
다음으로 사용 예를 제시하겠습니다.라이브러리는 zlib-1.2.11 입니다.
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
두 번째 추측은 함수 오버로드에 대한 것입니다.그렇지 않으면 이러한 인수는 사용할 수 없습니다.하나의 구체적인 함수로, 이제는 같은 이름의 함수가 무한히 많아졌습니다.
언급URL : https://stackoverflow.com/questions/1585390/c-function-syntax-parameter-types-declared-after-parameter-list
'source' 카테고리의 다른 글
TRUE 매크로와 FALSE 매크로의 이상한 정의 (0) | 2022.08.30 |
---|---|
Vue.js에서 "async/ait"을 사용할 수 있습니까? (0) | 2022.08.30 |
Nuxt.js nuxtServerInit 및 Vuex를 사용하여 데이터 서버를 로드하는 중 (0) | 2022.08.30 |
컴포넌트 VUE 2(웹팩)에 외부 js 파일을 로드하는 방법 (0) | 2022.08.30 |
공백 문자가 있는 입력에서 문자열을 읽으시겠습니까? (0) | 2022.08.30 |