신기한 코드

서지훈의 이미지

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main( int argc, char *argv[] )
{
    int     a[100];
 
 
    printf( " a[1] = [%d]\n", 1[a] );
 
    a[1] = 11111;
 
    printf( " a[1] = [%d]\n", 1[a] );
 
 
    return 0;
}

위 코드의 결과는...

언젠가 저와 같은 코드를 본거 같은데도... 하도 신기해서... ㅢㅡ

컴파일러 빡씨게 하신분은 쉽게 알라나 ?

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

dg의 이미지

a[1] == *(a + 1)
1[a] == *(1 + a)

therefore

a[1] == 1[a]

sDH8988L의 이미지

흠...

예전에 이와 같은 걸 어떤 책에서 본 거 같은데요... 기억이 잘 안나네요...

위에 dg님께서 쓴 것처럼 Array 계산을 단순하게 Pointer 연산으로 바꿔하기 때문에 생기는 결과죠...

이런 건 C가 타입을 그렇게 강하게 체크하지 않는다는 반증이 아닐까 합니다...

gcc, g++ 다 컴파일, 실행이 됩니다...

cppig1995의 이미지

Rational 클래스를 만들었는데 Rational(1, 3) * 7은 돼도 7 * Rational(1, 3)은 안된다면
그건 타입 체크의 문제가 아니라 실용성, 유용성(가끔씩, 그리고 정신상태)의 문제입니다.
마찬가지 맥락에서 해석하시면 좋겠습니다.

첨자 표현은 연산자 오버로딩이 되지 않은 이상 syntactic sugar 의미구조입니다.
(... 그래서 && || ,를 오버로딩 안하는 것처럼 저는 [] 오버로딩 안합니다.)



돼지군 작업실 rev. E: E-Prot (가명), Fourword 64bit OS, ...
Ubuntu Hardy Beta on I4 'jeongu' / 서명 변경일 2008/3/26

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

cats96의 이미지

dg님 글보니까 이해는 하는데요. 약간의 의문점이 있네요.
int a[100];

a+1 == a + (sizeof(int) *1);
1+a == 1 + a;

char형이라면 같겠지만 int형이면 틀릴거 같은데요?
물론 안해봤습니다^^;;

klyx의 이미지

a+1 == a + (sizeof(int) *1);

이것 자체가 잘못된 표현입니다.

어떤 타입 Type의 포인터 a에 대해서 a+1은 현재 a의 위치에서 sizeof(Type)만큼 뒤의 위치를 가리키는 포인터입니다.

이것이 컴파일 될때 a+sizeof(Type)*1로 변환되어 컴파일 된다는 의미가 아닙니다.

컴파일될떄 변환되는건 배열이나 포인터의 a[1]같은 []연산자가 a+1과 같은 포인터 연산자로 변환되는 것입니다.

애시당초 포인터와 정수 사이의 +라는 연산자는, 정수와 정수 사이의 +연산자와 그 의미가 다른 것입니다.

만약 a가 int*이고, a + (sizeof(int) *1) 이렇게 적는다면, sizeof(int)가 (보통은)4이므로 결국 a+4가 되고, 현재 a의 위치에서 int 4개분 뒤쪽을 가리키는 포인터가 되겠지요.

포인터연산의 좀더 자세한건 http://www.winapi.co.kr/clec/cpp1/10-1-3.htm 여길 참고해보세요.

select99의 이미지

표현만그렇지.. 1번지에다 a 만큼 더한다는게 아닌것같군요.
후자도 역시나 a 번지에 1만큼이란 의미로 받아들여지는것 같군요.

appler의 이미지

서지훈님 질문은

일달 100개의 정수형 공간을 할당하고

중간쯤에 다른 값으로 들어갑니다.=11111;

쉽게 쉽게 생각하죠.ㅎㅎ

값으로 뽑았을때

1[a] == a[1]
*(1+a) == *(a+1)

이렇게 되므로 가능하다 입니다.

대괄호를 조져서 값을 뽑아볼랬는데

대괄호는 우선순위 경쟁에서 1위를 차지한 넘이라...

ㅠㅠ 도저히 ㅎㅎ..

물론 다른 연산도 해보았지요.ㅎㅎ

[1]a , [a]1 <== 이런 말도 안되는 걸 해봤더니 컴파일러가 욕하더군요..ㅎㅎ

규칙 일변도로 나오는 값은

주소에 해당번지만큼뛰는것입니다.

저게 32비트 정수가 아니라면.....이라고 생각하려니깐

두통과 퇴근시간이 지나서....ㅎㅎ

댓글의 치열한 논란이 생기면 돌아오겠습니다..

-_-;;
제 의견을 반박해주세요.......

<------ 시스너쳐 ------> 3가지 미덕 : 게으름(laziness), 조급성(impatience), 자기 과신(hubris)


laziness, impatience, hubris

不恥下問 - 진정으로 대화를 원하면 겸손하게 모르는 것은 모른다고 말하는 용기가 필요하다.