C 언어
Mon, Nov 16 2020 08:05:02업데이트: 2024.01.04
C 언어를 공부해야 하는 이유
1. 호환성이 좋고 기본적으로 성능이 좋습니다.
소스코드를 약간만 수정하여 다양한 시스템에서 돌릴 수 있습니다. 또한 각종 언어에서 c 로 만든 라이브러리를 호출하는 것이 가능합니다.
2. c 를 쓰는 곳이 많습니다.
운영체제, 응용 어플, 시스템 소프트웨어, 라이브러리 등이 c 언어로 만들어져 있는 것이 많습니다. c 언어 프로젝트가 매우 많아서 오픈소스 기여도 손쉽습니다. C 를 쓰는 곳이 많아서 일자리가 많습니다.
3. 한번 배워 놓으면 10년 20년 주구장창 써먹을 수 있습니다.
4. 취미로도 무지 좋은 언어입니다.
가량 오디오 DAC 만들 때에도 써먹을 수 있는 언어가 C 언어입니다. 그리고 입력기, 비디오 다운로도 등 시스템 어플 및 응용 어플 및 GUI 어플 제작이 가능합니다.
5. 각종 시험 및 책에 c 언어가 나옵니다.
수능 시험, 대학 시험, 정보처리기사 시험에 c 언어가 나오므로 학생이라면 반드시 c 언어를 공부해야 합니다. 또한 각종 책의 예제소스 c 소스가 나오기 때문에 c 를 모르면 책이나 블로그 글을 이해할 때 애로 사항이 생기게 됩니다.
가성비 최고의 언어가 바로 c 언어입니다.
#define
문
C 언어에서 #define
은 매크로 기능을 합니다.
#define C_MAX(a, b) (((a) > (b)) ? (a) : (b))
C_MAX(1, 2)
라는 코드를 컴파일러는 (((1) > (2)) ? (1) : (2))
이러한 코드로 치환합니다.
전역 변수
전역 변수는 자동으로 초기화됩니다.
static 변수
static 변수는 정적 변수를 의미합니다. static 으로 선언하면 초기값을 지정하지 않았을 경우 전역 변수든 지역 변수든 0 으로 초기화됩니다.
문자열 입력 받기
scanf
함수로 문자열을 입력 받기 위해서는 버퍼를 미리 설정해 두어야 하는데 예를 들어 버퍼 크기를 10바이트로
설정하면 10바이트보다 큰 문자열을 입력받으면 에러가 발생하게 됩니다. 이러한 이유 때문에 scanf
함수로
문자열을 받는 것은 좋지 않습니다. 리눅스, BSD 등의 POSIX 를 지원하는 운영체제에서는
getline
함수를 제공하므로 getline
함수를 사용하여 문자열을 입력 받으시면 되겠습니다.
#include <stdio.h>
#include <stdlib.h>
/* 문자열 2개를 입력 받아서 출력 */
int main ()
{
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
printf ("첫 번째 문자열을 입력하세요: ");
if ((linelen = getline (&line, &linecap, stdin)) > 0)
printf ("첫 번째 문자열: %s\n", line);
printf ("두 번째 문자열을 입력하세요: ");
if ((linelen = getline (&line, &linecap, stdin)) > 0)
printf ("첫 번째 문자열: %s\n", line);
free (line);
}
그러나 MS윈도우에는 getline
함수가 없을 것이므로 아래처럼 함수를 만들어서 사용하시면 되겠습니다.
#include <stdio.h>
#include <stdlib.h>
/*
* 컴파일 방법
* cc -o exam exam.c
* scanf 사용할 때 오퍼플로우 문제 때문에 scanf 를 쓰지 말라고 권고하는 추세임.
* fread() 함수를 이용하여 stdin 으로부터 1문자씩 읽어서 realloc 로 가변 문자열을 만드는 방법임
*/
char *get_line_from_stdin ()
{
char *buf = malloc (sizeof (char));
int i = 0;
fflush (stdout);
fflush (stderr);
while (fread (buf + i, sizeof (char), 1, stdin) == sizeof (char))
{
if (buf[i] == 10 || feof (stdin)) /* LF or CTRL+D */
break;
i = i + sizeof (char);
buf = realloc (buf, sizeof (char) + i);
}
buf[i] = 0; /* null-terminated string */
return buf;
}
int main (int argc, char **argv)
{
char *str;
printf ("type: ");
str = get_line_from_stdin ();
printf ("%s\n", str);
free (str);
return 0;
}
입력이 있으면 realloc
을 이용하여 버퍼 크기도 그에 따라 늘립니다. 가변 문자 배열입니다.
CTRL+D 누르는 상황을 대비하여 feof()
로 체크합니다.
buf[i] == 10
에서 10
은 아스키문자를 십진수로 나타낸 것입니다. LF(line feed)가 10
에
해당합니다. scanf
대신에 유용하게 사용할 수 있습니다.
Out Of Memory 메모리 부족 에러
메모리가 부족할 때 이러한 에러가 발생합니다. malloc
함수는 할당 실패하면 NULL
을 반환하고
errno
를 ENOMEM
으로 설정합니다. 그래서 아래처럼 NULL
체크를 해줘야 합니다.
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main ()
{
void *mem;
mem = malloc (1000 * 1000);
if (!mem)
{
fprintf (stderr, "malloc failed: %s\n", strerror (errno));
abort ();
}
return 0;
}
메모리 할당 실패의 원인은
- 물리적 메모리가 부족한 경우
- 메모리 누수가 발생하는 경우
- 잦은 메모리 할당과 해제로 인한 메모리 파편화
등이 원인일 수 있습니다.
1의 경우는 메모리를 증설해야할 것이며,
2의 경우는 메모리 누수가 발생하는 부분을 찾아서 버그를 해결해야 하며
3의 경우는 메모리 할당과 해제를 가급적 줄이도록 프로그래밍을 해야겠습니다.