포인터 고급

한준수·2023년 6월 14일
0

C-Lang

목록 보기
6/12

📖 포인터 기본내용

  • 컴퓨터의 모든 메모리에는 주소(Address)가 지정되어 있다.
  • int aa[3]; 과 같이 배열을 선언하면 aa는 변수가 아닌 메모리의 주소값 그 자체를 의미하고, 이를 '포인터 상수' 라고도 한다
  • 포인터 변수란 "주소를 담는 그릇(변수)"이다
  • 포인터 변수에는 주소만 대입해야 하는데, 이는 변수 앞에 '&'를 붙이면 된다.

⌨ 예제 코드

#include<stdio.h>

void main(){
	int aa[3];
    int *p;
    int i, hap = 0;
    
    for(i = 0; i < 3; i++){
    	printf("%d 번째 숫자 : ", i + 1);
        scanf("%d", &aa[i]);
    }
    
    p = aa;
    
    for(i = 0; i<3; i++){
    	hap = hap + *(p+i);
    }
    
    printf("입력 숫자의 합 => %d\n", hap);
}

💻 결과


📖 동적 메모리 확보 - malloc()

동적 메모리 확보의 개념

프로그램 실행 시 필요한 메모리 크기가 고정되는 경우 -> 문제 x

  • 필요로 하는 메모리으 크기가 다른 경우 -> 메모리 낭비 문제 발생

  • 해결 방법 : 메모리를 미리 잡아두지 않고, 필요할 때마다 확보, malloc() 함수 사용

    malloc() 함수는 null로 초기화 되기 때문에 문자형에 유리하다.

  • 형식

포인터 변수 = (포인터 변수의 데이터형*) malloc(포인터 변수의 데이터형 크기 x 필요한 크기)

int* p;

p = (int*)malloc(4*3);
p = (int*)malloc(sizeof(int)*3);

📌malloc() 함수 사용 종료

  • free() 함수 : 사용한 메모리 반납
  • 포인터 변수에 널(null)값을 넣는다는 의미
  • 포인터 변수는 아무것도 가리키지 않으므로, 이 공간을 운영체제에 반납한다.

⌨ 예제 코드

#include<stdio.h>
#include<malloc.h>

void main(){
	int* p;
    int i, hap = 0;
    int cnt;
    puts(" 입력할 개수는 ? ");
    scanf("%d", &cnt);
    
    p = (int*)malloc(sizeof(int) * cnt);
    
    for(i = 0; i < cnt; i++){
    	printf("%d 번째 숫자 : ", i + 1);
        scanf("%d", p+i);
    }
    
    for(i = 0; i < cnt; i++){
    	hap = hap + *(p+i);
    }
    
    printf("입력 숫자 합 ==> %d\n", hap);
    
    free(p);
}

💻 결과


입력할 숫자의 개수를 scanf로 입력받아 malloc함수로 입력한 개수만큼 메모리를 확보했다.
공간이 확보된 포인터 변수 p에 숫자를 입력(배열처럼 &p[i]로 입력해도 된다.)


동적 메모리 할당함수 - calloc()

calloc() 함수는 처음부터 0으로 초기화 된 메모리를 확보한다.
사용형식은 malloc() 함수와 동일

0으로 초기화 되기 때문에 숫자형에 유리하다

⌨ 예제코드

#include<stdio.h>
#include<malloc.h>

void main(){
	int *p, *s;
    int i, j;
    
    printf("malloc() 함수 사용\n");
    p = (int*) malloc(sizeof(int) * 3);
    
    for(i = 0; i < 3; i++){
    	printf("할당된 곳의 초기값 p[%d] ==> %d\n",i,p[i]);
    }
    free(p);
    
    printf("\ncalloc() 함수 사용\n");
    s = (int*)calloc(sizeof(int),3);
    
    for(j = 0; j < 3; j++){
    	printf("할당된 곳의 초기값 s[%d] ==> %d\n",j, s[j]);
    }
    free(s);
}

💻 결과


실시간 메모리 할당 - realloc()

메모리의 크기를 실시간으로 변경해주는 함수이다

  • 형식
포인터 변수 = (포인터 변수의 데이터형*) realloc(기본 포인터, 포인터 변수의 데이터형 크기 x 필요한 크기);

p = (int*) realloc(p,sizeof(int) * 10);

