귀하의 게시물에서 말하는 것은 절대적으로 정확합니다. 나는 모든 C 개발자가 C 언어에 대한 특정 수준의 숙련도에 도달하면 정확히 똑같은 발견과 똑같은 결론에 도달한다고 말하고 싶습니다.
응용 프로그램 영역의 세부 사항이 특정 고정 크기의 배열을 호출 할 때 (배열 크기는 컴파일-시간 상수 임) 이러한 배열을 함수에 전달하는 유일한 적절한 방법은 포인터-배열 매개 변수를 사용하는 것입니다.
void foo(char (*p)[10]);
(C ++ 언어에서 이것은 참조로도 수행됩니다.
void foo(char (&p)[10]);
).
이렇게하면 언어 수준 유형 검사가 활성화되어 정확하게 정확한 크기의 배열이 인수로 제공되는지 확인할 수 있습니다. 사실, 많은 경우 사람들은이 기술을 깨닫지도 못한 채 암시 적으로 사용하여 typedef 이름 뒤에 배열 유형을 숨 깁니다.
typedef int Vector3d[3];
void transform(Vector3d *vector);
/* equivalent to `void transform(int (*vector)[3])` */
...
Vector3d vec;
...
transform(&vec);
또한 위 코드는 다음과 관련하여 변하지 않습니다. Vector3d
유형이 배열 또는 struct
. Vector3d
언제든지 의 정의를 배열에서 a struct
로 전환 할 수 있으며 함수 선언을 변경할 필요가 없습니다. 두 경우 모두 함수는 "참조에 의해"집계 객체를 수신합니다 (이에 대한 예외가 있지만이 논의의 맥락에서 이것은 사실입니다).
그러나이 배열 전달 방법이 명시 적으로 너무 자주 사용되는 것을 보지 못할 것입니다. 왜냐하면 너무 많은 사람들이 다소 복잡한 구문으로 인해 혼란스러워하고 C 언어의 이러한 기능을 적절하게 사용하기에 충분하지 않기 때문입니다. 이러한 이유로 실제 생활에서 배열을 첫 번째 요소에 대한 포인터로 전달하는 것이 더 널리 사용되는 접근 방식입니다. "단순"해 보입니다.
그러나 실제로 배열 전달을 위해 첫 번째 요소에 대한 포인터를 사용하는 것은 매우 틈새 기술이며 매우 특정한 목적을 제공하는 트릭입니다. 유일한 목적은 다른 크기 (즉, 런타임 크기)의 배열 전달을 용이하게하는 것입니다. . 런타임 크기의 배열을 처리 할 수 있어야하는 경우 이러한 배열을 전달하는 적절한 방법은 추가 매개 변수가 제공하는 구체적인 크기를 사용하여 첫 번째 요소에 대한 포인터를 사용하는 것입니다.
void foo(char p[], unsigned plen);
실제로 많은 경우 런타임 크기의 배열을 처리 할 수있는 것이 매우 유용하며 이는 메서드의 인기에 기여합니다. 많은 C 개발자는 고정 크기 배열을 처리해야하는 필요성을 결코 발견하지 못하거나 인식하지 못하므로 적절한 고정 크기 기술을 알지 못합니다.
그럼에도 불구하고 배열 크기가 고정되어 있으면 요소에 대한 포인터로 전달
void foo(char p[])
안타깝게도 요즘 널리 퍼져있는 주요 기술 수준의 오류입니다. 포인터-배열 기술은 이러한 경우 훨씬 더 나은 접근 방식입니다.
고정 크기 배열 전달 기술의 채택을 방해 할 수있는 또 다른 이유는 동적으로 할당 된 배열을 입력하는 순진한 접근 방식이 우세하기 때문입니다. 예를 들어, 프로그램이 유형의 고정 배열을 호출하는 경우 char[10]
(예제에서와 같이) 평균 개발자는 다음 malloc
과 같은 배열을 사용합니다.
char *p = malloc(10 * sizeof *p);
이 배열은 다음과 같이 선언 된 함수에 전달할 수 없습니다.
void foo(char (*p)[10]);
이는 일반 개발자를 혼란스럽게하고 더 이상 생각하지 않고 고정 크기 매개 변수 선언을 포기하게 만듭니다. 하지만 실제로 문제의 근원은 순진한 malloc
접근 방식에 있습니다. malloc
위 형식은 런타임 크기의 배열에 예약해야합니다. 배열 유형에 컴파일 시간 크기가있는 경우 더 나은 방법 malloc
은 다음과 같습니다.
char (*p)[10] = malloc(sizeof *p);
물론 이것은 위에서 선언 한 것에 쉽게 전달할 수 있습니다. foo
foo(p);
컴파일러는 적절한 유형 검사를 수행합니다. 그러나 다시 말하지만 이것은 준비되지 않은 C 개발자에게는 지나치게 혼란 스럽기 때문에 "일반적인"평균 일상 코드에서 너무 자주 보지 않을 것입니다.
10
가 없으며 범위의 모든 변수로 대체 할 수 있습니다