상세 컨텐츠

본문 제목

Function / Header File

개발생활/C C++

by 한국인맛집 2021. 4. 13. 20:31

본문

반응형

 

 

함수란?

 

※ 함수는 자판기입니다.



왜 함수가 자판기 일까요?

 

* 이해를 위해 함수 종류 중에서 파라미터(매개변수) 없이 동작하는 함수는 제외합니다.

 

 

 

(예문)

“ 자판기에는 콜라, 사이다, 환타 가 있습니다.

저는 자판기에서 콜라를 먹고싶어 돈1000원을 투입했습니다. 

자판기에서 1000원을 인식하고 1000원에 해당하는 제품 버튼에 불이 들어왔습니다. 

저는 콜라 버튼을 눌렀습니다. 

그리고 제품을 받는곳에 콜라가 나왔습니다. “

 

그럼 예문을 보며 함수와 매칭시켜보겠습니다.

 

 

“자판기에는 콜라, 사이다 , 환타가 있습니다.”  = 함수내부에 구현되어있는 상태,

 

“자판기에 현금 1000원 투입”  함수에 1000원을 파라미터로 입력하여 함수호출

 

“자판기에서 1000원을 인식하고 1000원에 해당하는 제품에 불이 들어왔다.”

= 함수내부에서 파라미터를 인식하고 해당 결과를 사용자에게 표현

 

“콜라버튼을 눌렀다” = 사용자가 입력값을 입력

 

“제품 투입구 에서 콜라가 나왔다” = 함수 연산결과값을 리턴.

 

 

 

 

함수 원형.

 

타입(반환타입)    함수이름 ( 매개변수 , ...  ){

 

}

 

 

함수를 선언할때 타입을 void로 한다면 함수는 반환값을 입력하지 않아도 됩니다.

 

하지만. 반환타입이 void가 아니라면 해당 반환타입에 맞게 결과를 리턴해줘야합니다.

 

또한 프로젝트에서 main() 함수는 반드시 1개 만 있어야합니다.

 

간혹가다 1개의 프로젝트에 소스파일을 여러개 만들고, 각 소스파일마다 메인함수를 각각 만드는 경우가 있는데.

절대 해선 안된다. 프로그램이 정상 작동하지않고. LINK 에러를 뱉게 된다.

 

 

함수의 사용의 예는 다음과 같습니다.

 

 

기본형 (매개변수가 없는 함수)

void func(){

}

int function(){
  return 0;
}

float functionFloat(){
   return 0.0;
}

 

매개변수가 있는 형태

void funcVoid(){
	// 매개변수가 없는형태

}

int function(int args, int arg2){
	// 인트매개변수 2개 를 받는 형태
  	return 0;
}

float functionFloat(float floatingType){
	// float 형태로 매개변수를 받는타입
    return 0.0;
}

int* pointerFunction(int* pointer){
	// 인트 포인터 형태 매개변수 
    // 리턴타입로 정수 포인트 로 반환
}

char* charPointerFunction(char[] arrayType){
	// 배열 자체를 받을수도 있음.
    // 리턴은 케릭터 포인터 형태로 리턴함
    
    return arrayType;
}

 

 

매개변수?  파라미터?

 

매개변수와 파라미터는 같은말 입니다.

 

매개변수의 내용이 어렵다면, 자판기로 생각했을때, 동전을 넣는 동전 이라고생각하면 됩니다.

 

함수를 사용하기 위해선 매개변수가 없을수도있지만, 매개변수를 받아 사용할수있습니다.

 

개발자가 필요에따라 함수를 구성하는건 자유입니다.

 

필요하다면 매개변수를 넣을수 있고, 필요없다면 매개변수를 추가하지않아도 됩니다.

 


함수를 왜사용할까?

 

함수는 프로그램에서 정말 많이 사용되고, 함수를 사용하면 코드가 간결해지는 장점을 가지고있습니다.

 

예를 들어 아래 프로그램을 보겠습니다.

 

