여기에 내 의견이 있습니다.
C 언어의 개발은 C 에서 배열 유형의 진화에 대한 통찰력을 제공합니다.
배열에 대해 간략히 설명하겠습니다.
C의 선구자 B와 BCPL에는 다음과 같은 선언과 같은 고유 한 배열 유형이 없습니다.
auto V[10] (B)
or
let V = vec 10 (BCPL)
V는 메모리 10 "워드"의 사용되지 않는 영역을 가리 키도록 초기화되는 (유형이 지정되지 않은) 포인터로 선언됩니다. B는 이미 *
포인터 역 참조에 사용 되었으며 오늘날 C / C ++에서 []
와 *(V+i)
같이을 의미 하는 약칭 표기법 V[i]
을 사용했습니다. 그러나 V
배열이 아니라 일부 메모리를 가리켜 야하는 포인터입니다. Dennis Ritchie가 구조체 유형으로 B를 확장하려고 할 때 문제가 발생했습니다. 그는 오늘날 C 에서처럼 배열이 구조체의 일부가되기를 원했습니다.
struct {
int inumber;
char name[14];
};
그러나 포인터로서 배열의 B, BCPL 개념을 사용하면 런타임 에 구조체 내 14 바이트의 메모리 영역에 대해 초기화 해야하는 name
포인터를 필드에 포함해야했습니다 . 초기화 / 레이아웃 문제는 결국 배열에 특별한 처리를 제공함으로써 해결되었습니다. 컴파일러는 배열을 포함하는 표현식을 제외하고는 데이터에 대한 포인터를 실제로 요구하지 않고도 구조, 스택 등에서 배열의 위치를 추적합니다. 이 처리를 통해 거의 모든 B 코드가 계속 실행될 수 있으며 "배열을 보면 포인터로 변환" 규칙 의 소스가 됩니다. 개방형 크기 등의 배열을 허용했기 때문에 매우 편리한 것으로 판명 된 호환성 해킹입니다.
그리고 배열을 할당 할 수없는 이유는 다음과 같습니다. 배열은 B의 포인터 였으므로 간단히 다음과 같이 작성할 수 있습니다.
auto V[10];
V=V+5;
"배열"을 리베이스합니다. 배열 변수의 기본이 더 이상 lvalue가 아니기 때문에 이것은 이제 의미가 없습니다. 따라서이 할당이 허용되지 않아 선언 된 배열을 기반으로 한 몇 가지 프로그램을 포착하는 데 도움이 되었습니다.. 그리고이 개념이 고착되었습니다. 배열은 C 유형 시스템에서 인용 된 일급 클래스로 설계되지 않았기 때문에 대부분 사용하면 포인터가되는 특수한 짐승으로 취급되었습니다. 그리고 특정 관점 (C- 어레이가 잘못된 해킹이라는 것을 무시 함)에서 배열 할당을 허용하지 않는 것은 여전히 의미가 있습니다. 열린 배열 또는 배열 함수 매개 변수는 크기 정보가없는 포인터로 취급됩니다. 컴파일러에는 배열 할당을 생성 할 수있는 정보가 없으며 호환성을 위해 포인터 할당이 필요했습니다.
typedef int vec[3];
void f(vec a, vec b)
{
vec x,y;
a=b;
x=y;
a=x;
x=a;
}
1978 년 C의 개정판이 구조체 할당 ( http://cm.bell-labs.com/cm/cs/who/dmr/cchanges.pdf )을 추가했을 때 변경되지 않았습니다 . 레코드 는 C에서 고유 한 유형 이었지만 초기 K & R C에서는이를 할당 할 수 없었습니다. memcpy를 사용하여 멤버별로 복사해야했고 함수 매개 변수로 포인터 만 전달할 수있었습니다. 어시 그먼트 (및 매개 변수 전달)는 이제 단순히 구조체 원시 메모리의 memcpy로 정의되었으며 기존 코드를 깰 수 없었기 때문에 쉽게 배치되었습니다. 의도하지 않은 부작용으로 이것은 암시 적으로 일종의 배열 할당을 도입했지만 구조 내부 어딘가에서 발생했기 때문에 배열이 사용되는 방식에 실제로 문제를 일으킬 수 없었습니다.