함수 포인터
- 함수명 앞에
*
만 붙여주면 함수 포인터가 선언된다.
자료형(*함수 포인터 이름)(인자목록)
int (*func)(int a);
- 함수 포인터도 포인터이므로 주소값을 저장.(함수의 주소값만 저장하는 함수 포인터)
#include <stdio.h>
int Plus(int a, int b) {
return a+b;
}
int main(){
int (\*fPtr)(int pa, int pb);
fPtr = Plus; // 주소를 받아 간접 참조
int result = fPtr(20,10);
printf("결과값: %d\n", result);
return 0;
}
함수 포인터의 사용 이유?
직접 함수 호출하지 않고 왜 복잡하게 함수 포인터를 사용?
메모리의 크기 및 위치가 결정되는 시점은 컴파일 타임 또는 런타임 시점.
컴파일 타임 시점에 결정은 정적 바인딩, 런타임 시점 결정은 동적바인딩되었다고 한다.
새로운 기능을 추가하게 되면 매번 다시 컴파일해야하는 불편함이 있으나 플러그인 방식 시 그럴 필요가 없다.
함수 포인터의 사용은 프로그램의 유연한 확장성 제공
구조체
- 하나 이상의 서로 다른 종류의 변수들을 묶어 새로운
데이터 타입
을 정의하는 것 =>클래스가 일종의 구조체사용하는 이유
- 연관된 변수들을 하나로 묶어 관리함으로써 데이터 관리에 유용
- 데이터 양(변수의 개수)이 많아지면 구조체가 유리구조체 정의하기
struct student {
char name[10];
int age;
int height;
}
- 구조체의 기본 형태
- struct 키워드는 구조체라는 데이터 타입을 의미
- student는 내가 만든 구조체의 이름
- name, age, height는 구조체 멤버
- 구조체 student는 사용자인 내가 정의한 새로운 데이터타입.구조체 멤버에 접근하기
- 구조체 변수를 통해 구조체 멤버의 값을 참조해야 한다.
- 멤버에 접근시 .을 사용하는데 이를 직접접근이라고 한다.
평가 문제
- 우체국에서 물건의 종류, 무게, 높이 등의 정보를 입력할수있도록 구조체 정의
#include <stdio.h>
#include <string.h>
struct objectBox{
char name\[10\];
int height;
int weight;
}st1
int main() {
strcpy(st1.name, "책");
st1.height = 30;
st1.weight = 2;
printf("이름 : %s, 높이 : %d, 무게 : %d\n", st1.name, st1.height, st1.weight);
return 0;;
}
공용체(union), 열거형(enum)
공용체
- 구조체와 동일하게 서로 연관된 서로 다른 타입의 데이터를 묶어 새로 정의한 타입
- 차이점은 메모리 공간을 공유한다.열거형
- enumeration의 약자. 연속된 데이터를 새로운 데이터타입으로 정의하고자할 때 주로 사용
- 데이터들을 열거한 집합
- 컴파일러는 열거형 멤버들을 정수형 상수 취급
enum Week{
sun = 0,
mon,
tue,
wed,
thu,
fri,
sat,
// sun을 기준으로 순서대로 0, 1, 2, 3 ... 값이 설정됨
}
동적 메모리 할당
메모리 구조
메모리 영역
- 메모리는 크게 코드/스택/힙/데이터 영역 총 4가지로 구분
동적 메모리 영역을 알아보자
- 코드 영역 : 실행할 명령어들이 순서대로 쌓인다 CPU가 이 영역에서 명령어들을 하나씩 가져다 처리
- 스택 영역 : LIFO
- 스택 구조(스택 메모리)를 사용하는 가장 대표적인 곳 : 함수의 지역 변수 및 매개 변수
- 힙 영역 : 큐. 컴퓨터 메모리의 일부가 할당되었다가 회수되는 일들의 반복.
- 힙은 컴파일 시가 아닌 실행 시 사용자로부터 할당 메모리를 입력 받음 (앞으로 많이 사용하게 될 영역)
- 데이터 영역 : 전역 변수와 static 변수가 저장되는 메모리 영역. 프로그램 종료시 소멸
- 동적으로 메모리를 할당하는 이유
- 일반 변수 선언 : 메모리 할당은 컴파일 타임에 이루어진다.
- 전교생이 10명인 학교의 학생 수를 배열로 선언한 후 학생 수가 늘어나게 된다면? -> 결국 학생 수는 유동적이므로 고정하지 말고 실행 시 결정하자
int num;
fputs("학생 수 입력 : ", stdout);
scanf("%d", &num);
int student[num];
- 문제점
scanf
는 런타임에 실행
int student[num]
은 컴파일 타임에 실행
- 런타임에 입력받은 변수를 컴파일 타임에 대입하는 형태는 내일 사용할 변수를 오늘 입력받는다는 것과 같은 논리이므로 시점 논리에 맞지 않음.
- 해결 방법 : 실행 중에 학생 수를 알아야 하는 경우 동적 메모리 할당 기법을 통해 해결 가능동적 메모리 할당 함수의 원형
void* malloc(size_t size);
- 할당받고 싶은 메모리의 바이트 수를 인자값으로 넘겨주면 해당 만큼의 메모리를 할당해서 리턴
- 리턴 타입이 void포인터로, 타입이 지정되지 않은 포인터임을 의미. 정수, 실수임을 특정하지 않고 더미로 받겠다.
- 당신이 원하는 메모리 크기만큼 할당해줄테니, 메모리는 당신이 원하는 형태로 정해서 사용하세요.
- 전달인자 size는 바이트 단위로 입력
- 메모리 할당이 되면 메모리의 주소값 리턴
- 메모리 부족시 NULL 포인터 리턴