C언어 포인터의 이해 2편
C언어를 배우면서 가장 많이 혼란을 겪는 주제 중 하나가 바로 포인터이다. 특히 * 기호의 다양한 역할이 이 혼란의 주범이다. 이 포스팅에서는 * 기호가 가지는 세 가지 역할을 친절하게 설명함으로써 포인터에 대한 당신의 이해를 한 단계 업그레이드시킬 것이다.
⭐1. 포인터 변수 선언: *의 첫 번째 정체
포인터를 선언할 때 *를 사용하는 이유는, 단순히 "이 변수는 메모리 주소를 저장한다"는 사실을 나타내기 위함이다. int* ptr;라고 선언하면, "ptr은 정수의 주소를 저장하는 변수"라는 의미가 된다. 여기서 *는 포인터 변수의 타입 부분에 포함되어, 이 변수가 "주소"를 저장하는 특별한 종류의 변수임을 알려주는 역할을 한다.
⭐2. 역참조 연산자: *의 두 번째 정체
변수 앞에 *가 사용되면, 그것은 "역참조 연산자"가 됩니다. 역참조 연산자는 포인터가 가리키는 메모리 위치에 저장된 값을 접근하게 해준다. 예를 들어, *ptr = 10;은 ptr이 가리키는 메모리 위치에 10을 저장한다. 만약 ptr이 int var의 주소를 가지고 있다면, 이 연산은 사실상 var = 10;과 같은 효과를 가진다. 여기서 *는 "ptr이 가리키는 위치에..."라는 의미로 변신한다.
⭐3. 곱셈 : *의 세 번째 정체
이제 수학 시간으로 돌아간다. C언어에서 *는 두 수를 곱하는 곱셈 연산자로도 사용된다. 이 경우, *는 포인터와 전혀 관련이 없으며, 단순히 두 값을 곱하려는 용도로 사용된다. 예를 들어, int result = 4 * 5;는 result 변수에 20을 저장한다. 이 때 *는 "곱하기"의 기호로 사용되며, 우리가 평소에 수학에서 보던 그 곱셈과 같다.
⭐4. (*)의 이해
이 세 가지 역할을 명확히 이해하는 것은 C언어에서 포인터를 다루는 데 있어 필수적이다. 특히, * 기호의 역할이 문맥에 따라 달라지므로, 코드를 읽을 때는 주변 코드와 함께 *의 사용 방식을 정확히 파악해야 한다.
- 포인터 변수를 선언할 때는 *가 타입의 일부로서 "이 변수는 주소를 저장하는 포인터"임을 나타낸다.
- 변수 앞에서 *를 사용할 때는, 그것이 역참조 연산자로 작동하여 포인터가 가리키는 메모리의 값을 읽거나 쓰는 역할을 한다.
- 수학적 연산에서는, *는 단순한 곱셈 연산자이다.
포인터를 다루면서 헷갈리지 않기 위한 꿀팁을 하나 공유하자면, 포인터 선언과 역참조 시 *의 위치에 주의하는 것이다. 이를 명확히 구분하는 것은 코드를 더 읽기 쉽게 만들고, 의도하지 않은 오류를 방지하는 데 큰 도움이 된다.
4.1. 포인터 선언: 변수형 앞에 * 붙이기
포인터 변수를 선언할 때는, 변수 타입 앞에 *를 붙여 해당 변수가 포인터임을 나타낸다. 이 방식은 선언하는 변수가 일반 변수가 아닌 메모리 주소를 저장하는 포인터임을 명확히 한다. 예를 들어, int형 값을 가리키는 포인터를 선언하고 싶다면, int* ptr;와 같이 작성한다. 여기서 int*는 "정수형 주소를 가리키는 포인터"라는 의미를 가지며, ptr은 그러한 포인터 변수의 이름이다.
4.2. 역참조: 변수명 앞에 * 붙이기
포인터를 통해 가리키는 변수의 값을 접근하거나 수정할 때는 변수명 앞에 *를 붙여 역참조한다. 이는 포인터가 가리키는 메모리 위치에 저장된 실제 값을 의미한다. 예를 들어, *ptr = 5;라고 하면, ptr이 가리키는 메모리 위치에 5를 저장하는 것이다. 역참조를 통해 포인터로 가리키는 변수의 값을 읽거나 변경할 수 있다.
#include <stdio.h>
int main() {
// 1. 포인터 변수 선언: *가 포인터 타입을 나타냄
int value = 10;
int* ptr = &value; // ptr은 value의 주소를 가리킴
// 2. 역참조 연산자: *를 사용해 포인터가 가리키는 값을 접근 및 수정
printf("Before: %d\n", *ptr); // ptr이 가리키는 메모리(즉, value)의 값을 출력
*ptr = 20; // ptr을 통해 value의 값을 변경
printf("After: %d\n", value); // 변경된 value의 값을 출력
// 3. 곱셈 연산자: *를 사용한 수학적 곱셈
int a = 5;
int b = 4;
int result = a * b; // a와 b의 곱셈
printf("Multiplication: %d\n", result);
return 0;
}
이렇게 다양한 역할을 하는 *를 올바르게 이해하고 사용하면, 포인터의 개념도 훨씬 명확해질 것이다. 초기 혼란을 극복하고 *의 이러한 다양한 사용법에 익숙해지면, 포인터는 C언어 프로그래밍의 강력한 도구로서 여러분의 코드를 더욱 효율적이고 강력하게 만들어 줄 것이다.
'Language > C언어' 카테고리의 다른 글
[C/C++ Tip] 14. 동적 메모리 할당 (0) | 2024.10.29 |
---|---|
[C/C++ Tip] 13. MCU 제어를 위한 비트 연산 (0) | 2024.10.29 |
[C/C++ Tip] 11. C언어 포인터 기본 사용법 (1) | 2024.09.19 |
[C/C++ Tip] 10. Call by Value vs Call by Reference (0) | 2024.09.14 |
[C/C++ Tip] 9. memset, memcpy (0) | 2024.09.08 |