함수 포인터
함수 포인터의 사용
🔸함수명 앞에 *만 붙여주면 함수 포인터가 선언된다.
자료형 (*함수 포인터 이름)(인자목록);
int (*func)(int a);
🔸함수 포인터도 포인터이므로 주소값을 저장한다.
🔸형식은 함수이지만 함수가 아닌 주소값을 저장하는 포인터 변수일뿐이다.
🔸함수의 주소값만 저장하기 때문에 함수 포인터라고 한다.
🔸함수 포인터를 만들땐 함수의 자료형과 같아야 한다.
함수 포인터 선언해서 사용해보기
함수 포인터 반복문 돌면서 switch case 값에 따라 주소값 바꿔서 printf() 찍어보기
🔥함수 포인터의 사용 이유
- 직접 함수를 호출하면 되는데 왜 복잡하게 함수 포인터를 사용할까?
- 메모리의 크기 및 위치가 결정되는 시점은 컴파일 타임 또는 런타임 시점이다.
- 컴파일 타임 시점에 크기나 위치가 결정되는 것은 정적 바인딩,
- 런타임 시점의 결정되는 크기나 위치는 동적 바인딩 되었다고 한다.
- visual studio code에서 사용되는 extension 들은 플러그인 방식으로 동작한다.
- 새로운 기능을 추가하게 되면 매번 다시 컴파일 해야하는 불편함이 있으나,
- 플러그인 방식을 사용하면 그럴 필요가 없다.
- 함수 포인터의 사용은 프로그램의 유연한 확장성을 제공한다.
구조체, 공용체, 열거형
구조체
🔸하나 이상의 서로 다른 종류(타입)의 변수들을 묶어서 새로운 데이터 타입을 정의하는 것
구조체를 사용하는 이유
🔸연관된 변수들을 하나로 묶어서 관리함으로써 데이터 관리에 유용하다.
🔸데이터 양(변수의 개수)이 많아지면 구조체가 유리하다.
예를들어 학생 정보 관리 시스템이라고 가정했을때,
- 이름, 나이, 성별 등의 정보들을 모두 변수로 선언
- 각각의 변수를 별도로 관리하면 연관성을 알 수 없다.
- 학생 수가 10명 이내로 적으면 커버가 되지만, 100, 200명으로 늘어나면 변수의 관리가 힘들어진다.
- => 구조체가 대안
- 학생 한 명을 그룹으로 지정하여 이름, 나이, 성별 등의 정보들을 그룹으로 묶는다. => 그룹이 구조체
구조체 정의하기
🔸구조체의 기본 형태 (학생 정보)
struct student {
char name[10];
int age;
int heigth;
}
- struct 키워드는 구조체라는 데이터 타입을 의미
- student는 내가 만든 구조체의 이름
- name, age, height는 구조체 멤버
❄️클래스가 구조체의 형태이고 클래스는 곧 데이터 타입을 새롭게 정의한 것이다.
🔸구조체 student는 사용자인 내가 정의한 새로운 데이터 타입니다.
선언된 구조체 변수의 형태
student st1;
student st2;
...
구조체 멤버에 접근하기
🔸구조체 변수를 통해 구조체 멤버의 값을 참조해야 한다.
[구조체 변수명].[구조체 멤버]
ex) st1.name, st1.age, st1.heigth
🔸멤버에 접근시 .(점)을 사용하는데, 이를 직접 접근 연산자라고 한다.
공용체
🔸공용체도 사용자 정의 자료형이다.
🔸구조체와의 차이점은 메모리 공간을 공유한다는 점이다.
🔸타입스크립트에서도 타입을 공유하는 것이 있다.
union unTemp {
char a;
int b;
double c;
}
❄️구조체와 차이점은 메모리를 공유한다는 점이다.
열거형
🔸열거형은 enumeration의 약자로 enum(이넘)이라고 읽는다.
🔸데이터들을 열거한 집합이다.
🔸구조체, 공용체와 같이 직접만든 사용자 정의 타입
🔸구조체 공용체 : 연관된 데이터
🔸열거형은 연속적인 데이터로 성격이 조금 다르다.
🔸컴파일러는 열거형 멤버들을 정수형 상수로 취급한다.
enum Week {
sum = 0,
mon,
tue,
wed,
thu,
fri,
sat
};
🔸열거형의 멤버들은 각 요일을 나타낸다.
🔸첫 번째 멤버 sun을 0으로 설정하면 다음 멤버 mon은 1씩 증가한다.
메모리 구조
메모리 영역
🔸메모리는 크게 코드영역, 스택영역, 힙영역, 데이터영역 총 4가지로 구분
🔸코드영역
- 실행할 명령어들이 순서대로 쌓인다.
- CPU가 이 영역에서 명령어 들을 하나씩 가져다 처리한다.
🔸스택영역
- 스택이란 모든 원소들의 삽입, 삭제를 한쪽 방향에서만 수행하도록하는 선형 자료구조이다.
- 이를 후입선출방식(LIFO)이라고 한다.
- 지역변수 및 매개변수 등은 모두 스택 메모리 사용
🔸힙영역 == 큐
- 힙은 컴퓨터 메모리의 일부가 할당되었다가 회수되는 일들의 반복
- 힙은 컴파일 시가 아닌 실행 시 사용자로부터 할당 메모리를 입력받음 => 동적메모리
🔸데이터영역
- 전역변수와 static 변수가 저장되는 메모리 영역
- 이 메모리는 프로그램 종료 시 소멸
동적으로 메모리를 할당하는 이유
🔸일반 변수 선언 - 메모리 할당은 컴파일 타임에 이루어진다.
🔸예로 학생수는 유동적이므로 그때마다 이미 선언된 변수 크기 선언을 계속 바꿔주기 어렵다.
🔸따라서 고정으로 변수 크기를 선언하는 것이 아니라 실행시 결정하게 코드를 짜자.
💢scanf()함수로 받아서 쓰는것은 문제점이 있다. scanf는 런타임에 실행되고, 배열변수 선언은 컴파일타임에 실행된다. 따라서 런타임에 입력받은 변수를 컴파일 타임에 대입하는 형태는 시점 논리에 맞지 않음 |
🔸실행 중 학생수를 알아야 하는 경우, 동적 메모리 할당 기법을 통해 문제 해결이 가능하다.
동적 메모리 할당 및 해제
🔸동적 메모리 할당 함수의 원형
void* malloc(size_t size);
- 전달인자 size는 바이트 단위로 입력한다.
- 메모리 할당이 되면 메모리의 주소값을 리턴한다.
- 메모리 부족 시 NULL 포인터를 리턴한다.
- void*의 의미: 타입이 지정되지 않은 포인터
- malloc()은 힙메모리에 저장한다.
✨C언어에서 gc를 free()함수로 사용하고 gc를 해주지 않으면
메모리누수, 메모리릭 현상이 발생한다.
객체지향에 대한 이해
왜 객체지향 철학을 이해해야 하는가?
🔸자바스크립트가 객체를 사용하는 객체 기반 언어이다.
🔸객체를 생성하는 원리를 이해하면 객체를 더욱 잘 사용할 수 있다.
🔸타입스크립트와 리액트 기반에서 필요하다.
객체지향이란?
🔸객체: 영문으로 Object, '사물'을 나타내는 추상적인 개념
🔸지향: 영문으로 Oriented, '~를 향한다'는 의미
🔸이 세상의 모든 사물을 프로그래밍화 시키겠다는 의미❗
구조적 프로그래밍과 객체 지향 프로그래밍
✨구조적 프로그래밍 방식 - 순차적, 하향식, 폭포수 방식이라고 한다.
🔸기능적인 기본 단위는 함수이다.
🔸시퀀스가 한 쪽 방향으로 흘러가는 프로그래밍 방식
🔸건축과 비슷하다고 생각하면 되는데, 건축도 설계를 시공하면서 변경하기가 어렵듯
구조적 프로그래밍도 설계를 완벽하게 해야한다. (도중에 변경하기가 어렵다.)
🔸그래서 요구사항 변경이 있을 수 있는 요즘의 소프트웨어와 잘 맞지 않다.
✨객체지향 프로그래밍 방식
🔸기능 단위는 객체이다.
🔸유연하기 때문에 구조적방식과 다르게 요구사항 변경에 용의하다.
🔸대표적인 예가 이벤트 기반의 모든 윈도우 프로그램이다.
추상화
🔸추상: 대상에서 특징만을 뽑아낸 것
🔸우리 일상의 사물들은 관념적이고 추상적인 것들이 많다.
🔸플라톤의 이데아(Idea)는 추상화 개념과 일맥 상통한다.
캡슐화
🔸은닉하다, 숨긴다는 의미
🔸캡슐화하는 것은 외부에서 그 내부를 볼 수 없게 한다는 의미
🔸마냥 숨기기만 한다면 데이터는 무용지물임
🔸외부로부터 데이터를 조작할 인터페이스가 필요
클래스 = 데이터 + 메소드 |
클래스
🔸클래스는 사용자 정의 데이터타입이다.
🔸데이터와 메소드를 사용자인 내가 새로 정의한 테이터타입이기 때문에
클리스를 추상적인 데이터타입이라고 함
🔸클래스 본질은 데이터타입(Data Type)이라는 점이다.
🔸구조체와 비슷하다.
🔸멤버 변수와 멤버 함수로 구성된다.
클래스의 구성
🔸사물의 특성을 정리하여 필드의 메소드로 표현하는 과정이 추상화
🔸추상화된 결과를 하나의 클래스에 포함시키고 스스로 보호하는 것을 캡슐화
클래스의 선언 형식
🔸클래스 선언 시 class 키워드를 쓰고, 그 뒤에 클래스 이름을 붙인다.
🔸클래스의 요소로는 생성자, 멤버변수, 메소드 등으로 구성한다.
접근지정자
C#을 통한 클래스 선언
객체의 생성
🔸클래스는 데이터타입이라고 얘기했으니 변수선언과 같이
int a; char a; 처럼 Dog a; 로 사용하여 선언 할 수 있다.
🔸Dog a; 는 변수가 아닌 객체로 부른다.
🔸객체는 힙메모리에 저장
🔸말록은 데이터 사이즈를 사용자가 입력해줘서 사용하지만,
클래스 생성은 new로 선언했을때 자동으로 계산해서 사용할 수 있게 해준다.
Dog a = new Dog();
C#
생성자의 개념
🔸모든 변수는 선언이 되면 값을 초기화해야 한다.
🔸객체도 본질적으로 변수이므로 선언되면 초기화해야 한다.
🔸객체 생성 시 초기화 전용 메소드를 제곡하는데 바로 생성자(constructor)이다.
🔸객체 생성시 자동으로 호출되는 메서드
C#
상속성
🔸현실 세계의 상속개념
🔸이미 완성된 클래스를 다른 클래스에 상속할 수 있다.
🔸부모 클래스로부터 상속을 받을 때 C++,C#은 클래스 이름 끝에 콜론(:),
자바, js의 경우 extend를 붙인 후 부모클래스의 이름을 적는다.
C++, C#
접근지정자 클래스이름 : 부모클래스 {
// 멤버목록
}
C# 에서 상속에 대해 살펴봤다.
💢강의에서 각 변수들을 private로 설정했더니 오류가나서 protected로 바꾸고 오류가 다 사라졌다. private는 클래스 내부에서만 접근가능해서 외부에서는 절대 접근 불가능하다. 그러므로 외부에서는 접근이 불가능하고, 자식은 접근가능하게 접근지정자를 protected로 설정해주어야 한다. |
🔸프로젝트 관점에서 상속개념
- A 프로젝트 (종료됨)
- B 프로젝트 (신규과제)
- A 프로젝트 기능이 B 프로젝트의 기능과 유사함
- B프로젝트는 A프로젝트를 상속받고 추가 기능만 구현하면 됨
다형성
🔸함수의 이름이 같더라도 전달인자나 타입이나 갯수에 따라 구분된다.
🔸객체지향에서는 대표적으로 오버로딩(overloading)과 오버라이딩(overriding) 기법이 있다.
오버로딩 (overloading)
🔸사전적 의미는 '과적하다', '적재하다'라는 의미를 가지고 있다.
🔸겉모습은 똑같지만 내용이 다른 경우
🔸이름이 같은 함수일지라도 전달인자 타입이나 갯수가 다른 경우
🔸스타크래프트 오버로드 유닛의 예
C# 오버로딩 예제
오버라이딩 (overriding)
🔸오버라이딩은 '위로 올라탄다', '엎어친다'는 의미를 갖는다.
🔸무언가에 올라타서 기존의 것을 덮어 버린다는 개념
🔸상속의 개념이 기반이 되어야 한다.
✨자바나 js같은 경우엔 클래스 오버라이딩시 부모 함수와 똑같이 선언하여 변경하면 되는데, C#같은 경우에는 부모의 함수 접근지정자앞에 virtual, 자식의 함수 접근지정자와 타입사이에 override를 명시하여 사용하여야 오류가 없이 출력된다. |
🔥부모 클래스에 자식 클래스 재할당해서 사용하면
오버라이딩에 의해 함수가 자식 함수로 변경되어 출력된다.
인터페이스에 관하여
인터페이스란?
🔸인터페이스란 메소드의 목록만을 가지고 있는 명세(Specification), 사용자 정의 타입이다.
🔸메소드의 목록만 선언하고 구현은 하지 않는다.
🔸인터페이스의 선언형태
🔸메소드의 목록을 선언 후 자식 클래스에서 상속을 해주고
자식 클래스에서 반드시 오버라이딩을 구현해야한다.
🔸인터페이스는 독립적으로 사용할 수 없다.
🔸인터페이스끼리도 기반인터페이스를 상속 할 수 있지만 필요하면 상속하고 없으면 생략해도된다.
// 인터페이스 선언형태
접근지정자 interface 이름 (: 기반인터페이스 // 있으면 사용 없으면 생략) {
메서드 목록
}
// 인터페이스를 상속받는 클래스의 형태
접근지정자 class 자식클래스 이름 : 인터페이스 이름 {
상속받은 인터페이스 메서드 오버라이딩
}
인터페이스를 사용하는 이유
🔸인터페이스는 본체가 정의되지 않는 추상메소드만 갖는다.
🔸인터페이스의 목적은 기존의 기능을 추가하거나 수정의 개념보다는
동일한 개념의 기능을 새롭게 구현하는 기능이다.
🔸공동작업 시 표준을 정하는 역할
추상 클래스를 상속하는 경우
🔸일반적으로 클래스를 상속하는 이유는 기능의 확장이 목적이다.
스마트폰을 예시로 들때, 스마트폰의 기본 기능들이 있으면 그 기능들을 추구하는 바에 맞게 확장시켜 삼성폰이나 아이폰으로 출시하는 경우를 생각할 수 있다. |
인터페이스를 상속하는 경우
🔸스마트폰의 기능 목록: 통화, 문제, 와이파이, 블루투스, 멀티미디어, ...등
🔸스마트폰과 상속 관계의 개념이 아니라 여러가지 기능의 나열
🔸인터페이스에서 기능을 명세하고, 자식클래스에서 상속한다.
🔸다중상속 가능
// 인터페이스 예
interface 통화기능 {
}
interface 문자메세지기능 {
}
interface 와이파이기능 {
}
interface 멀티미디어기능 {
}
interface 블루투스기능 {
}
// 스마트폰의 기본 설계를 위한 interface 다중상속
class 스마트폰_기본 : 통화기능, 문자메세지기능, 와이파이기능, 멀티미디어기능, 블루투스기능 {
통화기능구현
문자메세지구현
와이파이구현
멀티미디어구현
블루투스구현
}
이어지는 스마트폰의 예시로, 스마트폰의 기본 기능들의 앞 단에서 이루어지는 일들을 의미한다고 생각하면 된다. 인터페이스로 표준을 정하고 상속하여 거기서 원하는 메소드들을 오버라이딩하여 원하는 메서드로 사용하게 할 수 있는 설계를 위한 전 단계이다. 💢꼭 설계를 위한 전 단계보다도 중간 구현단계에서도 필요에 의해 새로운 기능을 명세할 때 사용한다. |
클래스와 인터페이스 간의 UML
인터페이스 코드 작성
🔸인터페이스를 생성하고, 인터페이스로부터 상속받은 클래스를 구현
🔸스타크래프트 게임의 3종족들의 유닛 기능 - 공격과 이동 등
🔸공격과 이동은 유닛의 필수 기능
🔸유닛 중에 저글링과 드라군 2개의 유닛을 인터페이스를 구현
메모리 관리
🔸플랫폼 기반의 객체 지향 언어는 가비지 컬렉터가 메모리를 자동 관리한다.
🔸백그라운드에서 더 이상 사용되지 않는 메모리를 찾아 회수한다.
🔸new 연산자로 생성하는 객체의 데이터는 힙메모리에 생성되기 때문에 동적 할당이 된다.초기 상태:
✨ 초기상태: [A][B][C][D][E][F][ ][ ][ ][ ] 여기서 A, B, C, D, E, F는 데이터를 나타내고, [ ]는 빈 공간 ✨ 단편화 발생: [A][ ][C][ ][E][ ][ ][B][ ][F] 일부 데이터가 삭제되고 새로운 데이터가 추가되면서 메모리/디스크 공간이 단편화됨 ✨ 외부 단편화: 위 상태에서 [ ]로 표시된 빈 공간들이 외부 단편화이다. 이 작은 빈 공간들은 개별적으로는 너무 작아서 새로운 큰 데이터를 저장하기 어렵다. ✨ 컴팩트(압축) 과정: [A][C][E][B][F][ ][ ][ ][ ][ ] 컴팩트 과정을 통해 데이터를 연속적으로 재배치하여 큰 빈 공간을 만든다. ✨ 결과: 컴팩트 후에는 연속된 큰 빈 공간이 생겨 새로운 데이터를 효율적으로 저장할 수 있게 됨 이 과정을 통해 단편화로 인한 공간 낭비를 줄이고 메모리/디스크 사용 효율을 높일 수 있다. |
람다를 통한 화살표 함수의 이해
익명 메소드
🔸메소드를 미리 정의하지 않고 사용할 때 정의한다.
🔸익명 메소드를 사용하면 코드가 간결해진다.
🔸익명 메소드는 별도의 메소드를 만들지 않으므로 코딩 오버헤드를 줄일 수 있다.
🔸익명 메소드는 내용 자체가 복잡하면 안된다.
🔸익명 메소든느 람다식에서 사용된다.
람다식이란
🔸기존 익명 메소드를 더욱 간결하게 만든다.
🔸코드를 짧고 간결하게 표현하는 것이 목적이다.
🔸일반메소드 기반
🔸익명메소드 기반
람다식 표현
🔸델리게이트 본체를 람다식으로 표현한다.
🔸델리게이트와 인수의 개수 및 타입은 일치해야 한다.
🔸익명 메소드의 식을 조금 더 간결하게 표현할 수 있는 것이 람다식
(인수) => 표현식 or 명령문
🔸delegate 키워드는 사라지며 람다식을 의미하는 => 기호로 대체된다.
🔸람다식 표현
'공부 > 타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js)' 카테고리의 다른 글
프론트엔드 기초: React + TypeScript(7)-타입스크립트 타입방법, 캡슐화, getter와 setter (0) | 2024.10.29 |
---|---|
프론트엔드 기초: React + TypeScript(6)-타입스크립트, 타입추론, 타입명시, 인터페이스, ?선택적 프로퍼티, 열거형 (0) | 2024.10.28 |
프론트엔드 기초: React + TypeScript(4)-포인터 변수 (0) | 2024.10.24 |
프론트엔드 기초: React + TypeScript(3)-프로그래밍 기본 원리(C언어를 통한) (3) | 2024.10.23 |
프론트엔드 기초: React + TypeScript(2) (2) | 2024.10.22 |