Post

[C] ν•¨μˆ˜

πŸ“Œ λ“€μ–΄κ°€λ©°

같은 μ½”λ“œλ₯Ό μ—¬κΈ°μ €κΈ° λ°˜λ³΅ν•΄μ„œ μ“°λŠ” 건 λΉ„νš¨μœ¨μ μ΄λ‹€. 자주 μ“°λŠ” μ½”λ“œ 덩어리λ₯Ό ν•˜λ‚˜λ‘œ λ¬Άμ–΄ 이름을 뢙여두고, ν•„μš”ν•  λ•Œλ§ˆλ‹€ 뢈러 μ“°λŠ” 것이 ν•¨μˆ˜(function)λ‹€.

ν•¨μˆ˜λž€? 자주 반볡 μˆ˜ν–‰ν•  μ½”λ“œ 덩어리λ₯Ό β‘  ν•¨μˆ˜λ‘œ β€˜μ •μ˜β€™ν•˜κ³ , β‘‘ ν•„μš”ν•  λ•Œλ§ˆλ‹€ β€˜ν˜ΈμΆœβ€™ν•˜μ—¬ μ‚¬μš©ν•˜λŠ” 것.


1. ν•¨μˆ˜μ˜ μ •μ˜Β·ν˜ΈμΆœΒ·λ¦¬ν„΄

ν•¨μˆ˜ μ •μ˜ (function definition)

1
2
3
4
λ¦¬ν„΄νƒ€μž… ν•¨μˆ˜μ΄λ¦„(λ§€κ°œλ³€μˆ˜λ“€ ...)
{
    ν•¨μˆ˜ 본체 (μˆ˜ν–‰ μ½”λ“œλ“€)
}
  • ν•¨μˆ˜ μ›ν˜•(function prototype) = λ¦¬ν„΄νƒ€μž… ν•¨μˆ˜μ΄λ¦„(λ§€κ°œλ³€μˆ˜λ“€). ν•¨μˆ˜λ₯Ό μ„ μ–Έλ§Œ ν•  λ•Œ 이 μ›ν˜•μ„ μ“΄λ‹€.

Desktop View

πŸ’‘ Visual Studio μ†ŒμŠ€ 파일 μ™Όμͺ½μ˜ μ‚Όκ°ν˜• λ²„νŠΌμ„ μ—΄κ³  λ‹«μœΌλ©΄, κ·Έ νŒŒμΌμ— μ–΄λ–€ ν•¨μˆ˜κ°€ μ›ν˜• ν˜•νƒœλ‘œ μ“°μ˜€λŠ”μ§€ λ³Ό 수 μžˆλ‹€.

ν•¨μˆ˜ 호좜 (function call)

1
ν•¨μˆ˜μ΄λ¦„(λ§€κ°œλ³€μˆ˜μ— 넣을 κ°’);

μš°λ¦¬κ°€ 늘 μ“°λ˜ main()도 사싀 ν•¨μˆ˜μ˜ 일쒅이닀.

ν•¨μˆ˜μ˜ μ‹€ν–‰ 흐름

μ»΄νŒŒμΌλŸ¬κ°€ 호좜 μ½”λ“œλ₯Ό λ§Œλ‚˜λ©΄ 잠깐 λ©ˆμΆ”κ³  호좜된 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œλ‹€. λ‹€ 읽으면 λ©ˆμ·„λ˜ 곳으둜 λŒμ•„μ˜¨λ‹€(return).

1
2
3
4
main() μ‹€ν–‰ 쀑  β”€β”€ν˜ΈμΆœβ”€β”€β–Ί  oper() μ‹€ν–‰
     β–²                        β”‚
     └────── return β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        (λ©ˆμ·„λ˜ 지점뢀터 계속)

TMI: ν˜ΈμΆœν•œ ν•¨μˆ˜λ₯Ό caller, 호좜된 ν•¨μˆ˜λ₯Ό callee라고 ν•œλ‹€.

λ§€κ°œλ³€μˆ˜ vs 인자

μš©μ–΄μ •μ˜
λ§€κ°œλ³€μˆ˜(parameter)ν•¨μˆ˜λ₯Ό μ •μ˜ν•  λ•Œ λͺ…μ‹œν•˜λŠ” λ³€μˆ˜ (κ·Έ ν•¨μˆ˜μ˜ μ§€μ—­λ³€μˆ˜λ‘œ λ™μž‘)
인자(argument)ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ μ „λ‹¬ν•˜λŠ” κ°’

