- 컴퓨터의 모든 메모리에는 주소(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);
}
프로그램 실행 시 필요한 메모리 크기가 고정되는 경우 -> 문제 x
필요로 하는 메모리으 크기가 다른 경우 -> 메모리 낭비 문제 발생
해결 방법 : 메모리를 미리 잡아두지 않고, 필요할 때마다 확보, malloc() 함수 사용
malloc() 함수는 null로 초기화 되기 때문에 문자형에 유리하다.
형식
포인터 변수 = (포인터 변수의 데이터형*) malloc(포인터 변수의 데이터형 크기 x 필요한 크기)
int* p;
p = (int*)malloc(4*3);
p = (int*)malloc(sizeof(int)*3);
- 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() 함수는 처음부터 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(기본 포인터, 포인터 변수의 데이터형 크기 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
한 줄의 문자열 저장 : 배열 또는 포인터 변수 사용
여러 줄의 문자열을 저장 : 다차원 배열
#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자가 되지 않으면 낭비되는 공간이 너무 많다.
- 포인터 배열은 이런 공간 낭비의 단점을 극복하기 위한 것.
#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);
}