본문으로 바로가기

자료구조 공부#8 (포인터)

category 이론공부/자료구조 2021. 3. 26. 12:11

2021.03.23 - [이론공부/자료구조] - 자료구조 공부#7 (희소 행렬)

참고하기 좋은 이전 내용 이다.

 

포인터(Pointer)

다른 변수의 주소를 가지고 있는 변수

비유를 하자면 편지가 변수의값 우체통이 편지의 주소(포인터) 라고 생각해보자.

char a = 'A';
char *p;
p = &a;

위는 선언 방법의 예제

 

 

*p = 'B';

위는 * 연산자를 이용하여 p주소 안에 값을 바꾸는 예시, 즉 char a를 포인터를 통해서 내용을 변경했다.

 

& : 주소의 참조(변수의 주소를 추출)

* : 포인터가 가리키고 있는곳의 값을 추출(벨류)

 

int *p;  // int 형 포인터
float *pf; // float 형 포인터
char *pc; // char 형 포인터

 

함수의 매개 변수로 포인터 사용하기

요즘 추세엔 잘 사용하지 않는 방식이지만 상황에 따라선 포인터를 사용하기도 한다. 

#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

지역함수에서 포인터를 통해 메인속 a,b 변수 주소를 받아와서 변수 값을 바꿀 수 있는것을 볼 수 있다.

 

배열과 포인터

배열의 이름 : 포인터와 같은 역활을 하고 있다.

위와 같은 배열이 있을때 A는 포인터 변수와 비슷한걸 알 수 있다.

A의 3 주소... A 의 2주소... A[3], A[2]

 

#include <stdio.h>
#defint SIZE 6

void get_int(int lizt[]){
	printf("6개의 정수를 입력하세요 :");
    
    for (int i=0;i< SIZE;i++){
    	scanf(%d, &list[i]);
    }

int cal_sum(int list[]){
	int sum = 0;
    for (int i = 0; i < SIZE; i++){
    	sum += *(list +i); 
    }
    return sum;
}

int main(void){
	int list[SIZE];
    get_int(list);
    printf("합= %d \n", cal_sum(list));
    return 0;
}

}

위와 같이 포인터와 배열이 비슷한 용도로 사용되고 있다.

*(list + i) = list[i] 와 같다

 

 

동적 메모리 할당

  • 프로그램의 실행중 메모리를 할당 받는 것
  • 필요한 만큼만 할당을 받고 필요한때 사용하고 반납
  • 메모리를 효율적으로 사용가능
main(){
	int *pi;
    pi = (int *)malloc(sizeof(int)); //동적 메모리 할당
    // pi 는 int 크기만큼 메모리 할당된 어느 주소

	.
    .
    .
    free(pi); // dealloc 메모리 반납
}

malloc 으로 할당 받고 free를 통해 할당된 공간을 반납한다.

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define SIZE 10

int main(void){
	int *p;
    p = (int *)malloc(sizeof(int));
    if (p == NULL){
    	fprintf(stderr, "메모리가 부족해서 할당을 할 수 없습니다. \n");
        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;
}

malloc 사용 예제

 

 

구조체와 포인터

(*ps).i 보다 ps ->i 를 많이 사용한다. 같은 표현이지만 가독성을 위해 후자를 많이 사용한다.

 

#include <stdio.h>
#include <stdlib.h>
#incude <string.h>

typedef struct studentTag{
	char name[10];
    int age;
    double gpa;
} student;


int main(void){
	student *p;
    p = (student *)malloc(sizeof(student));
    if (p == NULL){
    	fprintf(stderr, "메모리가 부족해서 할당을 할 수 없습니다. \n");
        exit(1);
    }
    
    strcpy(p->name, "Park");
    p->age = 20;
    free(p)
    
    return 0;
}

느낀점 : 포인터의 개념을 제대로 다시 확인해보자. 구조체와 배열에서는 포인터가 어떻게 사용되는지 보면 비슷한 관계란걸 알 수 있다. 동적메모리할당 또한 잘 이해하자