ν•¨μˆ˜ 호좜 μ‹œ μΈμžκ°€ λ§€κ°œλ³€μˆ˜λ‘œ β€˜λ³΅μ‚¬β€™λ˜μ–΄ μ‹€ν–‰λœλ‹€. (두 μš©μ–΄λŠ” μ‹€λ¬΄μ—μ„œ ν˜Όμš©λ˜κΈ°λ„ ν•œλ‹€.)


2. 예제둜 λ³΄λŠ” ν•¨μˆ˜

oper ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄ 보자. λ§€κ°œλ³€μˆ˜λŠ” int 2개, λ¦¬ν„΄νƒ€μž…μ€ void(리턴값 μ—†μŒ)λ‹€. λ³Έμ²΄μ—μ„œ 사칙연산을 μˆ˜ν–‰ν•œλ‹€.

Desktop View

main 밖에 ν•¨μˆ˜λ₯Ό λ§Œλ“€μ—ˆλ‹€. 그런데 μ΄λŒ€λ‘œ μ‹€ν–‰ν•˜λ©΄ oper μ•ˆμ˜ λ¬Έμž₯이 μ‹€ν–‰λ κΉŒ? μ•„λ‹ˆλ‹€. mainμ—μ„œ ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€.

Desktop View

oper(100, 10)은 β€œkμ—λŠ” 100, vμ—λŠ” 10을 λ„£μ–΄ μ‹€ν–‰β€ν•œλ‹€λŠ” λœ»μ΄λ‹€.

Desktop View

⚠️ μ‹€λ¬΄μ—μ„œλŠ” ν•¨μˆ˜λ“€μ΄ μ„œλ‘œλ₯Ό ν˜ΈμΆœν•˜λ©° λ³΅μž‘ν•˜κ²Œ μ–½νžŒλ‹€. main이 aaa()λ₯Ό ν˜ΈμΆœν•˜κ³ , aaa() μ•ˆμ—μ„œ λ‹€μ‹œ bbb()λ₯Ό ν˜ΈμΆœν•˜λŠ” 식이닀. λ”°λΌμ„œ ν•¨μˆ˜μ˜ 논리적인 호좜 μˆœμ„œλ₯Ό 잘 섀계해야 ν•œλ‹€.


3. 리턴(return)

리턴값: 자기λ₯Ό ν˜ΈμΆœν•œ ν•¨μˆ˜μ—κ²Œ λŒλ €μ£ΌλŠ” μ΅œμ’…κ°’ 1개. λ§€κ°œλ³€μˆ˜λ‘œ 식을 μˆ˜ν–‰ν•œ λ’€ λ‚˜μ˜¨ 결과값이닀.

Desktop View

두 κ°€μ§€ 방식을 λΉ„κ΅ν•˜μž.

1
2
3
4
5
6
7
8
9
10
11
// β‘  λ³€μˆ˜μ— λ‹΄μ•„ 리턴
int add(int a, int b) {
    int sum = a + b;
    return sum;
}
int result = add(10, 5);   // result = 15

// β‘‘ 식을 κ·ΈλŒ€λ‘œ 리턴
int sub(int a, int b) {
    return a - b;          // κ²°κ³ΌλŠ” 동일
}
  • add(10, 5)의 리턴값은 15μ΄λ―€λ‘œ, int result = add(10, 5);μ—μ„œ result에 15κ°€ λŒ€μž…λœλ‹€.
  • void νƒ€μž…μ€ 리턴값이 μ—†μœΌλ‹ˆ, printf 같은 λ¬Έμž₯으둜 κ²°κ³Όλ₯Ό μ²˜λ¦¬ν•˜λ©΄ λœλ‹€.

4. μˆœμ„œ β€” β€˜μ„ μ–Έβ€™κ³Ό β€˜μ •μ˜β€™

λ³€μˆ˜λ₯Ό μ„ μ–Έ 후에 μ“°λ“―, ν•¨μˆ˜λ„ μ •μ˜(λ˜λŠ” μ΅œμ†Œν•œ μ„ μ–Έ)κ°€ ν˜ΈμΆœλ³΄λ‹€ μ•žμ— μžˆμ–΄μ•Ό ν•œλ‹€. μ»΄νŒŒμΌλŸ¬κ°€ μœ„β†’μ•„λž˜λ‘œ 읽기 λ•Œλ¬Έμ΄λ‹€.

Desktop View

main μ•„λž˜μ— half ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λ©΄ 였λ₯˜κ°€ λ‚œλ‹€. ν•˜μ§€λ§Œ 방법이 μžˆλ‹€. β€˜μ •μ˜β€™λŠ” μ•„λž˜μ—μ„œ ν•˜λ˜, β€˜μ„ μ–Έβ€™λ§Œ μœ„μ—μ„œ ν•΄μ£Όλ©΄ λœλ‹€.

