Visual Basic의 배열

배열은 초등학교 각 학년의 학생 수와 같이 논리적으로 서로 관련된 값의 집합입니다.

배열을 사용하면 이러한 관련 값들을 동일한 이름으로 참조하고 인덱스 또는 첨자라고 하는 번호를 사용하여 각 값을 구별할 수 있습니다. 개별 값은 배열의 요소라고 합니다. 요소는 인덱스 0부터 최고 인덱스 값까지 연속되어 있습니다.

배열과 달리 단일 값을 포함하는 변수를 스칼라 변수라고 합니다.

예제

다음 예제에서는 초등학교 각 학년의 학생 수를 보유하는 배열 변수를 선언합니다.

Dim students(6) As Integer

위 예제의 students 배열에는 7개의 요소가 포함되어 있습니다. 요소 인덱스의 범위는 0부터 6까지입니다. 이 배열을 사용하는 것이 7개의 서로 다른 변수를 선언하는 것보다 간단합니다.

다음 그림에서는 students 배열을 보여 줍니다. 배열의 각 요소는 다음과 같은 특징을 갖습니다.

  • 요소의 인덱스는 학년을 나타냅니다(인덱스 0은 유치반).

  • 요소에 포함된 값은 해당 학년의 학생 수를 나타냅니다.

"students" 배열의 요소

학생 수를 보여 주는 배열 그림

다음 예제에서는 students 배열의 첫 번째, 두 번째 및 마지막 요소에 대한 참조 방법을 보여 줍니다.

Dim kindergarten As Integer = students(0)
Dim firstGrade As Integer = students(1)
Dim sixthGrade As Integer = students(6)
MsgBox("Students in kindergarten = " & CStr(kindergarten))
MsgBox("Students in first grade = " & CStr(firstGrade))
MsgBox("Students in sixth grade = " & CStr(sixthGrade))

인덱스를 지정하지 않고 배열 변수만 사용하면 배열 전체를 참조할 수 있습니다.

배열 차원

위 예제의 students 배열은 인덱스를 하나를 사용하므로 1차원이라고 합니다. 인덱스 또는 첨자를 둘 이상 사용하는 배열을 다차원 배열이라고 합니다. 자세한 내용은 Visual Basic의 배열 차원을 참조하십시오.

다른 종류의 배열로는 다른 배열이 요소로 포함되는 배열이 있습니다. 이러한 배열을 배열의 배열 또는 가변 배열이라고 합니다. 가변 배열은 1차원 또는 다차원일 수 있으며, 해당 요소 배열도 마찬가지입니다. 간혹 응용 프로그램의 데이터 구조는 2차원이지만 사각형 형태가 아닌 경우가 있습니다. 예를 들면 일 배열을 각 요소로 사용하여 구성되는 월 배열을 들 수 있습니다. 월에 따라 일 수가 달라지므로 배열 요소가 사각형의 2차원 배열을 형성하지 않습니다. 이러한 경우 다차원 배열 대신 가변 배열을 사용할 수 있습니다.

배열 선언

다른 변수와 동일한 방법으로 Dim 문을 사용하여 배열 변수를 선언할 수 있습니다. 변수 이름 뒤에 한 쌍 이상의 괄호를 붙여서 해당 변수에 스칼라(하나의 값을 포함하는 변수)가 아니라 배열이 포함됨을 나타냅니다.

1차원 배열 변수를 선언하려면 변수 이름 뒤에 괄호 한 쌍을 추가합니다.

Dim cargoWeights() As Double

다차원 배열 변수를 선언하려면 선언에서 변수 이름 뒤에 괄호 한 쌍을 추가한 다음 괄호 안에서 쉼표를 사용하여 차원을 구분합니다.

Dim atmospherePressures(,,,) As Short

가변 배열 변수를 선언하려면 변수 이름 뒤에 중첩된 배열의 수준 수만큼 괄호 쌍을 추가합니다.

Dim inquiriesByYearMonthDay()()() As Byte

