함수(function)
1. 함수란 ?
- 자주 반복되고 특징있는 내용들을 별도의 프로그램 형태로 기술해 놓고, 필요할 때마다 호출해서 사용하기 위한 블록단위의 코드들
- 프로그램의 유지보수가 편해지고, 메모리를 절약하며, 이식성을 좋게 한다.
2. 함수의 종류
1) 시스템 함수
2) 내장 함수(built-type function)
3) 외장 함수(user-defined type function)
3. 함수 작성시 유의 할 사항
1) 어떤 기능을 할 것인가?
2) 매개변수(parameter)의 사용 여부
3) return type의 효율적 사용
4. 함수의 구조
사용자 정의 함수 선언 --> 함수의 헤더가 들어간다
메인 함수부{}
사용자 정의 함수 정의{} --> 함수의 바디가 들어간다
5. 함수의 헤더
- 함수의 필수요소를 기재
- 리턴타입, 함수의 이름, ()
=======================================================
#include <stdio.h>
void getSum(); //함수를 선언할때는 함수의 헤더를 쓴다. 그리고 이름, 괄호, 리턴타입을 꼭 써 주어야한다. void 타입은 리턴을 안 받는다.
int main()
{
puts("Program is Starting");
getSum();
puts("Program is Over...");
return 0;
}
void getSum() //함수의 바디
{
int hap = 0;
int i;
for(i = 1 ; i < 101 ; i++) hap += i;
printf("1부터 100까지의 합은 %d입니다.\n", hap);
}
출력:
Program is Starting
1부터 100까지의 합은 5050입니다.
Program is Over...
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#include <stdio.h>
void getSum(int);
int main()
{
puts("Program is Starting");
getSum(50); //Call by Value
getSum(80);
getSum(10);
puts("Program is Over...");
return 0;
}
void getSum(int su)
{
int hap = 0;
int i;
for(i = 1 ; i < su; i++) hap += i;
printf("1부터 %d까지의 합은 %d입니다.\n", su, hap);
}
출력:
Program is Starting
1부터 50까지의 합은 1225입니다.
1부터 80까지의 합은 3160입니다.
1부터 10까지의 합은 45입니다.
Program is Over...
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#include <stdio.h>
void getSum(int, int);
int main()
{
puts("Program is Starting");
getSum(30,50); //Call by Value
getSum(1,80);
getSum(5,10);
puts("Program is Over...");
return 0;
}
void getSum(int start, int end)
{
int hap = 0;
int i;
for(i=start; i < end ; i++) hap += i;
printf("%d부터 %d까지의 합은 %d입니다.\n", start, end, hap);
}
출력:
Program is Starting
30부터 50까지의 합은 790입니다.
1부터 80까지의 합은 3160입니다.
5부터 10까지의 합은 35입니다.
Program is Over...
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
- 두개의 정수를 입력받아 5가지 연산을 수행
#include <stdio.h>
void input();
void calc(int, int, char);
int main()
{
char y_n = '\0';
puts("Program is Starting..");
do{
input(); //Call by Name
printf("Again(y/n) ? : ");
scanf("%*c%c", &y_n);
}while(y_n == 'y' || y_n == 'Y');
puts("Program is Over...");
return 0;
}
void input(){
int su, num;
char op;
printf("두개의 정수를 입력하세요 : ");
scanf("%d%d", &su, &num);
printf("연산자를 입력하세요(+,-,x,/,%%) : ");
scanf("%*c%c", &op);
calc(su, num, op); //argument variable
}
void calc(int first, int second, char operator){ //parameter variable
switch(operator){
case '+' : printf("%d + %d = %d\n", first, second, (first + second)); break;
case '-' : printf("%d - %d = %d\n", first, second, (first - second)); break;
case 'x' : printf("%d x %d = %d\n", first, second, (first * second)); break;
case '/' : printf("%d / %d = %d\n", first, second, (first / second)); break;
case '%' : printf("%d %% %d = %d\n", first, second, (first % second)); break;
default : puts("Invalid Operator");
}
}
출력:
Program is Starting..
두개의 정수를 입력하세요 : 35 35
연산자를 입력하세요(+,-,x,/,%) : /
35 / 35 = 1
Again(y/n) ? : y
두개의 정수를 입력하세요 : 42
44
연산자를 입력하세요(+,-,x,/,%) : +
42 + 44 = 86
Again(y/n) ? : n
Program is Over...
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
-call by valued 의 단점
#include <stdio.h>
void change(int);
int main()
{
int su = 5;
change(su);
printf("su = %d\n", su);
return 0;
}
void change(int num){
num *= 100;
printf("in change() num = %d\n", num);
}
출력:
in change() num = 500
su = 5
값 복사이기 때문에 밑의 함수에서 수행된 동작들이 메인 함수에 전혀 영향을 미치지 않는다.
------------------------------------
위의 단점을 극복하는 방법은 리턴을 받는 것이다.
#include <stdio.h>
char irum[20]; //값을 넘기기 위해 전역변수로..
char * getString();
int main()
{
char * str = getString();
printf("str = %s\n", str);
return 0;
}
char * getString(){
// char irum[20]; //전역변수를 안쓰고 이렇게 지역변수를 쓴다면 제대로 출력이 안된다.
printf("당신의 이름은 ? ");
scanf("%s", irum);
return irum;
}
출력:
당신의 이름은 ? 푸르르리
str = 푸르르리
------------------------------------------
위에서 풀었던 문제를 리턴타입을 받아서 출력해보면
#include <stdio.h>
int getSum(int, int);
int main()
{
puts("Program is Starting");
int result = getSum(30,50); //이런식으로 변수 result를 만들어서
printf("result = %d\n", result); // 출력해주어도 되고
printf("%d\n", getSum(1,80)); //이렇게 바로 출력해도 된다.
printf("%d\n", getSum(5,10));
puts("Program is Over...");
return 0;
}
int getSum(int start, int end)
{
int hap = 0;
int i;
for(i=start; i < end ; i++) hap += i;
return hap;
}
출력:
Program is Starting
result = 790
3160
35
Program is Over...
--------------------------------------------------
다시 메인이 다른함수에게 출력하라고 넘겨주는
#include <stdio.h>
int getSum(int, int);
void output(int, int, int);
int main()
{
puts("Program is Starting");
int result = getSum(30,50); //Call by Value
output(30,50,result);
printf("%d\n", getSum(1,80));
output(5,10,getSum(5,10));
puts("Program is Over...");
return 0;
}
int getSum(int start, int end)
{
int hap = 0;
int i;
for(i=start; i < end ; i++) hap += i;
return hap;
}
void output(int start, int end, int result){
printf("%d부터 %d까지의 합은 %d입니다.\n", start, end, result);
return; //함수가 끝난 것을 의미. 복귀하라.
}
출력:
Program is Starting
30부터 50까지의 합은 790입니다.
3160
5부터 10까지의 합은 35입니다.
Program is Over...
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
call by value 의 리턴은 하나밖에 실행이 안된다.
#include <stdio.h>
int change();
int main()
{
int result = change();
printf("result = %d\n", result);
return 0;
}
int change(){
printf("Enter a integral number : ");
int su;
scanf("%d", &su);
return 5; //return은 곧 함수의 끝을 의미한다. 그래서 아래문장은 실행하지 않는다.
printf("su = %d\n", su);
return 10;
}
출력:
Enter a integral number : 8
result = 5
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
리턴은 여러개를 쓸수있지만, 단 하나의 리턴만 실행한다. 그래서 조건문 같은 곳에서는 여러개가 있을 수있음.
#include <stdio.h>
char * change();
int main()
{
char * ptr = change();
printf("ptr = %s\n", ptr);
return 0;
}
char * change(){
printf("Enter a integral number : ");
int su;
scanf("%d", &su);
if(su % 2 == 0) return "짝수입니다";
else return "홀수입니다";
}
출력:
Enter a integral number : 133
ptr = 홀수입니다
===========================================================
call by pointer
//call by pointer, call by location, call by address
#include <stdio.h>
void change(int *);
int main()
{
int original = 100;
change(&original);
printf("original = %d\n", original);
return 0;
}
void change(int * ptr){ //int * ptr = &original
* ptr *= 100;
printf("in change() * ptr = %d\n", * ptr);
}
출력:
in change() * ptr = 10000
original = 10000
(call by value와 다르게 포인터 값으로 해준 경우 리턴을 안해줘도 값이 바뀜을 볼 수있다.)
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#include <stdio.h>
void input(int *, int *);
int main()
{
int a, b;
input(&a, &b);
printf("a = %d, b= %d\n", a, b);
return 0;
}
void input(int * first, int * second){ //int * first = &a, int * second = &b;
int su, num;
printf("두개의 정수를 입력하세요 : ");
scanf("%d%d", first, second); //&이 아닌 이미 first가 포인터 변수이므로...
}
출력:
두개의 정수를 입력하세요 : 5 8
a = 5, b= 8
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
배운 것을 이용한 성적관리 프로그램....
#include <stdio.h>
#include <stdlib.h>
void input(char *, char *, int *, int *, int *);
void calc(int, int, int, int *, double *, char *);
char getGrade(double);
void output(char *, char *, int, int, int, int, double, char);
int main()
{
char * hakbun, * irum, grade;
int kor, eng, mat, tot;
double avg;
hakbun = (char *)malloc(7);
irum = (char *)malloc(20);
puts("Program is Starting...");
input(hakbun, irum, &kor, &eng, &mat);
calc(kor, eng, mat, &tot, &avg, &grade);
output(hakbun, irum, kor, eng, mat, tot, avg, grade);
puts("Program is Over...");
return 0;
}
void input(char * hptr, char * iptr, int * kptr, int * eptr, int * mptr){
printf("학번, 이름, 국어, 영어, 수학 점수 입력 : ");
scanf("%s%s%d%d%d", hptr, iptr, kptr, eptr, mptr);
}
void calc(int k, int e, int m, int * tptr, double * aptr, char * gptr){
* tptr = k + e + m;
* aptr = * tptr / 3.;
char grade = getGrade(* aptr);
* gptr = grade;
}
char getGrade(double a){
char imsi;
switch((int)(a/10)){
case 10 :
case 9 : imsi = 'A'; break;
case 8 : imsi = 'B'; break;
case 7 : imsi = 'C'; break;
case 6 : imsi = 'D'; break;
default : imsi = 'F';
}
return imsi;
}
void output(char * hptr, char * iptr, int k, int e, int m, int t, double a, char g){
printf("%s %s %d %d %d %d %.2f %d\n", hptr, iptr, k, e, m, t, a, g);
}
출력:
Program is Starting...
학번, 이름, 국어, 영어, 수학 점수 입력 : 20051523 서루니 80 90 50
20051523 서루니 80 90 50 220 73.33 67
Program is Over...
----------------------------------------------------------------------------
위의 성적관리프로그램을 일입파출력을 이용해서.
먼저 성적파일 cat sungjuk.dat 만들고
145525 설운도 78 90 100
130132 이미자 100 56 88
113303 김구라 67 56 77
한 사람의 정보만 가져오면 파일을 열고 fscanf를 통해서 첫줄을 읽고 출력하는게 쉽지만, 전체를 가져오려면 복잡한 방법을 거쳐야한다.
전체를 읽기위해 메인에서 루프를 돌았다.
#include <stdio.h>
#include <stdlib.h>
void getPath(char *);
void input(FILE *, char *, char *, int *, int *, int *);
void calc(int, int, int, int *, double *, char *);
char getGrade(double);
void output(char *, char *, int, int, int, int, double, char);
int main()
{
char * hakbun, * irum, grade, * path;
int kor, eng, mat, tot;
double avg;
FILE * fp;
hakbun = (char *)malloc(7);
irum = (char *)malloc(20);
path = (char *)malloc(100);
puts("Program is Starting...");
getPath(path);
fp = fopen(path, "r");
if(path == NULL){
puts("File Not Found");
return -1;
}
while(1){
input(fp, hakbun, irum, &kor, &eng, &mat);
if(feof(fp)) break;
calc(kor, eng, mat, &tot, &avg, &grade);
output(hakbun, irum, kor, eng, mat, tot, avg, grade);
}
fclose(fp);
puts("Program is Over...");
return 0;
}
void getPath(char * pptr){
printf("성적 데이터 파일 경로 : ");
scanf("%s", pptr);
}
void input(FILE * fp, char * hptr, char * iptr, int * kptr, int * eptr, int * mptr){
fscanf(fp, "%s%s%d%d%d", hptr, iptr, kptr, eptr, mptr);
}
void calc(int k, int e, int m, int * tptr, double * aptr, char * gptr){
* tptr = k + e + m;
* aptr = * tptr / 3.;
char grade = getGrade(* aptr);
* gptr = grade;
}
char getGrade(double a){
char imsi;
switch((int)(a/10)){
case 10 :
case 9 : imsi = 'A'; break;
case 8 : imsi = 'B'; break;
case 7 : imsi = 'C'; break;
case 6 : imsi = 'D'; break;
default : imsi = 'F';
}
return imsi;
}
void output(char * hptr, char * iptr, int k, int e, int m, int t, double a, char g){
printf("%s %s %d %d %d %d %.2f %d\n", hptr, iptr, k, e, m, t, a, g);
}
출력:
Program is Starting...
성적 데이터 파일 경로 : ./sungjuk.dat
145525 설운도 78 90 100 268 89.33 66
130132 이미자 100 56 88 244 81.33 66
113303 김구라 67 56 77 200 66.67 68
Program is Over...
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#include <stdio.h>
void swap(int *, int *);
int main()
{
int num = 5, su = 9;
printf("Before Swapping num = %d, su = %d\n", num, su);
swap(&num, &su);
printf("After Swapping num = %d, su = %d\n", num, su);
return 0;
}
void swap(int * first, int * second){
int imsi = * first;
* first = * second;
*second = imsi;
printf("In Swap() * first = %d, * second = %d\n", * first, * second);
}
출력:
Before Swapping num = 5, su = 9
In Swap() * first = 9, * second = 5
After Swapping num = 9, su = 5
==========================================================
메인에 파라미터를 넣어준 경우.
#include <stdio.h>
int main(int su, char * array[])
{
int i;
for(i = 0; i < su ; i++){
printf("array [%d] = %s\n", i, array[i]);
}
}
이렇게 실행하면 ./main 바나나 딸기 포도 복숭아 사과
array [0] = ./main
array [1] = 바나나
array [2] = 딸기
array [3] = 포도
array [4] = 복숭아
array [5] = 사과
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
메인에 파라미터를 넣어 계산기를 만들어보자.
#include <stdio.h>
#include <stdlib.h>
int getValue(int a, int b, char op){
switch(op){
case '+' : return a + b; break;
case '-' : return a - b; break;
case 'x' : return a * b; break;
case '/' : return a / b; break;
case '%' : return a % b; break;
}
}
int main(int num, char * array[])
{
if(num !=4 ){
puts("Invalid Usage");
puts("Usage : ./calculator argu1 op argu2");
return -1;
}
int first = atoi(array[1]); //"4" --> 4 문자가 숫자로
int second = atoi(array[3]); //"5" --> 5
char operator = array[2][0]; // [2][1]에는 '\0' 값이 들어있음.
printf("%d %c %d = %d\n", first, operator, second, getValue(first, second, operator));
return 0;
}
출력:
이렇게 입력하면 ./calculator 5 + 3
5 + 3 = 8
./calculator 5 - 3
5 - 3 = 2
./calculator 5 x 3
5 x 3 = 15
./calculator 5 / 3
5 / 3 = 1
./calculator 5 % 3
5 % 3 = 2
============================================================
'Java & Oracle' 카테고리의 다른 글
c 배열 , 전처리기, 버블정렬, 선택정렬 (0) | 2014.03.04 |
---|---|
c 이클립스 설치 & 기억류 (0) | 2014.03.03 |
c 제어문 day9 (0) | 2014.02.27 |
c 입출력함수 day8 (0) | 2014.02.26 |
c 변수, 연산자 day7 (0) | 2014.02.25 |