C 배열에서 a[5] == 5[a] 가 어떻게 같은가요?


Stack Overflow podcast #34와 C 언어 프로그래밍(aka: K & R)에서 언급한 a[5] == 5[a]를 아직 잘 모르겠습니다.

포인터 연산 때문인것 같긴한데 어떻게 a[5] == 5[a]로 같을 수 있을까요?

  • 2016년 02월 02일에 작성됨

조회수 524


Banner summercoding 2x copy mjjdfw

3 답변


int main() {
  int a[10];
  a[5]=10;
  printf("%d %d",a[5],5[a]);
  return 0;
}

이렇게 하니까 10 10나오긴 하네요.

  • 2016년 02월 02일에 작성됨


alt text

link : stackoverflow

위와 같다고 나오네요. 결국 언어차원에서 정의된 오퍼레이터 관련 문제였네요.

  • 2016년 02월 02일에 작성됨
    우보천리를 지향하는 프로그래머 - 잘 하고 싶지만, 아직 부족한 프로그래머


c를 배우면서 생기는 괴상한 문법의 오류 인것 같습니다.

위에 분이 말씀하신대로 c는 배열과 포인터의 아주 밀접한 관계가 있습니다.

#include <stdio.h>

int main(void)
{
    int ar[5] = { 1, 2, 3, 4, 5 };

    printf("%d\n", ar[2]);
    printf("%d\n", 2[ar]);
    printf("%d\n", *(ar + 2));
    printf("%d\n", *(2 + ar));
    // 결과는 같습니다.

    return 0;
}

왜 이따구인 걸까요?

배열과 포인터의 관계를 성실히 배웠다면 아래 코드가 이해가 쉬울것 입니다. ar[1] == *(ar + 1)

왜그런지를 파헤쳐보자면

ar은 어떤 주소에 있습니다.

예를 들어, ar은 0x0012FF60 에 있다고 가정합시다. (32비트로 가정) 그럴때, ar[1]은 ar로 부터 sizeof(ar의 자료형 * 1) 만큼 이동한 주소를 가르킵니다.

위에 예시 코드에 따라서 ar이 int 형일때

ar[1] 즉, *(ar + 1)은

0x0012FF64 를 가르킵니다 (맞죠?)

하지만 우리는

*를 사용했습니다.

이친구는 간접지정 연산자 라고 불리는데, 어떤 x 라는 주소에 있는 값을 뽑아내는 역할을 해냅니다.

배열의 [인덱스] 도 같은 역할을 합니다.

주소를 알고 싶으면 &a[1] 또는 (ar + 1)을 하면 ar로 부터 1칸 떨어진 인덱스의 주소를 알 수 있겠죠?

주소를 가지고 쫒아가는게 대괄호 랑 * (애스터릭) 입니다.

그래서 5[a] 와 a[5] 가 같은이유는

배열과 포인터의 관계에서

a[5]는 a라는 원점에서 5칸이동한 것으로 *(a + 5)로 바꿀수 있습니다. 하지만 *(5 + a) 로 한다고 해서 안될것은 없습니다. (실제로 해보세요 되요!)

이 *(5 + a)를 풀어 쓰면 5[a]가 되는거죠 :)

하지만 a[5]가 문법적으로 맞는것 같아보이고.... 또 5[a]는 매우 끔찍한 혼종같은 문법입니다. 기왕쓰는거 a[5]가 훨씬 나아보이네요.

또, 가독성이 높은 코딩스타일을 위해서는 a[5]가 좋아보이네요.

모르겠습니다..... c 가 잠재적인 문법(오류)가 많은 언어여서 헷갈립니다.

쓸데없는 서론만 글게 주구장창 적어서 결론을 명쾌하게 올리지 못해서 죄송합니다.

혹시 제가 틀린내용을 올리면 댓글 달아주세요.


로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close