앞의 예제에서는 배열 변수를 선언만 하고 변수에 배열을 할당하지는 않습니다. 그래도 배열을 만들어 초기화한 다음 변수에 배열을 할당해야 합니다.

길이가 0인 배열

요소가 없는 배열은 길이가 0인 배열이라고도 합니다. 길이가 0인 배열을 보유하는 변수에는 Nothing 값이 포함되지 않습니다. 요소가 없는 배열을 만들려면 다음 예제와 같이 배열의 차원 중 하나를 -1로 선언합니다.

Dim twoDimensionalStrings(-1, 3) As String

길이가 0인 배열을 만들어야 하는 경우는 다음과 같습니다.

  • 코드에서 Array 클래스의 Length 또는 Rank 같은 멤버에 액세스해야 하거나, NullReferenceException 예외를 발생시키지 않고 UBound와 같은 Visual Basic 함수를 호출해야 하는 경우

  • Nothing을 특수한 경우로 확인할 필요가 없도록 하여 배열을 사용하는 코드를 보다 간단하게 하려는 경우

  • 하나 이상의 프로시저에 길이가 0인 배열을 전달해야 하거나 하나 이상의 프로시저에서 길이가 0인 배열을 반환하는 API(응용 프로그래밍 인터페이스)와 코드가 상호 작용하는 경우

배열 만들기

두 가지 방법으로 배열을 만들 수 있습니다. 배열을 선언할 때 또는 배열이 개체이기 때문에 배열의 크기를 제공할 수 있으므로 New 연산자(Visual Basic) 절을 사용하여 배열을 만들고 배열 변수에 할당합니다. 다음 예제와 같이 배열 선언의 일부로 이 작업을 수행하거나 후속 대입문에서 수행할 수 있습니다.

cargoWeights = New Double() {}
atmospherePressures = New Short(,,,) {}
inquiriesByYearMonthDay = New Byte()()() {}

이러한 문을 실행한 후에는 배열의 길이가 0이 됩니다.

참고

New 절에서는 형식 이름, 괄호 및 중괄호({})를 순서대로 지정해야 합니다. 괄호는 배열 생성자에 대한 호출을 나타내는 것이 아니라 해당 개체 형식이 배열 형식임을 나타냅니다. 초기화 값은 중괄호 안에 제공할 수 있습니다. 컴파일러가 제대로 동작하려면 값을 지정하지 않을 경우에도 중괄호가 있어야 합니다. 따라서 New 절에는 값이 없더라도 괄호와 중괄호를 모두 포함해야 합니다. 중괄호를 제외하면 컴파일러는 지정된 형식의 생성자를 호출하는 것으로 가정합니다.

몇 가지 방법으로 배열의 크기를 정의할 수 있습니다. 다음 예제와 같이 배열을 선언할 때 크기를 제공할 수 있습니다.

Dim cargoWeights(10) As Double
Dim atmospherePressures(2, 2, 4, 10) As Short
Dim inquiriesByYearMonthDay(20)()() As Byte

다음 예제와 같이 New 절을 사용하여 배열을 만들 때 배열의 크기를 제공할 수도 있습니다.

cargoWeights = New Double(10) {}
atmospherePressures = New Short(2, 2, 4, 10) {}
inquiriesByYearMonthDay = New Byte(20)()() {}

기존 배열이 있는 경우 Redim 문을 사용하여 해당 크기를 다시 정의할 수 있습니다. Redim 문이 현재 배열에 저장된 값을 유지하도록 지정하거나, 빈 배열을 새로 만들도록 지정할 수 있습니다. 다음 예제에서는 Redim 문을 사용하여 기존 배열의 크기를 수정하는 몇 가지 방법을 보여 줍니다.

' Assign a new array size and retain the current element values.
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five element values.
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values.
ReDim cargoWeights(15)

자세한 내용은 ReDim 문(Visual Basic)을 참조하십시오.

배열에 초기 값 채우기

