C 언매니지드 프로그래밍
이 강좌는 선수 과목인 '프로그래밍 입문'에서 배운 절차적 프로그래밍 지식을 기반으로 C언어가 언매니지드 언어로서 가지는 기능들에 대해서 알 아봅니다
배울 내용
- C 언어 사용법
- 하드웨어 동작 원리
- C 언어가 언매니지드 언어로서 가지는 기능들
요구 사항
- "프로그래밍 입문(C#)" 과목 수료
- "컴퓨터 공학용 수학" 과목 수료
설명
본 비디오 강좌는 포큐아카데미에서 진행하는 COMP2200 수업의 비디오 강좌입니다.
C는 가장 널리 사용되는 언매니지드 언어들 중 하나이며, 2019년 7월 기준 전 세계에서 2번째로 많이 사용되는 언어입니다. (출처: TIOBE)
현존하는 프로그래밍 언어는 크게 매니지드(Managed) 언어와 언매니지드(Unmanaged) 언어로 나눠지며, 이 둘의 차이는 프로그래머가 컴퓨터 하드웨어를 직접 제어할 수 있는지의 여부입니다. (예: 프로그래머가 직접 메모리를 관리하는가?) 대표적인 언매니지드 언어인 C는 하드웨어와 매우 가깝다는장점으로 40년이 넘는 세월 동안 살아남았을 뿐만 아니라 아직도 컴파일러, 운영체제, 임베디드 시스템 등 저수준의 제어 및 메모리 절약이 요구되는 곳에 왕성하게 사용되고 있습니다. 그리고 이런 트렌드는 한 동안 바뀌지 않을 전망입니다.
프로그래머의 지속적인 성장에 반드시 필요한 지식 중 하나는 컴퓨터 하드웨어에 대한 이해입니다. C는 대부분의 매니지드 언어와 달리 언매니지드 언어 특유의 기능 (예: 메모리 관리) 들을 포함하고 있기 때문에, 하드웨어의 동작 원리를 공부하고 싶은 분 들, 혹은 컴퓨터를 더 잘 이해하고 싶은 분들에게 좋은 입문용 언매니지드 언어라고 할 수 있겠습니다.
이 강좌는 선수 과목인 '프로그래밍 입문'에서 배운 절차적 프로그래밍 지식을 기반으로 C언어가 언매니지드 언어로서 가지는 기능들에 대해서 알 아봅니다. 이 코스를 성공적으로 마무리한 분들은 하드웨어에 대한 더 넓은 시야를 갖출 수 있을 것입니다.
본 강좌는 첫 주에 '프로그래밍 입문'과목에서 배운 기초 프로그래밍 개념들이 C에 어떻게 적용되는지 살펴 본 뒤 다음과 같이 크게 세 부분으로 나뉘며, 강의 진행도 이 순서를 따릅니다.
- ANSI C/C89: C의 기본이 되는 내용과 C로 구현하는 자료 구조들. (~11주 차)
- C99: C99 표준에서 추가된 기능들 (12주 차 ~ 13주 차)
- C++1x: C11/18 표준에서 추가된 최신 기능들 (14주 차~)
위와 같이 강의를 세 부분으로 나눈 이유는 아직도 많은 C 프로젝트들이 89년도의 표준을 사용하기 때문이며, 이런 트렌드는 바뀌지 않을 전망이기 때문입니다. 따라서 모든 프로젝트에서 쓸 수 있는 C의 지식을 중심으로 배우되 가능할 경우 새로 추가된 기능을 사용할 수 있는 실력을 갖추게 하는 것이 강좌의 목표입니다.
이 강좌의 대상
- 컴퓨터 공학의 기본기를 배우고 싶은 분들
- 프로그래머로서 평생 커리어를 꿈꾸는 분들
강좌 콘텐츠
- C89 표준 (4:36)
- Hello World (1:22)
- #include, stdio.h (9:21)
- main(void) 함수 (15:43)
- printf() 함수 (6:41)
- 주석(comment) (1:41)
- 복습 퀴즈 1
- 복습 퀴즈 2
- C언어의 기본 문법 (9:44)
- 자료형, unsigned와 signed (4:36)
- char 형 (12:25)
- 복습 퀴즈
- short 형 (2:15)
- 영상 퀴즈
- int 형, long 형 (10:52)
- 복습 퀴즈
- float 형, double 형, long double 형 (8:19)
- 복습 퀴즈
- 코드보기: 기본 자료형 (2:47)
- C언어의 bool 형 (10:38)
- 열거형(enum) (5:13)
- 코드보기: 열거형 (3:24)
- 변수 선언 (2:18)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 연산자 (6:59)
- sizeof 연산자 (3:05)
- size_t (13:22)
- 역 참조 연산자 (2:55)
- 구조체/공용체 멤버 접근자 (2:39)
- 비교 연산자, 논리 연산자, 조건 연산자 (1:00)
- 복습 퀴즈
- 조건문과 반복문, if 문, switch/case 문 (9:00)
- 코드보기: switch/case (1:59)
- for 문, while 문, do while 문 (5:47)
- 코드보기: 조건문/반복문 (1:56)
- 복습 퀴즈
- 함수 (7:37)
- 함수 정의의 문제 (1:24)
- 함수 선언 (9:08)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 함수 매개변수 평가 순서, 피연산자 평가 순서 (20:10)
- 연산자 우선순위와 평가 순서 1 (1:02)
- 연산자 우선순위와 평가 순서 2 (3:18)
- 영상 퀴즈
- 평가 순서를 강제하는 연산자 (9:03)
- 복습 퀴즈
- 범위(scope) (11:20)
- 코드보기: 전역 변수 (3:40)
- 복습 퀴즈 1
- 복습 퀴즈 2
- const 키워드 (11:48)
- 복습 퀴즈
- goto 문 (9:00)
- goto 문은 정말로 악마인가요? (19:38)
- 코드보기: goto 문 (5:30)
- 복습 퀴즈
- 배열 (2:28)
- 코드보기: 배열 (2:04)
- 스택 메모리 (15:05)
- 스택 메모리에 대해서 간단히 알아보자! (23:58)
- 스택 메모리 안의 배열, 스택 오버플로 (10:11)
- 배열의 요소 개수 구하는 방법 (8:37)
- 길이가 명시된 매개변수 배열 (6:04)
- 매개변수 배열의 길이, 배열 요소의 초기값 (8:54)
- 다차원 배열 (5:50)
- 코드보기: 다차원 배열 (1:19)
- 정리 (2:07)
- 소스코드에서 실행파일까지, C 프로그램의 빌드 과정 (10:59)
- .h와 .c 파일 (5:48)
- 헤더 파일이 필요한 이유 (5:48)
- #include <>와 #include "" (2:32)
- 빌드 과정: 전처리 단계 (5:40)
- 트랜슬레이션 유닛 보는 방법 (2:51)
- 빌드 과정: 컴파일 단계 (5:03)
- 어셈블리어 코드 보는 방법 (5:18)
- 빌드 과정: 어셈블 단계 (2:37)
- 오브젝트 코드 보는 방법 (3:12)
- 빌드 과정: 링크 단계 (4:39)
- 링크 단계가 분리되어 있는 이유 (5:32)
- 라이브러리(library), 정적/동적 라이브러리와 링크 (7:41)
- 분할 컴파일과 전역 변수 (2:58)
- 다른 파일에 있는 전역 변수 사용 시 문제점 (4:38)
- extern 키워드 (7:25)
- 코드보기: extern 키워드 (4:57)
- 전역 변수의 문제, static 키워드 (9:04)
- 코드보기: static 키워드 (6:15)
- .c와 .h 파일 정리, 순환 헤더 인클루드와 해결법 (6:17)
- 인클루드 가드 작동법 (2:05)
- 인클루드 가드 예제 (5:00)
- C 컴파일러의 종류와 특징 (5:12)
- 정리 (4:08)
- 포인터 (pointer) (6:27)
- 주소 연산자 & (6:12)
- 복습 퀴즈
- 메모리 주소 저장하기 (4:53)
- 포인터의 의미 (1:14)
- 메모리 주소에 저장된 자료형 (3:13)
- 포인터 변수를 선언하는 방법 (1:59)
- 포인터 변수를 부르는 방법 (6:15)
- 포인터 변수의 실제 메모리 뷰 (3:17)
- 포인터의 비유: 현실 세계 예 (3:20)
- 다른 포인터의 예 (4:49)
- 포인터에 저장된 주소도 바꿀 수 있나요? (1:23)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 역 참조 연산자 * (4:06)
- 참조와 역 참조 (3:42)
- 역 참조를 이용한 값 변경 예 (3:57)
- 복습 퀴즈
- 포인터로 두 변수의 값 바꾸기 (4:50)
- 값에 의한 전달 vs 참조에 의한 전달 (3:58)
- 코드보기: Min, Max 한 번에 구하기 (5:02)
- 포인터와 함수 반환 값 (3:10)
- 댕글링 포인터(dangling pointer) (4:03)
- 널(NULL) 포인터 (4:53)
- NULL이 가지는 문제들 (4:34)
- 널 포인터는 언제 사용하나요? (7:52)
- 복습 퀴즈
- 포인터의 비교 (2:44)
- 포인터의 크기 (5:30)
- 포인터와 배열의 비교 (0:48)
- 배열 포인터에 대입하기 (4:01)
- 배열 속 각 요소의 위치, 각 요소의 위치 계산하기 (5:57)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 복습 퀴즈 3
- 배열 요소에 포인터로 접근하기 (3:31)
- 포인터 중간 정리, 포인터의 캐스팅 (3:31)
- 영상 퀴즈
- 딱 '한' 바이트만 옮기기 (2:52)
- 코드보기: int 메모리 뷰어 (2:29)
- 코드보기: 두 배열이 겹치는가? (6:22)
- 두 주소 간의 사칙연산 (2:47)
- 자바와 C#에서는 모든 것이 포인터다 (2:04)
- 포인터를 사용한 안전하지 않은 코드 (3:14)
- 포인터와 배열의 차이 (8:06)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 다시 만나는 연산자 결합 법칙 (2:41)
- 영상 퀴즈 1
- 영상 퀴즈 2
- 영상 퀴즈 3
- 영상 퀴즈 4
- 포인터와 연산자 우선순위 및 결합 법칙 (4:57)
- 동일한 우선순위를 갖는 연산자들 (1:27)
- 조금 더 빠른 배열의 요소 더하기 함수 (3:28)
- 왜 *p++이 더 빠르죠? (1:57)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 포인터와 const (1:49)
- 주소를 보호하는 const 포인터 (3:44)
- 값을 보호하는 const를 가리키는 포인터 (4:23)
- 두 const의 정리와 예 (1:01)
- 주소와 값 모두 지키는 const (1:07)
- const 포인터 읽는 방법 정리 (1:42)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 복습 퀴즈 3
- const는 절대 제거하지 말자 (3:03)
- 코드보기: 벡터 덧셈 (3:05)
- 포인터의 용도 (4:02)
- 포인터 배열 (4:45)
- 2차원 포인터 배열 (6:47)
- 코드보기: 2D 배열을 배열의 배열로 바꾸기 (6:50)
- 정리 (5:42)
- 문자열의 표현과 길이 (5:14)
- 문자열 관리 시 길이의 문제 (2:45)
- 문자열 길이 문제 해결방법 1 (5:09)
- 문자열 길이 문제 해결방법 2, C 스타일 문자열 (9:01)
- 영상 퀴즈
- C 스타일 문자열의 장단점, 문자열 길이 구하기 (19:44)
- 문자열 조작, 두 문자열의 비교 (6:53)
- 문자열 비교 알고리듬 (1:24)
- 더 효율적인 문자열 비교 함수 작성하기 1 (7:11)
- 더 효율적인 문자열 비교 함수 작성하기 2, strcmp()와 strncmp() (3:52)
- 복습 퀴즈
- 코드보기: 대소문자 구분없는 문자열 비교 (5:22)
- 문자열 복사, strcpy(), strncpy() (12:07)
- 문자열 합치기, strcat(), strncat() (6:08)
- 코드보기: 문자열 버퍼를 이용한 출력 (8:31)
- 복습 퀴즈
- 문자열 찾기 (7:01)
- 문자열 찾기 함수가 메모리 주소를 반환하는 이유 (4:38)
- 문자열 토큰화 (11:10)
- 복습 퀴즈
- 코드보기: 문자열을 대문자 또는 소문자로 바꾸기 (12:14)
- 출력, 서식 지정(formatted) 출력, 서식 문자열(format string) (8:00)
- 일반적인 서식 문자열 형식, 서식 지정자(format specifier) (17:55)
- 복습 퀴즈
- 코드보기: ASCII 표 그리기 (8:05)
- 코드보기: 바이트 단위 변환 표 (4:56)
- 서식 문자열이 필요한 이유, fprintf(), stdout, 버퍼링, sprintf() (10:08)
- 출력 함수의 안정성, 기타 출력 함수 (4:07)
- 정리 (4:14)
- 입력 (6:11)
- 한 글자씩 읽기, 한 글자씩 읽는 알고리듬 1 (5:55)
- getchar()와 EOF 키 (5:23)
- 한 글자씩 읽기 알고리듬 2, EOF 키는 어디 있나요? (7:35)
- 복습 퀴즈
- 코드보기: 공백(whitespace)과 줄 수 세기 (3:52)
- 한 줄씩 읽기, gets() (13:45)
- fgets()로 안전하게 한 줄 읽기 (9:36)
- 한 줄씩 읽는 방법이 유용한 경우 (1:44)
- 복습 퀴즈
- 한 데이터씩 읽기, scanf() (7:48)
- scanf()의 일반적인 서식 문자열 형식 (6:45)
- scanf() 사용 예 (5:25)
- 문자를 읽을 때 scanf()의 문제점과 해결책, clearerr() (9:49)
- 코드보기: 게임 전적 쓰고 읽기 (15:42)
- 복습 퀴즈
- 한 블록씩 읽기 (5:52)
- 파일 입출력 (1:33)
- 파일 열기 (7:49)
- 파일에 쓰기/읽기 예, fflush(), 파일에 이어 쓰기 예 (8:25)
- 파일 닫기, 파일 오류처리, stderr, strerror(), perror() (14:45)
- 복습 퀴즈
- 코드보기: 파일 복사하기 (4:46)
- 파일 탐색 (14:26)
- 코드보기: 도돌이표 (8:17)
- 입출력 리디렉션 (9:22)
- 커맨드 라인 인자 (5:23)
- 복습 퀴즈
- 커맨드 라인 인자 메모리 뷰 (3:53)
- 코드보기: 제대로 된 파일복사 (3:39)
- 정리 (3:53)
- 구조체, 구조체의 필요성 (13:50)
- 구조체의 선언 및 사용 (6:30)
- typedef 이란?, typedef 사용법 (8:00)
- 구조체 변수 초기화 하기 (10:04)
- 구조체 매개변수 (12:12)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 함수 반환값으로서의 구조체, 구조체 배열 (8:50)
- 영상 퀴즈
- 얕은 복사, 깊은 복사 (9:49)
- 구조체 사용 시 포인터 저장의 문제 (7:01)
- 구조체를 다른 구조체의 멤버로 사용하기, 바이트 정렬 (14:36)
- 복습 퀴즈
- 코드보기: 점, 선, 직사각형 (14:16)
- 비트 필드 (8:38)
- 공용체 (5:41)
- 코드보기: 색상 표현하기 (6:52)
- 메모리 공유만을 위한 공용체의 예 (5:38)
- 복습 퀴즈
- 함수 포인터, 함수를 변수에 저장할 수 있을까? (10:45)
- 함수를 매개변수로 전달할 때 필요한 것들, 함수 포인터 선언 (10:40)
- 함수 포인터 읽는 방법, 오른쪽-왼쪽 규칙(Right-Left Rule) (7:11)
- 함수 포인터 쉽게 읽기 (4:58)
- 복습 퀴즈
- 코드보기: 콜백 함수 (14:31)
- 배열의 포인터, 퀵 정렬, void 포인터 (15:54)
- 코드보기: 구조체를 사용한 퀵 정렬 (10:08)
- 코드보기: 기수(radix) 정렬 (11:35)
- 정리 (8:10)
- 메모리의 종류 (9:40)
- 스택 메모리 (1:57)
- 레지스터 (7:39)
- 어셈블리어로 보는 레지스터 (5:55)
- register 키워드 (10:55)
- 힙 메모리 (17:23)
- 동적 메모리 (6:11)
- 메모리 할당 및 해제 함수, malloc() (3:31)
- free(), malloc() 사용 예 (19:19)
- 동적 메모리 할당 시 문제 (11:10)
- 복습 퀴즈
- free()는 몇 바이트를 해제할지 어떻게 알지?, calloc(), memset(), realloc() (13:54)
- realloc()의 메모리 누수 문제, memcpy() (8:30)
- 복습 퀴즈
- memcmp(), 정적 vs 동적 메모리 (16:13)
- 동적 메모리의 소유권 문제 (12:05)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 다중 포인터, 이중 포인터 (10:20)
- 영상 퀴즈
- 다중 포인터를 쓰는 이유, 다중 포인터 예 (8:59)
- 코드보기: 단어 정렬 (5:15)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 복습 퀴즈 3
- 정리 (6:19)
- 자료구조 기초 (18:55)
- 배열, 배열의 삽입 (8:30)
- 배열의 삭제 (4:26)
- 배열의 검색, 배열의 접근 (3:16)
- 복습 퀴즈
- 코드보기: 빠른 배열 (6:46)
- 스택(stack) (6:53)
- 스택의 삽입 (1:56)
- 스택의 제거 (2:20)
- 스택의 검색 (4:14)
- 스택의 용도 (9:00)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 큐(queue) (5:05)
- 큐의 삽입 (3:48)
- 큐의 삭제 (2:18)
- 큐의 검색 (2:39)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 복습 퀴즈 3
- 연결 리스트, 연결 리스트의 삽입/제거/검색 (10:10)
- 연결 리스트: 전체 출력 예 & 노드 메모리 해제 예, 헤드 노드, (9:40)
- 연결 리스트: 삽입하기 예 (10:19)
- 연결 리스트: 오름차 순으로 삽입하기 예 (8:48)
- 연결 리스트: 노드 삭제 (7:14)
- 연결 리스트의 용도 (7:16)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 복습 퀴즈 3
- 해시 테이블 (6:48)
- 해시 테이블의 크기는 2배 이상인 소수로 (6:09)
- 중복 색인 문제의 해결 (17:34)
- 복습 퀴즈
- 해시란 무엇인가? (11:20)
- 해시 테이블에 문자열 저장하기 (9:07)
- 해시 맵 (5:13)
- 해시 충돌과 훌륭한 해시 함수 (5:39)
- 해시 충돌 방지와 성능 향상 (15:27)
- 복습 퀴즈
- 코드보기: 여러 데이터형과 해시 함수 (6:14)
- 정리 (7:13)
- 복습 퀴즈
- 나만의 라이브러리 만들기 (6:12)
- 정적 라이브러리 만들기 (19:25)
- 동적 라이브러리와 링크 (6:17)
- 정적 vs 동적 라이브러리 (6:32)
- 복습 퀴즈
- C99 표준 (1:37)
- 인라인 함수 (4:52)
- 인라인 함수 제대로 사용하는 법 (4:46)
- 링킹 오류가 나는 이유 (5:30)
- 링킹 오류 해결법 (7:45)
- C++ 인라인과의 차이 (4:48)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 코드보기: 정적 인라인 함수 (7:38)
- restrict 키워드 (16:05)
- 복습 퀴즈 1
- 복습 퀴즈 2
- 한 줄 주석 (0:46)
- 변수 선언 (0:36)
- va_copy() (1:56)
- snprintf() (7:18)
- 새로운 자료형 long long int (3:22)
- 불(bool)형 (4:21)
- 고정 폭 정수형 (5:37)
- 허수를 표현하는 자료형 (3:37)
- IEEE 754 부동 소수점 지원 (1:49)
- 정리 (4:36)
- 부동소수점 예외 (14:24)
- Type-Generic 수학 (7:07)
- 가변 길이 배열 (5:21)
- 가변 길이 배열의 메모리 위치 (8:23)
- 복습 퀴즈
- 배열 색인 안의 static 키워드 (7:08)
- 복합 리터럴 (4:35)
- 가변 인자 매크로 (3:07)
- 유니버셜 문자 이름 (10:41)
- 멀티바이트 문자 (8:48)
- 다국어 지원의 역사 1탄 (5:00)
- 다국어 지원의 역사 2탄: wchar_t (14:53)
- 정리 (4:04)
- C11 (0:39)
- 유니코드 지원 (2:01)
- 다국어 지원의 역사 3탄: UTF-16/32 (11:03)
- 다국어 지원 접근 방법 (6:47)
- 새로운 안전한(?) 함수 (6:27)
- gets_s() (3:19)
- sprintf_s(), snprintf_s() (1:58)
- fopen_s() (1:44)
- strnlen_s() (2:51)
- strcpy_s() (4:53)
- strncpy_s() (1:41)
- _s 함수를 과연 써야 할까? (9:51)