C 2주차 - 함수

Gunter·2024년 3월 10일
0

C

목록 보기
7/13

함수

 

함수란 ?

C언어 프로그램도 명령문들을 주욱 나열해서 작성하는 것보다 어떤 작업을 수행하는 일련의 명령문들을 한데 묶어서 그룹으로 만들어 두는게 좋다.
그래서 C언어는 소스 코드를 그룹화 할 수 있도록 함수(Function)라는 문법을 제공한다.

정해진 단위 작업을 수행하도록 여러 개의 명령문들을 하나의 그룹으로 묶은 것을 함수라고 한다.

 


#include <stdio.h>

void main(){
	printf("Hello, World!");
}

 
여기서 사용한 함수는 main 함수이다.

C언어로 작성한 프로그램은 함수들의 집합체이고 그 함수들끼리 서로 불러서 사용하는 형태로 진행된다. C언어는 main 이라는 이름의 함수를 프로그램 시작 함수로 정해 놓았다.
즉, main 함수는 컴파일러에게 프로그램이 시작한다고 알려주는 특별한 함수다.

 

+) void -> 함수가 작업을 마치면 어떤 결과 값이 나온다. 함수 이름 앞에 쓰는 키워드는 그 결과 값의 형태를 나타낸다. 지금은 '함수의 수행 결과 값이 정해지지 않았다.'는 void 예약어를 사용하고 있다.









함수 정의하기

  1. 함수 이름 : 함수가 하는 일을 짐작하기 쉽게 짓는 것이 좋다.
  2. 매개변수 : 함수가 작업을 수행할 때 필요한 데이터가 있다면 변수 단위로 명시.
  3. 작업 내용 : 함수가 작업할 내용을 중괄호 { } 안에 명령문으로 나열한다.
  4. 반환값 : 함수가 작업한 결과 값을 반환해야 할 때 사용한다.

 






함수 호출하기

sum은 피호출자(불리는 함수)이고, main은 호출자(부르는 함수)이다.







함수의 매개변수

매개변수는 호출자(main)에서 전달하는 값을 피호출자(sum)에서 전달받는 역할을 하는 변수를 의미하며, sum 함수의 value1value2가 여기에 해당한다.
이때 main에서 전달한 순서대로 sum 함수의 매개변수가 값을 전달 받기 때문에 순서나 개수를 잘 맞추어야 한다.

sum 함수가 a, b를 직접 사용할 수 없기 때문에 main함수의 a, b 변수 값을 sum 함수가 사용하기 위해 매개변수(Parameter)가 필요하다.

 






함수의 반환값

sum 함수가 수행한 결과 값을 호출자로 넘겨주면 sum 함수의 역할은 끝이 난다.
함수에서 return이라는 예약어를 사용하면 함수는 그 위치에서 종결되며, return 뒤에 명시된 result 변수 값이 sum 함수의 반환값(return value)이 된다.

그리고 함수가 값을 반환한다는 뜻은 호출자의 어떤 변수에 값을 대입한다는 뜻이기도 하다.
따라서 변수를 선언할 때 처럼 함수 이름 앞에 함수의 반환값에 대한 자료형을 명시해야 한다.

위의 예제에서 main 함수는 sum 함수의 반환값을 value로 받기 때문에 value에는 5가 저장된다.

 

반환자료형매개변수반환자료형 기입return문
xxvoidx
xovoidx
oxint, chat, float, doubleo
ooint, char, float, doubleo

 








함수의 스코프

  • 참조 대상 식별자(identifier)를 찾아내기 위한 규칙
  • 전역에 선언된 변수는 어디에서든 참조 가능
  • 함수 내에서 선언된 변수는 함수 내부에서만 참조할 수 있고 함수 외부에서는 참조할 수 없음
  • 중첩 스코프는 가장 인접한 지역을 우선하여 참조

 


재귀 함수

  • 함수 내에서 자기 자신을 다시 호출하는 함수
  • 자신의 로직을 내부적으로 반복하다가, 일정한 조건이 만족되면 함수를 이탈하여 결과를 도출
// 재귀함수를 호출하는 부분을 상단에 두고 표현
def function(입력):
    if 입력 > 일정값:    // 입력이 일정 값 이상이면
        return function(입력 - 1)    // 입력보다 작은 값
    else:
        return 일정값, 입력값, 또는 특정값    // 재귀 호출 종료
// 재귀함수가 돌아가는 부분을 아래 부분에 삽입
def function(입력):
    if 입력 <= 일정값:    // 입력이 일정 값보다 작으면
        return 일정값, 입력값, 또는 특정값    // 재귀 호출 종료
    function(입력보다 작은 값)
    return 결과값

 






함수 포인터

  • 함수의 주소 저장했다가 해당 주소의 함수 호출하는 역할
  • 포인터의 자료형은 포인터가 사용할 대상의 형식을 의미

// 포인터 변수임을 선언하고 싶을 때, 참조 연산자(*)를 붙여서 선언
반환값자료형 (*함수포인터이름) (매개변수 자료형);
// 포인터 변수에는 주소 값이 할당되어야 하고, 문자나 숫자 등이 할당되어서는 안 됨

