2013년 9월 3일 화요일

C Experiment (1)

C언어 기초에 대한 instruction 도중 돌발 질문이 들어왔다.
정수형 포인터를 선언할 때

int*j;

이렇게 띄어쓰기 없이 모두 붙여써도 에러가 나지 않는가?

순간 살짝 당황스럽기도 하고 궁금하기도 하여 한번 해 보기로 했다.

#include <stdio.h>

int main()
{
    int i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int*j;

    j = i;
    printf("%d\n", *j);

    j += 5;
    printf("%d %d %d\n", *j, *(j+1), j[-3]);
    printf("%d %d %d\n", *i, *(i+1), i[-1]);

    return 0;
}

결론부터 말하면 컴파일이 아무 문제 없이 잘 된다. 그렇다면 실행은?

1
6 7 3
1 2 -1216678940

예상한 답이 그대로 나왔다.

결론은, 위의 돌발 질문과 같이 사용해도 에러가 나지 않으며, 심지어 잘 실행이 된다.
printf 부분에서 사용한 배열의 index에 음수가 들어간 부분 역시 잘 실행이 된다.
(물론 i[-1] 의 값은 unsafe하지만...)

여기서 다시 한번 확인할 수 있다.

배열을 사용할 때 선언부에서는 할당할 양을 지정해주어야 하므로 항상 [] 안에 묵시적, 혹은 명시적으로 양의 정수값이 들어가야 하지만, 선언부가 아닌 곳에서 [] 를 사용할 때에는 양수든 음수든 0이든 정수값이면 된다는 것이다.

왜냐하면 C언어에서는 선언부가 아닌 곳에서는 다음의 식이 서로 완전히 같기 때문이다.
즉 , *(i+1) 와 i[1] 은 완전히 같은 의미이다.

또한 void * 를 제외한 포인터는 모두 증감연산이 가능하므로 당연히 *(i-1) 과 같은 식이 유효하며, 그 뜻은 즉 i[-1] 도 가능하다는 뜻이다.

이상, trivial 한 사실일 지도 모르겠지만 C의 철학(?)을 다시금 느끼게 된다.

댓글 1개: