5월 26일용 - dlekdbs0710/rlakf1wnck GitHub Wiki
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* pa = NULL; //pa는 int형 데이터를 가리키는 포인터
double* pb = NULL; //pb는 double형 데이터를 가리키는 포인터
pa = (int*)malloc(sizeof(int)); //malloc():지정된 바이트 수만큼 힙 메모리를 할당
pb = (double*)malloc(sizeof(double)); //반환값: void*
*pa = 10; //pa가 가리키는 메모리 주소에 10 저장
*pb = 3.14; //pb가 가리키는 메모리 주소에 3.14 저장
printf("int : %d\n", *pa); // %d:정수 출력
printf("double : %g\n", *pb); //%g: 실수 출력(소수점 자릿수, 지수 표기 자동 조절)
free(pa); // 메모리 해제-> 메모리 누적 방지를 위해서 해야함
free(pb);
}
- malloc()은 지정된 바이트 수만큼 힙 메모리를 할당함
- free(): 메모리 해제, 메모리의 누적을 방지하기 위해서 해야함
int : 10
double : 3.14
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* pa = NULL; // 정수형 메모리를 가리킬 포인터
double* pb = NULL;// 실수형 메모리를 가리킬 포인터
// CRUD(Create, Read, Update, Delete)
// 동적 메모리 할당(create)
pa = (int*)malloc(sizeof(int)); //4바이트 정수형 메모리 확보
pb = (double*)malloc(sizeof(double));// 8바이트 실수형 메모리 확보
// 값 저장 및 출력(Update & Read)
*pa = 10; //할당된 정수형 메모리 공간에 10 저장
*pb = 3.14; // 실수형 메모리 공간에 3.14 저장
printf("int : %d\n", *pa); // 결과: int: 10
printf("double : %g\n", *pb); // 결과: double: 3.14
free(pa);
free(pb); //메모리 해제=> pa=NULL; pb=NULL;로 초기화도 가능, 결론: pa, pb가 가리키는 메모리만 해제, 포인터 변수 자체는 남음
}
#include <stdio.h>
#include <stdlib.h>
// 메모리 할당 함수들(Create)
int* AllocInt()
{
return (int*)malloc(sizeof(int)); => int와 double 하나를 저장할 수 있는 크기의 힙 메모리를 할당하고 포인터 반환 , malloc()실패시, NULL 반환됨->사용시 주의 필요
}
double* AllocDouble()
{
return (double*)malloc(sizeof(double));
}
// 값 설정 함수들(Update)==> 전달받은 포인터(p)가 가리키는 위치에 값 저장
void SetInt(int* p, int data)
{
*p = data; // 해당 메모리 공간에 값을 대입
}
void SetDouble(double* p, double data)
{
*p = data;
}
// 값 출력 함수들(Read)==> 값만 받아서 출력(포인터가 아닌 복사된 값을 받음)
void PrintInt(int data)
{
printf("int : %d\n", data);
}
void PrintDouble(double data)
{
printf("double : %g\n", data);
}
// 메모리 해제 함수들(Delete)==>free()을 통해 메모리 해제, 이후에 해당 포인터 다시 사용시, '정의되지 않은 동작'이라고 뜸
void FreeInt(int* p)
{
free(p);
}
void FreeDouble(double* p)
{
free(p);
}
int main() //main 함수 동작의 흐름
{
int* pa = NULL;
double* pb = NULL;
pa = AllocInt(); //int* 메모리 할당
pb = AllocDouble();//double* 메모리 할당
SetInt(pa, 10);//SetInt(&*pa, 10); // 할당된 메모리에 10 저장
SetDouble(pb, 3.14); //3.14 저장
PrintInt(*pa); //10 출력
PrintDouble(*pb); //3.14 출력
FreeInt(pa); //메모리 해제
FreeDouble(pb);
}
int : 10
double: 3.14
#include <stdio.h>
#include <stdlib.h>
//
int* AllocInt()
{
return (int*)malloc(sizeof(int));
}
double* AllocDouble()
{
return (double*)malloc(sizeof(double));
}
void SetInt(int* p, int data)
{
*p = data;
}
void SetDouble(double* p, double data)
{
*p = data;
}
void PrintInt(int data)
{
printf("int : %d\n", data);
}
void PrintDouble(double data)
{
printf("double : %g\n", data);
}
void FreeInt(int* p)
{
free(p);
}
void FreeDouble(double* p)
{
free(p);
}
int main()
{
int* pa = NULL;
double* pb = NULL;
pa = AllocInt();
pb = AllocDouble();
SetInt(pa, 10);//SetInt(&*pa, 10);
SetDouble(pb, 3.14);
PrintInt(*pa);
PrintDouble(*pb);
FreeInt(pa);
FreeDouble(pb);
}
- 전체 구조 개요
- C: 동적 메모리 할당(Create)
- R: 값을 읽어 출력(Read)
- U: 메모리 값 저장(Update)
- D: 메모리 해제(Delete)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* pa = (int*)malloc(sizeof(int) * 10); //int형 크기만큼 10개의 메모리 할당, 4X10(int가 4바이트인 경우=> 40바이트), pa = 이 메모리의 블록의 시작 주소를 가리킴
for (int i = 0; i < 10; ++i) // 결과적으로 pa[0]~pa[9]: 값 1~10이 됨
pa[i] = i + 1; // pa[i]=*(pa + i)와 동일
for (int i = 0; i < 10; ++i) // 배열에 저장된 값을 한 줄씩 출력
printf("data : %d\n", pa[i]);
free(pa); // 동적으로 할당된 메모리 해제
}
data : 1
data : 2
data : 3
data : 4
data : 5
data : 6
data : 7
data : 8
data : 9
data : 10
#include <stdio.h>
#include <stdlib.h>
void AllocIntArray(int** pp, int capacity) //이중 포인터(int **pp)를 사용-> 함수 외부의 포인터 변수에 해당
{
*pp = (int*)malloc(sizeof(int) * capacity); // main()안에서는 AllocIntArray(&pa, 10);형태로 호출
}
void InitIntArray(int* pa, int size) // 동적 배열이나 일반 배열을 초기화할 수 있음
{ // int size는 배열의 크기(원소 개수)
for (int i = 0; i < size; ++i)
pa[i] = i + 1;
}
void PrintIntArray(int* pa, int size) //전달받은 정수 배열을 순서대로 출력
{
for (int i = 0; i < size; ++i)
printf("data : %d\n", pa[i]);
}
void FreeIntArray(int* pa)
{
free(pa);
}
int main()
{
int* pa = 0;
AllocIntArray(&pa, 10);
InitIntArray(pa, 10);
PrintIntArray(pa, 10);
FreeIntArray(pa);
}
#include <stdio.h>
#include <stdlib.h>
int* AllocIntArray(int capacity) // 반환값으로 포인터 전달
{
return (int*)malloc(sizeof(int) * capacity);
}
void InitIntArray(int* pa, int size)
{
for (int i = 0; i < size; ++i) //main에서는 int* pa=AllocIntArray(10);처럼 간단히 사용
pa[i] = i + 1;
}
void PrintIntArray(int* pa, int size)
{
for (int i = 0; i < size; ++i)
printf("data : %d\n", pa[i]);
}
void FreeIntArray(int* pa)
{
free(pa);
}
int main()
{
int* pa = AllocIntArray(10);
InitIntArray(pa, 10);
PrintIntArray(pa, 10);
FreeIntArray(pa);
}
#include <stdio.h>
#include <stdlib.h> //이 코드는 굳이 필요X
int main()
{
int a = 10;
int b = 20;
int* p = NULL;
//p = &a; //활성화하면 출력값은 10
p = &b; // 포인터 p가 b를 가리키므로 p는 20
printf("data : %d\n", *p);
}
data : 20
#include <stdio.h>
#include <stdlib.h>
void AssignAddress(int** pp,int* pdata)
{
*pp = pdata; //pp는 int*의 주소(즉, int**), pdata: 어떤 정수형 변수의 주소(int*)
} // pp가 가리키는 포인터에 pdata를 넣음->즉 , 포인터 변수 자체를 바꿔줌
int main()
{
int a = 10;
int b = 20;
int* p = NULL;
//p = &a;
//p = &b;
AssignAddress(&p, &b); //p가 b의 주소를 가리키게 변경됨-> *p는 b의 값인 20을 출력
printf("data : %d\n", *p);
}
data : 20
#include <stdio.h>
#include <stdlib.h>
typedef int I; //I는 int와 완전히 동일한 타입
typedef int* PI; //PI는 int*와 동일한 타입[PI p; = int* p;]
void AssignAddress(PI* pp, I* pdata)
{
*pp = pdata; //pp는 p를 가리키는 포인터(즉 &p), p=pdata;와 같음=> 즉, p가 이제 pdata가 가리키는 주소(b의 주소)임
}
int main()
{
I a = 10; //int a=10;
I b = 20; // int b =20;
PI p = NULL;// int* p = NULL;
//p = &a;
//p = &b;
AssignAddress(&p, &b);// int** 전달, int* 전달==> p=&b가
printf("data : %d\n", *p);//b를 가리키게 되었으므로 *p==20
}
data : 20
- pp는 &p(p의 주소 )
- *pp는 p 자신
- pdata는 &b(b의 주소)
#include <stdio.h>
struct Point //struct는 사용자 정의 자료형을 만든다는 뜻임, Point- x,y의 좌표를 저장하는 구조체 타입
{
int x; //구조체에 두 개의 멤버 변수 x, y 가 있다는 뜻임
int y;
};
int main()
{
int n = 10; //일반 정수 변수 선언
Point pt = { 2,3 }; //구조체 변수 pt 선언 및 초기화
printf("%d\n", n);
printf("(%d, %d)\n", pt.x, pt.y); //pt 구조체의 x, y 멤버 출력(2,3)
}
10
(2, 3)
#include <stdio.h>
struct Point // Point는 int 두개(x, y)를 멤버로 갖는 구조체
{
int x; // 메모리상에서 x와 y는 연속된 메모리에 저장됨
int y;
};
int main()
{
Point pt = { 2,3 };
printf("(%d, %d)\n", pt.x, pt.y);
printf("%p %p\n", &pt, &pt+1); //&pt는 구조체 변수 pt의 시작 주소 , &pt+1: 구조체 크기만큼 그 다음 구조체의 주소
printf("%p %p\n", &pt.x, &pt.x+1); //&pt.x: pt의 첫 번째 멤버 x의 주소, &pt.x+1: pt.y의 주소와 같음
Point* p1 = &pt; // p1은 구조체 전체를 가리킴(Point*)
int* p2 = &pt.x; //p2는 정수 x를 가리킴(int*)-> 연속해서 y도 접근 가능
}
#include <stdio.h>
struct Point
{
int x;
int y;
};
int main()
{
Point pt = { 2,3 };//구조체 변수 pt 선언 및 초기화 (x, y)
Point* p = &pt;// 구조체 변수 pt의 주소를 포인터 p에 저장
printf("(%d, %d)\n", pt.x, pt.y);//pt를 통해 접근
printf("(%d, %d)\n", p->x, p->y);// 포인터 p를 통해 pt의 멤버에 접근
} //📌 ->연산자는 구조체 포인터가 구조체의 멤버에 접근할 때 사용(간접 참조)
(2,3)
(2,3)
#include <stdio.h>
struct Point //구조체의 정의(Point는 두 개 int 멤버 x, y)
{
int x; //메모리 상에서는 연속된 8바이트로 저장됨(int가 4바이트 기준)
int y;
};
int main()
{
Point pt = { 2,3 }; //pt는 구조체 변수, x=2, y=3
Point* p = &pt; //p는 pt를 가리키는 구조체 포인터
printf("(%d, %d)\n", pt.x, (&pt)->y);
printf("(%d, %d)\n", (*p).x, p->y); //(*p).x → p가 가리키는 구조체의 x값 → 2
//p->y → p가 가리키는 구조체의 y값 → 3
}
##결과
(2,3)
(2,3)
#include <stdio.h>
// 구조체의 정의
struct Point
{
int x;
int y;
};
//구조체를 매개변수로 받는 함수
void PrintPoint(Point pt)
{
printf("(%d, %d)\n", pt.x, pt.y);
}
int main()
{
Point pt = { 2,3 };
PrintPoint(pt); //구조체를 함수에 전달(구조체 전체를 복사)
}
#include <stdio.h>
//구조체의 함수 전달 방식(Call by Value)-값 전달
struct Point
{
int x;
int y; //int가 4바이트라면 Point 구조체는 총 8바이트, 구조체 변수는 두 개의 정수값을 연속된 메모리에 저장
};
// 함수 내부
void PrintPoint(Point pt)
{
printf("(%d, %d)\n", pt.x, pt.y); //단순히 구조체의 멤버 x, y를 출력
}
int main()
{
// 선언
Point pt = { 2,3 };
Point pt2 = { -1, 3 };
// 함수 호출
PrintPoint(pt);
PrintPoint(pt2);
}
(2, 3)
(-1, 3)
#include <stdio.h>
struct Point
{
int x;
int y;
};
// 함수 정의 - 구조체의 주소를 받아서 멤버에 접근
void PrintPoint(Point* p) //Point* p는 구조체 Point의 포인터
{
printf("(%d, %d)\n", p->x, p->y); //-> 연산자 활용
}
int main() // 두 개의 구조체 변수 pt, pt2 선언, 초기화
{
Point pt = { 2,3 };
Point pt2 = { -1, 3 };
PrintPoint(&pt); //&pt, &pt2: 각각의 구조체 변수의 주소값
PrintPoint(&pt2);
}