4주차

2025. 4. 30. 21:55프로그래밍1및실습

함수(Function)

  • 효과적인 문제 해결의 중요한 요소는 문제의 분해
  • 하나의 프로그램은 하나 이상의 파일로 구성되기 때문에 0개 혹은 그 이상의 함수로 포함된다.
  • main()를 보통 포함

함수의 정의

  • 함수의 정의는 함수의 반환 type으로 시작
  • 매개변수 목록에는 쉼표로 구분된 선언들의 리스트
  • 함수 호출 시에 매개변수들도 포함해야함

함수의 정의

int factorial(int n){ //int 타입 함수, int 타입의 매개변수
      int i, idx=1;
      for(int i=2;i<=n;i++){
            idx*=i;
      }
      return idx;
}

void f(){ //void 타입 함수, 매개변수 없음
      printf("%d",100);
}

f(){ //타입을 생략하고 사용가능
      printf("%d",100);
}

return 문

  • 함수 도중 return 문을 만나면 함수 수행이 종료
  • 함수가 호출된 곳으로 control이 반환됨

Function Prototypes

  • Compiler에게 함수에 전달되는 매개변수의 수와 자료형을 알려줌
  • 함수에서 반환되는 값의 자료형을 알려줌
  • Compiler가 코드를 보다 철저하게 점검할 수 있도록 함
#include <stdio.h>

// 함수 프로토타입 선언
int add(int a, int b);

int main() {
    int result = add(3, 4);
    printf("Result: %d\n", result);
    return 0;
}

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

함수 정의 순서 스타일

  1. #include와 #define을 맨 위에 작성
  2. enumeration types, structures and unions
  3. function prototypes
  4. function definition, starting with main()

함수 실행과 Call by Value

  • program control이 함수의 이름을 만나면 함수 호출됨
  • 작업 후 제어는 다시 호출함 함수로 전달됨
  • 함수로부터 전달되는 모든 인자는 Call by Value
#include <stdio.h>

void addTen(int x) {
    x = x + 10;
    printf("Inside function: %d\n", x); //Inside function: 15
}

int main() {
    int x = 5;
    addTen(x);
    printf("After function: %d\n", x); //After function: 5
    return 0;
}
  • 결론적으로 모든 인자는 함수 내에서 평가되고, 그 값은 local 하게 활용된다.

Developing a Large Program

  • 규모가 큰 program은 보통. h와. c파일의 모음으로 구현
  • pgm.h 헤더 파일에 #include, #define 그리고 함수 프로토타입이 선언됨
  • 그리고. c파일이 pgm.h를 통해서 헤더를 불러온다.
  • 즉, pgm.h를. c파일에서 활용하기 때문에 파일들 전체가 연결되어진다.

지역 변수&전역 변수

  • 지역 변수: 한정된 지역에서만 활용가능
  • 전역 변수: 프로그램 전체에서 사용가능

변수의 저장 기간

  • 특정 변수의 저장 공간이 존재하는 기간!
  • 지역 변수를 포함하는 함수가 있으면 호출 후에 저장 공간이 자동으로 할당되고, 이후에는 저장 공간이 해제된다.
  • 저장 기간의 종류: automatic, static , dynamic

블록 스코프

  • 해당 변수를 참조할 수 있는 코드의 일부분
  • 지역변수는 블록 스코프를 가짐!
  • 만약 지역 변수에서 블록 스코프가 중첩되면 가장 가까운 위치에 선언된 변수를 사용
#include <stdio.h>

int main() {
    int a=5;
    if(a==5){
          int a=3;
          printf("%d\n",a); //3이 출력
    }
    printf("%d", a); //5가 출력
}
  • if문 내에서 a를 출력할 때 범위 내에서 가장 최근에 선언된 부분은 int a=3이다.
  • if문 밖에서는 int  a=3이 아니라 범위 내에 있는 int a=5를 출력한다.
#include <stdio.h>

int main() {
    int a = 1, b = 2, c = 3;
    printf("%3d%3d%3d\n", a, b, c);      // 출력:   1  2  3

    {
        int b = 4;
        float c = 5.0;
        printf("%3d%3d%3.1f\n", a, b, c);  // 출력:   1  4  5.0
        a = b;

        {
            int c;
            c = b;
            printf("%3d%3d%3d\n", a, b, c);  // 출력:   4  4  4
        }

        printf("%3d%3d%3.1f\n", a, b, c);  // 출력:   4  4  5.0
    }

    printf("%3d%3d%3d\n", a, b, c);      // 출력:   4  2  3
    return 0;
}
  • 블록에서 나갈 때 할당된 공간이 해제되기 때문에 이러한 문법을 활용한다.

