제 4장 메모리
가. 메모리 영역의 구성 요소
메모리에는 여러 가지 영역이 있다. 그 중, 프로그램이 OS로부터 할당 받는 대표적인 메모리 영역은 크게 4가지 가 있다.
메모리의 낮은 주소(low memory)부터 높은 주소(high memory)까지 차례로
코드(Code) 영역, 데이터(Data) 영역, 스택(Stack) 영역, 힙(Heap) 영역이 존재한다.
나. 코드(Code) 영역
코드 영역에는 여러 데이터가 들어간다. 대표적인 것 들을 살펴보자면,
우리가 작성한 소스코드가 코드 영역에 저장이 된다. 물론 컴파일 된 기계어 형태로 저장이 된다. 또한, 상수 도 코드 영역에 저장이 된다.
다. 데이터(Data) 영역
데이터 영역은 프로그램 시작과 함께 메모리에 적재되며, 프로그램 종료 시 메모리에서 해제가 된다. 이러한 특성을 가지고 있는 전역 변수와 정적 변수가 데이터 영역에 저장이 된다. 또한, 구조체도 데이터 영역에 저장이 된다.
참고로, 초기화 되지 않은 데이터는 BSS(Block Stated Symbol) 영역에 저장이 되고, 초기화 된 데이터만 데이터 영역에 저장된다.
라. BSS 영역
앞에서 서술한 대로 BSS(Block Stated Symbol) 영역에는 초기화가 되지 않은 데이터 들이 저장이 된다.
BSS영역에는 실제 변수가 차치할 공간이 할당되지 않아 그 만큼 binary size가 작아진다.
마. 스택(Stack) 영역
스택 영역은 함수 호출과 관계가 있는 각종 변수 가 저장되는 영역이다. 함수가 호출될 때 스택에 함수의 매개변수, 호출이 끝난 뒤 돌아갈 반환 주소 값, 해당 함수에서 선언이 된 지역 변수가 저장이 된다. 이렇게 스택 영역에 저장되는 함수의 호출 정보를 스택 프레임이라 한다.
1 |
|
아래 그림은 위 예제 코드에 의한 스택 프레임의 변화이다.
바. 힙(Heap) 영역
메모리의 힙 영역은 사용자가 직접 관리하는 영역이다. 힙 영역은 사용자가 필요할 때 할당해서 쓰고 다 쓰면 해제된다. 힙 영역은 스택 영역과 다르게 낮은 주소에서 높은 주소로 메모리가 할당된다.
제 5장 메모리 동적 할당
c언어에서 메모리를 동적으로 할당할 때에는 malloc 함수를 사용하고, 원형은 다음과 같이 생겼다.
1 |
|
이 함수는 할당 받을 바이트 수를 인수로 받은 뒤, 힙 영역에서 메모리 크기에 맞고, 아직 할당되지 않은 적당한 블록을 찾아서 할당을 한다. 그렇게 찾은 블록의 첫 번째 바이트 주소를 반환한다. 반환 값이 주소 값이기 때문에 해당 공간에 직접 접근할 때에는 포인터를 사용해야 한다.
제 6장 구조체
가. 구조체란?
구조체는 여러 가지의 자료형을 묶어 새로운 자료형을 만드는 것이다. 만약 점의 x, y좌표를 저장하고 싶다면 int/float/double같은 형태의 변수 2개 대신에 그 것들을 구조체로 묶어 하나의 자료형으로 만들 수 있다.
나. 구조체의 선언과 사용
구조체는 struct키워드로 선언한다. 선언문의 형태는 다음과 같다.
1 |
|
위에서 들었던 예시처럼 점의 좌표를 저장하는 구조체를 만들어보자.
1 |
|
이런 식으로 구조체를 선언한다.
점의 정보를 저장하는 변수를 만들고, 그 점의 x, y좌표 값에 접근해보자.
1 |
|
이런 식으로 값에 접근이 가능하다.
제 7장 열거형
가. 열거형이란?
열거형은 정수형 상수에 이름을 붙여준다. 만약 다음과 같이 상수 여러 개를 선언하면 귀찮아진다.
1 |
|
이럴 때 열거형을 사용하면 조금 더 편하게 선언할 수 있다.
나. 열거형의 선언
열거형은 다음과 같이 정의한다.
1 |
|
열거형은 선언만 하면 되는게 아니라 따로 변수도 선언해주어야 한다.
enum 열거형_이름 변수이름;
형태로 선언을 할 수 있다.
다. 열거형의 활용
열거형으로 요일을 정의해보자.
1 |
|
일단 이 코드는 2를 출력한다.
열거형은 첫 값만 할당을 해주면 그 아래에 있는 값들은 각각 1씩 증가하면서 자동으로 할당된다. 따라서 sun에 0을 할당해주면 그 다음에 있는 mon, tue, wed … 는 각각 1, 2, 3 …이 할당된다.
제 8장 파일 입출력
가. 파일 열기
파일을 열고 닫는 함수는 다음 2가지다.
1 |
|
위 함수를 쓰기 위해서는 FILE* 형 변수가 필요하다.
1 |
|
a.txt를 열고자 한다면
1 |
|
파일 경로는 만약 같은 폴더라면 파일 이름만, 아니라면 상대주소 혹은 절대주소로 표현한다.
나. 파일 열기 방식
모드 | 기능 | 파일 없음 | 파일 있음 | 기존 파일 보호 |
---|---|---|---|---|
r | 읽기 | 에러 | 기존 파일 이용 | 에러 |
r+ | 읽기/쓰기 | 에러 | 기존 파일 이용 | 덮어쓰기 |
w | 쓰기 | 새로 생성 | 새로 생성 | 덮어쓰기 |
w+ | 쓰기/읽기 | 새로 생성 | 새로 생성 | 덮어쓰기 |
a | 이어쓰기 | 새로 생성 | 기존 파일 이용 | 이어쓰기 |
a+ | 이어쓰기/읽기 | 새로 생성 | 기존 파일 이용 | 이어쓰기 |
다. 파일 읽어오기
파일을 읽어오는 함수 fscanf, fgets 2가지를 소개하고자 한다.
두 함수는 다음과 같이 사용한다.
1 |
|
fscanf의 첫 번째 인자는 stream의 이름을 적어주고, 나머지 인자는 표준 입출력의 scanf함수와 똑같다.
fgets는 첫 인자에 내용을 저장할 문자열을 넣고, 두 번째 인자는 읽어올 문자열의 길이, 세 번째 인자에 stream의 이름을 넣어주면 된다.
라. 파일 쓰기
파일을 읽어오는 함수 fprintf, fputs를 소개하겠다.
두 함수는 다음과 같이 사용한다.
1 |
|
fprintf는 첫 번째 인자에 stream이름이 들어가고, 나머지 인자는 printf함수와 똑같다.
Fputs는 첫 번째 인자에 내용을 적고, 두 번째 인자의 stream이름을 넣는다.
참고 문헌
- https://ko.wikipedia.org/wiki/%EB%B6%80%EB%8F%99%EC%86%8C%EC%88%98%EC%A0%90
- https://dojang.io/mod/page/view.php?id=480
- http://desire-with-passion.tistory.com/169
- http://tcpschool.com/c/c_pointer_intro
- http://tcpschool.com/c/c_memory_structure
- http://tcpschool.com/c/c_memory_stackframe
- https://blog.perfectacle.com/2017/01/25/c-ref-003/
- http://sfixer.tistory.com/entry/%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%ADcode-data-stack-heap
- https://kldp.org/node/122255