⌨ 필요에 따라서 메모리의 크기를 실시간으로 변경하는 프로그램

#include<stdio.h>
#include<malloc.h>

void main(){
	int* p;
    int i, hap = 0;
    int cnt = 0;
    int data;
    
    p = (int*)malloc(sizeof(int)*1);
    printf("1번째 숫자 : ");
    scanf("%d", &p[0]);
    cnt++;
    
    for(i = 2; ; i++){
    	printf("%d 번째 숫자 : ", i);
        scanf("%d", &data);
        
        if(data != 0){
        	p = (int*) realloc(p, sizeof(int) * i);
        }else{
        	break;
        }
        p[i-1] = data;
    	cnt++;
    }
    
    for(i = 0; i <cnt; i++){
    hap = hap + p[i];
    }
    
    printf("입력 숫자 합 ==> %d\n", hap);
    
    free(p);
}

💻 결과



📖 포인터 배열

여러 줄의 문자열을 처리 : 2차원 배열
문자 하나만 저장 : char
한 줄의 문자열 저장 : 배열 또는 포인터 변수 사용
여러 줄의 문자열을 저장 : 다차원 배열

⌨ 2차원 배열을 사용한 프로그램

#include<stdio.h>

void main(){
	char data[3][100]; 
    int i;
    
    for(i = 0; i < 3; i++){
    	printf("%d 번째 문자열 : ", i + 1);
        gets(data[i]);
    }
    
    printf("\n -- 입력과 반대로 출력(이차원 배열) -- \n");
    for(i = 2; i >= 0; i--){
    	printf("%d : %s\n", i+1, data[i]);
    }
}

💻 결과



위 그림에서 보듯이 사용자가 입력한 글자가 100자가 되지 않으면 낭비되는 공간이 너무 많다.

  • 포인터 배열은 이런 공간 낭비의 단점을 극복하기 위한 것.

📌 일반 배열과 포인터 배열의 차이

  • 일반배열 : 정수 또는 문자가 들어감
  • 포인터 배열 : 주소값이 들어감(주소값(예로 1000번지) 자체가 의미 있는 것이 아니라 그 주소값이 가리키는 곳의 값이 중요)

⌨ 2차원 배열을 포인터 배열로

#include<stdio.h>
#include<malloc.h>
#include<String.h>

void main(){
	char* p[3];
    char temp[100];
    int i, size;
    
    for(i = 0; i < 3; i++){
    	printf("%d 번째 문자열 : ", i+1);
        gets(temp);
        
        size = strlen(temp);
        p[i] = (char*)malloc((sizeof(char) * size) + 1);
        
        strcpy(p[i], temp);
    }
    
    printf("\n -- 입력과 반대로 출력(포인터) -- \n");
    
    for(i = 2; i>=0; i--){
    	printf("%d : %s\n", i + 1, p[i]);
    }
    for(i = 0; i < 3; i++){
    	free(p[i]);
    }
}

💻 결과

결과는 위와 동일하다

temp 변수에 저장된 문자열의 주소값이 p[i]에 저장된 거다.
이렇게 함으로써 필요한 양의 메모리만 할당하여 사용할 수 있다.


📃 퀴즈

  • 사용자가 입력한 여러 숫자 중에서 짝수의 합계를 구하는 프로그램을 작성하라.
    • 실행결과

#include<stdio.h>
#include<malloc.h>

void main(){
	int* p;  // 정수형 포인터 변수 선언
    int  hap = 0;  // for문에 사용할 i와 합계를 저장할 hap 변수
    int i, count; // 입력할 개수와 포인터 변수의 사이즈를 정해줄 변수
    
    printf("입력할 개수는? ");
    scanf("%d", &count);
    
    p = (int*)malloc(sizeof(int) * count); //정수형 포인터를 카운트만큼 메모리 크기 할당
    
    for(i = 0; i < count; i++){
    	printf("%d번째 숫자 : " , i + 1);
        scanf("%d", p+i); // 할당 받은 메모리 공간에  scanf 를 통해 값 입력. 
        //p+i = for문이 돌며 메모리 주소를 정수형 크기만큼 이동시킴
        if(*(p+i) % 2 == 0){
        	hap += *(p+i);
        }
    }
    
    
    
    prtinf("입력 짝수 합 ==> %d\n", hap);
}

0개의 댓글