Storage Classes

  • C의 모든 변수와 함수는 두 개의 특성이 존재함 - type과 storage class
  • auto, extern , register, static이 존재

Auto

  • 함수에 선언된 변수들은 기본적으로 auto임
  • 블록에 들어갈 때 메모리를 할당하고 범위 내에서만 동작

Extern

  • 블록과 함수 너머로 정보를 전달하는 방법 중 하나
  • 변수가 함수 외부에 선언되면 저장 공간이 해당 공간에 영구적으로 할당됨
  • 해당 변수는 이후에 global 하게 동작함
함수에 정보를 전달하는 2가지 방법
1. external variable
2. parameter를 사용
  • main.c
#include <stdio.h>

extern int shared;  // 외부 변수 선언

int main() {
    printf("shared = %d\n", shared);
    return 0;
}
  • shared.c
int shared = 42;  // 외부 변수 정의
file1.c
#include <stdio.h>

int a = 1, b = 2, c = 3;  // 외부 변수

int f(void);  // 함수 선언

int main(void)
{
    printf("%3d\n", f());             // f() 호출 결과 출력
    printf("%3d%3d%3d\n", a, b, c);   // 외부 변수 값 출력
    return 0;
}​

 

file2.c
int f(void)
{
    extern int a;     // 외부 변수 a를 참조
    int b, c;
    a = b = c = 4;
    return (a + b + c);
}​


결과

 12
  4  2  3
Difinition & Declaration

Difinition: 변수가 생성, 공간 할당
int a=1, b=2, c=3

Declaration: 변수는 선언, 하지만 공간 할당(X)
external int a;

외부 변수나 함수의 범위는 코드가 끝날 때까지 계속 지속됨
Declare
-컴파일러에게 다음의 정보를 전달
-이러한 이름을 갖는 무언가 있음
-이러한 타입을 가지고 있음
-모두 함수 body를 작성할 필요 없음

Definition
-해당하는 것을 만들기 위한 모든 필요한 정보를 제공

register

  • 실행 속도를 빠르게 하는데 목적이 있음
  • 가장 빈번하게 접근하는 변수를 register 변수로 선언

  • 하지만 전역 변수로 사용할 수 없고, 주소를 구할 수 없음
  • 레지스터의 사용 여부는 컴파일러가 결정함(컴파일러가 최적화 과정에서 메모리를 사용하는 것이 이득이라고 판단하면 메모리를 사용함)

static

  • 지역 변수가 블록에 다시 진입하더라도 이전 값을 보존해 줌.
  • auto변수와는 다르게 동작
#include <stdio.h>

void f(int x){
      static int cnt=0;
      cnt+=x;
      printf("%d\n",cnt);
      return;
}

int main() {
    f(4);
    f(3);
}
4
7

변수의 기본 초기화

  • external and static: 시스템에 의해 기본적으로 0으로 초기화
  • auto and register: 가비지 값이 들어 있음

재귀

  • 자기 자신을 호출하는 경우 recursive 하다고 함

재귀 함수

  • 어떤 숫자 n부터 시작하여서 4242보다 큰 경우에 리턴하여서 역을 출력하는 재귀함수 코
#include <stdio.h>

void f(int x){
      printf("%d\n",x);
      if(x<=4242){
            f(x*2);
            printf("%d\n",x);
      } else{
            printf("%d\n",x);
            return;
      }
}

int main() {
    f(840);
}
840
1680
3360
6720
6720
3360
1680
840

하노이 타워

1. n-1개를 A=> B로 옮김
2. 가장 큰 n번째 원반을 A=> C로 옮김
3. 다시 n-1개를 B=> C로 옮김
#include <stdio.h>

void hanoi(int n, char from, char temp, char to) {
    if (n == 1) {
        printf("Move disk 1 from %c to %c\n", from, to);
        return;
    }
    hanoi(n - 1, from, to, temp); // 위 n-1개를 보조 기둥으로
    printf("Move disk %d from %c to %c\n", n, from, to); // 가장 큰 원반 이동
    hanoi(n - 1, temp, from, to); // 보조 기둥의 n-1개를 목표 기둥으로
}

int main() {
    int n = 3; // 원반의 개수
    hanoi(n, 'A', 'B', 'C');
    return 0;
}

'프로그래밍1및실습' 카테고리의 다른 글

week2(실습 문제)  (0) 2025.05.22
배열과 문자열  (0) 2025.05.01
3주차(2)  (0) 2025.04.30
3주차  (0) 2025.04.08
2주차  (0) 2025.03.16