C언어 #13

동적 메모리 할당

calloc 함수

malloc 함수와 똑같은 기능을 갖는다.
전달인자의 형태만 조금 다르다. 메모리 개수와 자료형의 크기를 대입한다.

  • calloc 함수와 malloc 함수의 비교
int* a = (int*)calloc(elt_count, elt_size);
int* a = (int*)malloc(size* sizeof(int));

memset 함수

메모리 블록에서 모든 바이트를 특정 값으로 설정할 때 사용하는 초기화 함수

void* memset(void* dest, int c, size_t count);

dest : 메모리 대상이 되는 포인터(주소값)을 넣어줌

memcpy 함수

메모리를 복사하는 함수

void* memcpy(void* dest, void* src, size_t count);


전처리

전처리란 무엇인가

  • 프로그램 개발 과정
    컴파일을 통해 목적파일 생성
    목적파일은 링크과정 통해 실행파일 생성
    컴파일 단계 이전에 무언가 수행?

컴파일은 컴파일러(Compiler)가, 링크는 링커(Linker)가, 전처리 과정은 전처리기(Preprocessor)가 처리.

전처리기의 사용 규칙

  • 전처리문 앞에 #을 붙인다.
    헤더에서 include 앞에 #을 붙여서 사용.
    #문자로 시작하는 문장은 무조건 전처리문.
    이 문장은 컴파일러에서 처리하지 않고, 전처리기에서 처리.

  • 전처리문 끝에는 ;을 붙이지 않는다.

  • 한 줄에 하나의 전처리문만 사용 가능
    변수 선언 시 여러 개의 문장 사용 가능했지만, 전처리기는 한 줄의 하나의 문장만 사용 가능.

  • 전처리기 지시자의 종류
    헤어 파일 선언 #include
    매크로 정의 #define
    조건부 컴파일 #ifdef

--

매크로 상수

매크로 상수 선언

#define 전처리기 지시자를 사용하여 매크로 상수를 선언

#define : 매크로를 실제값으로 정의하겠다, 또는 치환하겠다는 의미
VAL : 매크로
10 : 치환하게 될 값
VAL이 10이라는 상수로 치환되었으므로 VAL은 매크로 상수이다.

매크로 상수 사용 시 좋은 점

  • 첫 번째 : 상수의 이름만으로 용도를 파악할 수 있다. PI라는 이름은 원주율을 의미
  • 두 번째 : 상수의 값 변경을 일괄 적용 가능하다. 매크로 사용처가 여러 군데라면 매크로 선언부만 수정해주면 일괄 적용된다.

파일 분할

파일 분할의 필요성

  • 지금까지의 코드
    코드 양도 작고, 기능도 간단.
    하나의 파일에서 코드를 작성.
    코드 양과 라인이 많아지면 하나의 파일에서 관리하기 힘들어진다.
    파일을 나누어 관리하는 이유는 효율성을 극대화시키기 위함이다.

  • 어떻게 나눌 것인가?
    작게는 기능 단위(함수), 크게는 모듈 단위(연관된 함수들이 모여서 만들어진 집단)로 나눈다.
    객체지향기반에서는 클래스 단위로 나눈다.

  • 파일의 분할
    크게 문제는 없어보이나 하나의 파일에서 Add 함수의 선언부와 정의부가 분리되어 있으므로 문제가 될 소지가 있다.
    Add 함수 선언 시 앞에 extern(외부의) 키워드를 붙여주면 외부에서 Add 함수를 호출하겠다는 의미가 된다.

헤더 파일

헤더 파일의 의미

특정 표준함수를 사용하기 위해서는 표준함수가 정의된 헤더를 인크루드.
printf함수를 사용하기 위해서는 반드시 stdio.h를 포함해야만 한다.

헤더 파일의 사용법

헤더 파일을 사용하는 방법은 3가지 형태이다.

내가 만든 헤더 파일이라면 큰따옴표를 사용해서 불러온다.
절대경로는 쓰지 않는 것이 좋고 상대경로를 쓰는 것이 좋다.

