wxogus25   3년 전

http://codeforces.com/contest/...


코포 라운드 423 div2 1위의 C번 코드입니다.

메인 함수 위에 gf(int x) 함수를 보시면 'x=f[x]=x[f][f]' 부분이 보입니다.\

x 는 int 형이고 f 는 int* 인데 x[f][f] 가 어떻게 가능할까요??


gallopsys   3년 전

포인터 연산도 교환법칙(commutative law)이 성립하기 때문에 합법적인 문장이 됩니다.

예를 들어 1차원 배열에서 한 원소를 접근하려고 할 때, 일반적인 방법대로 세 번째 위치에 있는 원소에 접근한다면 "x[2]"라고 하면 되겠죠.
하지만 C언어에서 배열은 결국 베이스 주소가 있고, 그만큼 덧셈/뺄셈 연산을 통해 해당하는 메모리 위치에 접근하는 구조를 띄므로 "*(x + 2)"라고 표기할 수도 있습니다.

여기서 재밌는 현상이 있는데, 과연 "*(x + 2)" 대신에 "*(2 + x)"라고 한다면 어떤 일이 벌어질까요? 뭐 덧셈에선 교환법칙이 성립하니까 충분히 가능한 것처럼 보입니다.
그렇다면 "2[x]"는요? 말도 안 되는 소리 같아 보이지만 놀랍게도 컴파일 해봤을 때 아무런 오류도 발생하지 않고 잘 실행되는 모습을 보실 수 있습니다.

바로 "교환법칙"이 성립하기 때문이죠. 문의하신 코드도 마찬가지로 한 번 분석해보도록 합시다.

x[f][f]를 순서대로 해석해보면, (x[f])[f]순으로 해석되니까 {*(x + f)}[f]고, 이는 다시 {*(f + x)}[f]가 되며, *(f + x)값은 f[x]값이랑 같으니 int형을 반환하겠죠?
그 나온 int값을 y라고 한다면 y[f]니까 제가 말한대로라면 f[y]라고 해석할 수 있을 것입니다.

한 번 int f[3000007];에 순서대로 1, 2, 3, ...이라 집어넣고 int x = 3;이라고 예를 들면 순서대로 다음과 같이 해석해볼 수 있을 거예요.
1) x[f][f] == 3[f][f]
2) 3[f][f] == (*(3 + f))[f]
3) (*(3 + f))[f] == (*(f + 3))[f]
4) (*(f + 3))[f] == 4[f]
5) 4[f] == f[4]
6) f[4] == 5

최종: 5


이해 안 가는 부분이 있으면 질문하셔도 좋습니다.

wxogus25   3년 전

감사합니다!!

지금까지 포인터를 사용하면서 나름 알고있다고 생각했는데 전혀 아니였네요

공부할 것이 또 생겼네요 좋은 지식덕분에 모르는 것을 확실히 알고갑니다!!

댓글을 작성하려면 로그인해야 합니다.