27-1 프로그래밍의 모듈화


- 일반적인 소프트웨어 공학에서 이야기하는 모듈은 하나의 파일이 될 수도 있고, 하나의 함수가 될 수도 있다.

extern int i;
- 키워드 extern은 전역 변수가 다른 파일에 이미 선언되어 있음을 알려준다.

- 키워드 static은 전역 변수가 다른 파일에서 사용될 수 없게 한다.

-링크는 파일간에 접근하는 변수가 어디에 있는지, 호출하는 함수가 어디에 있는지 연결해주는 작업이다.


27-2 헤더 파일의 구현과 유용성

- 헤더 파일은 #include 전처리기 지시가에 의해서 파일 내에 그대로 포함된다.

- < >을 사용하면 표준 디렉토리에서 표준 헤더 파일을 포함시킨다.
- " "을 사용하면 디렉토리를 직접 지정하는 것이 가능하다.(파일 이름만 적으면 현재 작업 디렉토리에서 찾는다.)

- 헤더 파일을 사용하면 파일들 사이의 변수와 함수에 extern 선언을 하지 않아도 된다.


27-3 조건부 컴파일

#if 조건1
내용1
#elif 조건2
내용2
#else
내용3
#endif

- 위의 구문으로 컴파일 할 대상을 지정할 수 있다.


#ifndef head
#define head

#endif

- 헤더 파일에 위의 구문이 삽입되어 있으면 다른 파일에서 중복 포함되더라도 한번만 포함시킨다.



'학부 전공 > C' 카테고리의 다른 글

26. 매크로와 전처리기  (0) 2010.07.16
25. 메모리 관리와 동적 할당  (0) 2010.07.16
24. 파일 입출력  (0) 2010.07.16
23. 구조체와 사용자 정의 자료형 2  (0) 2010.07.15
22. 구조체와 사용자 정의 자료형  (0) 2010.07.15

26-1 전처리기에 의한 매크로 처리

- 일반적으로 말하는 컴파일은 전처리 과정이 포함되어 있다.

- 전처리 과정은 소스코드중 #이 붙은 문장을 처리하는 과정이다.

- #이 붙은 문장을 전처리기 지시자 라고 한다.

- #define이 붙은 문장은 단순 치환 작업을 요청할 때 사용하는 지시자이다.

#define PI 3.14
- PI는 매크로 상수이고, 3.14는 대체 리스트 라고 한다.

- 이미 선언된 매크로를 다른 매크로 선언에서 사용할 수 있다.
- 대체 리스트 영역에서는 공백도 존재할 수 있다.


26-2 매크로를 이용한 함수

#define SQUARE(x) x*x
- 위와 같이 선언된 SQUARE(x)를 매크로 함수 라고 한다.

- 매크로 함수는 자료형에 독립적이며, 실행 속도가 빠르다.

- 함수의 크기가 작아야 매크로 함수로 쓰기에 적당하다.

- 단순치환이므로 괄호를 사용하지 않을 경우, 연산자 우선순위에 의해 착오가 생길 수 있다.

- 매크로에 의한 치환은 문자열 내에서는 이루어지지 않는다.
- 대체 리스트의 앞에 #을 붙이면 문자열로 치환된다.

- 토큰이란 컴파일러가 인식하는 의미를 지니는 문자나 문자열의 최소 단위 이다.

- ##은 토큰을 결합할 때 사용한다.

 * 표준 매크로
_FILE_ : 현재 소스 코드의 파일명을 나타내는 문자열
_TIME_ : 컴파일 시각을 "시: 분: 초"의 형태로 나타내는 문자열
_DATE_ : 컴파일 날짜를 "년 월 일"의 형태로 나타내는 문자열
_LINE_ : 현재 처리중인 소스파일의 행 번호를 나타내는 문자열


'학부 전공 > C' 카테고리의 다른 글

27. 모듈화 프로그래밍  (0) 2010.07.16
25. 메모리 관리와 동적 할당  (0) 2010.07.16
24. 파일 입출력  (0) 2010.07.16
23. 구조체와 사용자 정의 자료형 2  (0) 2010.07.15
22. 구조체와 사용자 정의 자료형  (0) 2010.07.15


