본문 바로가기
스파르타코딩 클럽/사전 캠프

7. 스파르타 코딩클럽 [사전캠프 - 반복문 이해하기]

by UDDT 2025. 2. 5.

기본

반복문

  1. 반복문 비교하기

구 분 설 명 코 드
for - in 문 정해진 횟수만큼 반복해야 할 때 사용
∴ 반복 회수가 정해져 있을 때 사용
for i in 1 ... 5 {
     print("반복 \(i)회")
}
while문 특정 조건을 만족할 때만 반복하려고할 때 사용
조건을 먼저 확인하고 실행할 때 사용
// 10 이하의 숫자를 반복 출력
var number = 1

while number <= 10 {
    print("현재 숫자: \(number)")
    number += 1
}
repeat - while문 최소 1회 실행을 보장하고,
조건을 검사하여
특정 조건이 참일 때만 반복하려고할 때 사용
 반드시 1회는 실행하고, 조건을 확인할 때 사용
var count = 0


repeat {
    print("반드시 한번 실행됩니다! (현재 count: \(count))")
    count += 1
} while count < 3

 

반복문 응용하기

  1. for - in문

/*
사용자로부터 N을 입력받아 1부터 N까지의 합을 계산하는 프로그램을 작성하세요.
*/

let n = 5
var sum = 0

for i in 1...n {
    sum += i             // sum + i = sum (sum과 i를 더한 후 좌변에 할당)
}

print("1부터 \(n)의 합은 \(sum)입니다.")
//n을 사용자가 입력하게 하려면

print("n을 입력하세요: ", terminator: "")
if let input = readLine(), let n = Int(input) {
    var sum = 0

    for num in 1 ... n {
        sum += num
    }

    print(sum)
}

 

  <for문 Deep Dive하기>

위의 코드에서 i는 for문에서 선언하는 변수 이름이다.
본래 변수는 let i = 0과 같이 선언을 해줘야하는데, 어떻게 위 코드에서는 변수나 상수 선언을 하지 않고 사용할 수 있을까?

for-in 반복문에서 사용하는 변수는 자동으로 선언되기 때문에,
반복문 안에서 변수 이름을 지정할 때 별도로 선언하지 않아도 되는 것.

예를 들어,
for num in 1...n {
    sum += num
}
여기서 사용된 num은 임시변수로써
반복문 내에서 자동으로 생성된 변수이고,
반복문을 빠져나가면 그 값은 더 이상 유효하지 않기 때문에
let num = 0 과 같이 선언하지 않아도 됨.

 

  2. for문 + if문

/*
1부터 20까지 숫자 중 짝수만 출력하는 프로그램을 작성하세요.
*/

for num in 1 ... 20 {
    if num % 2 == 0 {
        print(num)
    }
}

/*
만약 결과값을 배열로 저장하고자 한다면
*/

var numberArr: [Int] = []               // 변수 타입을 배열로 설정하고

for num in 1 ... 20 {
    if num % 2 == 0 {
        numberArr.append(num)           // .append로 값을 추가
    }
}

print(numberArr)

 

  3. while문

/*
컴퓨터가 랜덤 숫자를 생성하고, 그 숫자가 5가 나올 때 까지 반복하는 프로그램
*/

var number = 0

while number != 5 {
    number = Int.random(in: 1 ... 10)
    print(number)
}
print("5가 나왔습니다")

 

  4. repeat - while문

/*
사용자가 정해진 비밀번호 "1234"를 입력할 때까지 계속 입력을 요구하는 프로그램을 작성하세요.
*/

var password = ""

repeat {
    print("비밀번호 입력: ")
    password = readLine() ?? ""
} while password != "1234"

print("로그인 성공")

//repeat-while문은 반복문을 먼저 실행해서 조건을 확인하고, 조건에 맞지 않으면 계속 반복하는 것

 

  4-1. 변수 초기화

var password = ""

 

4-2. repeat을 통해 최소 1회는 실행을 보장(while의 조건과 관계 없음)

repeat {
    print("비밀번호를 입력하세요: ")
    password = readLine() ?? ""
    
//입력된 비밀번호를 readLine()을 통해 불러오고, 입력이 잘못되었거나 입력이 없으면 ""을 리턴.

 

} while password != "1234"
print("로그인 성공")

/* 
while의 조건에 따라 반복을 실행 (비밀번호가 1234가 아니면 계속 반복됨)
비밀번호가 1234가 되면 while의 조건이 false가 되기 때문에 반복 종료
*/

 

 + 사용자 입력을 받을 수 있는 프로젝트 만들기

  1. New - Project - macOS - Command Line Tool

 

실습

숫자 맞추기 게임 만들기

