parameter

함수의 호출 시 parameter(매개변수)는 모두 적어야한다. 하지만 함수를 정의할 때 매개변수의 기본값을 명시해 놓으면 호출시에 매개변수를 명시하지 않아도 기본값으로 대입된다. 

func fn_1 (name:String, age:Int, marriage:Bool){
    print("name:\(name), age:\(age), marriage: \(marriage)")
}

func fn_2 (name:String, age:Int=21, marriage:Bool = false){    //marriage, age에 기본값 설정
    print("name:\(name), age:\(age), marriage: \(marriage)")
}

fn_1(name:"차은우", age:34, marriage: false)//기본값을 명시하지 않아 인수를 모두 명시해야한다.
fn_2(name:"차은수", age:24)    //기본값이 입력되어있는 매개변수는 인수를 작성하지 않아도 된다.
fn_2(name:"차은미")    //기본값이 입력되어있는 매개변수는 인수를 작성하지 않아도 된다.

fn_1()과 달리 fn_2()는 매개변수에 기본 값이 설정되어 있기에 호출 시 생략이 가능하다.

func exam(name:String, type:String = "일반", kor:Int, eng:Int, art:Int){
    var res = 0
    if type == "일반"{	//type이 일반일 경우와 아닐경우를 나누어서 점수를 계산한다.
        res = (kor + eng + art)/3
    } else {
        res = Int((Double(kor)*0.3) + (Double(eng)*0.2) + (Double(art)*0.5))
    }
    
    print("\(type) \(name) : \(res)")
}

exam(name: "차금우", kor: 87, eng: 90, art: 30)    //기본값인 일반으로 계산
exam(name: "차동우", type: "특기생", kor: 87, eng: 90, art: 30)   //일반이 아닌 다른 경우로 계산

이어서 매개변수에는 가변매개변수가 있다. 자료형 뒤에 ...을 붙여 명시하며 이는 호출 시 연속하여 자료를 입력받고, 이를 배열로 처리한다. 호출시에 배열형태로 입력을 받으면 에러가 일어난다는 점을 기억하자.

func fn_3(id:String, size:[Int]){   //매개변수를 배열로 받음
    print("id: \(id), size: \(size)")
}

func fn_4(id:String, size:Int...){  //정수형 가변매개변수
    print("id: \(id), size: \(size)")
}

fn_3(id:"aaa", size: [5,7,2,3,9])
//fn_3(id:"aaa", size: 5,7,2,3,9)   //배열형태가 아니어서 에러


fn_4(id:"ccc", size: 5,7,2,3,9)     //입력 정수들을 알아서 배열로 묶어준다. 매개변수의 갯수에 따라 다른 연산도 가능하다.
//fn_4(id:"ccc", size: [5,7,2,3,9])   배열형태면 에러.


가변매개변수 예제

가변매개변수를 사용하여 각 다른 과목수의 평균, 합계를 구한다.

//Q.숫자들을 입력하여 총점, 평균을 출력하는 함수를 구현하세요.
func res(_ score:Int...){
    var result = 0
    
    for i in score{
        result += i
    }
    
    print("총점:",result, "평균:",result/score.count)
}
res(67,62,66,65,68)
res(77,75,73)


return

함수는 크게 4가지 종류로 나뉜다.

  • 매개변수와 return이 있는 함수
  • 매개변수는 있지만 return이 없는 함수
  • 매개변수가 없지만 return이 있는 함수
  • 둘 다 없는 함수 

여기서 return에 대해서 이야기 해본다면 return이 없는 함수의 경우 4가지 방법으로 정의할 수 있다.

func fn_1(){
    print("fn_1 () 실행 1")
    print("fn_1 () 실행 2")
    print("fn_1 () 실행 3")
    print()
}

func fn_2(){
    print("fn_2 () 실행 1")
    print("fn_2 () 실행 2")
    print("fn_2 () 실행 3")
    print()
    return;     //reutrn;은 항상 생략되어있다.
}

func fn_3() -> Void{    //return이 없다는 뜻이다.
    print("fn_3 () 실행 1")
    print("fn_3 () 실행 2")
    print("fn_3 () 실행 3")
    print()
    return;     //reutrn;은 항상 생략되어있다.
}

func fn_4() -> (){    //return이 없다는 뜻이다.
    print("fn_4 () 실행 1")
    print("fn_4 () 실행 2")
    print("fn_4 () 실행 3")
    print()
    return;     //reutrn;은 항상 생략되어있다.
}


fn_1()
fn_2()
fn_3()
fn_4()

return; 문구는 별다른 반환없이 종료한다는 얘기이다. 그렇다면 return; 문구는 함수 중간에 적어보겠다.