#include<stdio.h>

void main(){


  printf("안녕하세요 두수를 입력하면 두수의 사칙연산을 구해줍니다.\n");
  
  
  int inputNumber1, inputNumber2;
  
  printf("첫번째 수를 입력해주세요.\n");
  
  scanf_s("%d",&inputNumber);
  fseek(stdin,0,SEEK_END);
  
  printf("두번째 수를 입력해주세요.\n");
  
  scanf_s("%d",&inputNumber);
  fseek(stdin,0,SEEK_END);
  
  int sum, sub, mul, div;
  
  sum = inputNumber + inputNumber2;
  sub = inputNumber - inputNumber2;
  mul = inputNumber * inputNumber2;
  div = inputNumber / inputNumber2;
  
  
  printf("덧셈 결과= %d",sum);
  printf("뺄셈 결과= %d",sub);
  printf("곱셈 결과= %d",mul);
  printf("나눗셈 결과= %d",div);

  fgetc(stdin);
}

 

2개의 수를 입력받으면 사칙연산의 결과값을 출력해주는 프로그램입니다.

그런데 사용자로부터 입력받는 값이 계속 늘어나거나, 덧셈, 뺄셈과같이 계속 써야하는 경우엔? 코드를 계속 복사하고,

코드의 길이가 길어집니다.

코드가 길어지면 코드를 읽는게 상당히 피로감이 느껴집니다.

 

그래서 이럴때 반복적으로 사용할것으로 보이는 곳을 함수 처리할수 있습니다.

 

 

#include<stdio.h>


