-
Swift - Loop StatementsProgramming/Swift 2020. 9. 30. 20:36
오늘은 Loop Statements(반복문)에 대해서 공부해보려 합니다.
반복적인 코드를 작성해야 할 때 하나하나 작성한다면 매우 비효율적입니다.
이때 사용하는 게 반복문입니다.
반복문은 크게 2가지로 나눌 수 있습니다.
- For-in Loops
- While Loops
For-in Loops
1부터 100까지의 숫자를 출력해보려 합니다.
이렇게 해서 100까지 작성하면 우리가 원하는 대로 100까지 출력할 수는 있습니다.
하지만 매우 비효율적이죠
이때 For-in Loop를 이용하면 간단하게 출력할 수 있습니다.
For-in 반복문은 다음과 같이 작성합니다.
loopConstant는 반복 상수라고 합니다.
주의해서 봐야 하는 부분은 상수입니다.
변수가 아니라 상수입니다!
반복 상수는 for-in문 안에서 임시적으로 사용하는 상수입니다.
Range는 range의 값이 차례대로 반복 상수에 전달되면서 statement를 반복합니다.
Range의 LowerBound에서 UpperBound까지의 값이 반복 상수에 전달되기 때문에 반복 상수의 Type은 Range의 LowerBound 또는 UpperBound의 Type과 같습니다.
말로 설명했을 때 이해가 어려울 수 있으니 예시를 보도록 하겠습니다.
For-in 반복문을 사용해서 1부터 100까지 출력해보도록 하겠습니다.
반복 상수를 num이라는 이름으로 지정했습니다. 그리고 범위를 1 ... 100으로 설정했습니다.
그렇다면 처음에 범위의 LowerBound인 1이 반복상수 num에 전달됩니다.
그리고 statement가 실행되겠죠? 이때 num은 1입니다. 그래서 print(num)이 실행되고 1이 출력됩니다.
그다음 2가 반복 상수 num에 전달됩니다. 그리고 다시 statement가 실행되고 이때 num은 2이기 때문에 print(num)이 실행되면 2가 출력됩니다.
1과 2 Int Type이 계속 반복 상수에 전달되죠?? 그러므로 이때 num의 Type은 Int Type입니다.
이러한 방식으로 반복을 100까지 하게 되고 1부터 100까지 출력되게 됩니다.
반복 상수는 for-in문 안에서 임시적으로 사용하는 상수라고 말씀드렸죠?? 그래서 for-in문 밖에서 num을 사용하지 못합니다.
그리고 반복상수는 상수라고 했습니다.
만약 이렇게 num에 다른 값을 할당하려고 한다면 let이기 때문에 할당할 수 없다는 에러 메시지가 출력됩니다.
WildcardPattern
만약 반복 상수를 {} 안에서 사용하지 않는다면 _(underscore)를 사용하여 생략해주는 것이 좋습니다.
반복 상수를 만들때 메모리를 따로 생성하지 않으므로 메모리 관리에 더 효율적이게 됩니다.
stride(from:to:by:) 함수
만약 반복을 0 ... 100까지 2씩 건너뛰며 하고 싶다면 어떻게 해야 할까요?? 아니면 4씩 건너뛰고 싶다면 어떻게 해야 할까요??
이때 stride함수를 사용하면 손쉽게 해결 가능합니다.
in 키워드 다음에 stride(from:to:by:) 함수를 사용하면 from부터 to까지 by만큼 건너뛰며 반복 상수에 값을 전달합니다.
하지만 이때 주의해야 할 점은 마지막 to는 포함하지 않습니다!!!
로그를 확인하면 100은 제외하고 98까지만 출력이 됐습니다. 100까지 출력하고 싶다면 to에 101을 넣으면 됩니다.
혹은 파라미터가 다른 stride함수를 사용해도 됩니다.
to대신 through를 파라미터로 받는 stride 함수를 사용하면 마지막 through를 포함하며 반복 상수에 값을 전달합니다.
로그를 출력해보면 100까지 모두 출력되는 것을 확인할 수 있습니다.
stride 함수를 사용하면 범위를 거꾸로 하는 것도 쉽게 가능합니다.
이전에 우리가 범위를 범위 연산자로 지정하면 lowerbound가 upperbound보다 크다면 에러가 발생했습니다.
그래서 만약 범위를 거꾸로 하고싶다면 .reversed 메서드를 사용했습니다.
하지만 stride(from:to:by:) 함수를 사용하면
이렇게 손쉽게 구현할 수 있습니다.
Collection 반복
Range에는 숫자 범위뿐만 아니라 Collection도 사용할 수 있습니다.
Collection에 대해서는 다음에 자세히 포스팅하도록 하겠습니다.
오늘은 Range에 Collection도 사용이 가능하다는 것만 알아주세요.
간단하게 예를 보겠습니다.
list라는 문자열 배열을 만들고 Range대신 list를 넣었습니다.
이렇게 되면 배열 안의 요소들이 차례대로 반복 상수인 str에 전달됩니다.
그럼 이때 str의 Type은 배열의 요소인 String Type이 됩니다.
for-in 반복문 중첩
if를 중첩시킨 것처럼 for-in 반복문도 얼마든지 중첩시킬 수 있습니다.
구구단을 출력하는 중첩 반복문입니다. 흐름을 한번 따라가 보겠습니다.
위에서 아래 순서로 i에 2가 전달되고 바로 j에 1이 전달됩니다.
그러면 2 X 1 = 2가 출력이 되겠죠??
그리고 밖에 있는 i에 3이 전달되는 게 아니라 안쪽에 있는 j에 2가 전달됩니다.
그렇다면 2 X 2 = 4가 출력이 됩니다.
이렇게 안에 있는 j가 1 ... 9까지 전달되고 난 후에 i에 3이 전달되고 다시 j에 1 ... 9까지 전달됩니다.
Infinite Loop
Infinite Loop(무한루프)는 반복문을 사용할 때 가장 주의해야 하는 부분입니다.
만약 이렇게 범위의 끝을 주지 않고 for-in문을 작성하면 어떻게 될까요??
컴파일 에러가 발생하지는 않지만 이 반복문은 메모리상에 문제가 생기거나 Xcode가 종료될 때까지 계속 반복합니다.
그러므로 반복문을 사용할 때에는 반드시 반복문이 무한루프에 빠지지 않도록 주의를 해야 합니다.
While Loops
For-in Loop는 반복하는 범위가 정해져 있을 때 사용합니다.
이와 다르게 While Loop는 조건에 따라 반복을 하고 싶을 때 사용하는 반복문입니다.
condition에는 Boolean Expression만 올 수 있습니다.
그리고 codition이 true인 동안 statement를 반복적으로 실행합니다.
condition이 false가 되면 statement를 실행하지 않고 반복문을 종료합니다.
예를 보며 for와 다른 점을 살펴보겠습니다.
for-in 반복문과는 다르게 num을 선언해주지 않고 바로 사용할 수 없습니다.
num을 사용하기 위해서 반복문을 사용하기전에 변수나 상수로 선언을 해줘야 합니다.
하지만 우리는 마지막에 num을 바꾸고 있기 때문에 변수로 선언하겠습니다.
처음에 num변수에 1을 저장했습니다.
그리고 반복문에서 num이 100보다 작거나 같다면 num을 출력하고 나서 num에 + 1을 더했습니다.
흐름을 따라가 보도록 하죠.
처음에 num = 1입니다. 1 <= 100 이므로 1이 출력되고 +1을 한 2가 num에 저장됩니다.
그럼 다시 while 반복문의 condtion으로 돌아가서 2 <= 100 이므로 2가 출력되고 +1을 한 3이 num에 저장됩니다.
이는 num이 100일 때까지 반복됩니다. 그리고 num = 100이 되면 100 <= 100 이므로 100이 출력되고 +1을 한 101이 num에 저장됩니다.
그렇다면 이번에는 101 <= 100은 false입니다.
그럼 while반복문의 { statement }를 실행하지 않고 아래에 있는 코드가 print("num : \(num)") 실행 됩니다. 이때 num은 101이기 때문에 마지막에 num : 101이 출력됩니다.
Repeat While Loop
repeat-while 반복문은 while과 비슷하지만 한 가지 차이점이 있습니다.
statement를 먼저 실행하고 나서 condition이 true인지 평가합니다.
만약 true라면 다시 statement를 반복하고 false라면 statement는 실행되지 않고 다음 코드가 실행됩니다.
쉽게 말해서 일단 코드를 한 번 실행하고 그 이후에 조건을 판단합니다.
while문에서 보았던 예시를 repeat-while문으로 작성해 보겠습니다.
위에 while문과 차이가 없어 보이지만 내부적으로 돌아가는 순서는 다릅니다.
다시 num을 1로 초기화시킨 후 repeat-while문을 실행시키면
num에는 1이 저장돼있습니다.
print(num)으로 1이 출력되고 num에 +1을 더해서 2가 됩니다.
그러고 나서 조건을 비교합니다.
2 <= 100 이므로 다시 repeat으로 돌아갑니다. 그럼 num = 2 이므로 print(num)으로 2가 출력이 되고 num에 1을 더해 3이 됩니다.
이렇게 쭉 반복을 하다 num이 100이 되면 num <= 100이므로 다시 repeat으로 돌아가 print(num)으로 100이 출력되고 num에 +1을 더해 101이 됩니다.
그럼 101 <= 100 이므로 반복을 종료하고 print("num : \(num)")이 실행되어 num : 101이 출력됩니다.
Infinite Loop
while반복문도 마찬가지로 무한루프를 조심해야 합니다.
1부터 100까지 출력하고 싶어 다음과 같이 작성한다면 무한루프에 빠지게 됩니다. 코드를 따라가 보겠습니다.
num에는 1이 저장돼있습니다. 그리고 1 <= 100 이므로 1이 출력됩니다.
문제는 여기서 발생합니다. 1이 출력이 되고 다시 condition으로 돌아가는데 num은 그대로 1이기 때문에 다시 1 <= 100을 평가합니다. num이 변하지 않기 때문에 1 <= 100 은 무조건 true가 되고 condition이 계속 true로 평가되어 이 반복문은 무한루프에 빠지게 됩니다.
이렇게 반복문을 작성할 때는 무한루프에 빠지지 않도록 항상 주의하며 코드를 작성해야 합니다.
참고자료
https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html
728x90'Programming > Swift' 카테고리의 다른 글
Swift - Optional, Forced-Unwrapping (0) 2020.10.01 Swift - Control Transfer Statements (0) 2020.10.01 Swift - Conditional Statement (if, switch, guard) (0) 2020.09.29 Swift - Operator 종류 (0) 2020.09.28 Swift - Operator 기본 (0) 2020.09.28