func fn_5(){    //return이 없다는 뜻이다.
    print("fn_5 () 실행 1")
    print()
    return;     //여기서 함수가 종료된다. 즉 return은 함수의 탈출을 뜻한다.
    print("fn_5 () 실행 2")
    print()
    return;
    print("fn_5 () 실행 3")
    print()
    return;
}

fn_5()	//함수실행

실행1부분만 출력되고 그 이후는 함수가 종료된다. 즉 return; 은 함수의 탈출을 의미한다.

func fn_6(_ num : Int){
    if num >= 88{
        print("fn_6(): 우수")
        print()
        return;
    }
    
    if num >= 60{
        print("fn_6(): 정상")
        print()
        return;
    }
    
    print("fn_6(): 미달")
    print()
    return;
}
fn_6(59)    //미달
fn_6(89)    //우수
fn_6(66)    //정상

이런식으로 조건문을 사용하여 함수의 종료시점을 정해줄 수 있다는 것이다.


일반적으로 return은 하나의 자료만 반환이 가능하다. 그렇다면 여러 자료를 반환하려면 어떻게 하면될까?

func fn_7() -> Int {
    print("fn_7() : 실행")
    return 100
}

func fn_8() -> [Int] {
    print("fn_8() : 실행")
    return [100,200]
}

func fn_9() -> (String,Int) {
    print("fn_9() : 실행")
    return ("아기상어",200)
}

var rr = fn_7()
print("rr: \(rr)"); print()

var rr2 = fn_8()
print("rr2: \(rr2)"); print()

var rr3 = fn_9()
print("rr3: \(rr3)"); print()

//튜플을 리턴받아 대입에 사용할 수 있다.
var ss:String
var ii:Int
(ss,ii) = fn_9()
print("ss:\(ss), ii:\(ii)"); print()

배열이나 튜플과 같이 시퀀스자료를 반환하면 여러자료를 반환할 수 있고, 이러한 반환을 대입에도 사용할 수 있다.


return 예제1

가변매개변수로 연속하여 자료를 받고, 해당 매개변수에서 가장 큰 값과 작은 값을 리턴하는 함수이다.

typealias numType = (max:Int, min:Int)
func max_min(_ nums:Int...) -> numType{     //typealias로 묶어서 반환이 가능하다.
    
    if nums.count == 0{     //빈배열이 들어온다면?
        print("연산불가")
        return(0,0);
    }
    
    var max = nums[0]   //첫번째 수로 초기화 -> 처음에 비교할 기준이 필요하기 때문
    var min = nums[0]   //첫번째 수로 초기화
    
    for i in nums{	//대소비교 시작
        if max < i {
            max = i
        }
        if min > i {
            min = i
        }
    }
    
    return (max, min)	//numType으로 리턴
}

var ret = max_min(67,32,98,2,15,65,3,76)
print("최대: \(ret.max)")
print("최소: \(ret.min)");
print("--------------------------")

var rrr = max_min()
print("최대: \(rrr.max)")
print("최소: \(rrr.min)")


return 예제2

num의 배수에 해당하는 숫자들을 리턴하는 함수를 구현하세요
mulArr(num:3, 45,56,67,78,76,12,34,26)

func mulArr(num:Int, _ nums: Int...) -> [Int]{
    var res = [Int]()
    
    for i in nums{
        if i%num == 0{  //배열속의 숫자가 num으로 나누어지면 res배열에 추가.
            res.append(i)
        }
    }
    
    print("\(num)의 배수는 \(res)입니다.")
    return res;
}
print(mulArr(num:3, 45,56,67,78,76,12,34,26))


funcCall

함수는 다른 함수를 호출할 수 있다.

func fnTot(){
    var aa = 10
    print("fnTot() 실행 1 \(aa)")
    fn_1()      //함수 내에서 함수를 호출한다.
    print("fnTot() 실행 2 \(aa)") //여기서는 fn_1()의 bb를 호출할 수 없다.
    fn_2()      //함수 내에서 함수를 호출한다.
    print("fnTot() 실행 3 \(aa)")
}

func fn_1(){
    var bb = 20
    print("fn_1() 실행 \(bb)")  //여기선 fnTot()의 aa를 호출할 수 없다.
}
func fn_2(){
    print("fn_2() 실행 ")
}

fnTot()	//fnTot()호출

여기서 알아두어야 할 점은 fnTot()에서 fn_1()을 호출했다 하더라도 fnTot()에서는 fn_1()에서 선언된 변수 bb에 접근 할 수 없다는 것이다. 함수는 각각 정해진 영역을 가지고 동작하며, 이러한 특성을 생각해서 변수의 지정과 선언을 잘해야한다.

'iOS > TJ' 카테고리의 다른 글