1
2
3
4
5
6
7
8
9
double half(int n);   // μœ„μ—μ„œ 'μ„ μ–Έ' (ν•¨μˆ˜ μ›ν˜•)

int main() {
    ... half(10) ...   // 호좜 κ°€λŠ₯!
}

double half(int n) {   // μ•„λž˜μ—μ„œ 'μ •μ˜'
    return n / 2.0;
}

Desktop View

Desktop View

잘 μ‹€ν–‰λœλ‹€.


5. 헀더 파일둜 μ„ μ–Έ λΆ„λ¦¬ν•˜κΈ°

μ—¬λŸ¬ μ†ŒμŠ€ νŒŒμΌλ§ˆλ‹€ ν•¨μˆ˜λ₯Ό 일일이 μ„ μ–ΈΒ·μ •μ˜ν•˜λŠ” 건 λ²ˆκ±°λ‘­λ‹€. κ·Έλž˜μ„œ 헀더 파일(.h)에 ν•¨μˆ˜μ˜ 선언을 λͺ¨μ•„λ‘”λ‹€.

Desktop View

헀더 νŒŒμΌμ΄λž€? ν•¨μˆ˜μ˜ μ„ μ–Έ, 맀크둜, μƒμˆ˜ 등을 λͺ¨μ•„λ‘” 파일. μš°λ¦¬κ°€ 늘 μ“°λŠ” #include <stdio.h>도 헀더 νŒŒμΌμ΄λ‹€. κΈ°λ³Έ ν•¨μˆ˜λ“€μ˜ 선언이 κ±°κΈ° μžˆμ–΄μ„œ, κ·Έκ±Έ 포함해야 κ·Έ ν•¨μˆ˜λ“€μ„ μ“Έ 수 μžˆλ‹€.

ꡬ뢄포함 λ°©μ‹μ˜ˆ
ν‘œμ€€ 헀더#include <...>#include <stdio.h>
직접 λ§Œλ“  헀더#include "..."#include "myfunction.h"

μ—­ν•  뢄리λ₯Ό 그림으둜 μ •λ¦¬ν•˜λ©΄ 이렇닀.

1
2
3
myfunction.h  ←  ν•¨μˆ˜ 'μ„ μ–Έ'만 λͺ¨μŒ
myfunction.c  ←  ν•¨μˆ˜ 'μ •μ˜'만 λͺ¨μŒ
test.c(main)  ←  #include "myfunction.h" ν›„ '호좜'만

Desktop View

ν”„λ‘œμ νŠΈμ˜ μ†ŒμŠ€ 파일 λͺ©λ‘μ„ 보면, λΉŒλ“œμ—μ„œ μ œμ™Έ(κΈˆμ§€ ν‘œμ‹œ)된 νŒŒμΌλ“€μ΄ μžˆλ‹€. ν™œμ„±ν™”λœ 것은 β‘  main을 ν¬ν•¨ν•œ 파일과 β‘‘ ν•¨μˆ˜ μ •μ˜λ₯Ό λͺ¨μ€ 파일 두 κ°œλ‹€. (μ •μ˜ νŒŒμΌμ—λŠ” main이 μ—†λ‹€.)

Desktop View

μ •λ¦¬ν•˜λ©΄ 이렇닀.

ν•œ μ†ŒμŠ€ νŒŒμΌμ— ν•¨μˆ˜λ₯Ό β€˜μ •μ˜β€™ν•˜κ³ , 헀더 νŒŒμΌμ— ν•¨μˆ˜λ₯Ό β€˜μ„ μ–Έβ€™ν•˜κ³ , main이 μžˆλŠ” μ†ŒμŠ€ νŒŒμΌμ— κ·Έ 헀더λ₯Ό #includeν•˜λ©΄ β†’ main νŒŒμΌμ—μ„œλŠ” κ·Έλƒ₯ β€˜ν˜ΈμΆœβ€™λ§Œ ν•˜λ©΄ λœλ‹€.

power(3, 4) (3의 4제곱 = 81)λ₯Ό 예둜 확인해 보자. μ •μ˜λŠ” myfunction.c, 선언은 헀더에, ν˜ΈμΆœμ€ test.cμ—μ„œ.

Desktop View

Desktop View

main에 선언도 μ •μ˜λ„ 없이 호좜만으둜 잘 λ™μž‘ν•œλ‹€.


