Swift

[Swift] 범위 연산자 및 for 문

챎 님 2024. 6. 3. 17:38

# 범위 연산자

범위를 표현하는 연산자입니다.

반복할 범위를 표현할 때 사용하거나 배열에서 특정 부분을 추출할 때 사용합니다.

스위프트에서는 두 가지 범위 연산자를 제공합니다. 마지막 범위의 포함 여부에 따라 구분합니다.

 

# Closed Range Operator

닫힌 범위라고 부르기도 합니다.

문법에 대해 간단히 설명해 보겠습니다.

lowerBound ... upperBound // 이항 연산자를 사용시 시작 위치부터 종료 위치의 범위를 생성.
lowerBound... // 단항 후치 연산자면 시작 위치를 생성, 종료 위치는 해당 코드에 따라 결정. 반복문은 무한대.
...upperBound // 단항 전치 연산자 종료 위치 생성, 시작 위치는 실제 코드를 보고 결정.

lowerBound 는 시작 위치, upperBound 는 종료 위치를 나타냅니다.

 

코드를 통해 자세히 설명해 보겠습니다.

1 ... 10
// 10 ... 1 이와 같은 내림차순의 식은 만들 수 없습니다.

(1 ... 10).reversed() // 이 코드를 통해서 내림차순의 식을 만들어야 합니다.

 

for 문을 통해 간단한 코드를 만들어 보겠습니다.

for num in 1 ... 10 {
	print(num)
}

10 번 반복하니 10 까지 출력이 됩니다.

여기서 10 을 제외하면 upperBound 가 없어지니 코드가 멈추지 않고 무한대로 계속 실행됩니다.

 

# Half-Open Range Operator

lowerBound ..< upperBound
..<upperBound

기본적으로 Closed Range Operator 와 똑같지만 두 가지 차이점이 존재합니다.

먼저, upperBound 가 범위에 포함되지 않습니다. < 가 포함되지 않음을 알려 줍니다.

단항 연산자로 보면 전치 연산자로만 사용이 가능합니다.

 

코드를 통해 알아보면,

for num in 1 ..< 10 {
	print(num)
}

이 코드는 9 번 실행됩니다.

종료 위치가 범위에 포함되지 않기 때문에 피연산자가 같을 때 Closed Range 보다 하나 적게 실행됩니다.

let range = ...5
// First-class Citizen 으로 부릅니다.

range.contains(3)
// 을 통해 true, false 확인 가능.

First-class Citizen 은  상수나 변수에 저장할 수 있고 파라멘트로 이동할 수 있으며 함수에서 리턴 가능합니다.

 

# for 문

 

지정한 횟수만큼 코드를 반복하는 문장입니다.

범위 연산자를 사용하여 반복 범위를 지정할 수 있습니다. Loop 라고 부를 수 있습니다.

for loopConstant in Range {
	statements
}

loofConstant 는 루프 변수가 아닌 루프 상수이기 때문이기 때문에 값을 바꿀 수 없고 전달되는 값을 읽을 수만 있습니다.

루프 상수의 타입은 본인이 지정할 수 없고 범위 표현식에 있는 Bound 에 타입과 같습니다.

print("Hello")
print("Hello")
print("Hello")
print("Hello")
print("Hello") // 비효율적인 코드

반복되는 문장을 이렇게 사용하게 되면 비효율적입니다.

이러한 상황에서 사용되는 것이 for 문입니다.

 

for 문을 사용하여 코드를 간결하게 나타내 보겠습니다.

for index in 1 ... 10 {
	print("Hello")
}

Hello 를 열 번 반복하는 코드를 세 줄로 작성할 수 있습니다.

이러한 코드를 작성하면 경고 문구가 뜨게 됩니다.

 

경고 문구를 분석하기 전 두 가지 언어를 해석해 보면,

Immutable value는 불변 값입니다. (상수)

mutable value 는 가변 값입니다. (변수)

 

경고문에서는 index 를 수정하거나 지우라고 얘기합니다.

하지만 루프 상수는 지울 수 없기 때문에 _ 로 변경하면 경고문이 사라집니다.

for _ in 1 ... 10 {
	print("Hello")
}

이렇게 언더 스코어 문자로 바꾸는 행위를 Wildcard Pattern 이라고 합니다.

Wildcard pattern 은 생략으로 암기하면 편합니다.

 

2의 거듭제곱을 구하는 코드를 구현해 보겠습니다.

let power = 10 // 상수에 지수 저장.
var result = 1 // 변수 생성, 결과를 누적하게 설정.

for _ in 1 ... power { // 루프 상수 생략.
	result *= 2 // 누적된 결과에 2 를 곱하기.
}
result // 1024 출력.

 

# stride

for num in stride(form: 0, to: 10, by: 2) {
	print(num)
}

이 코드는 동작 방식이 Half-open Range 와 동일함으로 10 이 범위에 포함되지 않습니다.

즉, 출력이 8 까지만 된다는 뜻입니다.

 

이러한 문제를 해결하기 위해서는 to 대신에 through 를 사용해 주면 해결됩니다.

for num in stride(form: 0, through: 10, by: 2) {
	print(num)
}

10 까지 출력이 가능하게 합니다.

 

1 에서부터 10까지 합을 작성하는 코드를 작성해 보겠습니다.

var sum = 0 // 합을 저장하는 변수

fo num in 1 ... 10 {
	sum += num
}
sum

 

마지막으로 구구단을 출력하는 코드를 보여드리겠습니다.

for i in 2 ... 9 {
	for j in 1 ... 9 {
    print("\(i) * \(j) = \(i * j)")
    }
}

밖에 있는 for 문이 한 번 반복할 때마다 안에 있는 for 문은 9 번씩 반복합니다.

안에 있는 for 문이 반복이 마무리되어야 밖에 있는 for 문이 다음 회차로 넘어가게 됩니다.