25-1 C언어의 메모리 구조

- 프로그램이 실행되면 메모리에 데이터영역, 스택영역, 힙영역이 생긴다.

- 데이터 영역 : 전역 변수와 static변수가 저장 된다. 프로그램이 종료될 때까지 유지된다.
- 스택 영역 : 지역변수와 매개 변수가 저장된다. 해당하는 함수가 종료될 때까지 유지된다.
- 힙 영역 : 프로그래머가 관리하는 메모리 영역이다. 

- 배열 선언시 상수를 써야 하는 이유 : 스택과 데이터 영역에 할당될 메모리의 크기는 컴파일타임에 결정되어야 한다.

- 할당해야 할 메모리의 크기를 런타임에 결정해야 하는 경우, 힙 영역을 사용한다.


25-2 메모리 동적 할당

- 힙에 메모리를 할당하는 것을 동적 할당이라 한다.

void* malloc(size_t size);
- size만큼 메모리를 할당한다. 실패하면 NULL포인터를 리턴한다.

- 힙에 할당된 메모리 공간에는 포인터를 사용해서 접근해야 한다.

int* i = (int*)malloc(sizeof(int));
- void포인터로 리턴하고 있기 때문에 사용하기 전에 위처럼 형 변환을 해주어야 한다.

void free(void* ptr);
-해당하는 메모리 공간을 해제한다.

void *calloc(size_t elt_count, size_t elt_size);
- elt_size 크기의 변수를 elt_count 개수만큼 할당.



'학부 전공 > C' 카테고리의 다른 글

27. 모듈화 프로그래밍  (0) 2010.07.16
26. 매크로와 전처리기  (0) 2010.07.16
24. 파일 입출력  (0) 2010.07.16
23. 구조체와 사용자 정의 자료형 2  (0) 2010.07.15
22. 구조체와 사용자 정의 자료형  (0) 2010.07.15

24-1 파일의 open과 close

- 파일을 open한다는 것은 파일과 데이터를 주고 받을 수 있는 스트림을 생성한다는 의미이다.

FILE* fopen(const char* filename, const char* mode)

- 두번째 인자인 mode는 open하는 파일의 특징 및 용도를 결정한다.

 * 파일 접근 모드
- r : 읽기 가능
- w : 쓰기 가능, 파일이 존재하면 지워버리고 새로 쓴다.
- a : 쓰기 가능, 파일이 존재하면 그 뒤에 추가해서 쓴다.
- r+ : 읽고 쓰기 가능, 파일이 존재하면 그 위에 덮어 쓴다.
- w+ : 읽고 쓰기 가능, 파일이 존재하면 지워버리고 새로 쓴다.
- a+ : 읽고 쓰기 가능, 파일이 존재하면 그 뒤에 추가해서 쓴다.

 * 데이터 입출력 모드
- t : 텍스트 모드
- b : 2진 모드

- Carriage Return : 특수문자 \r로 표현되며, 커서의 위치를 줄 맨 앞으로 이동시킨다.
- Line Feed : 특수문자 \n으로 표현되며, 커서를 한 줄 아래로 이동시킨다.

- C의 소스코드에서의 \n은 텍스트 파일상에서 \r\n과 같은 의미이다. 텍스트 모드에서는 이 변환이 일어나지만 2진 모드에서는 일어나지 않는다.

- fopen함수의 리턴값은 파일 포인터이다.


int fclose(FILE * stream);
- 파일을 닫는다. 정상적으로 동작하면 0을 리턴한다.



24-2 파일 입출력 함수

- 문자,문자열 입출력 함수를 파일 입출력에 사용한다. 사용하는 스트림을 파일 포인터로 쓸 뿐이다.

int fprintf(FILE* stream, const char* format, ....)
int fscanf(FILE* stream, const char* format, ...)
-형식 지정 입출력 함수를 사용할 수 있다.

