ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C언어_09장
    Computer Sci‧ence/C 2014. 2. 13. 15:38
    반응형

    함수


    1. printf

    int a = 0;

    int b = 0;


    a=printf("12345.\n");

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


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

    ----------------------------------------------

    출력화면 //모니터에 출력한 데이터의 크기를 바이트 단위로 반환해준다. 

    ----------------------------------------------    

    12345.    

    I love my home.

    7 16

    Press any key to continue . . .

    ---------------------------------------------

         


    1.1 함수는 1. 이름을 정하고

              2. 기능을 구현하고

              3. 전달인자와 

              4. 반환값의 형태를 결정 으로 만들어 잇다. 

    * 함수 호출시 전달되는 인자의 수는 여러개가 될 수 있지만 

    반환할 수 있는 값의 개수는 최대 1개를 넘지 못한다

    따라서 반환하고자 하는 자료형만 정의해 두면 된다. 


    1.2 함수의 형태는 

    1. 전달인자 有, 반환 값 有

    2. 전달인자 有, 반환 값 無

        void result_print(int val)

       {

         ......  //return 문이 없다. 

        }

    3. 전달인자 無, 반환값 有

         int Input (void)

         { 

                int input;

                scanf("%d", &input)

                return input;

          }

    4. 전달인자 無, 반환값 無

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


    #include <stdio.h>


    int Add(int i, int j)  //함수 원형 선언( 먼저 함수의 원형을 선언한다)


    int main(void)

    {


    int d;

    d= Add(3,4);

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

    return 0;


    int Add(int i, int j)   //함수의 정의

    {

    int result = i + j;

    return result; 

    }


    함수의 원형을 선언하는 경우 제공해야 하는 정보는 반환형과 함수 이름, 그리고 매개변수의 자료형과 개수이다. 즉 매개변수의 이름은 사실상 필요 없는 부분이다. 

    따라서 int Add(int a, int b); 라는 선언을 int Add(int, int) 라는 선언으로 대신 할 수도 있다. 




    ---------------------예제 코드---------------------------

    #include <stdio.h>


    int Add(int i, int j);  //함수 원형 선언( 먼저 함수의 원형을 선언한다)

    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("%d", &input);

    return input;

    }


    void result_print(int val)

    {

    printf("덧셈에 대한 결과: %d \n",val);

    printf("****END****\n");

    }


    void intro(void)

    {

    printf("****Start****\n");

    printf("두개의 정수 입력:");

    }

    -------------------------------------------------------------------------------------------------


    1.3 하나의 함수 내에 둘 이상의 return 문이 존재하는 경우:

    * 함수의 실해에서 Return 문을 만나게 되면 값을 반환하면서 함수를 빠져나간다. 


    int Large_Num(int a, int b);  //함수 원형 선언( 먼저 함수의 원형을 선언한다)


    int main(void)

    {

    printf("3과 4중에서 큰 수는 %d 이다. \n", Large_Num(3,4));

    printf("7과 2중에서 큰 수는 %d 이다. \n", Large_Num(7, 2));

    return 0;


    int Large_Num(int a, int b)

    {

    if (a > b)

    return a;

    else

    return b;

    }


    1.4 절대값 함수


    int Also_Large(int a, int b);  //함수 원형 선언( 먼저 함수의 원형을 선언한다)

    int Also_val(int val);


    int main(void)

    {

    int a, b;

    printf("두 개의 정수 입력: \n");

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


    printf("%d와 %d중 큰 절대 값: %d \n",a,b,Also_Large(a,b));

    return 0;


    int Also_Large(int a, int b)

    {

    if (Also_val(a) > Also_val(b))

    return a;

    else

    return b;

    }


    int Also_val(int val)

    {

    if (val < 0)

    return val *= -1;

    else

    return val;

    }


    1.5 피보나치 함수

    int pibo(int p)

    {

    int val1=0;

    int val2 = 1;

    int val3; 

    int i;


    if (p <= 0)

    {

    printf("error\n");

    return 0;

    }

    else if (p == 1)

    {

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

    }

    else if (p == 2)

    {

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

    }

    else

    {

    printf("%d %d ", val1, val2);

    for (i = 1; i <= p - 2; i++)

    {

    val3 = val1 + val2;

    printf("%d ", val3);


    val1 = val2;

    val2 = val3;

    }

    printf("\n");

    return 0;

    }

    }


    2. 변수의 범위 (메모리상에 존재하는 기간, 변수에 접근할 수 있는 영역)

    *문법적인 특정을 차치하고 전역변수와 동일한 이름의 지역 변수를 선언하는 것은 좋지않은 습관이다. 


    1. 지역변수

    2. 전역변수 : main 함수 밖에서 정의되는 변수, 전역변수는 초기에 값을 정해주지 않으면 0으로 자동 초기화 된다. 지역내에서는 지역변수보다 전역변수가 우선시 된다. 

    3. register 변수: 지역변수 선언시 register 라는 키워드를 붙여서 register변수를 선언 할 수 있다. 

    이렇게 되면 변수는 CPU 의 '레지스터' 라는 메모리 영역에 저장이 된다. 하지만 이것은 명령이 아니라 요청에 가깝다. 왜냐하면 CPU의 레지스터는 그 크기가 제한되어 있는 메모리 공간이기 때문에 공간에 변수를 할당하는 것이 여의치 않을 경우 이러한 요구는 충분히 무시될 수 있다. register 변수의 선언과 관련해서 고민할 필요는 없을 수도 있는 것이 컴파일러가 코드 최적화라는 것을 수행하기 때문이다. 

    4. static 변수 : 지역 내에서만 접근을 허용한다라는 점을 제외하고는 전역변수와 동일하다. 



    함수는 먼저 main 함수가 호출되고, main 함수내에서 호출하는 함수들로 호출된다. 




    **

    int main(void)

    {

    int i; //어디서나 main안에서는 접근이 가능함

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

    {

    int a = 0;  //for 루프를 돌 때마다 변수 a는 메모리상 올라갔다 소멸되는 과정을 반복하세 된다 

    a++;

    printf("%d 번째 for 루프, 지역변수 a는 %d\n", i, a);

    }


    if (i == 3)

    {

    int a = 10;

    a++;

    printf("if 문 내에 존재하는 지역 변수 a는 %d\n", a);

    }

    return 0;


    --------------------------------------출력화면--------------------------

    0 번째 for 루프, 지역변수 a는 1   //for문에서++ 하면 

    1 번째 for 루프, 지역변수 a는 1

    2 번째 for 루프, 지역변수 a는 1

    if 문 내에 존재하는 지역 변수 a는 11

    Press any key to continue . . .

    --------------------------------------------------------------

    "지역변수는 외부에 선언된 동일한 이름의 변수를 가릴 수 있다"
    모든 매게변수는 지역변수다. 


    3. 재귀적 함수 호출

    : 재귀적 함수 호출을 이용하면 어렵고 복잡한 문제를 쉽게 해결할 수 있다. 따라서 자료구조와 알고리즘에서는 빠질 수 없는 기념이다. 

    재귀적 함수 호출이란 함수 내에서 자기 자신을 다시 호출하는 형태의 함수 호출을 의미한다.

    호출시 메모리가 부족하면 컴퓨터가 메모리의 부족으로 문제가 있음을 파악하고 실행을 중지시켜 버린다. 

    함수의 호출이라는 것은 메모리 공간을 필요로 한다. 비록 그 안에 변수 선언을 하지 않아도 말이다. 함수가 호출되면 함수 실행을 위한 메모리 공간이 할당된다. 이 메모리 공간은 함수 호출이 완료되면 함게 반환된다. 그러나 하수가 계속적으로 호출되지만 완료되지는 않으면 실행이 완료되지 않은 함수들이 계속해서 쌓이게 되고 메모리의 보족이 발생하게 된다. 


    재귀함수를 호출할때에는 종료 조건을 함께 명시(구현)해 주어야 한다.

    void recursive(int n)

    {

    ......

    if (n==1)

    return; 


    recursive(n-1);

    }


    예시-----------! 재기함수를 정의하는데 있어서 탈출의 조건은 아주 중요하다. 

    #include <stdio.h>


    void recursive(int);



    int main(void)

    {

    int a = 2;

    recursive(a);

    return 0;

    }


    void recursive(int n)

    {

    printf("recursive call!\n");

    if (n == 1) //재귀함수 탈출조건

    return;   //return은 1. 값의 반환, 2. 함수의 종료역할을 한다. 

    recursive(n - 1); //n-1을 전달. n의 값을 하나 줄임


    return 0;

    }

    -------------------------------------------


    Factorial 계산 예제


    #include <stdio.h>


    int f(int n);



    int main(void)

    {

    int val;

    int result;

    printf("정수입력:");

    scanf("%d", &val);

    if (val < 0)

    {

    printf("0이상을 입력해야 합니다.\n");

    return 1;

    }


    result = f(val); //factorial 계산

    printf("%d!의 계산 결과: %d \n", val, result);

    return 0;

    }


    int f(int n)

    {

    if (n == 0) //재귀함수 탈출조건

    return 1;

    else  //아니면 n*(n-1)을 반환

    return n*f(n - 1);



    이번장에서 공부한 내용 정리

    1. 함수의 종류를 반환형과 매겨 변수의 유무에 따라서 4가지 형태로 나눠서 이야기를 전개하엿다.

    2. 다양한 종류의 변수를 살펴보았다. 가장 중요한 것은 지역변수와 전역변수 그리고 static 변수이다. 무엇보다도 변수 선언에 있어서 주의사항을 기억하고 있기 바란다. 전역 변수는 많이 선언할 수록 좋은가? 나쁜가? static 변수는 언제 사용하는 것이 이상적인가?

    3. 지역 변수의 특징 중에는 외부에 선언된 같은 이름의 변수를 가린다는 특징이 있다. 이것이 무엇을 의미하는지 잊지 말아야 한다. 

    4. 재귀적 함수 호출에 대해서 살펴보았다. 분명히 어려운 내용이다 한번에 완벽히 이해하려 하지 말고 시간이 날 때마다 반복해서 정복하기 바란다. 필자도 과거 오랜 시간에 걸쳐서 정복한 내용이다. 



     

    반응형

    'Computer Sci‧ence > C' 카테고리의 다른 글

    C언어_11장  (0) 2014.02.17
    C언어_10장  (0) 2014.02.14
    scanf vs. scanf_s "_CRT_SECURE_NO_WARNINGS"  (0) 2014.02.13
    백견이 불여일타요 백타가 불여일작이다!  (0) 2014.02.12
    C언어_08장  (0) 2014.02.12

    댓글

Designed by Tistory.