본문 바로가기
작업/Programming

Perfect C 프로그래밍 연습 8장 해결

 

1, 2번.

 

//문제1
    char asterisk = '*';
    char *p = &asterisk;

     printf("0x%x  %d   %c", p, *p, *p);



//문제2
    int data1 = 10;
    int data2 = 20;
    int sum = 0;
    int *p;

    p = &data1;
    *p = 100;    //포인터로 data1 접근
    sum +=*p;    //data1값 더함


    p = &data2;
    *p = 200;    //포인터로 data2 접근
    sum +=*p;    //data2값 더함

    printf("data1 + data2 = %d\n", sum);

 

 

포인터를 간단하게 활용하는 문제입니다.

 

 

 

포인터 개념

 

 

[int *p;]로 선언한 포인터 변수는 int 변수의 주소를 저장할 수 있습니다.

 

 

[p = &data1;]의 문장은 data1로 정의된 공간에 10을 저장하는 것처럼

p로 정의된 공간에 data1의 '주소'를 저장하는 것입니다.

 

 

 

p에는 data1의 값이 저장된 주소를 저장했기 때문에

p를 출력시키면 주소 값이 나타납니다.

 

 

*(asterisk) 연산자를 활용하면 주소에 해당하는 값에 접근이 가능하며

값을 바꿀 경우 원래의 값(data1)이 변경됩니다. (*p = 20;)

 

 

 

☆ 포인터는 값이 저장된 변수의 '주소'를 저장

☆ 포인터에 저장된 값(주소)의 데이터에 접근하기 위해서는 * 사용

 


 3번.

 

 

//문제3
    int data1 = 10;
    int data2 = 20;
    int sum =0;

    int *p1 = &data1;
    int *p2 = &data2;
    int **dp;

    dp = &p1;
    **dp = 100;
    sum +=**dp;    //data1값 더함

    dp = &p2;
    **dp = 200;
    sum +=**dp;    //data1값 더함

    printf("data1 + data2 = %d\n", sum);

 

다중 포인터에 대한 개념이 적용된 문제입니다.

 

 

 

 

 

 

다중 포인터는 '포인터의 주소'를 저장하는 개념이며

사용 구문에 *와 **의 차이만 있을 뿐 방법은 같습니다.

 

 

 


4번.

 

//문제4
    int value = 0x2F24263F;
    char *pc;
    pc = (char *) &value; //pc는 value의 포인터

    //값은 맨 마지막에 해당하는 값부터 차례대로 해당 주소에 저장된다.

    for(int i=0; i<4; i++){ //int는 4byte, char는 1byte. 4번의 반복이 수행됨.
        printf("%x는 %c이며 저장된 주소는 %x\n", *pc, *pc, pc);
        pc+=1;
    }

 

 

포인터의 자료형(char)과 값이 저장된 변수의 자료형(int)이 다를 경우

어떻게 처리가 되는지 이해하는 문제입니다.

 

 

1바이트인 char는 4바이트의 int보다 작습니다.

 

따라서 포인터의 자료형(char)에 맞도록 변수의 값(int)을 가져오게 된다면

데이터가 분할되어 저장되는 현상이 일어납니다.

 

 

 

문제에서는 16진수 8자리가 int 변수에 저장되어 있습니다.

16진수 1자리는 4bit이며 2자리는 8bit(=1byte)의 크기를 가집니다.

따라서 포인터는 1바이트 크기의 16진수 2자리만 저장된 주소를 저장하게 됩니다.

 

 

 

 

 

4분할로 값들이 저장되어있기 때문에 접근할 때에도 포인터에 +x의 연산을 해주어야 합니다.

 

 

기본적으로 &value를 저장한 pc는 4분할 중 처음 값(3F)이 저장된 공간만 가리킵니다.

다른 값들은 char 기준 1바이트 간격으로 다음 주소에 저장되어 있습니다.(102, 103, 104)

 

 

만약 int 기준이었다면 주소 간의 간격은 4바이트입니다. (101, 105, 109, ...)

출력에서 확인하면 주소 간의 간격이 1바이트임을 알 수 있습니다.

 

 


5번.

 

 //문제5
    int i = 0x324F3A24;
    char *p = (char *) &i; 

    for(int j=3; j>-1; j--){ //int는 4byte, char는 1byte. 4번의 반복이 수행됨.
        printf("%X", *(p+j));
    }

 

 

4번에서 알 수 있듯이 분할되어 저장되게 된다면 가장 낮은 자리부터 첫 주소에 저장됩니다.

i의 값을 그대로 출력하기 위해서는 저장된 값의 주소 중 가장 큰 주소부터 접근해야 합니다.

 

for 반복문을 통해 간단하게 모든 주소에 접근이 가능합니다.

 

 


6번.

 

//문제6
    int i = 0x3C405B7B;
    char *p = (char *) (&i)+1;

    printf("주소 p가 가리키는 값 = %c\n", *p);
    printf("주소 p-1이 가리키는 값 = %c\n", *(p-1));
    printf("주소 p+1이 가리키는 값 = %c\n", *(p+1));
    printf("주소 p+2가 가리키는 값 = %c\n", *(p+2));

 

 

 

위의 문제들과 동일하게 int형 변수에 저장된 값이 char형 포인터에 의해 분할되었습니다.

 

 

값들이 저장된 주소가 분할 기준(char)의 바이트 크기의 간격으로 되어있다는 것을 이해하셨다면

포인터의 시작 주소를 값의 처음 주소가 아닌 5b가 저장된 주소로 지정하시면 간단히 해결 가능합니다.

 

 

출력 순서를 p-1부터 p+2까지 하신다면 for문을 사용하시는 것이 간결하고 좋습니다.

저는 p-1을 중간에 넣어서 반복을 사용하지 않았습니다.

 

 

-끝-