- 파일 포인터 내에는 파일 위치 지시자가 존재하여 어디까지 읽었는지/썼는지 알 수 있다.


24-3 파일의 끝

- 파일의 끝에서 fgetc, fscanf는 -1을, fgets는 0을 리턴한다.

- 함수 fgetc의 리턴 값을 char형에 저장할 경우, 숫자 -1과 EOF를 구별할 수 없게 된다. 따라서 int형에 저장해야한다.

int feof(FILE *stream);
- 파일의 끝에 도달한 경우 0이 아닌 값을 리턴한다.


24-4 Random Access 파일 입출력

- 파일 위치 지시자를 임의의 위치로 이동시킬 수 있다.

int fseek(FILE *stream, long offset, int wherefrom);
- 성공했을 경우 0을 리턴한다.
- wherefrom의 값은 0/1/2를 가지고, 각각 맨 앞/현재/맨 뒤를 의미한다.



23-1 구조체 변수의 전달과 리턴

- 함수 호출 시 구조체 변수를 인자로 전달하거나 리턴하는 것은 기본 자료형 변수로 하는 것과 동일하다.

- 구조체 변수도 값에 의한 전달, 참조에 의한 전달이 존재한다.


23-2 구조체의 유용함

- 구조체를 사용하면 자료를 관리하기가 쉬워진다.

- 구조체를 사용하면 함수의 리턴 값을 여러개 받을 수 있다.


23-3 구조체를 포함하는 구조체

- 구조체를 포함하는 구조체를 중첩된 구조체라 한다.

- 중첩된 구조체의 선언과 초기화는 일반적인 구조체와 동일하다.


23-4 새로운 자료형

- typedef 라는 키워드는 자료형에 새로운 이름을 붙이기 위해 사용된다.

struct position
{
int x;
int y;
};
typedef struct position POSITION;


typedef struct position
{
int x;
int y;
}POSITION;


23-5 공용체

-공용체는 서로 다른 자료형의 변수를 하나의 메모리 공간에서 사용한다.

-구조체의 크기는 멤버의 크기의 총 합이지만, 공용체의 크기는 가장 큰 멤버의 크기이다.

-공용체는 하나의 멤버만 의미있게 사용할 수 있다.


23-6 열거형

선언 : enum day {MON, TUE, WED, THU, FRI, SAT, SUN};

사용 : enum day today = MON;

- 변수 today는 열거형에 정의된 7가지 값들 중 하나를 가질수 있다. 각각의 값은 상수인데, 따로 값을 지정해주지 않으면 0부터 시작해서 자동으로 정해진다.



'학부 전공 > C' 카테고리의 다른 글

25. 메모리 관리와 동적 할당  (0) 2010.07.16
24. 파일 입출력  (0) 2010.07.16
22. 구조체와 사용자 정의 자료형  (0) 2010.07.15
21. 문자와 문자열 처리 함수  (0) 2010.07.15
19. 함수 포인터와 void 포인터  (0) 2010.07.14

22-1 구조체


-구조체란 하나 이상의 변수를 그룹 지어서 새로운 자료형을 정의하는 것이다.

struct position
{
int x;
int y;
};
- 여기서 position이 구조체의 이름이 되고, x와 y가 구조체 멤버가 된다.

- 선언할때는 struct 키워드를 꼭 붙여야 한다. ex) struct position p1;

- 구조체 멤버에 접근하기 위해서는 .연산자를 사용한다.

- 구조체 멤버는 배열과 같은 형태로 선언하면서 초기화 할 수 있다.


22-2 구조체와 배열과 포인터

- 구조체를 배열의 요소로 쓸 수도 있다.

- 구조체가 요소인 배열은 2차원 배열과 같은 구조로 생각할 수 있다.

- 구조체 포인터를 선언하여 구조체 변수를 가리킬 수 있다.
- 구조체의 맴버로 포인터 변수가 선언 될 수 있다.

- 구조체 변수의 주소 값은 첫번째 멤버의 주소 값과 일치한다.



