반응형
📝배열
// 배열
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=10, b=20, c=30, d=40; // 비연속적으로 메모리에 저장
int arr[4] = {10, 20, 30, 40}; // 연속적으로 메모리에 저장
printf("%d %d %d %d\n", a, b, c, d); // 10, 20, 30, 40
printf("%d %d %d %d\n", arr[0], arr[1], arr[2], arr[3]); // 10, 20, 30, 40
}
📝포인터
// 포인터
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=10, b=20, c=30, d=40;// 비연속적으로 메모리에 저장
int arr[4] = { 10,20,30,40 };// 연속적으로 메모리에 저장
int* p = &a; // a의 주소값을 보관 (물론 주소값을 보관하기 때문에 p라는 변수로서 할당된다.)
int* pa = arr; // arr[0]의 주소값을 보관
printf("p : %d, pa : %d\n", p, pa); // 1823472356, 1823472488
printf("&a : %d, arr : %d\n", &a, &arr[0]); // 1823472356, 1823472488
printf("p의 값 = a의 값 = %d\n", *p); // 10
printf("pa의 값 = arr[0]의 값 = %d\n", *pa); // 10
printf("&p(p의 주소) : %d, &pa(pa의 주소) : %d\n", &p, &pa); // 1823472536, 1823472568
// 배열 Pointer의 경우 배열처럼 사용가능
printf("%d %d %d %d\n", pa[0], pa[1], pa[2], pa[3]); // 10, 20, 30, 40
}
포인터란 메모리에 할당된 주소를 가르키게 된다
- 자료형* 변수명 = &할당된 변수명
- 할당된 변수명의 주소(&)를 기억하는 변수가 만들어지게 된다.
- *변수명을 통해 해당 주소의 실제 값을 읽어올 수 있다
배열의 경우 연속된 공간에 저장한다 그래서 포인터를 이용해 해당 주소를 가르키게 되면 포인터 변수명[0], 포인터 변수명[1] 과 같이 실제 값을 가져올 수 있습니다
📝메모리 저장 영역 (stack, Heap)
// 데이터 영역
#include <stdio.h>
#include <stdlib.h>
int g = 30; // G-D 영역 (전역변수, 정적변수, 상수)
int main()
{
int m = 20; // stack 영역 (함수내의 변수)
int n = 20; // stack 영역
int* p; // stack 영역
p = (int*)malloc(4); // Heap 영역 (4byte 할당)
*p = 10; // Heap 영역에 10 할당
printf("%d", *p);
// 4byte의 크기를 Heap 영역에 생성 후 p라는 포인터 변수가 그 주소값을 가르키게 된다.
free(p); // 영역 할당을 free로 제거 시켜야 사라지게 된다.
}
메모리는 크게 2가지로 나뉘는데 stack영역과 Heap 영역으로 나뉘게 됩니다.
📝stack영역의 경우
호출된 함수가 마치고 복귀할 주소 및 데이터(지역변수, 매개변수, 리턴 값 등)를 임시로 저장하는 공간입니다 만약 재귀함수가 많이 발생해 stack영역을 초과하게 되면stack overflow 에러가 발생하게 됩니다. Stack은 컴파일 타임에 크기가 결정되기 때문에 무제한으로 할당 할 수 없습니다
📝Heap영역의 경우
런타임(프로그램 동작) 시 크기가 결정됩니다. malloc등으로 Heap영역의 메모리를 사용해 원하는 공간만큼 할당해 사용합니다. 이렇게 공간을 할당하고 해제하지 않으면 Memory Leak이 발생하게 됩니다. JAVA의경우 JVM이 이 행위를 대신 해주죠 Stack의 비해 메모리 공간이 많지만 포인터로 접근해야 하기 때문에 속도가 느립니다
📝 정적배열, 동적배열
// 정적배열, 동적배열
#include <stdio.h>
#include <stdlib.h>
int main()
{
int arr[20]; // 정적배열
arr[0] = 0;
arr[1] = 10;
arr[2] = 20;
arr[3] = 30;
arr[4] = 40;
for (int i = 0;i < 5; i++) {
printf("%d\n", arr[i]); // 0, 10, 20, 30 , 40
}
int* p;
p = (int*)malloc(40); // 동적 배열
p[0] = 0;
p[1] = 10;
p[2] = 20;
p[3] = 30;
p[4] = 40;
for (int i = 0;i < 5; i++) {
printf("%d\n", p[i]); // 0, 10, 20, 30 , 40
}
free(p);
// sizeof를 이용한 할당방식
int* ps;
ps = (int*)malloc(sizeof(int) * 5); // sizeof(int) * 5 → int형 5개를 생성
ps[0] = 0;
ps[1] = 10;
ps[2] = 20;
ps[3] = 30;
ps[4] = 40;
for (int i = 0;i < 5; i++) {
printf("%d\n", ps[i]); // 0, 10, 20, 30 , 40
}
free(ps);
}
정적배열의 경우 stack영역을 사용하는 걸 의미하고 동적배열의 경우 Heap영역을 사용하는 걸 의미합니다.
📝 사용자에게 값을 입력 받기
// 사용자에게 배열크기 입력받기
#include <stdio.h>
#include <stdlib.h>
int main()
{
int size = 0;
printf("배열의 크기를 입력해주세요 : ");
scanf_s("%d", &size); // size을 사용자에게 입력 받는다.
// int arr[size]; // 정적배열인 경우 배열크기에 변수 할당 불가
int* pa = (int*)malloc(sizeof(int) * size); // 동적배열은 가능하다.
for (int i = 0; i < size; i++) {
printf("[%d] 배열의 값을 입력해주세요 ", i);
scanf_s("%d", &pa[i]); // 배열을 입력해주세요
}
for (int i = 0; i < size; i++) {
printf("pa[%d] : %d\n", i, pa[i]);
}
}
반응형
'[C, C++]' 카테고리의 다른 글
[C, C++] 구조체(struct), typedef(별칭), 구조체 변수 접근 (->), 구조체 포인터 (5) | 2022.10.17 |
---|---|
[C, C++] IF문, FOR문, printf (글자 출력하기) (1) | 2022.10.17 |
[C, C++] Visual Studio community 설치 및 컴파일 해보기 (1) | 2022.10.17 |