본문 바로가기
Programming/C++

C 언어의 핵심 함수

by OKOK 2017. 8. 4.

함수를 정의하고 선언하기

변수의 범위에 대해서

재귀적 함수 호출에 대해서 살펴봅시다


프로그램 구성에 있어서 중요한 위치를 차지하는 것을 가리켜 핵심이라고 일컬어야 합니다. 함수를 잘 구성하는 프로그래머는 실력 있는 프로그래머이고, 함수를 적절히 구성하지 못하는 프로그래머는 아무리 문법적으로 탄탄해도 그 실력을 인정받지 못합니다. 


함수를 정의하고 선언하기

함수를 만들어야 하는 이유

나누어서 정복하기.


함수에 대한 기본적인 이야기

구현하고자 하는 함수의 특성에 따라서 전달 인자가 없거나 반환 값이 없을 수도 있습니다. 


#pragma warning(disable:4996)


#include <stdio.h>


int main(void)

{

int a = 0;

int b = 0;


a = printf("12345 \n");

b = printf("I love my home\n");


printf("%d %d \n", a, b);

return 0;


모니터에 출력한 데이터의 크기를 바이트 단위로 반환해 주고 있습니다. 


다양한 형태의 함수 정의하기

함수를 정의한다는 것은 기능을 지니는 함수를 하나 만드는 것입니다. 함수의 이름을 정하고, 기능을 구현하고, 전달 인자와 반환 값의 형태를 결정짓는 것이 바로 함수를 정의하는 것입니다. 


전달 인자와 반환 값, 둘다 있는 함수

함수 호출시 전달되는 인자를 저장할 변수에 대한 선언입니다. 이를 가리켜 매개 변수 선언이라고 합니다. 둘째로 이야기할 것은 함수의 기능입니다. 함수의 몸체 부분을 보면 i와 j 값을 더해서 그 결과를 반환하고 있는 것을 볼 수 있습니다. 함수 호출 시 전달되는 인자의 수는 여러 개가 될 수 있지만 반환할 수 있는 값의 개수는 최대 1개를 넘기지 못합니다. 반환하고자 하는 자료형만 정의해 두면 됩니다. 


#pragma warning(disable:4996)


#include <stdio.h>


int Add(int i, int j)

{

int result = i + j;

return result;

}


int main(void)

{

int d;

d = Add(3, 4);

printf("%d \n", d);

return 0;


main 함수의 정보다는 Add 함수의 정의가 먼저 등장했다는 점을 유념합니다. 프로그램의 주 흐름은 main 함수의 호출에서부터 시작하는 것을 알 수 있습니다. 


전달 인자는 있지만 반환 값이 없는 함수


전달 인자는 없지만 반환 값이 있는 함수

함수를 호출할 때는 인자를 전달할 필요가 없다는 뜻입니다. 함수 내에서는 변수를 하나 


전달 인자도 없고, 반환 값도 없는 함수

intro 함수와 같은 경우는 반환 값을 지닐 필요가 없습니다. 그러나 이러한 형태의 함수라 할지라도 보통은 int형을 반환형으로 지정하는 경우가 많습니다. 그 이유는 오류 검사를 하기 위함입니다. 문제없이 정상적으로 함수 호출이 완료되었을 경우 0을, 문제가 발생했을 경우에는 0이 아닌 다른 값을 반환하게끔 함수를 구현합니다. 


함수의 정의와 그에 따른 원형 선언

컴파일러는 위에서 아래로 컴파일을 진행합니다. 함수는 호출되기 전에 미리 정의되어야 합니다. 함수의 원형을 선언하는 경우 제공해야 하는 정보는 반환형과 함수 이름, 그리고 매개 변수의 자료형과 개수입니다. 즉 매개 변수의 이름은 사실상 필요 없는 부분입니다. 따라서 int Add(int, int)라는 선언으로 대신 할 수도 있습니다.


#pragma warning(disable:4996)


#include <stdio.h>


int Add(int a, int b);

int Input(void);

void Result_Print(int val);

void Intro(void);


int main(void)

{

int a, b;

int output;

Intro();

a = Input();

b = Input();


output = Add(a, b);

Result_Print(output);


return 0;

}


int Add(int i, int j)

{

int result = i + j;

return result;

}


int Input(void)

{

int input;

scanf_s("%d", &input);

return input;

}


void Result_Print(int val)

{

printf("result: %d\n", val);

}


void Intro(void)

{

printf("tow intenger input");

}



예제를 통한 함수 구현의 이해

하나의 함수 내에 둘 이상의 retrun 문이 존재하는 경우를 설명하기 위함입니다. 


#include <stdio.h>


int Large_Num(int a, int b);


int main(void)

{

printf(" 3 and 4 bigger %d \n", Large_Num(3, 4));

printf("7 and 2 biggeer %d \n", Large_Num(7, 2));


return 0;

}


int Large_Num(int a, int b)

{

if (a > b)

return a;

else

return b;


printf 함수를 호출하면서 두 개의 인자를 전달하고 있스니다. 첫 번째 전달 인자는 문자열이고, 두 번째 전달 인자 함수 호출입니다. 함수 호출 결과로 반환되는 값을 두 번째 인자로 전달해야 하겠군. return 문은 함수의 중간에도 올 수 있음을 기억하기 바랍니다. 


#include <stdio.h>


int Abso_Large(int a, int b); 

int Abso_Val(int val);


int main(void)

{

int a, b;

printf(" two intenger input");

scanf_s("%d %d", &a, &b);


printf("%d %d value: %d\n", a, b, Abso_Large(a, b));


return 0;

}


int Abso_Large(int a, int b)

{

if (Abso_Val(a) > Abso_Val(b))

return a;

else

return b;

}


int Abso_Val(int val)

{

if (val < 0)

return val*-1;

else

return val;


프로그램의 흐름은 main 함수에서 Abso_large 함수로, 거기서 다시 Abso_Val 함수의 호출로 이어질 것입니다. 비교의 대상이 되는 피연산자가 와야 할 위치에 함수 호출이 왔네. 그러면 함수 호출 시 반환되는 반환 값을 가지고 비교 연산을 해야겠습니다.



변수의 범위에 대해서

변수가 선언되는 위치가 함수와 깊은 관계가 있습니다. 전역 변수와 지역 변수의 가장 큰 차이점은 메모리 상에 존재하는 기간과 변수에 접근할 수 있는 영역입니다. 지역변수, 전역변수, static 변수, register 변수 이렇게 총 4가지 유형의 변수에 대해서 소개합니다. 


지역 변수란 (Local variable or Automatic variable)

중괄호에 의해서 형성되는 지역을 의미합니다. 즉, 중괄호 내에 선언되는 변수는 모두 지역 변수입니다. 지역 변수는 선언된 지역 내에서만 유효하다는 특징을 지닙니다. 


지역 변수에 접근할 수 있는 범위

지역변수는 해당 지역 변수의 선언을 포함하는 함수 내에서만 접근이 가능합니다. 이 변수는 fct_one 이라는 함수의 중괄호 내에 선언되어 있습니다. 따라서 지역 변수 입니다. 두 함수 내에 one 이라는 동일한 이름의 변수가 존재합니다. 문제가 되지 않습니다. 변수가 선언되어 있는 영역이 다르면 동일한 이름이 존재해도 문제될 것이 없습니다. 


지역 변수가 메모리상에 존재하는 기간

지역 변수는 함수가 호출될 때 메모리상에 올라갔다가, 함수가 종료되면 메모리상에서 사라집니다. 


다양한 형태의 지역 변수

#include <stdio.h>


int main(void)

{

int i;

for (i = 0; i < 3; i++)

{

int a = 0;

a++;

printf("%dth for loop, local vai a is %d\n", i, a);

}

if (i == 3)

{

int a = 10;

a++;

printf("if sentence loca var a is %d \n", a);

}


return 0;


지역 변수는 외부에 선언된 동일한 이름의 변수를 가릴 수 있습니다. 


#include <stdio.h>


int main(void)

{

int val = 0;

if (1)

{

int val = 0;

val += 10;

printf("if local variable : %d\n", val);

}


printf("main local vari val: %d\n", val);

return 0;


다음은 아무 의미 없는 중괄호를 통해서도 지역 변수가 만들어지나는 것을 확인하기 위한 예제입니다. 


#include <stdio.h>


int main(void)

{

int val = 0;

{

int val = 0;

val += 10;

printf("local var val : %d\n", val);


}

printf("main var val : %d\n", val);

return 0;




중괄호가 어색할 것입니다. 그러나 문법상으로 전혀 문제가 없습니다. 이러한 선언을 통해서도 지역을 만들어 낼 수 있습니다. 


모든 매개 변수는 지역 변수입니다.

매개 변수도 지역 변수에 포함이 되므로 함수가 실행되는 동안에만 유효하다는 특징과 외부에 선언된 변수를 가릴 수 있따는 지역 변수의 특징을 그대로 적용 받습니다. 지역 변수를 다른 표현으로 자동 변수라고도 합니다. 지역 내에서 생성되었다가 지역을 벗어나면 자동으로 사라진다고 해서 붙여진 이름입니다. 또한 원칙적으로 지역 변수 선언 시, 앞에다가 auto 라는 키워드를 붙여주게 되어 잇지만 생략이 가능하며, 생략하는 것이 일반적입니다.


전역 변수

전역 변수가 지니는 특징과 선언 방법 프로그램 어디에서나 접근이 가능한 변수를 말합니다. 초기화해 주지 않을 경우, 쓰레기 값이 들어가는 것이 아니라 0으로 초기화됩니다. 이는 지역 변수와는 차이를 보이는 특징입니다. 


전역 변수와 같은 이름의 지역 변수가 존재하는 영역


#include <stdio.h>


int val = 0;


void fct(void);


int main(void)

{

val = 10;

printf("val : %d\n", val);

fct();

printf("val:%d\n", val);

return 0;

}


void fct(void)

{

int val = 20;

val++;


지역 내에서는 지역 변수가 전역 변수보다 우선시됩니다. 지역 내에서 선언된 지역 변수는 외부에 선언된 같은 이름의 전역 변수를 가립니다. 가급적이면 전역 변수와 다른 이름의 지역 변수를 선언하는 것이 좋습니다. 


전역 변수가 메모리상에 존재하는 기간

분명한 것은 프로그램 시작과 동시에 어디서든 접근이 가능하고, 프로그램이 종료되기 전까지 어디서든 접근이 가능하다는 것입니다. 따라서, 프로그램이 사작하자 마자 메모리상에 올라가서 프로그램이 종료될 때까지 계속 존재한다고 결론 내릴 수 있습니다. 지역 변수는 함수가 호출되어야 메모리 상에 올라가게 되고, 함수가 종료되면 메모리상에서 내려옵니다.


함수 내에 선언되는 static 변수

static 변수의 기본 개념

static 변수란 변수 선언 시 앞에다가 static 이라는 키워드를 붙여서 선언한 변수를 가리키는 것입니다.