ANK Co., Ltd.| 김성훈 역| 성안당| 2006.09.14 | 256p | ISBN : 8931549288
- 전각 공백문자를 " "의 외부에 사용하면 에러가 발생합니다. 발견하기 어려우므로 주의합니다.
- 예약어 : auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while
- BCPL(Martin Richards) -> B(Ken Thomson) -> C(Dennis Ritchie) -> the C Programming Language(Kernighan & Dennis Ritchie)
- 선언과 대입을 동시에 하는 것을 "변수를 초기화한다"라고 합니다.
- 문자열 변수에 값을 대입할 때, "="을 사용할 수 있는 것은 초기화할 때 뿐입니다.
- \r : 복귀(CR)
- ASCII 코드(반각 영문자, 숫자), 2바이트 코드(전각)
- 정수끼리의 연산에서는 가장 범위가 넓은 자료 형으로 변환됩니다.
-
연산자 우선순위
연산자 계산방향 () [] .(피리어드, 구조체의 멤버 선택) -> ++(후치) --(후치) > ! ~ ++(전치) --(전치) +(부호) -(부호) &(포인터) *(포인터) sizeof < 캐스트 연산자 < * / % > + - > << >> > < <= > >= > == != > &(비트 연산) > ^ > && > | > || > ?:(3항 연산자) < = += -= *= /= %= &= |= ^= <<= >>= < ,(콤마) > -
윤년 : (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
-
- switch : 수치값만 가능
- %x : 16진수로 표기
- b = *p의 "*"와 char *p의 "*"의 의미는 다릅니다.
- 메모리 내용을 모드 같은 값으로 설정하는 memset()함수 : memset(buf, 0, 5)
- 메모리의 내용을 카피하는 memcpy()함수 : memcpy(dst, src, 5)
- int (*a)[4] : 배열 포인터, int *a[4] : 포인터 배열
- argv[0]가 가리키는 문자열의 내용은 시스템에 따라 달라집니다.
- fopen("filename", "mode")의 모드 : r, w, a, rb, wb, ab
- fread(buf, sizeof(short), 3, fp) : 바이너리 테이터를 읽을 때
- fwrite(buf, sizeof(short), 3, fp) : 바이너리 데이터를 써넣을 때
- c = getchar() : 키보드를 통해 입력된 한 문자만을 변수에 저장
- fseek(fp, 10, SEEK_SET) : SEEK_SET, SEEK_CUR, SEEK_END
텍스트 바이너리 모드 1바이트씩 처리(행바꿈 코드가 2바이트가 되는 경우 - windows - 주의) - typedef struct data {} DATA; DATA list; 에서 data - 구조체 템플릿, list - 구조체 변수, DATA - 구조체명
- 인수가 많은 경우, 값을 하나하나 전달하면, 그 때마다 데이터의 이동이 발생하지만, 참조 전달을 하게 되면, 구조체를 가리키는 포인터 하나만 넘기면 끝나기 때문에, 속도면에서도 유리합니다.
- static을 붙인 글로벌 변수를 선언하면, 변수의 유효 범위는 그 선언된 파일로 제한됩니다.
- static으로 선언된 로컨 변수는 프로그램이 실행을 시작할 때 만들어지고, 프로그랭이 종료할 때까지 값을 가진 채로 사라지지 않습니다.
- 함수의 인수가 const 선언이 되어 있는 경우, 그 변수의 값이 함수 안에서 변경되지 않는다는 것이 보증됩니다.
- #define DEBUG_MODE 와 같이 쓰면 "DEBUG_MODE가 정의되어 있다"는 사실을 나타냅니다.
- #define MINUS(x, y) ((x) - (y))
- #define MINUS (x, y) ((x) - (y)) // error
-
Microsoft C 컴파일러
- /GS : Pentium 프로세서에 최적화된 코드를 생성합니다.
- /Ot : 처리 속도를 우선하여 최적화합니다.
- /Os : 실행 파일의 크기를 최소화하는 것을 우선하여 컴파일합니다.
- 공용체 : 멤버의 값을 사용할 때는 반드시 "마지막에 대입한 멤버"를 참조하십시오. 동일한 기억 장소를 공유하기 때문에, 순서가 달라지면 값을 보증할 수 없습니다.
-
열거형 : int형의 정수식에 이름을 붙일 수 있습니다.
- enum _month { January, February, March, .. December} month;
- month = March;
- ^ : xor
- << >> : shift logical left / right
-
현재 시각 알아내기
- time_t ct;
- ct = time(NULL); // 그리니치 표준시로, 1970/1/1 00:00:00일 때부터 현재까지의 경과 시간을 초 단위로 반환합니다.
-
알아온 시각 변환하기
- struct tm *now; // time.h에 정의된 구조체
- now = localtime(&ct);
- tm구조체 : tm_sec, tm_min, tm_hour, tm_mday, tm_mon(0-11), tm_year(-1900), tm_wday(0-6), tm_yday(0-365), tm_isdst(서머타임 적용될 때 0이외의 양수값, 적용 않될 경우 0, 확실치 않은 경우 음수값. DST(Daylight Saving time)의 계산은 미국 법률에 따름
-
localtime() : time_t형 변수 -> tm 구조체
- time_t t;
- struct tm *ptmtime - localtime(&t);
-
gmtime() : time_t형 변수 -> tm 구조체 (시차를 고려하지 않음)
- time_t t;
- struct tm *ptmtime = gmtime(&t);
-
mktime() : tm 구조체 -> time_t
- struct tm tmtime;
- tmie_t t = mktime(&tmtime);
-
asctime() : tm 구조체 -> 문자열
- struct tm tmtime;
- char *s = asctime(&tmtime);
-
ctime() : time_t형 변수 -> 문자열
- time_t t;
- char *s = ctime(&t);
-
난수 만들기 : #include <stdlib.h>
- srand(time(NULL));
- n = rand();
-
qsort() : #include <stdlib.h>
- int nums[] = {4, 6, 1, 3};
- qsort(nums, 4, sizeof(int), compare);
- int compare(const void *a, const void *b)
- {
- int x = *((int *)a);
- int y = *((int *)b);
- if(x > y)
- return 1;
- else if(x < y)
- return -1;
- else
- return 0;
- }
-
bsearch() : 배열(단, 정렬되어 있을 것)에서 지정한 데이터를 찾음
- #include <stdlib.h>
- const int a = 1;
- bsearch(&a, nums, 4, sizeof(int), compare); // compare는 위 정의와 같음
- C언어는 하향식(Top-down)설계, 프로그래머 지향적이다.
-
fgets() 함수는 행바꿈 문자도 읽기 때문에, 행바꿈 문자를 삭제해 둡니다.
- string[strlen(string) - 1] = '\0';
-
다양한 C언어
- Borland C++ builder(무료) : http://www.borland.com
- LSI C-86(시험판 무료) : http://www.lsi-j.co.jp MS-DOS(64KB제한)에서 사용가능
- cygwin : http://sources.redhat.com/cygwin 윈도우에서 리눅스 사용하기
-
Visual C++의 커맨드 프롬프트에서의 개발
- 커맨드 프롬프트 안에서 Visual C++를 인스톨한 폴더의 bin폴더 속에 있는 VCVARS32.BAT를 실행하여 주십시오. 그러면 컴파일에 필요한 환경 변수가 설정되어 컴파일러 등의 툴을 사용할 수 있게 됩니다.
- 커맨드 프롬프트에서의 컴파일은 cl.exe를 사용합니다.
- 프로그램을 구성하는 파일이 복수일 경우는, 그 파일들을 각각 컴파일해서 링크해야만 합니다. 이 과정을 자동적으로 수행하려면 파일 구성이나 그 순서들을 기술한 메이크파일이 필요합니다. 메이크 파일의 작성 방법은 상당히 복잡하기 때문에 지면을 할애해야겠지만, 프로젝트가 만들어져 있다면, 메뉴의 [Project] - [Export Makefile] 을 이용하여 자동적으로 생성할 수도 있습니다. Visual C++의 메이크 프로그램은 nmake.exe라는 이름의 프로그램입니다. "nmake <메이크 파일>"이라고 입력하면 프로그램을 빌드할 수 있습니다.
-
Visual C++ 디버거 단축키
- 브레이크 포인트 설정(F9)
- 디버그 실행(F5)
- 스텝 오버(F10) : 소스 프로그램을 한 줄씩 실행하며 진행합니다.
- 스텝 인(F11) : 다른 함수를 호출하고 있을 때, 그 함수 속에 들어갑니다.
- 스텝 아웃(Shift + F11) : 현재 실행 중인 함수를 벗어납니다.
- 커서 앞까지 실행(Ctrl + F10) : 커서가 있는 위치에서 프로그램이 정지합니다. 단, 브레이크 포인트가 있을 경우는 그 위치에서 정지합니다.
-
error C1010 : unexpected end of file while looking for precompiled header directive
- Visual C에서 precompiled header를 '*.c'혹은 '*.cpp'파일에 include하지 않은 경우에 발생하는 에러입니다.
- 소스 파일에 #include "stdafx.h"를 추가합니다.
- 프로젝트 세팅을 변경합니다.
project-Setting-c/c++ tab - Project Option text box에서 /Yu"stdafx.h" 부분을 찾아 삭제합니다. 이렇게 하면 precompiled header를 사용하지 안게 되므로 에러가 발생하지 않습니다.
-
error C2143 : syntax error : missing ';' before '}'
error C1004 : unexpected end of file found- '{'와 '}'의 쌍이 맞지 않는 경우에 발생하는 에러입니다.
- C2143 에러의 경우 '}'의 개수가 '{'의 개수보다 많은 경우입니다.
- C1004 에러의 경우 '{'의 개수가 '}'의 개수보다 많은 경우입니다.
-
error C1853 : 'Debug/filename.pch' is not a precompiled header file created with this compiler
- filename이 지금 사용하는 컴파일러에 의해 만들어진 precompiled header가 아닌 경우에 발생합니다. 혹은 컴파일러 버전에 따라서 다른 경우에더 이러한 에러가 발생합니다.
- Rebuild All을 합니다
Visual C에서 [Build] - [Rebuild All] 메뉴를 선택하면 현재 프로젝트의 모든 파일들을 다시 컴파일하고 링크 과정을 거치게 됩니다. 그러므로 혹 컴파일러 버전의 문제인 경우에는 이렇게 해결할 수 있습니다. - C code에서 C++ precompiled header를 사용하는 경우
Visual C에서 프로젝트를 만들 때 console을 선택하고 empty project 이외의 설정을 선택하게 되면 실제로 stdafx.h, stdafx.cpp, filename.cpp 파일이 생성됩니다. 이 경우에 사용자가 새로운 파일을 추가하면서 newfile.c와 같이 만들고 이 파일에 #include "stdafx.h"와 같이 하는 경우에는 위와 같은 에러가 발생합니다. 이러한 에러는 C와 C++의 호환성 문제이므로 newfile.c를 newfile.cpp로 바꾸어 저장하면 에러를 피할 수 있습니다.
-
error C1017 : invalid integer constant expression
- #if sizeof(int) == 4 // 컴파일러가 처리해야 함
- #define INT_MAX_BYTE 4
- #else
- #define INT_MAX_BYTE 2
- #endif
- 이러한 에러는 #if 문을 컴파일러가 처리하지 못하는 경우에 발생합니다. 가령 위와 같은 경우에는 sizeof(int)를 컴파일러가 컴파일해야만 그 결과를 알 수 있습니다. 하지만 전처리기(preprocessor)에서는 이러한 컴파일 과정 이전에 수행되는 것이므로 sizeof(int)의 값을 알 수 없습니다.
define 관련 버그
- #define max(a, b) ((a) > (b) ? (a) : (b))
위와 같이 max값을 얻어 오는 매크로를 작성하면 실제로 어떤 값이든 비교가 가능하다는 장점이 있습니다. 가령 함수로 작성한다고 하면 a와 b의 데이터 형식을 지정해 주어야 하므로 비교가 어렵지요. 하지만 이러한 매크로에도 단점은 있습니다.
- k = max(i++, j++);
과 같이 사용한다고 하면 i++와 j++중 큰 값을 k에 넣는다고 쉽게 생각할 수 있습니다. 바로 이 부분이 함정입니다. 위 문을 컴파일러가 먼저 매크로를 이용하여 바꾼 소스를 보면 다음과 같습니다.
- k = ((i++) > (j++) ? (i++) : (j++));
즉 i++가 j++보다 큰 경우에는 '?' 뒤의 'i++'를 한 번 더 실행하게 되는 것이지요. 즉, 1이 증가된 값이 아닌 2가 증가된 값을 얻게 되므로 이러한 경우를 조심해야 합니다. 이러한 경우에는
- i += 1;
- j += 1;
- k = max(i, j);
와 같이 변경해서 사용해야 합니다.
if와 else의 버그
- if(a > 0)
- for(i = 0; i < a; ++i)
- if(i > 10
- {
- printf("i > 10");
- }
- else // 이 else는 바로위 if에 연결됨
- for(i = 0; i > a; --i)
- if(i < -10)
- {
- printf("i <- 10");
- }
ASCII 코드표
NUL | ^@ | DLE | ^P | SP | space | 0 | 0 | @ | @ | P | P | ` | ` | p | p |
SOH | ^A | DC1 | ^Q | ! | ! | 1 | 1 | A | A | Q | Q | a | a | q | q |
STX | ^B | DC2 | ^R | " | " | 2 | 2 | B | B | R | R | b | b | r | r |
ETX | ^C | DC3 | ^S | # | # | 3 | 3 | C | C | S | S | c | c | s | s |
EOT | ^D | DC4 | ^T | $ | $ | 4 | 4 | D | D | T | T | d | d | t | t |
ENQ | ^E | NAK | ^U | % | % | 5 | 5 | E | E | U | U | e | e | u | u |
ACK | ^F | SYN | ^V | & | & | 6 | 6 | F | F | V | V | f | f | v | v |
BEL | ^G | ETB | ^W | ' | ' | 7 | 7 | G | G | W | W | g | g | w | w |
BS | ^H, Backspace | CAN | ^X | ( | ( | 8 | 8 | H | H | X | X | h | h | x | x |
HT | ^T, Tab | EM | ^Y | ) | ) | 9 | 9 | I | I | Y | Y | i | i | y | y |
LF | ^J, Line Feed | SUB | ^Z | * | * | : | : | J | J | Z | Z | j | j | z | z |
VT | ^K | ESC | ^L, esc | + | + | ; | ; | K | K | [ | [ | k | k | { | { |
FF | ^L | FS | ^\ | , | , | < | < | L | L | \ | \ | l | l | | | | |
CR | ^M, Return | GS | ^] | - | - | = | = | M | M | ] | \ | m | m | } | } |
SO | ^N | RS | ^^ | . | . | > | > | N | N | ^ | ^ | n | n | ~ | ~ |
SI | ^O | US | ^_ | / | / | ? | ? | O | O | _ | _ | o | o | Del | Del |
용어 해설
- ASCII(American Standard code for Information Interchange)
- CGI(Common Gateway interface)
- Byte : 비트 표기에서는 b를 쓰지만 바이트 표기에서는 MB와 같이 대문자 B를 써서 구분한다.
- template : 입력의 수고를 덜기 위한 기능이나 소프트웨어. 또는 표 계산 소프트웨어로 특정 업무를 할 수 있도록 하는 워크시트를 말하기도 한다.
- prototype : 장치나 프로그램의 개정된 것이나 개량된 것에 대하여 그 가장 기본이 된 것, 혹은 장치나 프로그램을 만들 때의 모범이 된 것을 말한다.
이 글은 스프링노트에서 작성되었습니다.