내용 정리
함수는 크게 라이브러리 함수와
사용자 지정 함수로 나뉜다
라이브러리 함수는 6장의 링크를 참조하여 사용할 때 찾아보면 익숙해질 것이다.
이번 chapter에서는 사용자 지정 함수에 대해 공부해보자
간단한 예제를 통해서 사용자 지정 함수가 어떠한 것인지
함수는 어떻게 생겼는지 보자
※ 사용자 지정 함수
예제로 간단한 1차원 배열 문제를 확인하고 넘어가려 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
//함수
//두 수중 큰 값 구하기
#include <stdio.h>
int find_larger(int first, int second)
{
int larger;
if (first > second)
larger = first;
else
larger = second;
return larger;
}
int main()
{
int n1, n2, max;
printf("첫 번째:");
scanf("%d", &n1);
printf("두 번째:");
scanf("%d", &n2);
max = find_larger(n1, n2);
printf("%d, %d중큰 수는:%d\n",n1,n2,max);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
main함수를 실행하다 도중에
find_larger(n1,n2)를 만나
n1, n2를 인자로 사용하여 find_larger을 호출한다.
find_larger함수가 실행되며, n1값은 first로 n2값은 second로 전달되어 저장된다.
이때n1 == first는 아니다!
전달하는 시점에 값을 전달해주는 것뿐이다.
find_larger은 int형 변수인 larger을 반환해주면서 함수가 끝나고
다시 함수를 호출했던 부분인 main함수로 돌아와서 계속 main함수를 진행한다.
※ 함수의 인수 전달 (값에 의한 전달, 주소에 의한 전달)
값에 의한 호출로는
함수를 호출할 때 전달하는 인자와
호출한 함수의 변수(전달받은 인자가 저장된 값)는 다른 변수이기 때문에
호출한 함수 내부에서 값을 변경하더라도
main함수에서는 그대로임...
예를 들어
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#include <stdio.h>
void sort(int first, int second)
{
int temp;
if (first > second)
{
temp = first;
first = second;
second = temp;
}
printf("\nsort함수의 정렬 결과 first: %d, second: %d\n\n", first, second);
printf("first의 기억장소 주소: %u\n", &first);
printf("second의 기억장소 주소: %u\n\n", &second);
}
int main()
{
int n1 = 5000, n2 = 4000;
printf("함수 호출 전 n1: %d, n2: %d\n", n1, n2);
sort(n1, n2);
printf("함수 호출 후 n1: %d, n2: %d\n\n", n1, n2);
printf("n1의 기억장소 주소: %u\n", &n1);
printf("n2의 기억장소 주소: %u\n", &n2);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
main함수의 변수 값을 다른 함수에서 변경 할 수 없다.
결과를 확인하면 sort함수에서는 숫자가 오름차순으로 정렬이 되었으나
sort함수를 호출 하고 나서 main함수의 숫자는 정렬이 안된것을 확인 할 수 있다.
이유는 변수가 전혀 다른 변수이기 때문이다.
전혀 다른 변수라는것은 변수가 저장 되어있는 기억장소의 주소를 확인하면 알 수 있다.
n1와 first의 변수의 주소가 다르다.
따라서 다른 함수에서 호출 한 함수의 변수를 변경하고 싶으면
변수의 주소를 함수에 전달하여야 한다!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
#include <stdio.h>
void sort(int *first, int *second)
{
int temp;
if (*first > *second)
{
temp = *first;
*first = *second;
*second = temp;
}
printf("\nsort함수의 정렬 결과 first: %d, second: %d\n\n", *first, *second);
printf("first의 기억장소 주소: %u\n", first); //&(*first)도 같은 표현
printf("second의 기억장소 주소: %u\n\n", second);
}
int main()
{
int n1 = 5000, n2 = 4000;
printf("함수 호출 전 n1: %d, n2: %d\n", n1, n2);
sort(&n1, &n2);
printf("함수 호출 후 n1: %d, n2: %d\n\n", n1, n2);
printf("n1의 기억장소 주소: %u\n", &n1);
printf("n2의 기억장소 주소: %u\n", &n2);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
main에서 sort(&n1,&n2)로 변수의 주소 전달
sort함수는 main주소를 전달받았으므로
간접 참조 연산자*를 이용해 주소가 아닌 값을 받아올 수 있다.
결과를 보면 main함수의 변수들이 정렬된 것을 볼 수 있다.
주소를 확인하면 main함수의 변수와 sort함수의 변수가 같은 것을 확인할 수 있다.
주소를 전달받았기 때문이다.
추후 포인터를 공부한다면 좀 더 쉽게 이해할 수 있을 것이다.
※ 배열을 인자로 함수에 전달하기
배열명도 포인터이므로 포인터처럼 사용하여 인자로 전달하면 된다.
결론이지만
이해해보자
배열의 원소 하나를 함수의 인자로 전달하는 방식으로 모든 원소를 함수에 넣는다.
이 방법 번거롭고 많은 함수 호출이 일어난다.
일단 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
//함수
//배열의 원소 하나하나를 인자로 전달
#include <stdio.h>
#define N 10
int find_larger(int first, int second);
int main()
{
int freeze[N] = { 15, 0, -20, -30, 50, -5, -120, -5, 10, -12 };
int i, max;
max = freeze[0];
for (i = 1; i < N; i++)
{
max = find_larger(max, freeze[i]);
}
printf("어는 점 목록:");
for (i = 0; i < N; i++)
{
printf("%d ", freeze[i]);
}
printf("\n가장 높은 어는 점:%d\n", max);
return 0;
}
int find_larger(int first, int second)
{
if (first > second)
return first;
else
return second;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
max = find_larger(max, freeze[i]);
함수 호출할 때 freeze배열의 원소 하나하나 find_larger함수에 넣어서 최댓값을 찾는다.
처음에 max = find_larger[0] 로 지정해 놓았기 때문에
함수에는 1번 원소부터 넣어서
find_larger(max,freeze[1]) => 0~1중 큰 값이 리턴
find_larger(max,freeze[2]) => 0~2중 큰 값이 리턴
find_larger(max,freeze[3]) => 0~3중 큰 값이 리턴
find_larger(max,freeze[4]) => 0~4중 큰 값이 리턴
...
find_larger(max,freeze[9]) => 0~9중 큰 값이 리턴
총 9번 함수를 호출하여 큰 값을 구한다.
원소 하나하나 인자로 전달하는 방법은 상당히 비효율적이다.
=> 배열 전체를 인자로 전달한다.
포인터를 배우지 않았지만, 배열명 = 포인터라고 알아두자
배열명인 freeze를 인자로 전달하면 배열 전체를 전달할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
//함수
//배열의 전체를 인자로 전달
#include <stdio.h>
#define N 10
int find_larger(int arr[]);
int main()
{
int freeze[N] = { 15, 0, -20, -30, 50, -5, -120, -5, 10, -12 };
int max,i;
max = find_larger(freeze);
printf("어는 점 목록:");
for (i = 0; i < N; i++)
{
printf("%d ", freeze[i]);
}
printf("\n가장 높은 어는 점:%d\n", max);
return 0;
}
int find_larger(int arr[])
{
int larger;
int i;
larger = arr[0];
for (i = 1; i < N-1; i++)
{
if (larger < arr[i])
larger = arr[i];
}
return larger;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
max = find_larger(freeze);
freeze배열 전체를 인자로 전달하였다.
배열 이름인 freeze는 변수를 저장하고 있는 변수가 아니라
배열의 시작 부분을 가리키고 있는 주소와 같다.
위 그림을 보면 이해가 가능하다.
freeze를 인자로 전달하여 freeze [0~9]까지 접근이 가능하게 된다.
-정리-
원소 하나하나를 전달하는 방법에 비해 훨씬 효율적인 방법
배열명을 인자로 전달하면 된다.
배열명은 배열의 첫 시작 원소의 주소이다.
※ 난수 구하기
난수구하기 은근히 자주 사용하는데 이참에 정리해보자
JAVA,C++,C#,C,PYTHON 배울 때 모두 사용한 거 같다
좀 자세히 정리해봐야지
C언어의 난수 생성함수
rand() : 0~32767 범위 안의 임의의 값 반환
헤더파일 stdlib.h(standard library 맞나?) 필요
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, random;
for (i = 1; i <= 5; i++)
{
random = rand();
printf("%d번째 난수:%5d\n", i, random);
}
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
계속 같은 결과 나온다. 41,18467,6334,26500,19169 계속 이 순서...
난수 맞니??
씨드 설정 함수인 srand를 설정하여 난수가 순서를 변경한다.
=> 씨드가 같으면 생성되는 난수의 순서가 동일하다.
default값은 1로
위에서 씨드를 설정하지는 않았지만 srand(1)로 설정이 되어있는 상태인 것이다.
하지만 씨드값을 프로그램을 실행할 때 매번 다르게 할 수 없다.
time함수를 이용하여 현재 시간으로 씨드값을
설정하면 매번 다르게 자동적으로 씨드값을 설정할 수 있다.
srand(time(NULL)) time 함수 사용하기 위해 time.h 헤더파일 필요
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int i, random;
srand(time(NULL));
for (i = 1; i <= 5; i++)
{
random = rand();
printf("%d번째 난수:%5d\n", i, random);
}
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
매번 다르다!! 이 정도는 돼야 난수라고 인정하지
※ 스케일링
난수를 원하는 범위로 설정하는 방법
간단하다
rand() : 0~32767 이라고 했다.
rand()%6 을 하면 0부터 5까지 나오겠지
그럼 (rand()%6)+1 을 하면 1부터 6까지의 범위가 나온다. (주사위)
5~10은
(rand%6)+5
일반화
min~max는
(rand%(max-min+1)) + min
간단한 게임 만들기
컴퓨터가 숨긴 수 맞추기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
//컴퓨터가 숨긴 1~100 중의 정수를 맞히는 게임
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int begin = 1, end = 100;
int count = 0;
int computer, user;
srand(time(NULL)); //씨드 설정
computer = (rand() % (end - begin + 1)) + begin; //컴퓨터가 숨기는 수 생성
do
{
printf("%d~%d중의 값입니다. 얼마일까요?", begin, end);
scanf("%d", &user);
count++;
if (user < computer)
begin = user + 1;
else
end = user - 1;
} while (user != computer);
printf("\n%d를 %d번만에 맞췄습니다.\n", computer, count);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|

computer = (rand() % (end - begin + 1)) + begin;
이것만 이해하면 끝
연습 문제
8, 9번을 풀어보겠다.
문제8: 한 달 동안의 음성 통화 시간이 voice분이고 문자 전송 건수가 text건일 때 휴대폰 사용료 계산 방법을
사용해 휴대폰 사용료 charge를 구하는 프로그램을 작성하시오
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#include <stdio.h>
int voice(int time)
{
int charge; //음성통화 요금
if (time > 100) //100분 초과
charge = (100 * 100) + ((time - 100) * 80);
else
charge = 100 * time;
return charge;
}
int message(int num)
{
int charge; //문자 요금
if (num > 20) //문자 20건 초과
charge = (num - 20) * 20;
else
charge = 0;
return charge;
}
int main()
{
int voice_time; //음성 통화 시간
int message_num; //문자 전송 건수
int voice_charge; //음성 통화 요금
int message_charge; //문자 전송 요금
int sum_charge; //총 요금
int surtex; //부가세
printf("음성 통화 시간은(분)? ");
scanf("%d", &voice_time);
printf("문자 전송 건수는? ");
scanf("%d", &message_num);
//함수 호출
voice_charge = voice(voice_time);
message_charge = message(message_num);
sum_charge = voice_charge + message_charge + 10000;
surtex = sum_charge*0.1;
//출력
printf("휴대폰 사용 요금 청구서\n");
printf("=========================================\n");
printf("음성 통화 시간 %d\n",voice_time);
printf("문자 전송 건수 %d건\n", message_num);
printf("-----------------------------------------\n");
printf("기본요금\t\t\t%6d원\n", 10000);
printf("음성 통화료 %d분\t\t%6d원\n",voice_time,voice_charge);
printf("문자 전송료 초과 %d건(20건 무료)%6d원\n", message_num-20, message_charge);
printf("-----------------------------------------\n");
printf("합계\t\t\t\t%6d원\n", sum_charge);
printf("부가세(10%%)\t\t\t%6d원\n", surtex);
printf("=========================================\n");
printf("이번 달 요금\t\t\t%6d원\n", sum_charge+ surtex);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
그냥 텍스트 줄 맞추는데 힘들었다.
문제9: 학생 N명의 퀴즈 점수 10,8,7,9,6,10,9,8,7이 저장된 배열 class에 대해 사용자의 점수가 입력되면 순위를 출력하는 프로그램을 작성하시오. 입력된 점수 my_score의 순위를 구하는 함수 rank를 정의해 사용하시오.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#include <stdio.h>
#define N 9
int rank(myscore, otherscore)
{
if (myscore < otherscore) //더 높은 점수있으면 등수 1개 낮추기
return 1;
else //내가 더 높으면 등수 그대로
return 0;
}
int main()
{
int score;
int my_rank = 1;
int i;
int class[N] = { 10, 8, 7, 9, 6, 10, 9, 8, 7 };
printf("사용자의 점수를 입력하세요: ");
scanf("%d", &score);
for (i = 0; i < N; i++) //배열 원소 하나씩 함수에 전달
{
my_rank += rank(score, class[i]); //리턴 받은 수를 누적시키기
}
for (i = 0; i < N; i++)
{
printf("%3d", class[i]);
}
printf("과 비교\n");
printf("내 등수 = %d등\n", my_rank);
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
포인터로 배열 전체를 함수에 인자로 전달하면 더 쉬울 것을 하나하나 전달하니까
변수 생각하는데 더 머리가 아프다.
아직 포인터 진도 안나갔으니 하나하나 전달하여 해결
'programming > C프로그래밍 개념' 카테고리의 다른 글
[C프로그래밍 새내기를 위한 첫 C 언어 책] Chapter10(포인터) 정리 및 연습문제 (0) | 2019.11.04 |
---|---|
[C프로그래밍 새내기를 위한 첫 C 언어 책] Chapter7(배열) 정리 및 연습문제 (0) | 2019.06.25 |
[C프로그래밍 새내기를 위한 첫 C 언어 책] Chapter6(전처리기) 정리 및 연습문제 (0) | 2019.06.25 |
[C프로그래밍 새내기를 위한 첫 C 언어 책] Chapter5(제어문) 정리 및 연습문제 (0) | 2019.06.25 |
[C프로그래밍 새내기를 위한 첫 C 언어 책] Chapter4(연산자) 정리 및 연습문제 (0) | 2019.06.24 |