1. 컴퓨터가 1~100 사이의 숫자를 랜덤으로 선택합니다.
2. 사용자가 숫자를 입력하고, 컴퓨터가 선택한 숫자와 비교하여 힌트를 줍니다.
     •사용자가 입력한 숫자가 정답보다 크면 "더 작은 숫자를 입력하세요!" 출력.
     •사용자가 입력한 숫자가 정답보다 작으면 "더 큰 숫자를 입력하세요!" 출력.
     •정답을 맞히면 "축하합니다! 정답입니다!" 출력 후 종료.

 

  코드를 작성했는데, 다음과 같은 오류가 생겼다.

 


 오류 해결하기 : 문제를 바르게 이해하는 것이 중요하다.

var randomNumber = 0
var userInput = ""

repeat {
    print("숫자를 입력해주세요: ")
    randomNumber = Int.random(in: 1 ... 100)
    userInput = readline()            
    
    if randomNumber < userInput {
        print("더 작은 숫자를 입력하세요!")
    } else if randomNumber > userInput {
        print("더 큰 숫자를 입력하세요!")
    } else {
        print("축하합니다! 정답입니다")
    }
}

 

  문제를 잘못 이해했다.

1. 컴퓨터가 반복해서 숫자를 뽑는다.

2. 유저가 숫자를 계속 입력한다.

문제를 잘못 이해하다보니, 유저가 숫자를 무조건 뽑게 해야겠다고 생각해서

repeat-while문을 사용했고 코드가 어려워졌다.

 

일단 오류가 발생한 코드를 수정해보자.

 

 수정1

// 수정 전
var randomNumber = 0

 

컴퓨터가 숫자를 한번만 뽑고 랜덤숫자를 상수에 저장하도록 변경했다.

// 수정 후
let randomNumber = Int.random(in: 1 ... 100)

 

 수정2 : readLine 함수, optional Binding 이해하기

// 수정 전
let randomNumber = Int.random(in: 1 ... 100)
var userInput = ""

