C 언어 문법에서 기호의 결합 우선순위는 컴파일러가 변수의 정체(타입)를 결정하는 최우선 기준입니다.
[]와 함수 호출 소괄호 ()는 우선순위가 1등급으로 가장 높습니다. 결합 방향은 왼쪽에서 오른쪽(Left-to-Right)입니다.*는 우선순위가 이보다 낮으며, 결합 방향은 오른쪽에서 왼쪽(Right-to-Left)입니다.[]나 ()가 붙어 있다면, 그 변수는 무조건 배열 또는 함수로 먼저 판정됩니다.*를 먼저 결합시켜 포인터로 선언하려면, 반드시 변수와 *를 소괄호 (*변수명)으로 감싸야 합니다.int *p[5];
p 오른쪽에 [5]가 먼저 결합합니다. 따라서 p는 원소 5개를 담는 연속된 배열입니다.int *, 즉 8바이트 메모리 주소입니다.int (*p)[5];
(*p)가 먼저 결합합니다. 따라서 p는 배열이 아니라 단 하나의 8바이트 포인터 변수입니다.p가 가리키는 대상은 '정수 5개로 이루어진 int[5] 배열'입니다.p 자체는 메모리 주소 1개만을 저장하므로 시스템 규격상 정확히 8바이트만 차지합니다.p + 1을 실행했을 때 이동하는 메모리 보폭(Stride)은 단일 정수(4바이트)가 아니라, 가리키는 대상 전체 크기인 만큼 물리 번지수가 증가합니다.x에 [5]가 먼저 결합하므로 크기 5인 배열입니다.int **(이중 포인터)입니다.(*x)가 먼저 결합하므로 x는 단 하나의 8바이트 포인터 변수입니다.x가 가리키는 대상은 '8바이트 int* 포인터 5개로 이루어진 배열'입니다.*x를 수행하면 5개의 포인터를 담고 있는 배열의 시작 주소가 나오며, x + 1 연산 시의 이동 보폭은 입니다.int arr[5] = {10, 20, 30, 40, 50};
int *p = &arr[2];
arr[2]는 배열의 3번째 칸에 들어있는 4바이트 정수 값(30)을 의미합니다.&를 붙이면 &arr[2]는 해당 4바이트 메모리 공간의 물리 시작 번지수가 됩니다.int *가 되며, int * 타입 포인터 변수에 직접 대입할 수 있습니다.int matrix[2][5];
핀토스 운영체제는 하드웨어 인터럽트와 유저 시스템 콜을 처리할 때 복합 포인터 문법을 핵심 자료구조로 사용합니다.
threads/interrupt.c)typedef void intr_handler_func (struct intr_frame *);
static intr_handler_func *intr_handlers[256];
intr_handlers는 크기 256인 포인터 배열입니다.intr_handlers[0x20](frame) 코드를 통해 조건문 분기(if-else) 없이 해당 주소로 1클럭 내에 즉시 점프하여 핸들러를 호출합니다.userprog/syscall.c)SYS_WRITE, SYS_READ 등을 호출할 때, 시스템 콜 번호를 인덱스로 사용하여 함수 포인터 테이블 syscall_handlers[syscall_num](f) 형태로 커널 진입점을 분기 실행합니다.