{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 함수\n", "\n", "함수는 반복적인 동작에 이름을 붙여 호출할 때마다 실행되도록 하는 아주 유용한 기능이다. 함수의 리턴 형과 매개변수의 활용, 재귀함수 등이 기억해야할 주요한 요소들이다. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 문제\n", "\n", "함수의 프로토타입 또는 선언에 사용된 매개변수의 이름은 실제 정의에 사용된 매개변수의 이름과 같을 필요는 없다. 아래에 정의되어 있는 `multiply`라는 함수는 정의되어 있지만 호출하는 문장이 없어 오류가 발생한다. 어느 줄에 삽입해야 하는지 생각해보고 코드를 수정해보자. 또한, 함수의 바디/내용도 정의되어 있지 않다. 제곱을 구하는 코드로 함수 내용을 작성해보자." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#include \n", "\n", "int multiply(int value);\n", "\n", "int main()\n", "{\n", " int number, result;\n", " printf(\"Etner a number\");\n", " scanf(\"%d\", &number);\n", " printf(\"square of %d is %d\", number, result);\n", " \n", " return 0;\n", "}\n", "\n", "int multiply(int number)\n", "{\n", " // your code here\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 문제\n", "\n", "함수의 매개변수의 형과 함수의 리턴 형은 같을 필요가 없다. 그리고 하나 이상의 매개변수를 사용할 수 있으며 매개 변수 대신 다른 함수를 쓰는 경우도 있다. 아래는 리턴 형이 `double`이고 매개변수는 두 개의`int`형 변수를 쓰려고 한다. \n", "\n", "`area()` 라는 함수를 호출하면 삼각형의 넓이를 구하여 리턴하도록 아래의 코드를 작성해보자. 함수의 프로토타입과 정의를 작성해보자." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "// Global varaible\n", "\n", "#include \n", "\n", "// your code here\n", "\n", "int main()\n", "{\n", " double ans;\n", " num1 = 23; // height\n", " num2 = 30; // width of triangle\n", " ans = area(num1, num2);\n", " printf(\"Area of triangle= %f\\n\", ans);\n", " \n", " return 0;\n", "}\n", "\n", "// your code here" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 문제\n", "\n", "아래 코드에서 변수 i는 함수들 밖에 정의가 되어 있다. 이렇게 정의된 변수를 전역(global) 변수라고 한다. 이 변수는 모든 함수들에서 사용될 수 있다. 아래의 코드에서 사용된 것처럼 한 함수에서 변경된 변수의 값이 다른 함수에서도 보이기 때문에, 오동작을 일으킬 여지가 매우 크다. \n", "\n", "아래 지시문처럼, 변수 선언의 위치를 바꿔보고 그에 따른 오류를 수정해보자." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "// Static Variable\n", "\n", "#include \n", "\n", "void static_test();\n", "int i = 1; // 이 줄을 main 또는 static_test 안으로 이동하면 어떤 결과가 나오나?\n", "\n", "int main()\n", "{\n", " for(i; i <= 5; i++)\n", " static_test();\n", " \n", " return 0;\n", "}\n", "\n", "void static_test()\n", "{\n", " static int sum = 0;\n", " sum = sum + 100;\n", " printf(\"%d iteration, sum = %d\\n\", i, sum);\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 문제\n", "\n", "아래에서는 두 개의 함수가 정의되어 있다. 하나는 `print_kor()` 라는 함수이고, 다른 하나는 `print_average()`라는 함수이다. \n", "\n", "1. 각각의 하는 일을 파악해보자. \n", "2. 다음의 코드를 수정하여 `main` 함수 내에서 `print_kor`만 호출하면 성적들과 평균 점수를 같이 출력하도록 만들어 보자. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#include \n", "\n", "void print_kor(int value);\n", "float print_average(int score[3]);\n", "\n", "int main()\n", "{\n", " int score[] = {95, 100, 85};\n", " float average;\n", " \n", " print_kor(score[0]);\n", " \n", " average = print_average(score);\n", " \n", " printf(\"average score is %.2f\\n\", average);\n", " \n", " return 0;\n", "}\n", "\n", "void print_kor(int value)\n", "{\n", " printf(\"score: %d\\n\", value);\n", "}\n", "\n", "float print_average(int score[3])\n", "{\n", " int i, sum = 0;\n", " for(i = 0; i < 3; i++)\n", " {\n", " sum += score[i];\n", " }\n", " return (float)sum/3;\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 문제\n", "\n", "배열의 요소들을 역순으로 출력하는 프로그램을 작성하고자 한다. 배열에는 최초 0으로 초기화되어 있고, 루프를 사용하여 짝수들로만 저장한다. 그리고 `reverse()`라는 함수를 호출하여 역순으로 출력해보자. 아래의 코드에는 여러가지 오류들이 있다. 그 오류들을 해결하여 목적에 맞게 동작하도록 해보자.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#include \n", "\n", "int main()\n", "{\n", " int arr[] = {0};\n", " \n", " for (int i = 0; i <= 20; i = i+2)\n", " {\n", " arr[i] = i;\n", " }\n", " \n", " reverse(arr);\n", "\n", " return 0;\n", "}\n", "\n", "void reverse(int arr[])\n", "{\n", " for(int i = 10; i <= 0; i--)\n", " {\n", " printf(\"%d\\t\", arr[i]);\n", " }\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 랜덤 함수의 활용\n", "\n", "랜덤한 수를 생성하는 방법을 알아보자. \n", "* ``에 정의되어 있는 `rand()`함수는 랜던한 값을 출력한다. 하지만 여러번 반복 실행해보아도 똑같은 결과만 출력하기 때문에 예측가능한 랜덤 값을 만들어낸다. 그렇기 때문에 안전한 랜덤 함수가 아니다. \n", "* 이를 해결하려면 초기화를 해야 한다. 초기화하는 함수는 마찬가지로 ``에 정의된 `srand()`라는 함수이다. 초기화를 하기 위해 매개변수가 필요한데, 고정 된 값으로 초기화 된다면 마찬가지로 예측가능한 랜덤 함수가 된다. 인자로 어떤 수식을 쓴다면 좀 더 예측 불가능한 랜덤 함수로 쓸 수 있다.\n", "* 이 때 보편적으로 많이 쓰는 (심각한 프로그램이 아닌 경우) 함수가 시간 함수이다. ``에 정의된 `time()`을 쓰면 된다. 외워두면 좋을 용법은 다음과 같다. \n", " srand((unsigned) time(NULL));\n", "\n", "아래의 코드를 실행 해보고, 주석 처리한 부분을 해제한 후 다시 실행해보자. 둘 사이의 차이를 숙지하자." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#include \n", "#include \n", "#include \n", "\n", "int main(void)\n", "{\n", " //srand((unsigned) time(NULL));\n", " for(int i = 0; i < 10; i++)\n", " {\n", " printf(\"%d\\n\", rand());\n", " }\n", " \n", " return 0;\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 문제\n", "\n", "카드를 셔플하고 5장을 꺼내는 프로그램을 작성하고자 한다. 위에서 소개한 랜덤함수를 활용하자. 한 벌의 카드에는 같은 랭크와 슈트가 한 장씩만 있기 때문에 랜덤함수를 통해 선택된 카드가 이 전에 사용된 것인지 확인해야 한다. 중복 확인 용 함수(`duplicated()`)와 셔플 용 함수(`shuffle()`)를 작성하여 문제를 해결해보자.\n", "\n", "`duplicated()`는 중복되었는지 여부를 확인하여 0 또는 1을 리턴함\n", "\n", "`shuffle()`은 인자로 전달 받은 값으로 랜덤한 값을 생성하여 리턴함\n", " \n", "힌트 1: 카드의 랭크와 슈트를 두 개의 다른 배열로 작성하자.\n", "\n", " 랭크: 2, 3, 4, 5, 6, 7, 9, j, q, k, a\n", " 슈트: c, d, h, s\n", " \n", "힌트 2: 이차원 배열을 불리언 형으로 사용하여 중복 되었는지 검사한다.\n", "\n", "힌트 3: 랜덤함수를 사용할 때 나머지 연산자를 쓰면 생성되는 수를 범위 내로 한정할 수 있다.\n", "\n", "힌트 4: 2차원 이상의 배열에서는 1차원 배열을 길이를 한정 함수에 전달할 수 있음." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "// your code here\n", "\n", "int main(void)\n", "{\n", " int NumCards = 5;\n", " // your code here \n", " return 0;\n", "}\n", "\n", "\n", "// your code here" ] } ], "metadata": { "kernelspec": { "display_name": "C", "language": "c", "name": "c" }, "language_info": { "file_extension": ".c", "mimetype": "text/plain", "name": "c" } }, "nbformat": 4, "nbformat_minor": 2 }