C 언어에서 포인터나 배열을 함수에 전달할 때 사실상 포인터의 값 복사(즉, 메모리 주소)가 전달되며, 실제 배열이나 메모리 내용이 전달되는 것은 아닙니다. 역사적으로 C의 배열은 값으로 전달되지 않으며, 대신 배열의 첫 번째 요소에 대한 포인터가 함수로 전달됩니다. 이 메커니즘은 메모리를 절약하지만 잘못 사용할 경우 원치 않는 부작용을 초래할 수 있습니다.
문제 — 포인터와 배열 간의 혼동: 개발자들은 종종 함수 안에서 배열을 통해 외부 배열을 변경할 수 없거나 함수가 자동으로 전달된 배열의 크기를 알 수 있다고 생각합니다. 실제로 함수는 원래 배열의 크기를 잃고 쉽게 그 경계를 넘어설 수 있습니다.
해결책 — 항상 배열의 크기를 별도의 인자로 명시적으로 전달하고, 포인터의 복사와 객체의 복사 간의 차이를 명확히 이해하며, 포인터를 통해 이루어진 모든 변경이 원본 데이터에 반영됨을 잊지 말아야 합니다.
배열을 올바르게 전달하는 예:
void print_array(const int* arr, size_t size) { for (size_t i = 0; i < size; ++i) printf("%d ", arr[i]); } int main() { int nums[] = {1,2,3,4,5}; print_array(nums, sizeof(nums)/sizeof(nums[0])); return 0; }
주요 특징:
함수가 int arr[10]으로 선언된 전달된 배열의 길이를 알 수 있습니까?
답변: 아니요, 함수 안에서 sizeof(arr) 표현식은 포인터의 크기를 반환하고 전체 배열의 크기는 반환하지 않습니다. 크기는 별도로 전달해야 합니다.
함수에서 배열을 int arr[]와 int arr로 전달하는 것은 동일합니까?*
답변: 예, 함수의 시그니처에서 둘은 동등하며, 두 경우 모두 int에 대한 포인터가 전달됩니다. 차이는 문법에만 있습니다.
함수 내에서 배열의 요소를 변경하면 원본 배열이 변경됩니까?
답변: 예, 포인터가 전달되었기 때문에 함수는 포인터가 가리키는 메모리를 변경합니다.
프로젝트가 배열 초기화 함수를 구현할 때 배열 크기를 함수 내부에서 sizeof(arr) / sizeof(arr[0])로 정의했습니다. 테스트 단계에서 함수는 작동했지만 다른 배열을 처리할 때 외부 메모리를 덮어쓰거나 올바르게 작동하지 않았습니다.
장점:
단점:
함수는 항상 배열 크기를 개별 매개변수로 받아, 길이는 호출하는 쪽에서 계산했습니다. 함수 내부에서는 전달된 매개변수로만 작업했습니다.
장점:
단점: