C++에서 sizeof
이해하기: 왜 n
은 8
이 아닌가?
C++에서 배열을 다룰 때, 특히 배열을 함수에 전달할 때 sizeof
연산자와 관련된 예상치 못한 결과를 마주칠 수 있습니다. 이 블로그 포스트에서는 sizeof
를 함수 매개변수와 함께 사용할 때 발생하는 일반적인 혼란, 특히 **왜 함수 foo()
에서 n
이 8
이 아닌가?**라는 질문에 대해 탐구해 보겠습니다.
문제
아래 두 개의 코드를 살펴보면서 문제를 설명하겠습니다:
예제 1: 함수 foo()
void foo(char cvalue[8])
{
int n = sizeof(cvalue);
}
위의 예제에서 sizeof(cvalue)
를 호출할 때, 배열의 크기가 8
로 정의되어 있으므로 n
이 8
일 것이라고 생각할 수 있습니다. 그러나 이 경우는 그렇지 않습니다.
예제 2: 함수 bar()
void bar()
{
char cvalue[8];
int n = sizeof(cvalue);
}
두 번째 예제에서는 sizeof(cvalue)
가 실제로 8
과 같습니다. 그렇다면 왜 차이가 있을까요?
개념 이해하기
왜 각 함수에서 sizeof(cvalue)
가 다른 값을 반환하는지 이해하려면 C와 C++에서 배열이 어떻게 처리되는지 명확히 해야 합니다.
배열을 함수 매개변수로 사용하기
C나 C++에서 배열을 함수에 전달할 때, 실제로 배열 자체를 전달하는 것이 아닙니다. 대신 배열의 첫 번째 요소에 대한 포인터를 전달하는 것입니다. 함수 매개변수에서 사용되는 괄호는 단순히 문법적 표기일 뿐이며, 동작에 변화를 주지 않습니다. 다음 두 선언은 모두 동등합니다:
void foo(char cvalue[8])
void foo(char cvalue[])
void foo(char *cvalue)
이 모든 선언에서 cvalue
는 포인터로 해석됩니다. 따라서 foo()
안에서 sizeof(cvalue)
를 호출하면, 배열의 크기가 아니라 포인터의 크기가 반환됩니다. 대부분의 플랫폼에서 이 크기는 32비트 시스템에서 일반적으로 4
바이트, 64비트 시스템에서 8
바이트입니다. 그래서 foo()
에서 n
이 8
이 아닌 것입니다.
bar()
에서의 올바른 컨텍스트
반면, bar()
안에서 cvalue
는 크기 8
인 지역 배열로 정의됩니다. 따라서 여기서 sizeof(cvalue)
가 호출될 때, 전체 배열의 크기를 정확히 반영하여 n
이 8
이 됩니다.
주요 요점
- 포인터 동작 이해하기: 배열을 매개변수로 전달할 때, 실제로는 포인터를 전달하는 것이므로
sizeof
를 사용할 때 혼란스러운 값을 초래할 수 있습니다. - 지역 배열:
sizeof
는 함수 내에서 정의된 지역 배열의 실제 크기를 제공합니다. - 문법적 설탕: 함수 매개변수의 괄호는 배열 변수를 생성하는 것이 아니라 포인터를 다룬다는 것을 나타냅니다.
결론
C와 C++에서 배열을 처리하는 것은 언어에 익숙하지 않은 사람들에게는 까다로울 수 있습니다. 포인터와 배열의 차이를 이해하는 것은 정확한 계산과 디버깅을 위해 매우 중요합니다. 함수 내에서 배열로 간주되는 매개변수에 sizeof
를 적용하면 배열이 아니라 포인터의 크기를 반환한다는 점을 기억하세요.
이 설명이 함수의 배열 인자와 관련하여 sizeof
연산자의 동작을 명확히 이해하는 데 도움이 되기를 바랍니다. foo()
에서 n
이 8
이 아닌 이유와 bar()
에서 왜 8
인지의 차이를 설명했습니다. 코딩할 때 이러한 원칙을 기억하세요!