헤더 파일의 사용상 특징 및 규칙

  • 헤더 파일의 중복 시
    표준 헤더 파일 "stdio.h"와 사용자 정의 파일 "stdio.h"를 정의하였다면, 사용자 정의 파일 "stdio.h"만 적용

  • 헤더 파일 선언 시 대소문자 구분 안함
    윈도우 시스템 자체가 대소문자 구분 안함.
    #include<STDIO.H>와 #include<stdio.h>는 동일 취급

  • 경로 구분 시 '/'를 사용
    윈도우 환경에서 디렉토리를 구분할 경우에 보톨 역슬래시(\) 사용.
    #include에서는 디렉토리 구분 시 슬래시(/)를 사용.

  • 가급적 절대 경로를 사용하지 않는다.

헤더 파일의 사용자 정의

하나의 파일에 정의되었던 계산기 기능을 두 개의 파일로 나누었다.

  • 파일 분리 시 장점
    다른 모듈에서 cal.c 파일을 사용하고 싶다면, cal.c파일을 가져오면 된다.
    다른 모듈에서 이 함수들을 사용하려면 사용하고자 하는 함수의 선언이 필요하다.

  • 사용자 헤더 파일의 필요성
    4개 정도의 함수 선언은 대수롭지 않다.
    1010개 이상의 함수가 정의된 파일을 사용한다고 하면, 100개의 함수선언이 필요하다. 심각하다.

한가지 기능은 반드시 하나의 함수로 존재해야한다.
이것을 하나의 모듈로 만든다.

함수의 선언부만 모아져 있는 것 : 헤더 파일


조건부 컴파일

조건부 컴파일이란

조건에 따라 컴파일을 할 것인지 말 것인지 결정하는 것.
소스코드 내에서 특정 영역을 지정하여 컴파일 유무를 결정.
이기종 간의 두 개의 플랫폼 상에서 같은 소스를 동작시킬 경우.

조건부 컴파일 지시자 형식

  • 조건부 컴파일 지시자의 형식과 의미

if n(not) def(define)

endif를 꼭 써줄 것

#include <stdio.h>
#define DEBUG 1

void main()
{
#if DEBUG
	printf("디버그 모드로 동작합니다.\n");
#else
	printf("릴리즈 모드로 동작합니다.\n");
#endif
}

출력 결과
디버그 모드로 동작합니다.

매크로를 주석으로 막으면 else가 실행

디버그 상태 : 디버깅 하기 좋은 상태로 빌드하겠다는 의미.
배포할 단계 X, 개발 도구들이 들어가 있는 상태로 빌드

릴리즈 상태 : 배포하겠다는 의미. 디버깅 도구들이 빠진 상태로 exe 프로그램 제작

  • 헤더 파일의 중복 선언이 발생하는 경우

헤더가 중복된다는 것은 문제가 되지 않는다.
문제는 공유하고 있는 common.h에 있는 common 변수이다.

여러 파일에서 변수를 두 번 초기화 하게 되기 때문에 에러가 난다.

  • 문제 해결법
    근본적으로 common 변수를 한 번만 선언 및 초기화 해주도록 하면 된다.
    common.h 파일을 포함할 때 두 번 이상 포함되지 않도록 해주면 된다.
    조건부 컴파일 #ifdef가 제공해준다.

#ifdef A
#define A
#endif

  • 내장 매크로
    기본적으로 제공되는 내장 매크로가 존재한다.

(언더바 두 개씩)
내장 매크로는 코드 디버깅에 유용
로그를 남길 때 유용하다.

#include <stdio.h>
#define DEBUG 1

void main()
{
	printf("현재 날짜는 %s 입니다.\n", __DATE__);
	printf("현재 시간은 %s 입니다.\n", __TIME__);
	printf("현재 파일은 %s 입니다.\n", __FILE__);
	printf("현재 라인번호는 %d 입니다.\n", __LINE__);
}

출력결과
현재 날짜는 Sep 6 2022 입니다.
현재 시간은 11:32:32 입니다.
현재 파일은 C:\...\condition.cpp 입니다.
현재 라인번호는 15 입니다.

profile
알고 쓰자!

0개의 댓글