Chapter. 8

김동현·2022년 10월 17일
0

포인터의 대입 규칙

#include <stdio.h>

int main(void)
{
    int a = 10;                 // 변수 선언과 초기화
    int *p = &a;                // 포인터 선언과 동시에 a를 가리키도록 초기화
    double *pd;                 // double형 변수를 가리키는 포인터

    pd = p;                     // 포인터 p 값을 포인터 pd에 대입
    printf("%lf\n", *pd);       // pd가 가리키는 변수의 값 출력
   
    return 0;
}

컴파일러는 p에 저장된 값을 int형 변수의 주소로 생각하고, pd에 저장된 값을 double형 변수의 주소로 생각한다.

pd에 p를 대입한 후 연산을 진행하면, a에 할당되지 않은 영역까지 사용하게 된다.

그렇게 되면, 가리키는 자료형이 일치하지 않기 때문에 경고메시지를 출력한다.

→ 그렇다면 해결방법은 없을까? 형 변환 연산자를 활용하면 된다.

double a = 3.4;       // double형 변수 선언
double *pd = &a;      // pd가 double형 변수 a를 가리키도록 초기화
int *pi;              // int형 변수를 가리키는 포인터
pi = (int *)pd;       // pd값을 형 변환하여 pi에 대입

  

두 변수의 값을 바꾸며 포인터 이해하기.

💡 void swap(void); → 두 변수의 값을 바꾸는 함수 선언

  

포인터!! 를 사용한 두 변수의 값 교환

#include <stdio.h>

void swap(int *pa, int *pb);            // 두 변수의 값을 바꾸는 함수의 선언

int main(void) 
{
    int a = 10, b = 20;                 // 변수 선언과 초기화
 
    swap(&a, &b);                       // a, b의 주소를 인수로 주고 함수 호출
    printf("a:%d, b:%d\n", a, b);       // 변수 a, b 출력

    return 0;
}

void swap(int *pa, int *pb)             // 매개변수로 포인터 선언
{
    int temp;                           // 교환을 위한 임시 변수

    temp = *pa;                         // temp에 pa가 가리키는 변수의 값을 저장
    *pa = *pb;                          // pa가 가리키는 변수에 pb가 가리키는 변수의 값 저장
    *pb = temp;                         // pb가 가리키는 변수에 temp값 저장 
}

위의 식의 경우 void swap 부분이 먼저 실행되고 이후에 main함수가 실행된다.

우선 void swap부분을 살펴보면 과정은 아래와 같다.

  1. temp 자리에 pa의 값을 임시로 저장한다.
  2. pa의 자리에 pb의 값을 저장한다.

*여기까지 정리하면 기존 pa, pb의 값과 별개로 temp자리에는 pa의 값이, pa의 자리에는 pb의 값이 저장됐다.

  1. pb자리에 temp의 값이 저장된다. (결국 temp에 저장된 pa의 값이 pb의 자리에 들어가게 되는 것이다.)
  2. 결론적으로 pb의 자리에 pa가, pa자리에 pb의 값이 저장되어 출력된다.
#include <stdio.h>

void swap(void);                        // 두 변수의 값을 바꾸는 함수 선언

int main(void)
{
    int a = 10, b = 20;                 // 변수의 선언과 초기화

    swap();                             // 인수 없이 함수 호출 
    printf("a:%d", b:%d\n", a, b);      // 변수 a, b 출력

    return 0;
}

void swap(void)                         // 인수가 없으므로 매개변수도 없음
{
    int temp;                           // 교환을 위한 변수

    temp = a;                           // temp에 main 함수의 a 저징
    a = b;                              // main 함수의 a에 main 함수의 b값 저징
    b = temp;                           // main 함수의 b에 temp 값 저장 
}

  

여기서 내가 놓친 부분: 함수의 출력 순서를 잘못 이해하고 있었다.

  1. void swap함수를 통해 두 변수의 값을 바꾸는 함수를 선언한다.
  2. main함수 내부에서는 a의 값을 10으로 b의 값을 20으로 설정한다.
  3. swap함수를 출력했다. 그러나 swap함수에는 인수가 없다.
  4. void swap(void) 부분으로 넘어간다.
  5. 15행의 void swap(void) 부분에서는 a, b의 값을 설정하지 않았다. 따라서 어떤 결과값도 출력되지 않는다.
     

변수의 값을 인수!!로 주는 경우

1.     #include <stdio.h>
2.
3.     void swap(int x, int y);            // 두 변수의 값을 바꾸는 함수 선언
4. 
5.     int main(void)
6.     {
7.     int a = 10, b = 20;             // 변수 선언과 초기화
8.
9.     swap(a, b);                     // a, b의 값을 복사해서 전달
10.    printf("a:%d, b:%d\n", a, b);   // 변수 a, b 출력
11. 
12.    return 0;
13.    }
14.
15.    void swap(int x, int y)             // 인수 a, b의 값을 x, y에 복사해서 저장
16.   {
17.    int temp;                       // 교환을 위한 변수
18.
19.    temp = x;                       // temp에 x값 저장
20.    x = y;                          // x에 y값 저징
21.    y = temp;                       // y에 temp값 저장
22.    }

3행의 void swap 부분은 단지 변수의 값을 바꾸겠다는 함수를 선언한 부분이다.

5~7행 부분에서 a = 10, b = 20을 유지한다.

그러다가 9행의 swap 함수 부분을 통해 15행의 swap 함수 부분으로 넘어간다.

15행의 swap 함수에서는 int x, int y 부분을 통해 새로운 변수가 출력되었다.

17~22행 사이에서는 temp의 호출을 통해 a =20, b = 10 을 갖게된다.

그러다가 함수가 종료되어 다시 main함수로 돌아온다.

*그러나 이 부분에서 15~22행 내부에서 새로운 변수 출력을 통해 주솟값은 유지되고 겉의 이름만 바뀐

상태이기에 main함수에 영향을 미치지 않는다.

main 함수로 돌아가면 주솟값은 바뀌지않고 유지된 상태이기 때문에 a = 10을, b = 20을 출력한다.

💡 포인터는 인수값이 아닌 주소값을 바꾸는 기능을 한다!!

  

주소와 포인터는 상수와 변수의 차이가 있다.

포인터의 크기는 주소의 크기와 같다.

포인터에 주소를 저장할 때는 가리키는 자료형이 같아야 한다.

포인터의 주요 기능 중 하나는 함수 간에 효과적으로 데이터를 공유하는 것이다.

  

배열명으로 배열 요소 사용하기


#include <stdio.h>

int main(void)
{
    int ary[3];
    int i;

    *(ary + 0) = 10;
    *(ary + 1) = *(ary + 0) + 10;

    printf("세 번째 배열 요소에 키보드 입력: ");
    scanf("%d", ary + 2);

    for (i = 0; i < 3; i++);
    {
        printf("%5d", *(ary + i));
    }

    return 0;
}

이해가 안되서 그림을 그렸다.

ary는 하나의 덩어리로 인식해야한다. 자료형이 int이기에 4칸으로 생각했다.

*내가 이해하지 못한 부분은 8행과 9행이다.

8행에서는 ary에 0을 더하고 ary 0의 값을 10으로 설정했다. 9행에서는 ary +1 에 ary + 0인 10에 +10을 한 것이기에, ary + 1은 값으로 20을 갖게된다.

profile
디자인과 개발을 모두 할줄 아는 능력있는 개발자가 되고싶습니다.

0개의 댓글