배열 리터럴을 사용하여 초기 값 집합이 포함된 배열을 만들 수 있습니다. 배열 리터럴은 중괄호({})로 묶인 쉼표로 구분된 값의 목록으로 구성됩니다.

배열 리터럴을 사용하여 배열을 만드는 경우 배열 형식을 제공하거나 형식 유추를 사용하여 배열 형식을 결정할 수 있습니다. 다음 코드에서는 두 옵션을 모두 보여 줍니다.

Dim numbers = New Integer() {1, 2, 4, 8}
Dim doubles = {1.5, 2, 9.9, 18}

형식 유추를 사용할 때 배열 형식은 배열 리터럴에 제공된 값 목록의 기준 형식에 의해 결정됩니다. 기준 형식이란 배열 리터럴의 다른 모든 형식이 확대 변환될 수 있는 고유 형식입니다. 이 고유 형식을 확인할 수 없는 경우 기준 형식은 배열의 다른 모든 형식이 축소 변환될 수 있는 고유 형식입니다. 이러한 두 고유 형식을 모두 확인할 수 없는 경우 기준 형식은 Object입니다. 예를 들어, 배열 리터럴에 제공된 값 목록에 Integer, Long 및 Double 형식의 값이 포함되어 있으면 결과 배열은 Double 형식이 됩니다. Integer 및 Long은 모두 Double로 확대 변환되며, Double로만 확대 변환됩니다. 따라서 Double이 기준 형식이 됩니다. 자세한 내용은 확대 변환과 축소 변환(Visual Basic)을 참조하십시오. 이러한 유추 규칙은 클래스 멤버에 정의된 지역 변수인 배열에 대해 유추되는 형식에 적용됩니다. 클래스 수준 변수를 만들 때는 배열 리터럴을 사용할 수 있지만 클래스 수준에서 형식 유추를 사용할 수는 없습니다. 따라서 클래스 수준에서 지정된 배열 리터럴은 배열 리터럴에 제공된 값을 Object 형식으로 유추합니다.

배열 리터럴을 사용하여 만든 배열의 요소 형식을 명시적으로 지정할 수 있습니다. 이 경우 배열 리터럴의 값이 배열의 요소 형식으로 확대 변환되어야 합니다. 다음 코드 예제에서는 정수 목록에서 Double 형식의 배열을 만듭니다.

Dim values As Double() = {1, 2, 3, 4, 5, 6}

중첩된 배열 리터럴

중첩된 배열 리터럴을 사용하여 다차원 배열을 만들 수 있습니다. 중첩된 배열 리터럴에는 차원 및 결과 배열과 일치하는 차원 수(차수)가 있어야 합니다. 다음 코드 예제에서는 배열 리터럴을 사용하여 2차원 정수 배열을 만듭니다.

Dim grid = {{1, 2}, {3, 4}}

앞의 예제에서 중첩된 배열 리터럴의 요소 수가 일치하지 않으면 오류가 발생합니다. 배열 변수가 2차원 이외의 값으로 명시적으로 선언된 경우에도 오류가 발생합니다.

참고

서로 다른 차원의 중첩된 배열 리터럴을 제공하는 경우 내부 배열 리터럴을 괄호로 묶어 오류를 방지할 수 있습니다. 괄호를 사용하면 배열 리터럴 식이 강제로 계산되고, 결과 값이 외부 배열 리터럴에 사용됩니다. 이는 다음 코드에서 볼 수 있습니다.

Dim values = {({1, 2}), ({3, 4, 5})}

중첩된 배열 리터럴을 사용하여 다차원 배열을 만드는 경우 형식 유추를 사용할 수 있습니다. 형식 유추를 사용할 때 유추되는 형식은 중첩 수준의 모든 배열 리터럴에 있는 모든 값의 기준 형식입니다. 다음 코드 예제에서는 Integer 및 Double 형식인 값에서 Double 형식의 2차원 배열을 만듭니다.

Dim a = {{1, 2.0}, {3, 4}, {5, 6}, {7, 8}}

