Pointer

안효빈·2024년 6월 14일

자료구조

목록 보기
3/10

pointer: 다른 변수의 주소를 갖고 있는 변수

모든 변수는 메모리 공간에 저장되고, 메모리의 각 바이트는 주소를 갖고 있다.
이 주소가 pointer에 저장된다.

<포인터 관련 연산자>

포인터는 2가지 중요한 연산을 갖고 있다
1. & : 변수의 주소를 추출하는 주소 연산자

int a; //정수형 변수
p = &a; // 변수의 주소를 포인터에 저장

2.* : 포인터가 가리키는 장소에 값을 저장하는 간접참조 연산자

*p = 200;

p와 a는 동일한 실제적인 객체를 가리키기 때문에 p의 값을 변경하면 a의 값도 바뀐다.
또한 포인터가 아무것도 가리키지 않을 땐, NULL로 만들어둬야 한다.
다음은 포인터 예제이다.

#include <stdio.h>

void swap(int *px, int *py)
{
int tmp;
tmp = *px;
*px = *py;
*py = tmp;
}

 int main(void)
 {
 int a = 1 b = 2;
 printf("swap을 호출하기 전: a=%d, b=%d\n", a, b);
 swap(&a, &b);
 printf("swap을 호출한 다음: a=%d, b=%d\n", a, b);
 return 0;
 }
실행결과
swap을 호출하기 전: a=1, b=2
swap을 호출한 다음: a=2, b=1

<동적 메모리 할당>

'동적메모리할당'(dynamic memory allocation)은 운영체제로부터 필요한 만큼의 메모리를 할당받고, 사용 후 시스템에 메모리를 반납하는 기능이다.
'heap'라는 공간에 메모리를 할당받게 된다.

int *p;
p = (int *)malloc(sizeof(int)); //동적 메모리 할당
*p = 1000; // 동적 메모리 사용
free(p); // 동적 메모리 반납
  • malloc()는 동적 메모리 블럭의 시작 주소를 반환한다. 반환되는 타입은 vodi *이므로 적절한 포인터로 형변환을 시켜줘야 한다.
    (메모리 확보가 불가하면 NULL을 함수의 반환값으로 반환한다. 따라서 malloc()의 반환값이 NULL인지 항상 검사해야 함.)

  • (int *)는 캐스팅(다른 데이터타입으로 변환한다는 뜻)타입으로, void 타입을 int 타입으로 변환하는 캐스트 연산자이다. 따라서 malloc()이 할당한 메모리의 주소를 int * 타입의 포인터로 변환하여 반환한다.

  • sizeof키워드는 변수나 타입의 크기를 바이트 단위의 숫자로 반환한다.

  • free()는 할당된 메모리 블록을 운영체제에게 반환한다.

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    
    #define SIZE 10
    
    int main(void)
    {
    int *p;
    
    p = (int *)malloc(SIZE * sizeof(int));
    if( p == NULL){
    fprintf(stderr, "메모리가 부족해서 할당할 수 없습니다.");
    exit(1);
    }
    
    for(int i=0; i<SIZE; i++) p[i] = i;
    for(int i=0; i<SIZE; i++) printf("%d", p[i]);
    
    free(p);
    return 0;
    }
    실행결과
    0 1 2 3 4 5 6 7 8 9

    구조체와 포인터

    구조체에 대한 포인터를 선언하고, 포인터를 통해 구조체 멤버에 접근할 수 있다.
    표기법은 ->을 쓴다.

    (*ps).i 는 ps->i와 같다.

    동적으로 생성된 구조체는 포인터를 통해서만 접근 가능하다.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct studentTag{
    char name[10];
    int age;
    double gpa;
    }student;
    
    int main(void)
    {
    student *s;
    
    // student 구조체만큼의 크기를 할당받고, student 타입으로 캐스팅하여 s를 student 구조체를 가리키는 포인터로 사용
    s = (student *)malloc(sizeof(student)); 
    if(s==NULL){
    fprintf(stderr, "메모리가 부족해서 할당할 수 없습니다.\n");
    exit(1);
    }
    
    strcpy(s-<name, "Park"); // Park를 s->name에 복사하는 문자열 복사 함수
    s->age = 20;
    
    free(s);
    return 0;
    }
profile
피넛버터

0개의 댓글