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

조회수 1678회

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

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

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

답변을 하려면 로그인이 필요합니다.

Hashcode는 개발자들을 위한 무료 QnA 사이트입니다. 계정을 생성하셔야만 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)

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

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 계정을 생성하셔야만 글을 작성하실 수 있습니다.