다른 예제를 보려면 방법: Visual Basic에서 배열 변수 초기화를 참조하십시오.

배열에 값 저장

Integer 형식의 인덱스를 사용하여 배열의 각 위치에 액세스할 수 있습니다. 괄호 안에 포함된 인덱스로 각 배열 위치를 참조하여 배열의 값을 저장하고 검색할 수 있습니다. 다차원 배열의 인덱스는 쉼표(,)로 구분됩니다. 각 배열 차원에 대해 하나의 인덱스가 필요합니다. 다음 예제에서는 배열에 값을 저장하는 몇 개의 문을 보여 줍니다.

Dim i = 4
Dim j = 2

Dim numbers(10) As Integer
Dim matrix(5, 5) As Double

numbers(i + 1) = 0
matrix(3, j * 2) = j

다음 예제에서는 배열에서 값을 가져오는 몇 개의 문을 보여 줍니다.

Dim v = 2
Dim i = 1
Dim j = 1
Dim k = 1
Dim wTotal As Double = 0.0
Dim sortedValues(5), rawValues(5), estimates(2, 2, 2) As Double
Dim lowestValue = sortedValues(0)
wTotal += (rawValues(v) ^ 2)
Dim firstGuess = estimates(i, j, k)

각 배열 차원에서 GetUpperBound 메서드는 인덱스에 허용되는 가장 높은 값을 반환합니다. 가장 낮은 인덱스 값은 항상 0입니다.

배열 크기

배열의 크기는 배열의 모든 차원 길이를 곱한 값입니다. 이 값은 배열에 현재 포함된 요소의 전체 개수를 나타냅니다.

다음 예제에서는 3차원 배열을 선언합니다.

Dim prices(3, 4, 5) As Long

prices 변수의 배열 크기는 (3 + 1) x (4 + 1) x (5 + 1) = 120입니다.

Length 속성을 사용하여 배열의 크기를 확인할 수 있습니다. GetLength 메서드를 사용하면 다차원 배열에서 각 차원의 길이를 확인할 수 있습니다.

배열 변수에 새 배열 개체를 할당하거나 ReDim 문을 사용하여 배열 변수의 크기를 조정할 수 있습니다.

배열 크기를 결정할 때는 다음 사항을 고려해야 합니다.

차원 길이

각 차원의 인덱스는 0부터 시작합니다. 즉, 인덱스의 범위는 0부터 인덱스 상한까지입니다. 따라서 특정 차원의 길이는 해당 차원에 선언된 상한보다 1이 더 큰 값입니다.

길이 제한

배열의 모든 차원 길이는 Integer 데이터 형식의 최대값인 (2 ^ 31) - 1로 제한됩니다. 그러나 배열의 전체 크기는 시스템에서 사용할 수 있는 메모리에 따라서도 제한을 받습니다. 사용할 수 있는 RAM 용량을 초과하는 배열을 초기화하려고 하면 공용 언어 런타임에서는 OutOfMemoryException 예외를 throw합니다.

크기 및 요소 크기

배열의 크기는 해당 요소의 데이터 형식과 상관이 없습니다. 배열 크기는 항상 배열이 저장소에서 차지하는 바이트 수가 아니라 요소의 전체 개수를 나타냅니다.

메모리 사용

배열이 메모리에 저장되는 방식에 관해서는 어떤 가정도 하지 않는 것이 안전합니다. 저장소는 플랫폼의 데이터 너비에 따라 달라지므로 동일한 배열이라도 32비트 시스템에서보다 64비트 시스템에서 더 많은 메모리를 사용합니다. CLR(공용 언어 런타임)에서는 배열을 초기화할 때의 시스템 구성에 따라 저장소를 할당하여 가능한 한 조밀하게 요소를 압축하거나 원래의 하드웨어 경계에 모든 요소를 맞춥니다. 또한 배열을 사용하려면 해당 제어 정보에 대한 저장소 오버헤드가 필요하며 이 오버헤드는 차원이 늘어날수록 증가합니다.