6. μž¬κ·€ 호좜 (recursive call)

μž¬κ·€ 호좜: ν•¨μˆ˜κ°€ μ‹€ν–‰ 쀑에 자기 μžμ‹ μ„ λ‹€μ‹œ ν˜ΈμΆœν•˜λŠ” 것.

νŠΉμ§•μ„€λͺ…
μž₯μ λ³΅μž‘ν•œ 문제λ₯Ό λ‹¨μˆœν™”ν•˜μ—¬ κ΅¬ν˜„ κ°€λŠ₯
μ œμ•½λ¬΄ν•œ μž¬κ·€λŠ” λΆˆκ°€ (λ°˜λ“œμ‹œ μ’…λ£Œ 쑰건 ν•„μš”)

Desktop View

func1의 리턴값이 또 func1(n+1)이닀. mainμ—μ„œ func1(1)을 ν˜ΈμΆœν•˜λ©΄ μ–΄λ–»κ²Œ 될까? λ¬΄ν•œνžˆ ν˜ΈμΆœλœλ‹€.

Desktop View

⚠️ κ·Έλž˜μ„œ ν•¨μˆ˜ μ•ˆμ— if (n == ?) 같은 μ’…λ£Œ 쑰건(base case)을 두고, κ·Έλ•Œμ˜ 리턴값을 μ§€μ •ν•΄ λ¬΄ν•œ ν˜ΈμΆœμ„ 막아야 ν•œλ‹€.


πŸ“ 정리

1
2
3
4
5
6
7
8
ν•¨μˆ˜(function)
β”œβ”€ μ •μ˜    λ¦¬ν„΄νƒ€μž… 이름(λ§€κ°œλ³€μˆ˜) { 본체 }
β”œβ”€ 호좜    이름(인자);  β†’ callerκ°€ λ©ˆμΆ”κ³  callee μ‹€ν–‰ ν›„ return
β”œβ”€ λ§€κ°œλ³€μˆ˜/인자  μ •μ˜ μ‹œ λ³€μˆ˜ / 호좜 μ‹œ 전달값 (볡사됨)
β”œβ”€ return  ν˜ΈμΆœμžμ—κ²Œ μ΅œμ’…κ°’ 1개 λ°˜ν™˜
β”œβ”€ μˆœμ„œ    μ„ μ–Έ(μ›ν˜•)만 μœ„μ— 있으면 μ •μ˜λŠ” μ•„λž˜μ—¬λ„ OK
β”œβ”€ 헀더    .h에 'μ„ μ–Έ' λͺ¨μŒ β†’ #include 둜 μž¬μ‚¬μš©
└─ μž¬κ·€    자기 μžμ‹  호좜, λ°˜λ“œμ‹œ μ’…λ£Œ 쑰건 ν•„μš”
κ°œλ…ν•œ 쀄 μ •μ˜
ν•¨μˆ˜λ°˜λ³΅ μ½”λ“œλ₯Ό μ •μ˜ν•˜κ³  ν˜ΈμΆœν•΄ μž¬μ‚¬μš©ν•˜λŠ” λ‹¨μœ„
μ›ν˜•(prototype)λ¦¬ν„΄νƒ€μž… 이름(λ§€κ°œλ³€μˆ˜), 선언에 μ‚¬μš©
λ§€κ°œλ³€μˆ˜/μΈμžμ •μ˜ μ‹œ λ³€μˆ˜ / 호좜 μ‹œ 전달값
헀더 νŒŒμΌν•¨μˆ˜ μ„ μ–ΈΒ·λ§€ν¬λ‘œΒ·μƒμˆ˜λ₯Ό λͺ¨μ•„ μž¬μ‚¬μš©
μž¬κ·€ 호좜자기 μžμ‹ μ„ 호좜, μ’…λ£Œ 쑰건 ν•„μˆ˜

ν•¨μˆ˜λŠ” ν”„λ‘œκ·Έλž˜λ°μ˜ β€˜νš¨μœ¨κ³Ό μž¬μ‚¬μš©β€™μ„ λ‹΄λ‹Ήν•˜λŠ” 핡심 도ꡬ닀. μ„ μ–Έκ³Ό μ •μ˜μ˜ 뢄리, 그리고 헀더 파일둜 μ΄μ–΄μ§€λŠ” 흐름을 μ΄ν•΄ν•˜λ©΄ 규λͺ¨κ°€ 큰 ν”„λ‘œμ νŠΈλ„ κΉ”λ”ν•˜κ²Œ ꡬ성할 수 μžˆλ‹€.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.