repeat {
    print("숫자를 입력해주세요: ")
    userInput = readline()

 

  readLine() 함수는 사용자가 입력한 값을 읽고, 그 값을 password에 저장하는 함수인데 오타로 인해 실행되지 않았다.

오타를 고쳐도 다음과 같은 에러가 발생한다. (Value of optional type 'String?' must be unwrapped to a value of type 'String')

readLine() 함수는 optional String 을 리턴하기 때문에, optional Binding을 통해 처리해야 한다.

// 수정 후
let randomNumber = Int.random(in: 1 ... 100)
var userInput = ""

repeat {
    print("숫자를 입력해주세요: ")
    userInput = readLine() ?? ""

 

수정3 : 비교 연산은 같은 Type만 가능하다

// 수정 전
let randomNumber = Int.random(in: 1 ... 100)
var userInput = ""

repeat {
    print("숫자를 입력해주세요: ")
    userInput = readLine() ?? ""

    if randomNumber < userInput {
        print("더 작은 숫자를 입력하세요!")
    } else if randomNumber > userInput {
        print("더 큰 숫자를 입력하세요!")
    } else {
        print("축하합니다! 정답입니다")
    }
}

  비교 연산자는 같은 Type의 값만 비교할 수 있다.

여기에서 userInput은 String이고, randomNumber는 Int이기 때문에 Type을 맞춰줘야 한다.

// 수정 후
let randomNumber = Int.random(in: 1 ... 100)
var userInput = ""

repeat {
    print("숫자를 입력해주세요: ")
    userInput = readLine() ?? ""

    if let number = Int(userInput) {
        if randomNumber < userInput {
            print("더 작은 숫자를 입력하세요!")
        } else if randomNumber > userInput {
            print("더 큰 숫자를 입력하세요!")
        } else {
            print("축하합니다! 정답입니다")
            break
        }
    }
}

 

 수정4 : 상수나 변수의 이름을 헷갈리지 말 것

  number에 userInput을 담아주었기 때문에, 비교 연산 구문의 userInput을 number로 수정

let randomNumber = Int.random(in: 1 ... 100)
var userInput = ""

repeat {
    print("숫자를 입력해주세요: ")
    userInput = readLine() ?? ""

    if let number = Int(userInput) {
        if randomNumber < number {
            print("더 작은 숫자를 입력하세요!")
        } else if randomNumber > number {
            print("더 큰 숫자를 입력하세요!")
        } else {
            print("축하합니다! 정답입니다")
        }
    }
}

 

 그러나 이렇게만 하면 코드가 종료되지 않고 계속 반복 실행된다.

 

 수정5 : 코드 실행을 멈추는 break를 활용하자

  else 구문으로 조건을 만족해도 코드가 종료되지 않으므로, 조건을 만족했을 때 코드 실행을 멈추도록 break를 추가해준다.

let randomNumber = Int.random(in: 1 ... 100)
var userInput = ""

repeat {
    print("숫자를 입력해주세요: ")
    userInput = readLine() ?? ""

    if let number = Int(userInput) {
        if randomNumber < number {
            print("더 작은 숫자를 입력하세요!")
        } else if randomNumber > number {
            print("더 큰 숫자를 입력하세요!")
        } else {
            print("축하합니다! 정답입니다")
            break
        }
    }
}

 

수정6 : repeat - while문에서 조건을 확인하는 while을 누락하지 말 것

   숫자를 맞추지 못하면 코드를 다시 실행할 수 있도록, repeat - while문에서 중요한 while문을 추가해준다.

let randomNumber = Int.random(in: 1 ... 100)
var userInput = ""

repeat {
    print("숫자를 입력해주세요: ")
    userInput = readLine() ?? ""

    if let number = Int(userInput) {
        if randomNumber < number {
            print("더 작은 숫자를 입력하세요!")
        } else if randomNumber > number {
            print("더 큰 숫자를 입력하세요!")
        } else {
            print("축하합니다! 정답입니다")
            break
        }
    }
} while Int(userInput) != randomNumber

 

Type에 따른 값의 변화

 위의 코드에서 마지막 While문의 값은 이렇게 2개로 비교할 수 있다.

1. userInput을 Int로 변환하고 randomNumber와 비교하는 방식

} while Int(userInput) != randomNumber

 

2. randomNumber을 string으로 변환하고 userInput과 비교하는 방식

while userInput != String(randomNumber)

 

1번과 2번의 차이는 상수와 변수의 선언에서부터 차이가 있다.

let randomNumber = Int.random(in: 1 ... 100)
var userInput = ""

 먼저 1번은 변수로 선언된 userInput을 변환하는 것이고, 2번은 Type이 Int로 지정된 상수를 변환하는 것이다.

더 나아가 1번의 경우 사용자로부터 입력을 받게 되는데, 사용자가 값을 잘못 입력하면 nil이 return되므로 오류가 발생할 수 있다.

(예를 들면, 사용자가 값을 "삼"과 같이 입력할 경우, Int("삼")은 숫자로 변환이 되지 않기 때문에 nil이 return)

 

 따라서 코드를 작성할 때는 값의 형태를 잘 보고 어떤 값으로 비교하는 것이 안정적인지 고민해봐야 한다.


 문제의 의도를 잘 파악할 것

 문제의 의도(나중에는 클라이언트)를 잘못 파악하면, 코드가 복잡해지거나 오류가 많이 발생한다.

만약 위 코드를 while문으로 작성했다면 어떻게 됐을까?

let randomNumber = Int.random(in: 1 ... 100)
var userInput = 0

while userInput != randomNumber {
    print("숫자를 입력하세요: ")
    if let input = readLine(), let num = Int(input) {
        userInput = num
        if userInput > randomNumber {
            print("더 작은 숫자를 입력하세요!")
        } else if userInput < randomNumber {
            print("더 큰 숫자를 입력하세요!")
        } else {
            print("축하합니다! 정답입니다!")
        }
    }
}

 이처럼 비교적 간단한 코드로 완성될 수 있었을 것이다.

 

 이 코드를 분석해보면 다음과 같다.

let randomNumber = Int.random(in: 1 ... 100)       
var userInput = 0

/*
 랜덤 숫자를 randomNumber에 저장하고, userInput에 0을 저장(초기 값 설정)
*/
while userInput != randomNumber {
    print("숫자를 입력하세요: ")

/*
userInput과 randomNumber가 일치하지 않으면 숫자를 반복해서 입력하도록 설정
*/
    if let input = readLine(), let num = Int(input) {
        userInput = num
        
 /*
 readLine() 함수를 통해 사용자의 입력 값(String Type)을 input라는 상수에 저장.
 단, 이때 readLine() 함수는 optional String(String?)값을 저장하기 때문에,
 if let으로 optional Binding해서 string Type으로 input에 저장
 
 String Type인 input을 Int Type으로 변경하여 num이라는 상수에 저장.
 Int로 변경된 num을 다시 userInput에 저장. 
 */
        if userInput > randomNumber {
            print("더 작은 숫자를 입력하세요!")
        } else if userInput < randomNumber {
            print("더 큰 숫자를 입력하세요!")
        } else {
            print("축하합니다! 정답입니다!")
        }
    }
}

/*
 userInput을 Int Type으로 변경해주었기 때문에, 비교연산이 가능해짐.
*/

 

 

최근댓글

최근글

skin by © 2024 ttuttak