// 나쁜 예
int (*p) = 17;	// error
char (*p) = 'a';	// error

// 좋은 예
int num = 17;
int (*p) = &num;	// num의 주소값이 입력
int (*p) = NULL;	// 의도적으로 비워두든지 (가장 추천!)
int (*p);		// 선언만 해두든지
  • 일반 변수에 주소 연산자 &를 붙이면, 주소값이 튀어나옴
  • 포인터 변수에 참조 연산자 *을 붙이면, 변수값이 튀어나옴

P = 주소 ⟹ *P = 값  * : 값 찾아줘!

Num = 17 ⟹ &Num = 주소   & : 주소 찾아줘!

// 함수 포인터 사용 예시

#include <stdio.h>

int add(int a, int b) // 덧셈함수
{
    return a + b;
}

int sub(int a, int b) // 뺄셈함수
{
    return a - b;
}

int main()
{
    int (*fp)(int, int); // 함수 포인터 선언

    fp = add;   // add 함수의 메모리 주소를 함수 포인터 fp에 저장
    printf("결과 값 : %d\n", fp(10, 20)); //add 함수를 호출

    fp = sub;   // sub 함수의 메모리 주소를 함수 포인터 fp에 저장
    printf("결과 값 : %d\n", fp(10, 20)); //sub 함수 호출

    return 0;
}

 






가변인자

인자의 개수가 변하는 인자

// 예시
void func(int numargs , ...) // ...이 가변인자라는 표현
{
	소스코드
}

int mina()
{
	func(1,10); // numargs = 1 , 가변 인자 1개 10
    func(2,10,20); // numargs = 2 , 가변 인자 2개 10 , 20
	return 0;
}
  • <stdarg.h> 가변인자들을 제어하기 위한 라이브러리 헤더 파일
    • va_list : 가변 인자 목록으로 가변 인자의 메모리 주소를 저장하는 포인터
    • va_start : 가변 인자를 가져올 수 있도록 설정
    • va_arg : 가변 인자 포인터에서 특정 자료형의 크기만큼 값을 꺼냄
    • va_end : 가변 인자 처리가 끝났을 때 포인터를 NULL로 초기화
// 예시
#include <stdio.h>
#include <stdarg.h>
void func(int numargs, ...)
{
	//가변 인자들을 담을 목록 포인터 만들기
	va_list numlist;
	//가변 인자 목록 포인터에 들어온 가변인자 셋팅하기
	va_start(numlist, numargs);
	//가변 인자의 수만큼 반복하면서 가변인자 탐색해보기
	for (int i = 0; i < numargs; i++)
	{
		// 가변 인자를 담은 목록 포인터에서 int크기만큼 값을 꺼내서 확인 
		printf("%d 번째 가변인자 : %d \n", i + 1, (va_arg(numlist, int)));
	}
	//사용이 끝난 가변인자 목록 포인터의 소멸
	va_end(numlist);
}
int main()
{
	printf("함수 실행 1 \n");
	func(3, 20, 30, 40);
	printf("함수 실행 2 \n");
	func(5, 1, 2, 3, 4, 5);
	return 0;
}

 









연습

1.

 // 다음과 같은 코드를 이해해봅시다.
#include <stdio.h>

int add(int a, int b){
    return a + b;
}   // add라는 함수 정의

int main(){
    int result = add(5, 10);    // 반환값 15
    printf("The result is %d\\n", result);
    return 0;
}

// 실행결과
// The result is 15\n

 

2.

// 아래의 코드의 실행 결과를 예상하여 봅시다
#include <stdio.h>

void print_hello(int n){
    if(n <= 0) return;    // n값이 0보다 작거나 같으면 종료
    printf("Hello, World!\\n");
    print_hello(n - 1);    // n이 0이 되기 전까지 Hello, World!\n 출력
}

int main(){
    print_hello(5);    // 5번 출력
    return 0;
}

// 실행결과
// Hello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\n

 

3.

// 아래의 코드를 완성하여 봅시다
#include <stdio.h>

double add(double a, double b){
        return a+b;
}

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

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

double dvd(double a, double b){
        return a/b;
}

int main(){
        int select;
        int a, b;
       
// 함수포인터 선언부
        double (*pf[4])(double, double);    // 함수 포인터 배열 사용
                pf[0]=add;
                pf[1]=sub;
                pf[2]=mul;
                pf[3]=dvd;

        printf("===============\\n");
        printf("0. 덧셈\\n");
        printf("1. 뺄셈\\n");
        printf("2. 곱셈\\n");
        printf("3. 나눗셈\\n");
        printf("4. 종료\\n");
        printf("================\\n\\n");

        printf("메뉴를 선택하시오 : ");
        scanf("%d", &select);

        if(select==4){
                printf("종료되었습니다.\n");
                return 0;
        }

        printf("2개의 정수를 입력하시오 : ");
        scanf("%d %d", &a, &b);

        printf("연산결과 = %f\\n", pf[select](a,b));
}

0개의 댓글