day13_initializer, self, inheritance  (0) 2021.07.01
day12_funcVariable, selfCall, class  (0) 2021.06.29
day10_func()  (0) 2021.06.17
day09_dictionary, set  (0) 2021.06.16
day08_multiArray, tuple  (0) 2021.06.03

function

함수(function)는 프로그램의 가장 작은 단위이자 하나의 작은 프로그램이다. 함수를 사용하는 데에는 크게 두가지 이유가 있다. 첫번째는 작업단위의 모듈화. 두번째는 재사용의 용이성이다. 

함수는 미리 정의한 뒤, 호출을 통해서 사용할 수 있다. 다음은 함수의 정의 표현이다.

     func 함수이름 (매개변수:자료형 ... ) -> 리턴타입 {

          실행구문

          return 반환값

     }

매개변수에는 자료형을 명시해야하며 함수에 매개변수, 리턴타입이 없다면 생략이 가능하다. 다음은 함수의 호출형식이다.

     함수명(인수1, 인수2, ... )

     변수 = 함수명(인수1, 인수2, ... )

함수의 호출 시 인수의 순서는 바뀌면 안되며 반드시 함수의 매개변수에 맞게 인수를 적어야한다.

//함수정의
func fn_1(aa:Int, bnbn bb:String) -> Int{
    print("fn_1() 실행1 \(aa)")   //함수실행코드
    print("fn_1() 실행2 \(bb)")   //매개변수는 지역변수로 활용된다.
    print("fn_1() 실행3")
    
    return 1234 //리턴
}

var rr = fn_1(aa:10, bnbn:"아기상어")	//함수호출
print("rr: \(rr)")  //리턴 값 확인

fn_1()함수에 매개변수를 보면 bnbn bb : String이라 되어있다. 스위프트의 함수가 다른언어들과의 차이점이 매개변수와 인수를 따로 구분한다는 점이다. bnbn은 인수, 즉 외부에서 호출 시의 매개변수를 부르는 이름이다. 반대로 함수 내부에서는 bnbn이 아닌 bb로 사용해야 매개변수로서 접근이 가능하다. 코딩시 영어문장처럼 흘러가도록 하기위해 이와 같이 매개변수와 인수를 따로 구분하는 것으로 알고있다. 해당 문법이 불편하면 매개변수만 적게되으면 된다. 인수와 매개변수를 통일하여 사용 할 수 있다.

fn_1(aa: 20, bnbn: "아빠상어"); 
fn_1(aa: 678, bnbn: "엄마상어")
fn_1(aa: 1920, bnbn: "할머니상어")

이와 같이 함수를 사용하게 되면 반복작업을 손쉽게 처리할 수 있다.


label 생략

label(인수)은 생략이 가능하다. 인수명을 언더바로 적으면 호출 시에 인수명을 따로 적지 않고 바로 입력하여 함수를 호출 할 수 있다.

func fn_1(name:String, age:Int, marriage:Bool){
    print("fn_1() name:\(name), age:\(age), marriage:\(marriage)")
}

func fn_2(_ name:String, aa age:Int, mm marriage:Bool){
    print("fn_2() name:\(name), age:\(age), marriage:\(marriage)")
}

func fn_3(_ name:String, _ age:Int, _ marriage:Bool){
    print("fn_3() name:\(name), age:\(age), marriage:\(marriage)")
}

//fn_1(name: "정우성", marriage: false, age: 51) //인수의 순서는 바꾸면 안된다.
fn_1(name: "정우성", age: 51, marriage: false) //스위프트의 함수는 호출 시 인수(label)를 적어야 한다.
fn_2("정좌성", aa:51, mm:false)    //인수(label)를 언더바(_)로 생략처리하면 인수를 적으면 안된다.
fn_3("정남성", 51, false)


func 예제

정수형 배열을 매개변수로 받아 그 중 가장 작은 값을 반환하는 함수를 작성해보았다.

func minGo(arr:[Int]) -> Int{
    var res = arr[0]	//매개변수로 배열의 첫번째 요소를 res변수에 담는다. 
    
    for i in arr{
        if res > i {
            res = i	//res의 값보다 더 작은 값의 요소를 찾으면 res에 대입한다.
        }
    }
    return res		//res값을 반환한다.
}

var res = minGo(arr: [34,56,7,12,4,98,23,167,11])
print("res:",res)

'iOS > TJ' 카테고리의 다른 글

day12_funcVariable, selfCall, class  (0) 2021.06.29
day11_param, return, funcCall  (0) 2021.06.18
day09_dictionary, set  (0) 2021.06.16
day08_multiArray, tuple  (0) 2021.06.03
day07_array  (0) 2021.06.02

+ Recent posts