// 함수의 선언부는 항상 main보다 위에 위치 해야한다.
int sum(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int div(int a, int b);


void main(){


  printf("안녕하세요 두수를 입력하면 두수의 사칙연산을 구해줍니다.\n");
  
  
  int inputNumber1, inputNumber2;
  
  printf("첫번째 수를 입력해주세요.\n");
  
  scanf_s("%d",&inputNumber);
  fseek(stdin,0,SEEK_END);
  
  printf("두번째 수를 입력해주세요.\n");
  
  scanf_s("%d",&inputNumber);
  fseek(stdin,0,SEEK_END);
  
  printf("덧셈 결과= %d",sum(inputNumber1,inputNumber2));
  printf("뺄셈 결과= %d",sub(inputNumber1,inputNumber2));
  printf("곱셈 결과= %d",mul(inputNumber1,inputNumber2));
  printf("나눗셈 결과= %d",div(inputNumber1,inputNumber2));

  fgetc(stdin);
}


// 아래를 함수의 원형이라고 한다.

int sum(int a, int b){
	return a+b;
}

int sub(int a, int b){
	return a - b;
}

int mul(int a, int b){
	return a * b;
}

int div(int a, int b){
	return a/b;
}

 

반복적으로 코드가 사용이 보인다면 함수를 위에와 같이 함수를 사용하면 좋다. 

하지만 함수를 무차별적으로 많이 사용한다면 그겋또한 문제가 될 여지가 있으므로.

 

필요에따라 함수를 사용하것이 중요하다.

 

 

위에 코드를 보게되면.

 

함수의 원형부, 선언부 로 나뉘어져있는데.

 

C/C++에서 함수를 사용하기 위해선, 사용되는 부분보다 위에 선언되어 있어야한다!

 

쉽게말해.

 

main함수에서 함수를 사용하기 위해선. main 함수보다 위에 선언이 되어있어야한다.

 

선언부 없이 원형을 main 보다 위에 위치하면, 선언부가 없어도 된다.

 

하지만 이제곧 Header File을 이용하여 프로그래밍을 진행할것이므로, 선언부와 함수의 원형부를 분리하는것에 익숙해 지자.

 

 


Header File 과 source File 분리,

 

 

 

 

Visual studio 를 이용해 프로젝트를 만들고 코드를 작성할때 sourceFiles 에 소스를 만들고 프로그램을 작성하는것은 익숙할것이다.

 

하지만 이제부터 Header파일과 Source파일을 분리하는 이유에대해 알아야 한다.

 

 

현재는 다른 헤더파일을 포함하지않고, 간단한 내용만을 담고 있기때문에 headerFile에대해 따로 언급하지않았다.

 

이제 클래스와 여러 헤더파일을 이용한 프로그래밍을 진행할 예정이므로 header파일에대해 알아야한다.

 

헤더파일은 일반적으로 아래 내용을 적는다.

1. 클래스

2. 다른 헤더파일

3. 함수의 원형

4. 매크로 사용

5. 템플릿 파일.

 

 

 

 

헤더 파일 만들기

 

 

 

 

 

이렇게 만들면 되지만!

 

일반적으로 헤더파일과 소스파일의 이름을 같게 만드는것이 좋다.,

 

 

소스파일과 헤더파일의 이름은 맞게 만들어주는것이 중요하다.

 

 

 

혹시 소스파일의 위치를 다른폴더에 잘못만들었다면?

 

드래그해서 폴더로 옮겨주면 해결되니. 

 

잘못만들었다고 해서 삭제할필요는 없다.


헤더파일에 관하여.

 

 

헤더파일을 읽어오는 방법은 2종류가 있다.

 

1. 사용자 정의 헤더파일 불러오기

2. Visual studio에서 제공하는 헤더파일 불러오기.

 

 

VC++ Directory라고 있다.

 

그곳에  include Directories 라고 있는데.

 

해당 경로에 있는 파일을 visual studio에서 제공되는 헤더파일들이다.

 

프로그래밍을 잘모른다면 해당 디렉토리를 절대 변경하면 안된다!

 

변경하게되면 빌드가 안된다.

 

해당 헤더파일을 불러오는방법은  <> 를 사용하여 불러오도록 되어있다.

 

#include<>

 

그외 다른사람이만들어놓거나, 내가만든 헤더파일을 불러오기위해선  "" 큰 따옴표를 이용하여 불러올수있다.

#include" " 

만약 경로가 다르다면. 헤당 파일폴더의 절대경로, 상대 경로를 사용하여 불러올수 있다. 

 

 

※ 헤더파일에서 프로그램을 작성하지 않는다.

아래와 같은 행동은 절대 해선 안된다.

// Header.h

#include<stido.h>


void main(){
	printf("hello world");
}

 

 

헤더파일과 소스파일을 분리하여 사용하는방법은 아래와 같다.

 

 

// Header.h

#ifndef __HEADER_H_
#define __HEADER_H_

#include<stdio.h>
#incldue<stdlib.h>


void PrintFunction(){
   printf("hello world");
}

int sumFunction(int a, int b){
	return a + b;
}


#endif

 

#include"Header.h"

void main(){

   PrintFunction();
   fgetc(stdin);
}

 

 

 

 


전처리기 , Macro

 

전처리기, 전처리 지시문

 

전처리 지시문이란 프로그램코드에 # , 해쉬 문자가 붙는것을 말합니다. 해당 행은 실제코드가 컴파일이 시작되기전 코드를 검사하는것을 말합니다.

 

전처지시문의 예는 다음과 같습니다.

 

#include
#define
#undefine
#ifndef
#if
#endif

Macro정의

 

C/C++에서 매크로는 우리가 아는 반복실행하는 프로그램과 다릅니다.

 

전처리기가 해당 지시문을 발견하게되면 해당 코드블록을 치환해줍니다.

 

 

전처리기 종류

키워드 설명
#define 지시문이 정의되어있다면 계속 유지, 전처리기, 매크로
#if   -   #elif   - #else   #endif 전처리기에 조건을 부여가능하다.
#undifine 지시문이 정의 되어있지않다면 계속유지

 

코드로 예를 들어설명하겠습니다.

 

#include<stdio.h>

#define PI 3.141592


void main(){
  
  
  float r = 10;
  
  float result = r* r * PI;
  
  printf(" 원의 넓이  >> %f ", result);
  fgetc(stdin);
}

 

PI를 매크로 전처리기 라고 합니다.

 

 

 

PI 가 실질적으로 코드상에서 3.141592로 치환되어 사용되도록 하는것입니다.

치환되는 순간은 프로그램 코드를 디버깅하여 컴파일할때 PI 가 3.141592로 변환되어 코드가 수행하게 됩니다.

 

매크로 전처리기는 세미콜론으로 마무리짓지 않습니다.

 

또한 치환의 개념이기때문에 PI = 3.141592 라고 쓰지않습니다.

만약 쓴다면. 다음과 같이 사용할수는 있다.

// Main.h

#ifndef __MAIN_H_
#define __MAIN_H_



#define PI = 3.141592

#include<stdio.h>


#endif

 

// Main.cpp

#include"Main.h"

void main() {
	float pi  PI;
}

 

하지만 다음과같은 코드는 코드 문맥상 상당히 좋지않다.

최대한 사용하지 않는것이좋다.

 

 

 

매크로를 연산자로 치환도 가능하다.

#ifndef __MAIN_H_
#define __MAIN_H_

#define PLUS +

#include<stdio.h>


#endif

 

// Main.cpp


#include"Main.h"

void main() {
	int a = 10;
	int b = 20;

	 int result = a PLUS b;

	 printf("%d", result);
	 fgetc(stdin);
}

 

 

 

전처리기 매크로를 이용하면 헤더파일이  중복으로  include되는것을 막을수있습니다.

 

#if [조건1]
	// 조건1에 해당되면 해당 블록이 실행됨
    //
	
#elif  [조건2]
	// 조건 2에 해당되면 현재 블록이 실행됨
    //
#else
  //조건1, 조건2 가 아니라면
  // 이곳 블록코드가 실행됨

#endif  // #if 로 조건이 시작되면 endif 로 종료해줘야합니다.

 

헤더파일의 중복을 막기위해서 일반적으로 다음과같이 사용합니다.

#ifdef  - #endif 조건부가 참이라면 컴파일 하지않는다.
#ifndef - #endif 조건부가 거짓이라면 컴파일 하지않는다.
// Header.h 파일

// 헤더파일에 맞게 마크로로 처리해주고. 
// 중복이나 시스템 전처리기를 막기위해 
//__ 언더바 2개로 시작하고 끝도 __으로 마무리짓는게 일반적이다

#ifndef __HEADER_H__
#define __HEADER_H__

#include<stdio.h>



#endif

 

 

 

#ifndef [내용]

#define [내용]

 

#endif

 

 

#ifndef  전처리는 선언되어있지않다면 컴파일하지않는다.

 

#ifdef 선언되어 있다면 컴파일 하지않는다.

 

2개중에 하나만 사용한다.

 

일반적으로 #ifdef 보단, #ifndef 를 사용한다.

 

#ifndef 전처리기를 사용하고 반드시 #endif 로 닫아야한다.

 

 

자세한 전처리 내용은 아래 사이트에서 확인할수 있다.

 

 

www.cplusplus.com/doc/tutorial/preprocessor/

 

Preprocessor directives - C++ Tutorials

1234567891011121314 // function macro #include using namespace std; #define getmax(a,b) ((a)>(b)?(a):(b)) int main() { int x=5, y; y= getmax(x,2); cout << y << endl; cout << getmax(7,x) << endl; return 0; } 5 7

www.cplusplus.com

 

 

 

 

 

 

 

 

 

반응형

'개발생활 > C C++' 카테고리의 다른 글

pointer-2  (0) 2021.04.13
Array  (0) 2021.04.13
Flow control [Conditional Statements]  (0) 2021.04.04
Loop- 2  (0) 2021.04.04
c/c++ Gitignore file  (0) 2021.03.30
Loop -1  (0) 2021.03.21

관련글 더보기