본문 바로가기
문법관련/C

9. 포인터

by print_soo 2024. 6. 18.

메모리의 주소

int a; //메모리 공간 확보

a = 10; // 값 저장
[  0  |  0  |  0  |  10  ]
  100   101   102    103 <- 메모리 주소 값

우리는 이전까지 확보된 메모리를 사용할 때 변수 명으로 접근해왔다.

하지만 메모리 주소 값을 통해 메모리에 접근할 수 있는 방법이 있는데 그게 바로 주소 연산자이다.


주소 연산자(&)

:메모리 주소 값을 통해 메모리에 접근하는 방법

&a // == 100
#include <stdio.h>

int main(){
    int a;
    printf("a의 메모리 주소 값은 %p입니다.", &a); //%p는 16진수를 나타내는 연산자

    return 0;
}

// 출력
// a의 메모리 주소 값은 0x16b653248입니다.

위 방식처럼 주소 연산자를 사용하면 메모리에 접근할 수 있다.

다만 해당 메모리에 있는 값을 사용하기 위헤서는 다른 연산자가 필요한데 그게 바로 간접 참조 연산자(*)이다.


간접 참조 연산자

#include <stdio.h>

int main(){
    int a;

    *&a = 10;  //a의 메모리 주소 값을 가지고 있는 공간에 10을 대입

    return 0;
}

포인터 변수

: 포인터는 주소를 저장하는 변수로 일반 변수처럼 선언 후에 사용한다.

#include <stdio.h>

int main(){
    int a;
    int *pa; //포인터 선언

    pa = &a; //a의 메모리 주소 값을 pa에 대입
    *pa = 10; //a의 메모리 주소 값을 가리키는 공간에 10을 대입

    return 0;
}

❗️간접 참조 연산자(기호)와 포인터는 다르다.

  • int *pa
    • 주소를 저장하는 변수
  • *pa
    • pa라는 변수의 주소에 접근
     


const 포인터 변수

//경우 1

#include <stdio.h>

int main(){
    int a, b;
    const int *pa = &a; //const 포인터 선언
    
    pa = &b; //(o)
    *pa = 10;// (x)
	  
	  return 0;
}

//const 포인터 변수는 값을 변경할 수 없다. 다만 a는 직접적으로 변경이 가능하다. 

// 경우 2

#include <stdio.h>

int main(){
    int a, b;
    int *const pa = &a; //const 포인터 선언
    
    pa = &b; //(x)
    *pa = 10;// (o)
	  
	  return 0;
}


주소와 포인터의 크기

#include <stdio.h>

int main(){
    char ch;
    int in;
    double db;
    
    char *pc = &ch; // pc [ 100 ] = ch [ ]
    int *pi = &in; // pi [ 200 ] = in [ | | | ]
    double *pd = &db; // pd [ 300 ] = db [ | | | | | | | ]
    
    printf("char형 변수의 주소 크기: %d\\n", sizeof(&ch));) // 8
    printf("int형 변수의 주소 크기: %d\\n", sizeof(&in));) // 8
    printf("double형 변수의 주소 크기: %d\\n", sizeof(&db));) // 8
    
    printf("char * 포인터의 주소 크기: %d\\n", sizeof(pc));) // 8
    printf("int * 포인터의 주소 크기: %d\\n", sizeof(pi));) // 8
    printf("double * 포인터의 주소 크기: %d\\n", sizeof(pb));) // 8
    
    printf("char * 포인터가 가르키는 변수의 크기: %d\\n", sizeof(*pc));) // 1
    printf("int * 포인터가 가르키는 변수의 크기", sizeof(*pi));) // 4
    printf("double * 포인터가 가르키는 변수의 크기", sizeof(*pd));) // 8
    
}

ch, in ,db는 각각 변수 자체의 크기는 다르지만, 그 시작 주소 값의 크기는 모두 같다. 따라서 포인터가 가르키는 자료형에 상관 없이 크기는 모두 같다.

 


포인터의 대입 규칙

  1. 포인터는 가리키는 변수의 형태가 같을 떄만 대입 해야한다.
  2. 형 변환으로 사용한 포인터의 대입은 언제나 가능하다.
    1. 예시
    double a = 3.4; //double형 변수 선언
    double *pd = &a; //pd가 double형 변수 a를 가리키도록 초기화
    int *pi; //int형 변수를 가리키는 포인터
    pi = (int *)pd; //pd 값을 형 변환해 pi에 대입
    

'문법관련 > C' 카테고리의 다른 글

11-1. 아스키코드  (0) 2024.06.25
10. 배열과 포인터  (0) 2024.06.24
8. 함수  (0) 2024.06.14
7. 반복문 - do while  (0) 2024.06.13
6. 연산자  (0) 2024.06.12