좋아요! 🔥 이번에도 포인터 문제 한 번 꼼꼼하게 풀어보면서 이해를 확실히 해볼게요.
#include <stdio.h>
int main() {
int arr[4] = {5, 10, 15, 20};
int *p = arr; // p는 arr[0]을 가리킴
int **pp = &p; // pp는 p의 주소를 가리킴
printf("%d ", *p); // 출력1
printf("%d ", *p++); // 출력2
printf("%d ", *p); // 출력3
printf("%d ", **pp); // 출력4
(*pp)++; // p 한 칸 증가
printf("%d\n", *p); // 출력5
return 0;
}
arr : [5, 10, 15, 20]p → arr[0] (값 5)pp → p의 주소*pp가 가리키는 arr[0] 값 → 5 출력p는 이동하지 않음*p++*p++ = *(p++) 이므로p++ 하기 전 p가 가리키는 값 → 5 출력p가 한 칸 증가 → p가 arr[1] 가리킴*pp가 현재 arr[1]을 가리키므로 → 10 출력**pppp는 p의 주소 → *pp = p**pp = *pp는 arr[1] 가리키므로 → 10 출력(*pp)++;*pp는 p → (*pp)++ 는 p++ 와 같음p를 한 칸 증가시켜서 arr[2] 가리킴*pp는 arr[2]를 가리키므로 → 15 출력5 5 10 10 15
| 단계 | 설명 | 출력값 | p가 가리키는 위치 |
|---|---|---|---|
| 출력1 | *p (현재 arr[0]) | 5 | arr[0] (5) |
| 출력2 | *p++ (출력 후 p 증가) | 5 | arr[1] (10) |
| 출력3 | *p | 10 | arr[1] (10) |
| 출력4 | **pp = *p | 10 | arr[1] (10) |
(*pp)++ | p 증가 | arr[2] (15) | |
| 출력5 | *p | 15 | arr[2] (15) |
좋아요! 증감연산자(++, --) 특히 후위(postfix)와 전위(prefix)의 차이가 헷갈릴 때가 많죠.
이 부분은 C, Java, Python 등 거의 모든 언어에서 동일한 원칙이라 잘 이해해두면 실전에서 큰 도움이 됩니다.
| 종류 | 설명 | 동작 순서 | 예시 (x = 5) | 출력 값 |
|---|---|---|---|---|
전위(prefix) ++x | 변수 값을 먼저 증가시키고, 증가된 값을 반환 | 증가 → 반환 | ++x (x=6 됨) | 6 |
후위(postfix) x++ | 변수 값을 먼저 반환하고, 그 다음에 증가 | 반환 → 증가 | x++ (출력 5, 이후 x=6) | 5 (출력 후 증가) |
int x = 5;
printf("%d\n", ++x); // 전위: 먼저 증가, 출력 6
x = 5;
printf("%d\n", x++); // 후위: 먼저 출력 5, 나중에 증가
printf("%d\n", x); // 증가된 값 출력 6
x++**는 출력(사용)할 때는 아직 증가 전 값이라 헷갈림++x**는 출력 순간부터 값이 증가한 상태임int a = 3;
int b = a++; // b=3, a=4
int c = ++a; // a=5, c=5
| 상황 | 출력되는 값 (x=5) |
|---|---|
++x | 6 (증가 후 출력) |
x++ | 5 (출력 후 증가) |
y = ++x | x=6, y=6 |
y = x++ | y=5, x=6 |
알겠습니다! 후위 증감 연산자(x++) 때문에 헷갈릴 수 있는 복잡한 문제를 드릴게요.
포인터 없이 변수와 증감연산자만 섞여서 헷갈리기 딱 좋은 문제입니다.
#include <stdio.h>
int main() {
int x = 3;
int y = x++ + ++x + x++ + ++x;
printf("x = %d, y = %d\n", x, y);
return 0;
}
좋아요! 아주 헷갈리기 좋은 문제라 차근차근 한 줄 한 줄 설명해 드릴게요.
int x = 3;
int y = x++ + ++x + x++ + ++x;
printf("x = %d, y = %d\n", x, y);
x = 3y = x++ + ++x + x++ + ++x; 계산이 표현식에서 x가 계속 변하고, 후위/전위 증감 연산자가 섞여 있으니
가장 중요한 것은 왼쪽에서 오른쪽 순서로 차근차근 계산하는 것입니다.
| 항 | 설명 | x 값 (평가 전) | 평가값 (항 결과) | x 값 (평가 후) |
|---|---|---|---|---|
x++ | 후위 → 현재 값 사용 후 1 증가 | 3 | 3 | 4 |
++x | 전위 → 먼저 1 증가 후 값 사용 | 4 | 5 | 5 |
x++ | 후위 → 현재 값 사용 후 1 증가 | 5 | 5 | 6 |
++x | 전위 → 먼저 1 증가 후 값 사용 | 6 | 7 | 7 |
y 계산하기y = 3 + 5 + 5 + 7 = 20x = 7 (마지막 ++x 후 증가 완료)x = 7, y = 20
x++)는 현재 값 사용 → 증가++x)는 먼저 증가 → 값 사용x 값을 업데이트하면서 계산해야 함좋아요! 이번에는 Soojebi의 main까지 같이 있으니 후위 연산자(yyyy++)의 동작을 제대로 파헤쳐봅시다.
이 문제에서 많은 분들이 헷갈리는 부분은 바로 yyyy++가 언제 증가되고, 생성자에 어떤 값이 넘어가는가예요.
int yyyy = 2020;
Car c = new Car("SUV", "흰색", yyyy++); // 후위 증가
System.out.print(", year : " + c.yyyy);
int yyyy = 2020;yyyy = 2020new Car("SUV", "흰색", yyyy++);여기서 yyyy++의 동작을 주의깊게 보세요.
yyyy++는 후위 증가 연산자이므로:
2020을 **리턴(사용)**한 후,yyyy를 1 증가시킵니다 → 호출 후 yyyy = 2021즉, Car 생성자에게 2020을 넘깁니다.
Car(String model, String color, int yyyy) 생성자 내부:this.model = "SUV"this.color = "흰색"this.yyyy = 2020 (넘겨받은 값 대입)model : SUVSystem.out.print(", year : " + c.yyyy);c.yyyy에는 생성자 호출 시 받았던 2020이 저장되어 있음, year : 2020model : SUV, year : 2020
main() 끝나고 yyyy 값main() 안의 지역변수 yyyy는 이미 후위 증가되어 2021이지만,c.yyyy 필드에는 생성자 호출 때 전달된 2020이 남아 있어요.
yyyy++→ "지금 값(2020) 넘기고, 넘긴 후 증가하기 때문에 생성자에게는 2020이 넘어간다."