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

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

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

3답변

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

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

  • 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 가 잠재적인 문법(오류)가 많은 언어여서 헷갈립니다.

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

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

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.