배열 형식 및 기타 형식

데이터 형식

모든 배열에 데이터 형식이 있지만 해당 요소의 데이터 형식과는 다릅니다. 모든 배열에 사용할 수 있는 단일 데이터 형식은 없습니다. 대신 배열의 데이터 형식은 배열의 차원 수(차수)와 배열에 있는 요소의 데이터 형식에 의해 결정됩니다. 두 개의 배열 변수는 차수 및 요소의 데이터 형식이 같을 때만 데이터 형식이 같은 것으로 간주됩니다. 배열의 차원 길이는 배열 데이터 형식에 영향을 주지 않습니다.

모든 배열은 System.Array 클래스에서 상속하며, 변수를 Array 형식으로 선언할 수는 있지만 Array 형식의 배열을 만들 수는 없습니다. 또한 ReDim 문(Visual Basic)은 Array 형식으로 선언된 변수에는 사용할 수 없습니다. 이러한 이유와 형식 안전성을 위해 모든 배열은 위 예제의 Integer와 같이 특정 형식으로 선언하는 것이 좋습니다.

배열 또는 배열 요소의 데이터 형식을 확인하는 방법에는 여러 가지가 있습니다.

  • 변수에 대해 Object.GetType 메서드를 호출하여 변수의 런타임 형식에 대한 Type 개체를 얻을 수 있습니다. Type 개체의 속성과 메서드에는 다양한 정보가 들어 있습니다.

  • TypeName 함수에 변수를 전달하여 런타임 형식의 이름이 포함된 String을 받을 수 있습니다.

  • VarType 함수에 변수를 전달하여 변수의 형식 분류를 나타내는 VariantType 값을 받을 수 있습니다.

다음 예제에서는 TypeName 함수를 호출하여 배열 형식과 배열의 요소 형식을 확인합니다. 배열 형식은 Integer(,)이고 배열의 요소 형식은 Integer입니다.

Dim thisTwoDimArray(,) As Integer = New Integer(9, 9) {}
MsgBox("Type of thisTwoDimArray is " & TypeName(thisTwoDimArray))
MsgBox("Type of thisTwoDimArray(0, 0) is " & TypeName(thisTwoDimArray(0, 0)))

배열 대신 컬렉션 사용

컬렉션은 Object 데이터 형식을 다루는 데 주로 사용되지만 다른 모든 데이터 형식을 다루는 데에도 사용할 수 있습니다. 일부의 경우 배열보다 컬렉션에 항목을 저장하는 것이 더욱 효율적일 수 있습니다.

배열 크기를 변경하려면 ReDim 문(Visual Basic)을 사용해야 합니다. 이 작업을 수행하면 Visual Basic에서 새 배열을 만들고 이전 배열을 해제하여 삭제합니다. 이 작업에는 실행 시간이 필요합니다. 따라서 사용 중인 항목의 개수가 자주 변경되거나 필요한 항목의 최대 개수를 미리 알 수 없는 경우에 컬렉션을 사용하면 더 좋은 성능을 얻을 수 있습니다.

새 개체를 만들거나 기존 요소를 복사할 필요가 없는 컬렉션에서는 ReDim을 사용해야 하는 배열보다 더 짧은 실행 시간으로 크기 조정을 처리할 수 있습니다. 그러나 크기가 변경되지 않거나 아주 드물게만 변경되는 경우에는 배열이 더 효율적일 수 있습니다. 성능은 개별 응용 프로그램에 따라 크게 달라집니다. 배열과 컬렉션을 모두 시도해 보고 결정하는 것도 좋은 방법입니다.

특수 컬렉션

또한 .NET Framework에서는 일반 및 특수 컬렉션을 위한 다양한 클래스, 인터페이스 및 구조체를 제공합니다. System.CollectionsSystem.Collections.Specialized 네임스페이스에는 사전, 목록, 큐 및 스택을 포함하는 정의와 구현이 포함되어 있습니다. System.Collections.Generic 네임스페이스에서는 이러한 대부분의 항목을 하나 이상의 형식 인수를 받는 제네릭 버전으로 제공합니다.