'학부 전공 > C' 카테고리의 다른 글

24. 파일 입출력  (0) 2010.07.16
23. 구조체와 사용자 정의 자료형 2  (0) 2010.07.15
21. 문자와 문자열 처리 함수  (0) 2010.07.15
19. 함수 포인터와 void 포인터  (0) 2010.07.14
18. 다차원 배열과 포인터  (0) 2010.07.14

21-1 스트림과 데이터의 전송


- 스트림이 있어야 프로그램과 입출력장치 사이에 입력과 출력이 가능하다.

- 콘솔 입출력 스트림은 자동으로 생성되고, 자동으로 소멸된다.

- 파일 입출력 스트림은 직접 생성시키고, 소멸시켜야 된다.


21-2 문자 입출력 함수

int putchar(int c);
-문자 c를 화면에 출력한다.

int fputc(int c, FILE* stream);
-문자 c를 stream으로 출력한다.

int getchar(void);
-키보드로부터 한 문자를 입력받는다.

int fputc(FILE* stream);
-stream으로부터 한 문자를 입력받는다.


-위 함수들에서 오류가 발생하거나 파일의 끝에 도달했을 경우, EOF를 리턴한다.
-EOF의 실제 값은 -1이다.

-문자 입출력 함수들은 printf나 scanf와 비교하여 간단한 작업밖에는 할 수 없으나 그만큼 가볍고 메모리를 덜 차지한다.


21-3 문자열 입출력 함수

int puts(const char* s);
-문자열 s를 모니터로 출력한다. 그 후 줄을 바꾼다.

int fputs(const char* s, FILE* stream);
-문자열 s를 stream으로 출력한다. 줄을 바꾸지 않는다.

char* gets(char* s);
-문자열 s를 키보드에서 입력받는다.

char* fgets(char* s, int n, FILE* stream);
-문자열 s를 stream에서 길이 n만큼 입력받는다.

-gets는 선언한 배열보다 큰 길이의 문자열이 들어오면 오버플로우가 발생한다. 
fgets는 n까지만 읽어들인다.

-fgets는 항상 NULL문자를 삽입해 준다. n보다 긴 문자열이 입력될 경우, n-1까지만 읽고 n번째에는 NULL문자를 삽입한다.


21-4 표준 입출력과 버퍼

- 표준 입출력 함수를 사용하는 경우에는 버퍼를 제공받는다.

- 버퍼를 사용하는 이유는 성능 향상을 위해서이다. 버퍼에 모아두었다가 한꺼번에 처리하는 것이다.

int fflush(FILE* stream);
- 버퍼를 비우는 함수. 입력스트림은 내용이 전부 지워지고, 출력스트림은 즉시 출력된다.

- fgets함수를 사용할 때, 입력받은 문자열이 함수에서 지정한 n보다 크다면, 나머지는 버퍼에 그대로 남아있게 된다. 이 때, fflush함수를 쓰면 그것들을 전부 버릴수 있다.



21-5 문자열 조작 함수

size_t strlen(const char* s);
-문자열 s의 길이를 리턴한다. 문자열의 마지막에 있는 NULL문자는 포함하지 않는다.

char* strcpy(char* dest, const char* src);
-src의 문자열을 dest로 복사한다. dest의 길이가 더 작으면 오버플로우가 발생한다.

char* strncpy(char* dest, const char* src, size_t n);
-src의 문자열을 길이n만큼만 dest로 복사한다. 마지막에 NULL문자를 따로 삽입해주어야한다.

char* strcat(char* dest, const char* src);
-src의 문자열을 dest의 뒤에 추가한다. dest의 길이를 초과하는 결과가 나올경우, 오버플로우가 생긴다.

char* strncat(char* dest, const char* src, size_t n);
-stc의 문자열을 dest의 뒤에 길이 n까지 추가한다. (n은 합친 후의 문자열의 총 길이)

