Programming Tools/TCPL C Language

[C Language] Chap.4 Functions and Program Structure - Functions returning Non-Integers

LiDARian 2021. 6. 21. 18:10
반응형

Functions returning Non-Integers

int 타입 외에도 다양한 타입을 반환하는 함수를 만들 수 있다.

#include <ctype.h>

double atof(char s[]){ // double 자료형을 반환하는 함수
    double val, power;
    int i, sign;

    for(i = 0; isspace(s[i]); i++) ; // 공백 스킵

    sign = (s[i] == '-')? -1 : 1;
    if(s[i] == '+' || s[i] == '-')
        i++;
    for(val == 0.0; isdigit(s[i]); i++)
        val = 10.0 * val + (s[i] - '0');
    if(s[i] == '.')
        i++;
    for(power = 1.0; isdigit(s[i]); i++){
        val = 10.0 * val + (s[i] - '0');
        power *= 10.0;
    }
    return sign * val / power;

그리고 이 atof 함수를 사용하는 main함수를 적으면 다음과 같은데,

#include <stdio.h>

#define MAXLINE 100

int main(){
    double sum, atof(char []); // main 내부에서 함수를 선언할 수 있다.
    char line[MAXLINE];
    int getline(char line[], int max); // main 내부에서 함수를 선언할 수 있다.

    sum = 0;
    while(getline(line, MAXLINE) > 0)
        printf("\t%g\n", sum += atof(line));
    return 0;
}

main함수가 atof가 non-int value를 반환한다는 것을 main에 알리기 위해서 이와 같이 작성할 수 있다.이는 초기 C 표준에서 선언없이 함수를 호출했을 때 반환 자료형을 int로 처리했기에, 이와 같이 main 함수에 반환 자료형을 명시할 수 있다는 의미이다.
하지만 현실적으로 이렇게 main 내부에서 함수를 선언하는 일은 없다. 단지 function call 전에 function declaration을 하기만 하면 된다.

 


https://stackoverflow.com/questions/64855980/declaring-a-function-prototype-in-a-brace
에서의 결론을 보면,


You may declare a function in the file scope or in a block scope in which the function is called.
파일 전체 범위 혹은 블록 범위에서 함수를 선언할 수 있다....고 한다.

 

또한 만약 atof()함수가 main파일과 다른 파일로 컴파일 되는 경우,
main파일 내부에서 atof()를 자료형과 함께 다시 선언해주면 atof()가 반환하는 자료형이 int가 되는 등의 불상사를 방지하여 에러를 막을 수 있다.


현재로는 컴파일에러로 컴파일을 마감하겠지만, 이전의 초기 C 표준에서는,
함수의 프로토타입 선언이 없는 경우, 함수는 암시적으로 맨 처음의 expression을 기준으로 자료형을 반환한다.

즉 위의 main 파일에서 double atof(char [])의 선언이 없다고 하면, sum += atof(line)에 의해 atof()가 int 자료형을 반환하는 것으로 인식된다.


만약 함수 선언 시,

double atof()

처럼 argument에 아무것도 안적었다면, 모든 parameter checking이 작동하지 않는다.
이는 새로운 C 프로그램에 오래된 C 프로그램이 호환되도록하기 위해 설정된 부분이라는데,, 잘 모르겠다.
저자는 argument가 없으면 차라리 void를 넣으라고 한다.


// 문자열을 integer로 변환
int atoi(char s[]){
    double atof(char s[]);

    return (int) atof(s);
}

위 예제에서 보면, return 부분에서 double 자료형이 int 자료형으로 변환한다.

// 문자열을 integer로 변환
int atoi(char s[]){
    double atof(char s[]);

    return atof(s);
}

이와 같이 (int)를 빼더라도, 암시적으로 함수의 반환형에 맞게 double을 int형으로 변환한다.

실험해보면 다음과 같다.

#include <stdio.h>

int test(){
    double val = 2.2;

    return val;
}

int main(){
    double num;

    num = test();
    printf("%f\n", num);

    return 0;
}

출력 :
2.00000

반응형