컬렉션에 특정 데이터 형식의 요소만 포함될 경우 제네릭 컬렉션을 사용하면 형식 안전성이 보장됩니다. 제네릭에 대한 자세한 내용은 Visual Basic의 제네릭 형식(Visual Basic)을 참조하십시오.

특수 컬렉션

또한 .NET Framework에서는 일반 및 특수 컬렉션을 위한 다양한 클래스, 인터페이스 및 구조체를 제공합니다. System.CollectionsSystem.Collections.Specialized 네임스페이스에는 사전, 목록, 큐 및 스택을 포함하는 정의와 구현이 포함되어 있습니다. System.Collections.Generic 네임스페이스에서는 이러한 대부분의 항목을 하나 이상의 형식 인수를 받는 제네릭 버전으로 제공합니다.

컬렉션에 특정 데이터 형식의 요소만 포함될 경우 제네릭 컬렉션을 사용하면 형식 안전성이 보장됩니다. 제네릭에 대한 자세한 내용은 Visual Basic의 제네릭 형식(Visual Basic)을 참조하십시오.

예제

다음 예제에서는 .NET Framework의 제네릭 클래스 System.Collections.Generic.List<T>을 사용하여 Customer 개체의 목록 컬렉션을 만듭니다.

' Define the class for a customer.
Public Class Customer
    Public Property Name As String
    ' Insert code for other members of customer structure.
End Class

' Create a module-level collection that can hold 200 elements.
Public CustomerList As New List(Of Customer)(200)

' Add a specified customer to the collection.
Private Sub AddNewCustomer(ByVal newCust As Customer)
    ' Insert code to perform validity check on newCust.
    CustomerList.Add(newCust)
End Sub

' Display the list of customers in the Debug window.
Private Sub PrintCustomers()
    For Each cust As Customer In CustomerList
        Debug.WriteLine(cust)
    Next cust
End Sub

CustomerFile 컬렉션의 선언에서는 Customer 형식의 요소만 포함할 수 있도록 지정합니다. 또한 이 선언에서는 초기 크기를 200개의 요소를 포함할 수 있는 크기로 지정합니다. AddNewCustomer 프로시저에서는 새 요소의 유효성을 검사한 다음 이 요소를 컬렉션에 추가합니다. PrintCustomers 프로시저에서는 For Each 루프를 사용하여 컬렉션을 이동하고 해당 요소를 표시합니다.

관련 항목

용어

정의

Visual Basic의 배열 차원

배열의 차수 및 차원에 대해 설명합니다.

방법: Visual Basic에서 배열 변수 초기화

배열에 초기 값을 채우는 방법에 대해 설명합니다.

방법: Visual Basic에서 배열 내용을 반대로 정렬

배열 요소의 순서를 역순으로 바꾸는 방법을 설명합니다.

방법: Visual Basic에서 배열 정렬

배열의 요소를 사전순으로 정렬하는 방법을 설명합니다.

방법: 한 배열에 다른 배열 할당(Visual Basic)

다른 배열 변수에 배열을 할당하는 규칙과 단계를 보여 줍니다.

방법: 다른 배열로 배열 변경(Visual Basic)

가능한 변경과 변경 방법을 보여 줍니다.

방법: 프로시저나 속성에 배열 전달(Visual Basic)

프로시저나 속성에 배열을 인수로 전달하는 방법을 보여 줍니다.

방법: 프로시저 또는 속성에서 배열 반환(Visual Basic)

프로시저나 속성을 호출하는 코드에 배열을 반환하는 방법을 보여 줍니다.

배열 문제 해결(Visual Basic)

배열을 사용할 때 발생할 수 있는 몇 가지 일반적인 문제에 대해 설명합니다.

참고 항목

참조

Dim 문(Visual Basic)

ReDim 문(Visual Basic)

Array