카테고리 없음

김민찬 11주차 수업 후 과제

content9349 2025. 11. 12. 14:49

함수 중첩을 지원하는 프로그래밍 언어와 예시

함수 중첩(Function nesting)이란 함수 안에 또 다른 함수를 정의하거나, 함수를 인자로 전달하거나, 함수를 반환하는 형태로 함수를 중첩해서 사용하는 것을 말합니다.
언어마다 이를 지원하는 방식이 다르기 때문에 주요 언어별 예시를 정리하면 다음과 같습니다.


1. Python — 완전한 중첩 함수 지원

 
def outer(x): def inner(y): return x + y return inner add5 = outer(5) print(add5(3)) # 출력: 8
  • 내부 함수(inner)는 외부 함수(outer)의 지역 변수 x에 접근 가능하다.
  • 이런 구조를 클로저(closure) 라고 한다.

2. JavaScript — 중첩 함수 및 클로저 지원

 
function outer(x) { function inner(y) { return x + y; } return inner; } const add10 = outer(10); console.log(add10(7)); // 17
  • JavaScript의 함수는 일급 객체이므로 변수에 담거나 반환할 수 있다.
  • 내부 함수는 외부 스코프의 변수(x)에 접근할 수 있다.

3. Java — 직접적인 중첩 함수는 없으나 지역 클래스나 람다로 대체 가능

 
public class Main { public static void main(String[] args) { int x = 10; class Adder { int add(int y) { return x + y; } } Adder adder = new Adder(); System.out.println(adder.add(5)); // 15 } }
  • Java는 함수 안에서 다른 함수를 정의할 수는 없지만,
    지역 클래스(Local Class) 또는 람다식(Lambda Expression) 으로 비슷한 동작을 구현할 수 있다.

4. C — 표준에서는 불가능 (단, GCC 확장 기능에서는 가능)

 
#include <stdio.h> void outer(int x) { int inner(int y) { return x + y; } printf("%d\n", inner(3)); } int main() { outer(5); return 0; }
  • 위 코드는 GCC 전용 확장 기능으로만 작동한다.
  • 표준 C에서는 함수 안에 함수를 정의할 수 없다.

5. C++ — 중첩 함수는 없지만 람다로 대체 가능

 
#include <iostream> using namespace std; void outer(int x) { auto inner = [x](int y) { return x + y; }; cout << inner(7) << endl; } int main() { outer(3); }
  • C++에서는 함수 안에 함수를 정의할 수는 없지만,
    람다(lambda) 를 이용해 비슷한 효과를 낼 수 있다.
  • [x]는 외부 변수 x를 캡처(closure capture)한다.

6. Haskell — 함수 중첩이 자연스러운 함수형 언어

 
outer x = let inner y = x + y in inner 5 main = print (outer 3) -- 8
  • Haskell은 모든 함수가 일급 객체이며,
    let 구문을 사용해 함수 안에 또 다른 함수를 정의할 수 있다.

7. Lisp / Scheme — 함수 중첩의 원조

 
(defun outer (x) (flet ((inner (y) (+ x y))) (inner 4))) (print (outer 6)) ; 10
  • Lisp 계열 언어에서는 flet, labels 등을 사용해 함수 안에 함수를 정의할 수 있다.
  • 함수 중첩과 클로저 개념의 기원이 되는 언어이다.

8. Rust — 중첩 함수(로컬 함수) 명시적으로 지원

 
fn outer(x: i32) { fn inner(x: i32, y: i32) -> i32 { x + y } println!("{}", inner(x, 5)); } fn main() { outer(10); // 15 }
  • Rust는 함수 안에 명시적으로 다른 함수를 정의할 수 있다.
  • inner는 outer 내부에서만 접근할 수 있다.

정리표

언어중첩 함수 정의 가능 여부클로저 지원비고
Python 가능 가능 완전한 중첩 함수 지원
JavaScript 가능 가능 함수형 언어처럼 동작
Java 제한적 가능 람다/지역 클래스 사용
C 불가능 (GCC만 가능) 불가능 표준은 불허
C++ 제한적 가능 람다로 대체 가능
Haskell 가능 가능 함수형 언어의 기본
Lisp/Scheme 가능 가능 함수 중첩의 원조
Rust 가능 가능 로컬 함수 지원

 

============================================================================================

 

펑션(Function)”과 “메서드(Method)”는 비슷하지만, 완전히 같은 것은 아닙니다.
둘 다 “어떤 입력(인자)을 받아서 동작을 수행하고 결과를 반환하는 코드 블록”이라는 공통점을 가지지만, 소속과 사용 방식이 다릅니다.

아래에서 개념과 차이를 정리해드리겠습니다.


1. Function(함수)

정의:

  • 어떤 객체나 클래스에 속하지 않고 독립적으로 정의된 코드 블록입니다.
  • 보통 “입력 → 처리 → 출력”의 구조로 동작합니다.

특징:

  • 클래스 밖에서 정의된다.
  • 독립적으로 호출할 수 있다.
  • 어떤 객체에도 속하지 않는다.

예시 (Python):

 
def add(a, b): return a + b result = add(3, 4) print(result) # 7

→ add는 독립적인 함수로, 어떤 객체에도 속하지 않는다.

예시 (C):

 
int add(int a, int b) { return a + b; } int main() { printf("%d", add(2, 3)); // 5 }

→ C에서는 모든 것이 함수이며, 클래스 개념이 없기 때문에 전부 Function이다.


2. Method(메서드)

정의:

  • 클래스(class)나 객체(object)에 속한 함수를 말합니다.
  • 즉, “특정 객체의 동작(behavior)”을 정의한 함수입니다.

특징:

  • 클래스 내부에 정의된다.
  • 객체를 통해 호출된다.
  • 객체 자신(self 또는 this)을 첫 번째 인자로 암묵적으로 받는다.
  • 객체의 속성(멤버 변수)에 접근하거나 변경할 수 있다.

예시 (Python):

 
class Calculator: def add(self, a, b): return a + b calc = Calculator() print(calc.add(3, 4)) # 7

→ add는 Calculator 클래스에 속한 메서드이다.
→ 호출 시 calc.add(3, 4) 형태로 사용하며, 내부적으로 self가 전달된다.

예시 (Java):

 
class Calculator { int add(int a, int b) { return a + b; } } public class Main { public static void main(String[] args) { Calculator c = new Calculator(); System.out.println(c.add(2, 3)); // 5 } }

→ Java에서는 클래스 내부의 함수는 모두 메서드이다.


3. Function vs Method 요약 비교

구분Function (함수)Method (메서드)
소속 독립적 클래스나 객체에 속함
호출 방식 add(3,4) obj.add(3,4)
첫 번째 인자 없음 self(Python) 또는 this(Java, C++)
사용하는 언어 C, Python(일부), JavaScript 등 Java, Python, C++, C#, Kotlin 등
역할 독립적인 기능 수행 객체의 행동 정의

4. JavaScript의 예외적 특징

JavaScript에서는 함수도 객체이고, 메서드도 함수이므로 구분이 약간 느슨합니다.

 
function add(a, b) { return a + b; } const obj = { add: function(a, b) { return a + b; } }; console.log(add(2, 3)); // 5 (함수) console.log(obj.add(2, 3)); // 5 (메서드)

→ add는 함수, obj.add는 객체에 속한 메서드입니다.
→ 둘 다 “Function 객체”이지만, 호출 맥락(context) 이 다릅니다.


5. 결론

  • Function: 독립적인 함수 (객체에 속하지 않음)
  • Method: 객체나 클래스에 속한 함수
  • 즉, 메서드는 함수의 한 종류이지만, 객체지향 언어에서만 등장하며 객체의 행동을 정의한다는 점이 다릅니다.

============================================================================================

 

============================================================================================

함수가 두개 이상 같은 이름으로 있으면 function 워딩이라고한다.

다형성 - 기능이 비슷하면 이름을 하나만 쓰자

#include <iostream>
int add(int i, int j)
{
return (i+j);
}
double add(double i, double j)
{
return (i+j);
}
int main()
{
std::cout<<add(10,20)<<std::endl;
std::cout<<add(10.5,20.3)<<std::endl;
return 0;
}
 
============================================================================================
 

이름이 같아서 훨씬 수월함

 

============================================================================================

#include <iostream>
// 형식 매개변수 (기본값 사용 예시)
int add(int i = 1, int j = 2)
{
return (i + j);
}
int main()
{
std::cout << add() << ","; // 실매개변수 없음 → 1 + 2 = 3
std::cout << add(10) << ","; // 실매개변수 한 개 → 10 + 2 = 12
std::cout << add(10, 20); // 실매개변수 두 개 → 10 + 20 = 30
return 0;

 

}
 

============================================================================================

 

` ============================================================================================

#include <iostream>
// 함수 선언 (형식 매개변수에 기본값 지정)
int add(int i = 1, int j = 2);
int main()
{
std::cout << add() << ","; // 실매개변수 없음 → 1 + 2 = 3
std::cout << add(10) << ","; // 실매개변수 한 개 → 10 + 2 = 12
std::cout << add(10, 20); // 실매개변수 두 개 → 10 + 20 = 30
return 0;
}
// 함수 정의
int add(int i, int j)
// 형식 매개변수
{
return (i + j);
}
 

============================================================================================

#include <iostream>
class Dog{
private:
int age;
public:
Dog(int a=1){age=a;}
// 디폴트 매개변수를 갖는 생성자
~Dog();
int getAge();
void setAge(int a);
};
Dog::~Dog()
{
std::cout<<"소멸\n";
}
int Dog::getAge()
{
return age;
}
void Dog::setAge(int a)
{
age=a;
}
int main()
{
Dog meri,happy(5);
std::cout<<happy.getAge()<<","<<
meri.getAge()<<std::endl;
return 0;
}

2. 코드 동작 흐름

(1) 클래스 선언부

 
class Dog { private: int age; public: Dog(int a = 1) { age = a; } // 생성자 ~Dog(); // 소멸자 int getAge(); // age 반환 void setAge(int a); // age 설정 };
  • private:
    → 외부에서 직접 접근할 수 없는 멤버.
    → age는 오직 멤버 함수(getAge, setAge)를 통해서만 접근 가능.
  • public:
    → 외부에서 사용할 수 있는 함수들.
  • Dog(int a = 1)
    → 생성자(Constructor).
    → a의 기본값이 1로 설정되어 있음.
    → 따라서 인자를 생략하면 age = 1로 초기화된다.
  • ~Dog()
    → 소멸자(Destructor). 객체가 소멸될 때 자동 호출됨.
    → 여기서는 "소멸\n"을 출력하도록 정의됨.

(2) 생성자와 소멸자 정의

 
Dog::~Dog() { std::cout << "소멸\n"; }

→ 프로그램이 끝날 때 객체가 소멸되면 자동으로 실행된다.
→ 여기서는 "소멸"이라는 문구를 출력한다.


(3) 멤버 함수 정의

 
int Dog::getAge() { return age; } void Dog::setAge(int a) { age = a; }
  • Dog::는 Dog 클래스의 멤버 함수임을 명시하는 범위 지정 연산자이다.
  • getAge()는 멤버 변수 age의 값을 반환.
  • setAge()는 멤버 변수 age를 변경.

(4) main 함수

 
int main() { Dog meri, happy(5); std::cout << happy.getAge() << "," << meri.getAge() << std::endl; return 0; }
  • Dog meri, happy(5);
    • meri → Dog()의 기본 매개변수 1이 적용되어 age = 1
    • happy → 인자로 5를 전달했으므로 age = 5
  • 출력:→ happy.getAge()는 5,
    meri.getAge()는 1
    따라서 출력 결과는 5,1
  •  
    std::cout << happy.getAge() << "," << meri.getAge() << std::endl;

3. 프로그램 실행 순서 (메모리 및 생성/소멸 과정)

  1. meri 객체 생성 → 생성자 호출 (age=1)
  2. happy 객체 생성 → 생성자 호출 (age=5)
  3. std::cout으로 5,1 출력
  4. main 함수 종료 시점에 지역 객체들이 소멸
    → happy → meri 순서로 소멸자 호출
    → 콘솔에 "소멸"이 두 번 출력됨.

4. 실제 실행 결과

 
5,1 소멸 소멸

5. 주요 개념 요약

구분의미코드 예시
생성자(Constructor) 객체가 생성될 때 자동 실행되는 함수 Dog(int a=1)
디폴트 매개변수 인자를 생략할 수 있도록 기본값을 지정 (int a = 1)
소멸자(Destructor) 객체가 소멸될 때 자동 실행되는 함수 ~Dog()
접근 지정자 private, public 등으로 접근 제한 설정 private: int age;
멤버 함수 클래스 내부 데이터를 조작하는 함수 getAge(), setAge()

6. 결론

이 프로그램은

  • 클래스의 기본 구조
  • 생성자와 소멸자 사용법
  • 기본 매개변수의 개념
  • 멤버 변수 접근 제어와 함수 호출
============================================================================================