ex) int arr[100];
stdlib.h에 선언된 세 가지 메모리 할당 함수 중 하나를 호출해야 함.
ex)
malloc(memory allocation): 메모리 블록을 할당하지만 초기화는 하지 않습니다.(쓰레기 값으로 채움)
calloc(clear allocation): 메모리 블록을 할당하고 초기화까지 합니다.(데이터 타입의 기본값으로 채움)
realloc(re allocation): 이전에 할당된 메모리 블록의 크기를 조정합니다.
free: 사용이 끝난 힙 메모리를 시스템에 반환.(동적할당한 메모리를 해제하기 위해 사용)
스택공간에 동적할당된 메모리 주소를 가리킬 포인터를 생성하고 힙영역으로 주소를 지시하도록 함
#include<stdio.h>
#include<stdlib.h>
int main(void) {
int* ptr; //스택공간에 동적할당된 메모리 주소를 가라킬 포인터 생성
//동적할당 후 포인터로 주소를 지시하도록 함
ptr = (int*)malloc(sizeof(int)); //int 데이터 하나를 저장할 공간 할당
if (ptr == NULL) { //힙에 할당할 공간이 없으면 할당이 실패하면서 NULL 포인터 반환
printf("할당실패\n");
return 0;
}
else {//할당에 성공한 경우, 할당받은 공간에 데이터를 저장
*ptr
= 10;
printf("*ptr: %d\n", *ptr);
free(ptr); //할당이 실패한 경우 free를 호출하게 되면 시스템이 죽음
ptr = NULL; //가리키는 대상이 없어져 NULL을 가리키도록 조정
}
return 0;
}
배열 동적할당
#include<stdio.h>
#include<stdlib.h>
int main(void) {
int* ptr; //스택공간에 동적할당된 메모리 주소를 가라킬 포인터 생성
//동적할당 후 포인터로 주소를 지시하도록 함
ptr = (int*)malloc(sizeof(int)*5);
if (ptr == NULL) { //힙에 할당할 공간이 없으면 할당이 실패하면서 NULL 포인터 반환
//if(!ptr) == if(ptr ==NULL)
//if(ptr) == if(ptr != NULL)
printf("할당실패\n");
return 0;
}
else {//할당에 성공한 경우, 할당받은 공간에 데이터를 저장
ptr[0] = 10;
ptr[1] = 20;
ptr[2] = 30;
ptr[3] = 40;
ptr[4] = 50;
for(int i=0;i<5;++i)
printf("ptr[%d]: %d\n", i,*(ptr+i));
free(ptr); //할당이 실패한 경우 free를 호출하게 되면 시스템이 죽음
ptr = NULL; //가리키는 대상이 없어져 NULL을 가리키도록 조정
}
return 0;
}
memset함수를 이용한 메모리 초기화
#include<stdio.h>
#include<stdlib.h>
int main(void) {
int* iptr;
iptr = (int*)malloc(sizeof(int));
printf("%d\n", *iptr);
memset(iptr,0,sizeof(int));
printf("%d", *iptr);
free(iptr);
iptr = NULL;
return 0;
}
calloc, realloc함수 활용
#include<stdio.h>
#include<stdlib.h>
void print(int* arr, int n);
int main(void) {
int* iptr = (int*)calloc(10, sizeof(int));
if (iptr) {
for (int i = 0; i < 10; ++i) {
printf("iptr[%d]: ",i);
scanf_s("%d", &iptr[i]);
}
iptr = (int*)realloc(iptr, sizeof(int) * 20);
for (int j = 10; j < 20; ++j) {
printf("iptr[%d]: ",j);
scanf_s("%d", &iptr[j]);
}
print(iptr, 20);
free(iptr);
iptr = NULL;
}
else {
printf("동적 할당 실패\n");
return 0;
}
return 0;
}
void print(int* arr, int n) {
int i;
for (i = 0; i < n; ++i)
printf("%d ", *(arr+i));
printf("\n");
}
enum이라는 키워드로 시작하여 tag이름을 사용할 수 있습니다. tag 이름을 뒤따르는 중괄호 안에 상수로 사용될 이름들을 지정해 줍니다. 열거형은 값을 설정하지 않으면 맨 앞의 멤버부터 0,1,2,3순으로 자동으로 부여됨. 첫번째 멤버에 특정값을 지정하면 뒤따르는 멤버들은 1씩 증가해서 부여됨. 상수를 정의할 수 있으며 프로그램에서 가독성을 올려줌.
열거형을 이용한 ex
#include<stdio.h>
#include<stdlib.h>
typedef enum weapon_type {
WT_KATANA,
WT_BROADSWORD,
WT_LONGSWORD,
WT_HALBERD
}weaponType;
void attackMonster(weaponType type, int* monsterHP, int* damage) {
switch (type) {
case WT_KATANA:
*monsterHP -= damage[WT_KATANA];
break;
case WT_BROADSWORD:
*monsterHP -= damage[WT_BROADSWORD];
break;
case WT_LONGSWORD:
*monsterHP -= damage[WT_LONGSWORD];
break;
case WT_HALBERD:
*monsterHP -= damage[WT_HALBERD];
break;
}
}
int main(void) {
weaponType myWeapon;
int monsterHP = 50;
int damages[4] = { 5,10,20,30 };
printf("롱소드를 구매하여 장착합니다.\n");
myWeapon = WT_LONGSWORD;
attackMonster(myWeapon, &monsterHP, damages);
printf("공격 후 몬스터 체력: %d", monsterHP);
return 0;
}