int strcmp(const char* s1, const char* s2);
-문자열 s1과 s2가 같으면 0을 리턴, s1이 크면 양수를 리턴, s2가 크면 음수를 리턴한다.
-문자열이 더 크다는 것은 아스키 코드값을 비교한 결과이다. 사전순으로 뒤에 있을수록 큰 문자열이다.

int strncmp(const char* s1, const char* s2, size_t n);
-strcmp와 같지만 길이 n까지만 비교한다.

int atoi(char *ptr);
-문자열을 int형 데이터로 변환

int atol(char *ptr);
-문자열을 long형 데이터로 변환

int atof(char *ptr);
-문자열을 float형 데이터로 변환



19-1 함수 포인터

- 함수 포인터란 메인 메모리에 올라와 있는 함수를 가리킬 수 있는 포인터.

- 함수의 이름은 함수의 위치를 가리키는 포인터

리턴형 (*포인터)(매개변수) ;

- 함수 포인터는 함수 처럼 사용 가능하다.


19-2 void 포인터

- void로 선언된 포인터는 어떤 값이건 담을 수 있다.

- 타입 정보가 지정되지 않았기 때문에, 값의 참조나 포인터 연산이 불가능하다.
- 형 변환을 거쳐서 메모리의 동적 할당시에 사용된다.


19-3 main 함수의 인자의 전달

void main(int argc, char **argv)

로 메인을 선언하면 인자를 받을수 있다.

- argc는 인자의 개수, argv는 문자열 배열의 이름이다.


'학부 전공 > C' 카테고리의 다른 글

22. 구조체와 사용자 정의 자료형  (0) 2010.07.15
21. 문자와 문자열 처리 함수  (0) 2010.07.15
18. 다차원 배열과 포인터  (0) 2010.07.14
17. 포인터의 포인터  (0) 2010.07.14
16. 다차원 배열  (0) 2010.07.14


18-1 2차원 배열의 이름


- 1차원 배열의 이름이 배열의 첫번째 요소를 가리키는 포인터인 것처럼, 2차원 배열의 이름또한 배열의 첫번째 요소를 가리키는 포인터이다.

- 2차원 배열의 이름은 포인터 연산 시 행 단위로 이동한다.

- 포인터의 타입에는 표인터 연산시 이동하는 구간에 대한 정보가 들어있다.

- 2차원 배열의 이름은 해당하는 배열의 열의 개수에 따라 다른 의미를 가진다.
(포인터 연산 시, 열의 개수만큼 이동하게 된다.)
-따라서 2차원 배열을 가리키는 포인터를 선언할 때에는 열의 개수를 알려줘야 한다.

int (*pnt)[열의 개수];

- 함수의 매개변수 선언 일때는 int pnt[][열의 개수] 형태의 선언이 가능하다.



'학부 전공 > C' 카테고리의 다른 글

21. 문자와 문자열 처리 함수  (0) 2010.07.15
19. 함수 포인터와 void 포인터  (0) 2010.07.14
17. 포인터의 포인터  (0) 2010.07.14
16. 다차원 배열  (0) 2010.07.14
14. 포인터와 함수  (0) 2010.07.14


17 포인터의 포인터

int **dpnt = &pnt;
- 포인터를 가리키는 포인터. 더블 포인터 라고 한다.

- call-by-value와 call-by-reference는 상대적으로 결정된다.
변수 입장에서는 call-by-reference이지만, 포인터 입장에서는 call-by-value가 되는 것이다.
포인터 입장에서 call-by-reference를 하려면, 더블 포인터를 써야 한다.

- 간단하게 생각하면, call-by-value는 진짜 값을 바꿀수 없는 것이고, call-by-reference는 진짜 값을 바꿀수 있는 것이다.

- 포인터를 요소로 가지는 배열의 이름은 더블 포인터이다.



'학부 전공 > C' 카테고리의 다른 글

19. 함수 포인터와 void 포인터  (0) 2010.07.14
18. 다차원 배열과 포인터  (0) 2010.07.14
16. 다차원 배열  (0) 2010.07.14
14. 포인터와 함수  (0) 2010.07.14
13. 포인터와 배열  (0) 2010.07.14

+ Recent posts