상세 컨텐츠

본문 제목

[Day15] Function: 매개변수(4)

Swift&SwiftUI

by (방울)도마토 2024. 5. 2. 16:18

본문

https://bangul-domato.tistory.com/44

 

[Day14] Function : 매개변수(3)

내부 매개변수명, 외부 매개변수명 - 외부 매개변수 : 함수 외부에서 함수나 인자값을 구분하기 위해 사용하는 변수     - 인자값에 대한 레이블, 함수의 식별자 일부로 사용 - 내부 매개변수 :

bangul-domato.tistory.com

 

InOut 매개변수

- 함수 내부에서 발생하는 사건은 함수 외부에 영향을 미칠 수 없음 

    - 단순히 같은 값을 가지고 있을 뿐, 둘은 단절된 서로 다른 객체 

var cnt = 30

func autoIncrement(value: Int) -> Int {
    var value = value
    value += 1
    
    return value
}

print(autoIncrement(value: cnt)) // 함수 내부의 변수 value 값 : 31
print(cnt) // 함수 외부에서 정의된 cnt 값 : 30

- 외부에서 입력한 인자값(cnt)이 직접 함수 내부로 전달되는 것이 아니라 그 값이 복사된 다음 전달되기 때문

    - 인자값으로 전달된 cnt와 매개변수 value는 서로 다른 변수 

 

- inout 키워드를 활용해 함수 내부에서 수정된 인자값을 함수 외부까지 전달할 수 있음 

func foo(paramCount: inout Int) -> Int {
    paramCount += 1
    return paramCount
}

var count = 30 
print(foo(paramCount: &count)) // 함수 내부의 변수 paramCount 값 : 31
print(count) // 외부에서 정의된 변수 count 값 : 31

// 상수는 inout 매개변수에 인자값으로 전달할 수 없음 
let count1 = 30
foo(paramCount: &count1) // (X)

// literal은 inout 매개변수에 인자값으로 전달할 수 없음 
foo(paramCount: &30) // (X)

- inout 키워드가 붙은 매개변수는 인자값 자체를 함수 내부로 전달 → 인자값으로 사용된 변수와 동일한 객체 

- inout : 값이 저장된 메모리 주소를 전달 (C의 pointer)

    - inout 매개변수에 들어갈 인자값에는 주소 추출 연산자 &를 붙여주어야 정상적으로 전달함 

    - & : 변수나 상수 앞에 붙어서 값이 저장된 메모리 주소를 읽어오는 역할 

 

 

* 값에 의한 전달 : 값을 복사하여 전달 

- 내부적으로 복사를 통해 생성된 새로운 변수나 상수를 이용하여 함수의 기능을 실행

→ 인자값의 수정이 발생하더라도 원본 데이터에 영향 없음 

 

 

* 참조(Reference)에 의한 전달 : 주소를 전달하는 것 

- 값이 저장된 주소가 전달 → 인자값을 저장하고 있는 객체 자체가 전달 

- 외부의 인자값을 직접 참조하므로 함수 내부의 인자값이 수정되면 외부 인자값 원본에도 반영 

- 예외적으로 Class로 구현된 인스턴스 inout 키워드를 사용하지 않아도 항상 참조에 의해 전달 

    → 함수의 인자값으로 전달한 클래스 인스턴스는 함수 내부에서 값이 수정되면 원본 객체에도 영향

- inout 키워드가 붙은 매개변수는 변수만 인자값으로 사용 가능 

     - 상수, 리티럴은 전달 대상이 될 수 없음 

     - 함수 내부에서 원본 객체에 직접 값을 수정해야 하기 때문 

 


 

변수 생존 범위와 생명 주기

변수의 Scope(생존범위) : 전역변수와 지역변수

- 전역변수(Global variable)

    - 프로그램의 최상위 레벨에서 작성 

    - 일반적으로 프로그램 내 모든 위치에서 참조 가능 

    - 특별한 경우를 제외하곤 프로그램 종료 전까지는 삭제되지 않음 

- 지역변수(Local variable)

    - 특정 범위 내에서만 참조하거나 사용할 수 있는 변수 

    - 조건절, 함수 구문 등 특정 실행 블록 내부에서 선언된 변수 → 선언된 블록 범위 안에서만 변수 참조가 가능함 

    - 변수의 생명주기(Life Cycle) : 선언된 블록이 실행되면서 생겨났다가 실행 블록이 끝나면 제거 

// 지역변수 1.
do {
    do {
        var ccnt = 3 // 중첩된 do {} 안에서만 생존 
        ccnt += 1
        print(ccnt) // (1) 4
    }
    
    ccnt += 1
    print(ccnt) // (2) error : "Use of unresolved identifier 'ccnt'"
    // 선언되지 않은 변수 호출 시 발생 -> ccnt가 선언된 블록 바깥에서 사용되었기 때문(변수 범위의 바깥)
}
// 지역변수 2.
do {
    var ccnt = 0 // do {}(상위블록) 안에서 생존 가능 -> 중첩된 do {}(하위블록) 에서도 사용 가능 
    // 변수가 생성된 블록이 아닌 다른 블록에서 사용하려면 반드시 초기화되어 있어야 함
        // 하나의 블록에서 다른 블록으로 참조에 의한 전달 과정이 일어나는 것 
        // 변수가 초기화되지 않았다면 메모리를 할당받지 못한 상태이므로 주소값도 존재 X -> 오류 발생
    do {
        ccnt = 3
        print(ccnt) // (1) 3
    }
    
    ccnt += 1
    print(ccnt) // (2) 4
}

 

// 전역변수
var count = 30 
    // 최상위 블록에서 선언된 변수이므로 하위 블록인 함수 내부에서도 접근 가능함 
func foo() -> Int {
    count += 1
    return count
}

foo() // 31
    // 값이 참조 방식으로 전달되므로 블록 내부에서 값을 변경하면 외부에도 그대로 적용 가능 
    // 수정 또는 값의 접근 가능

 

// 전역 변수와 지역 변수의 이름과 타입이 동일한 경우 
var count = 30 // (2) 전역변수 count

func foo(count: Int) -> Int {
    var count = count // (1) 지역변수 count
    count += 1
    return count 
}

print(foo(count: count)) // (1) 함수 내부의 변수 count 값 : 31
print(count) // (2) 외부에서 정의된 변수 count 값 : 30

- 외부와 내부에 같은 이름의 변수가 존재한다면 내부에서 선언된 변수는 외부와 상관없이 새롭게 생성됨 

 

* 변수 검색 순서(컴파일러)

함수 내부에서 정의된 변수 → 함수 외부에서 정의된 변수 → 글로벌 범위에서 정의된 변수 → import된 라이브러리 범위 

'Swift&SwiftUI' 카테고리의 다른 글

[Day17] searchable  (0) 2024.05.21
[Day16] Function: 함수의 중첩과 클로저  (1) 2024.05.16
[Day14] Function : 매개변수(3)  (0) 2024.05.01
[Day12, 13] Function : 함수의 기본 개념(1), (2)  (0) 2024.04.23
[Day11] Optional(2)  (0) 2024.04.22

관련글 더보기

댓글 영역