Visual Basic의 배열
배열은 서로 논리적으로 관련이 있는 요소라고 하는 값의 집합입니다. 예를 들어 배열은 학교 각 학년의 학생 수로 구성될 수 있으며, 배열의 각 요소는 단일 학년의 학생 수입니다. 마찬가지로 배열은 수업에 대한 학생의 성적으로 구성될 수 있으며, 배열의 각 요소는 단일 등급입니다.
개별 변수를 사용하여 각 데이터 항목을 저장할 수 있습니다. 예를 들어 애플리케이션에서 학생 성적을 분석하는 경우 각 학생의 성적(예: englishGrade1
, englishGrade2
등)에 대해 별도의 변수를 사용할 수 있습니다. 이 접근 방식에는 세 가지 주요 제한 사항이 있습니다.
- 디자인 타임에 정확히 얼마나 많은 성적을 처리해야 하는지 알고 있어야 합니다.
- 많은 수의 성적을 빠르게 처리하는 것은 어려워집니다. 이렇게 하면 애플리케이션에 심각한 버그가 있을 가능성이 훨씬 높아집니다.
- 유지 관리가 어렵습니다. 새 등급을 추가하면 애플리케이션을 수정, 다시 컴파일 및 다시 배포해야 합니다.
배열을 사용하면 관련성 있는 값을 동일한 이름으로 참조하고, 인덱스 또는 첨자라는 숫자를 사용하여 서로 구분할 수 있습니다. 배열의 인덱스 범위는 0부터 배열의 총 요소 수보다 작은 수까지입니다. Visual Basic 구문을 사용하여 배열의 크기를 정의하는 경우 배열의 총 요소 수가 아니라 가장 높은 인덱스를 지정합니다. 배열을 단위로 사용할 수 있으며, 해당 요소를 반복하는 기능을 사용하면 디자인 타임에 포함된 요소 수를 정확히 알 필요가 없습니다.
설명하기 전에 몇 가지 빠른 예제는 다음과 같습니다.
' Declare a single-dimension array of 5 numbers.
Dim numbers(4) As Integer
' Declare a single-dimension array and set its 4 values.
Dim numbers = New Integer() {1, 2, 4, 8}
' Change the size of an existing array to 16 elements and retain the current values.
ReDim Preserve numbers(15)
' Redefine the size of an existing array and reset the values.
ReDim numbers(15)
' Declare a 6 x 6 multidimensional array.
Dim matrix(5, 5) As Double
' Declare a 4 x 3 multidimensional array and set array element values.
Dim matrix = New Integer(,) {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}}
' Declare a jagged array
Dim sales()() As Double = New Double(11)() {}
1차원 배열의 배열 요소
students
라는 배열을 만들어 학교에서 각 성적에 해당하는 학생 수를 저장하겠습니다. 요소의 인덱스 범위는 0부터 6까지입니다. 이 배열은 사용하는 것이 7개의 변수를 선언하는 것보다 더 간단합니다.
다음 그림은 배열 students
를 보여줍니다. 각 배열 요소에서
요소의 인덱스는 학년을 나타냅니다(인덱스 0은 유치원을 나타냄).
요소에 포함된 값은 해당 학년의 학생 수를 나타냅니다.
다음 예제에는 배열을 만들고 사용하는 Visual Basic 코드가 포함되어 있습니다.
Module SimpleArray
Public Sub Main()
' Declare an array with 7 elements.
Dim students(6) As Integer
' Assign values to each element.
students(0) = 23
students(1) = 19
students(2) = 21
students(3) = 17
students(4) = 19
students(5) = 20
students(6) = 22
' Display the value of each element.
For ctr As Integer = 0 To 6
Dim grade As String = If(ctr = 0, "kindergarten", $"grade {ctr}")
Console.WriteLine($"Students in {grade}: {students(ctr)}")
Next
End Sub
End Module
' The example displays the following output:
' Students in kindergarten: 23
' Students in grade 1: 19
' Students in grade 2: 21
' Students in grade 3: 17
' Students in grade 4: 19
' Students in grade 5: 20
' Students in grade 6: 22
이 예제에서는 다음 세 가지를 수행합니다.
- 7개의 요소가 있는
students
배열을 선언합니다. 배열 선언의6
숫자는 배열의 마지막 인덱스(배열의 요소 수보다 1 작음)를 나타냅니다. - 배열의 각 요소에 값을 할당합니다. 배열 요소는 배열 이름을 사용하고 개별 요소의 인덱스를 괄호 안에 포함하여 액세스합니다.
- 배열의 각 값을 나열합니다. 이 예제에서는
For
문을 사용하여 인덱스 숫자로 배열의 각 요소에 액세스합니다.
앞의 예제에서 students
배열은 하나의 인덱스가 사용되므로 1차원 배열입니다. 둘 이상의 인덱스 또는 아래 첨자를 사용하는 배열을 다차원 배열이라고 합니다. 자세한 내용은 이 문서의 나머지 부분과 Array Dimensions in Visual Basic을 참조하세요.
배열 만들기
여러 가지 방법으로 배열의 크기를 정의할 수 있습니다.
배열이 정의될 때 크기를 지정할 수 있습니다.
' Declare an array with 10 elements. Dim cargoWeights(9) As Double ' Declare a 24 x 2 array. Dim hourlyTemperatures(23, 1) As Integer ' Declare a jagged array with 31 elements. Dim januaryInquiries(30)() As String
배열을 만들 때
New
절을 사용하여 배열의 크기를 제공할 수 있습니다.' Declare an array with 10 elements. Dim cargoWeights() As Double = New Double(9) {} ' Declare a 24 x 2 array. Dim hourlyTemperatures(,) As Integer = New Integer(23, 1) {} ' Declare a jagged array with 31 elements. Dim januaryInquiries()() As String = New String(30)() {}
기존 배열이 있는 경우 ReDim
문을 사용하여 해당 크기를 다시 정의할 수 있습니다. ReDim
문이 배열에 있는 값을 유지하도록 지정하거나 빈 배열을 만들도록 지정할 수 있습니다. 다음 예제에서는 ReDim
문을 사용하여 기존 배열의 크기를 수정하는 여러 가지 방법을 보여 줍니다.
' Assign a new array size and retain the current values.
ReDim Preserve cargoWeights(20)
' Assign a new array size and retain only the first five values.
ReDim Preserve cargoWeights(4)
' Assign a new array size and discard all current element values.
ReDim cargoWeights(15)
자세한 내용은 ReDim 문을 참조하세요.
배열에 값 저장
Integer
형식의 인덱스를 사용하여 배열의 각 위치에 액세스할 수 있습니다. 괄호로 묶인 해당 인덱스를 통해 각 배열 위치를 참조하여 배열에 값을 저장하고 검색할 수 있습니다. 다차원 배열에 대한 인덱스는 쉼표(,)로 구분됩니다. 각 배열 차원에 대해 하나의 인덱스가 필요합니다.
다음 예제는 배열에 값을 저장하고 검색하는 몇 가지 문을 보여줍니다.
Module Example
Public Sub Main()
' Create a 10-element integer array.
Dim numbers(9) As Integer
Dim value As Integer = 2
' Write values to it.
For ctr As Integer = 0 To 9
numbers(ctr) = value
value *= 2
Next
' Read and sum the array values.
Dim sum As Integer
For ctr As Integer = 0 To 9
sum += numbers(ctr)
Next
Console.WriteLine($"The sum of the values is {sum:N0}")
End Sub
End Module
' The example displays the following output:
' The sum of the values is 2,046
배열 리터럴로 배열 채우기
배열 리터럴을 사용하면 배열을 만드는 동시에 초기 값 집합으로 배열을 채울 수 있습니다. 배열 리터럴은 중괄호({}
)로 묶인 쉼표로 구분된 값 목록으로 구성됩니다.
배열 리터럴을 사용하여 배열을 만드는 경우 배열 형식을 제공하거나 형식 유추를 사용하여 배열 형식을 결정할 수 있습니다. 다음 예제에서는 두 가지 옵션을 모두 보여줍니다.
' Array literals with explicit type definition.
Dim numbers = New Integer() {1, 2, 4, 8}
' Array literals with type inference.
Dim doubles = {1.5, 2, 9.9, 18}
' Array literals with explicit type definition.
Dim articles() As String = { "the", "a", "an" }
' Array literals with explicit widening type definition.
Dim values() As Double = { 1, 2, 3, 4, 5 }
형식 유추를 사용하는 경우 리터럴 값 목록의 기준 형식에 의해 배열 형식이 결정됩니다. 기준 형식은 배열의 다른 모든 형식이 확장될 수 있는 형식입니다. 이 고유 형식을 확인할 수 없는 경우 기준 형식은 배열의 다른 모든 형식이 축소될 수 있는 고유 형식입니다. 이러한 고유 형식을 모두 확인할 수 없는 경우 기준 형식은 Object
입니다. 예를 들어 배열 리터럴에 제공된 값 목록이 Integer
, Long
및 Double
형식의 값을 포함하는 경우 결과 배열은 Double
형식입니다. Integer
및 Long
이 Double
에만 확장되므로 Double
이 기본 형식입니다. 자세한 내용은 Widening and Narrowing Conversions을 참조하세요.
참고
형식 멤버에서 지역 변수로 정의된 배열에 대해서만 형식 유추를 사용할 수 있습니다. 명시적 형식 정의가 없는 경우 클래스 수준에서 배열 리터럴로 정의된 배열은 Object[]
형식입니다. 자세한 내용은 지역 형식 유추를 참조하세요.
이전 예제에서는 모든 배열 리터럴이 Integer
형식인 경우에도 values
를 형식 Double
의 배열로 정의합니다. 배열 리터럴의 값이 Double
값으로 확장될 수 있으므로 이 배열을 만들 수 있습니다.
중첩된 배열 리터럴을 사용하여 다차원 배열을 만들고 채울 수 있습니다. 중첩된 배열 리터럴에는 결과 배열과 일치하는 차원 수가 있어야 합니다. 다음 예제는 중첩된 배열 리터럴을 사용하여 정수의 2차원 배열을 만듭니다.
' Create and populate a 2 x 2 array.
Dim grid1 = {{1, 2}, {3, 4}}
' Create and populate a 2 x 2 array with 3 elements.
Dim grid2(,) = {{1, 2}, {3, 4}, {5, 6}}
중첩된 배열 리터럴을 사용하여 배열을 만들고 채우는 경우 중첩된 배열 리터럴의 요소 수가 일치하지 않으면 오류가 발생합니다. 배열 리터럴과 다른 수의 차원을 가지도록 배열 변수를 명시적으로 선언하는 경우에도 오류가 발생합니다.
1차원 배열에 대해 할 수 있는 것처럼 중첩된 배열 리터럴을 사용하여 다차원 배열을 만들 때 형식 유추를 사용할 수 있습니다. 유추된 형식은 모든 중첩 수준의 모든 배열 리터럴에 있는 모든 값에 대한 기준 형식입니다. 다음 예제는 Integer
및 Double
형식의 값에서 Double[,]
형식의 2차원 배열을 만듭니다.
Dim arr = {{1, 2.0}, {3, 4}, {5, 6}, {7, 8}}
추가 예제를 보려면 방법: Visual Basic에서 배열 변수 초기화를 참조하세요.
배열 반복
배열을 반복하는 경우 가장 낮은 인덱스부터 가장 높은 인덱스까지, 또는 가장 높은 인덱스부터 가장 낮은 인덱스까지 배열의 각 요소에 액세스합니다. 대체로 For...Next 문 또는 For Each...Next 문을 사용하여 배열의 요소를 반복합니다. 배열의 상한을 모르는 경우 Array.GetUpperBound 메서드를 호출하여 인덱스의 가장 높은 값을 가져올 수 있습니다. 가장 낮은 인덱스 값은 거의 항상 0이지만 Array.GetLowerBound 메서드를 호출하여 인덱스의 가장 낮은 값을 가져올 수 있습니다.
다음 예제에서는 For...Next
문을 사용하여 1차원 배열을 반복합니다.
Module IterateArray
Public Sub Main()
Dim numbers = {10, 20, 30}
For index = 0 To numbers.GetUpperBound(0)
Console.WriteLine(numbers(index))
Next
End Sub
End Module
' The example displays the following output:
' 10
' 20
' 30
다음 예제에서는 For...Next
문을 사용하여 다차원 배열을 반복합니다. GetUpperBound 메서드에는 차원을 지정하는 매개 변수가 있습니다. GetUpperBound(0)
는 첫 번째 차원의 가장 높은 인덱스를 반환하고, GetUpperBound(1)
는 두 번째 차원의 가장 높은 인덱스를 반환합니다.
Module IterateArray
Public Sub Main()
Dim numbers = {{1, 2}, {3, 4}, {5, 6}}
For index0 = 0 To numbers.GetUpperBound(0)
For index1 = 0 To numbers.GetUpperBound(1)
Console.Write($"{numbers(index0, index1)} ")
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Output
' 1 2
' 3 4
' 5 6
다음 예제에서는 For Each...Next 문을 사용하여 1차원 배열과 2차원 배열을 반복합니다.
Module IterateWithForEach
Public Sub Main()
' Declare and iterate through a one-dimensional array.
Dim numbers1 = {10, 20, 30}
For Each number In numbers1
Console.WriteLine(number)
Next
Console.WriteLine()
Dim numbers = {{1, 2}, {3, 4}, {5, 6}}
For Each number In numbers
Console.WriteLine(number)
Next
End Sub
End Module
' The example displays the following output:
' 10
' 20
' 30
'
' 1
' 2
' 3
' 4
' 5
' 6
배열 크기
배열 크기는 모든 차원의 길이 곱입니다. 현재 배열에 포함된 요소의 총 수를 나타냅니다. 예를 들어 다음 예제에서는 각 차원에 4개의 요소가 있는 2차원 배열을 선언합니다. 예제의 출력에서 보여주는 것과 같이 배열의 크기는 16(또는 (3 + 1) * (3 + 1))입니다.
Module Example
Public Sub Main()
Dim arr(3, 3) As Integer
Console.WriteLine(arr.Length)
End Sub
End Module
' The example displays the following output:
' 16
참고
배열 크기에 대한 설명은 가변 배열에 적용되지 않습니다. 가변 배열 및 가변 배열의 크기를 결정하는 방법에 대한 자세한 내용은 가변 배열 섹션을 참조하세요.
Array.Length 속성을 사용하여 배열의 크기를 찾을 수 있습니다. Array.GetLength 메서드를 사용하여 다차원 배열의 각 차원 길이를 찾을 수 있습니다.
새 배열 개체를 할당하거나 ReDim
문을 사용하여 배열 변수의 크기를 조정할 수 있습니다. 다음 예제에서는 ReDim
문을 사용하여 100개 요소의 배열을 51개 요소의 배열로 변경합니다.
Module Example
Public Sub Main()
Dim arr(99) As Integer
Console.WriteLine(arr.Length)
Redim arr(50)
Console.WriteLine(arr.Length)
End Sub
End Module
' The example displays the following output:
' 100
' 51
배열의 크기를 처리할 때 유의해야 하는 여러 가지 사항이 있습니다.
메모 | |
---|---|
차원 길이 | 각 차원의 인덱스는 0부터 시작하므로 0부터 상한까지의 범위입니다. 따라서 지정된 차원의 길이는 해당 차원에 대해 선언된 상한보다 1만큼 더 큽니다. |
길이 제한 | 배열의 각 차원 길이는 Integer 데이터 형식의 최대값, 즉 Int32.MaxValue 또는 (2 ^ 31) - 1로 제한됩니다. 그러나 배열의 총 크기는 시스템에서 사용 가능한 메모리에 의해서도 제한됩니다. 사용 가능한 메모리를 초과하는 배열을 초기화하려고 하면 런타임에서 OutOfMemoryException 예외가 throw됩니다. |
크기 및 요소 크기 | 배열의 크기는 해당 요소의 데이터 형식과 독립적입니다. 크기는 항상 메모리에서 사용하는 바이트 수가 아니라 요소의 총 수를 나타냅니다. |
메모리 소비 | 배열이 메모리에 저장되는 방법에 대해서는 어떠한 가정도 하지 않는 것이 좋습니다. 스토리지는 각 데이터 너비의 플랫폼마다 달라지므로 동일한 배열이 32비트 시스템보다 64비트 시스템에서 더 많은 메모리를 사용할 수 있습니다. 시스템 구성에 따라 배열을 초기화할 때 CLR(공용 언어 런타임)에서 스토리지를 할당하여 요소를 최대한 가깝게 압축하거나 모두 일반적인 하드웨어 경계에 맞출 수 있습니다. 또한 배열의 제어 정보로 인해 스토리지 오버헤드가 필요하며, 차원이 추가될 때마다 이 오버헤드가 증가합니다. |
배열 형식
각 배열에는 데이터 형식이 있으며, 해당 요소의 데이터 형식과 다릅니다. 모든 배열에 대한 단일 데이터 형식은 없습니다. 대신, 배열의 데이터 형식은 배열의 차원 수 또는 차수와 배열에 있는 요소의 데이터 형식에 의해 결정됩니다. 두 배열 변수는 동일한 차수이고 해당 요소가 동일한 데이터 형식인 경우에만 동일한 데이터 형식입니다. 배열의 차원 길이는 배열 데이터 형식에 영향을 주지 않습니다.
모든 배열은 System.Array 클래스에서 상속되며 Array
형식으로 변수를 선언할 수 있지만, Array
형식의 배열을 만들 수는 없습니다. 예를 들어 다음 코드는 arr
변수를 Array
형식으로 선언하고 Array.CreateInstance 메서드를 호출하여 배열을 인스턴스화하며, 배열의 형식은 Object[]로 입증됩니다.
Module Example
Public Sub Main()
Dim arr As Array = Array.CreateInstance(GetType(Object), 19)
Console.WriteLine(arr.Length)
Console.WriteLine(arr.GetType().Name)
End Sub
End Module
' The example displays the following output:
' 19
' Object[]
또한 ReDim 문은 Array
형식으로 선언된 변수에 대해 작업할 수 없습니다. 이러한 이유 및 형식 안전성을 위해 모든 배열을 특정 형식으로 선언하는 것이 좋습니다.
배열이나 해당 요소의 데이터 형식을 여러 가지 방법으로 확인할 수 있습니다.
- 변수에서 GetType 메서드를 호출하여 변수의 런타임 형식을 나타내는 Type 개체를 가져올 수 있습니다. Type 개체는 해당 속성과 메서드에 광범위한 정보를 보유합니다.
- TypeName 함수에 변수를 전달하여 런타임 형식의 이름을 포함하는
String
를 가져올 수 있습니다.
다음 예제에서는 GetType
메서드와 TypeName
함수를 모두 호출하여 배열의 형식을 확인합니다. 배열 형식은 Byte(,)
입니다. Type.BaseType 속성은 또한 바이트 배열의 기본 형식이 Array 클래스임을 나타냅니다.
Module Example
Public Sub Main()
Dim bytes(9,9) As Byte
Console.WriteLine($"Type of {nameof(bytes)} array: {bytes.GetType().Name}")
Console.WriteLine($"Base class of {nameof(bytes)}: {bytes.GetType().BaseType.Name}")
Console.WriteLine()
Console.WriteLine($"Type of {nameof(bytes)} array: {TypeName(bytes)}")
End Sub
End Module
' The example displays the following output:
' Type of bytes array: Byte[,]
' Base class of bytes: Array
'
' Type of bytes array: Byte(,)
반환 값 및 매개 변수로 사용되는 배열
Function
프로시저에서 배열을 반환하려면 배열 데이터 형식 및 차원 수를 Function 문의 반환 형식으로 지정합니다. 함수 내에서 동일한 데이터 형식 및 차원 수의 지역 배열 변수를 선언합니다. Return 문에 지역 배열 변수를 괄호 없이 포함합니다.
Sub
또는 Function
프로시저에 대한 매개 변수로 배열을 지정하려면 지정된 데이터 형식 및 차원 수의 배열로 매개 변수를 정의합니다. 프로시저 호출에서 동일한 데이터 형식 및 차원 수의 배열 변수를 전달합니다.
다음 예제에서 GetNumbers
함수는 Integer
형식의 1차원 배열인 Integer()
를 반환합니다. ShowNumbers
프로시저는 Integer()
인수를 사용합니다.
Module ReturnValuesAndParams
Public Sub Main()
Dim numbers As Integer() = GetNumbers()
ShowNumbers(numbers)
End Sub
Private Function GetNumbers() As Integer()
Dim numbers As Integer() = {10, 20, 30}
Return numbers
End Function
Private Sub ShowNumbers(numbers As Integer())
For index = 0 To numbers.GetUpperBound(0)
Console.WriteLine($"{numbers(index)} ")
Next
End Sub
End Module
' The example displays the following output:
' 10
' 20
' 30
다음 예제에서 GetNumbersMultiDim
함수는 Integer
형식의 2차원 배열인 Integer(,)
를 반환합니다. ShowNumbersMultiDim
프로시저는 Integer(,)
인수를 사용합니다.
Module Example
Public Sub Main()
Dim numbers As Integer(,) = GetNumbersMultidim()
ShowNumbersMultidim(numbers)
End Sub
Private Function GetNumbersMultidim() As Integer(,)
Dim numbers As Integer(,) = {{1, 2}, {3, 4}, {5, 6}}
Return numbers
End Function
Private Sub ShowNumbersMultidim(numbers As Integer(,))
For index0 = 0 To numbers.GetUpperBound(0)
For index1 = 0 To numbers.GetUpperBound(1)
Console.Write($"{numbers(index0, index1)} ")
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' 1 2
' 3 4
' 5 6
가변 배열
애플리케이션의 데이터 구조가 2차원 배열이지만 사각형이 아닌 경우도 있습니다. 예를 들어 배열을 사용하여 매월 매일의 최고 기온에 대한 데이터를 저장할 수 있습니다. 배열의 첫 번째 차원은 월을 나타내지만 두 번째 차원은 일 수를 나타내며, 각 월의 일 수는 균일하지 않습니다. 배열의 배열이라고도 하는 가변 배열은 이러한 시나리오를 위해 디자인되었습니다. 가변 배열은 요소가 배열인 배열입니다. 가변 배열 및 가변 배열의 각 요소에는 하나 이상의 차원이 있을 수 있습니다.
다음 예제에는 각 요소가 일 배열인 월 배열을 사용합니다. 이 예제에서는 각 월에 일 수가 다르므로 가변 배열을 사용합니다. 이 예제에서는 가변 배열을 만들고, 값을 할당하고, 해당 값을 검색 및 표시하는 방법을 보여줍니다.
Imports System.Globalization
Module JaggedArray
Public Sub Main()
' Declare the jagged array of 12 elements. Each element is an array of Double.
Dim sales(11)() As Double
' Set each element of the sales array to a Double array of the appropriate size.
For month As Integer = 0 To 11
' The number of days in the month determines the appropriate size.
Dim daysInMonth As Integer =
DateTime.DaysInMonth(Year(Now), month + 1)
sales(month) = New Double(daysInMonth - 1) {}
Next
' Store values in each element.
For month As Integer = 0 To 11
For dayOfMonth = 0 To sales(month).GetUpperBound(0)
sales(month)(dayOfMonth) = (month * 100) + dayOfMonth
Next
Next
' Retrieve and display the array values.
Dim monthNames = DateTimeFormatInfo.CurrentInfo.AbbreviatedMonthNames
' Display the month names.
Console.Write(" ")
For ctr = 0 To sales.GetUpperBound(0)
Console.Write($" {monthNames(ctr)} ")
Next
Console.WriteLine()
' Display data for each day in each month.
For dayInMonth = 0 To 30
Console.Write($"{dayInMonth + 1,2}. ")
For monthNumber = 0 To sales.GetUpperBound(0)
If dayInMonth > sales(monthNumber).GetUpperBound(0) Then
Console.Write(" ")
Else
Console.Write($"{sales(monthNumber)(dayInMonth),-5} ")
End If
Next
Console.WriteLine()
Next
End Sub
End Module
' The example displays the following output:
' Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
' 1. 0 100 200 300 400 500 600 700 800 900 1000 1100
' 2. 1 101 201 301 401 501 601 701 801 901 1001 1101
' 3. 2 102 202 302 402 502 602 702 802 902 1002 1102
' 4. 3 103 203 303 403 503 603 703 803 903 1003 1103
' 5. 4 104 204 304 404 504 604 704 804 904 1004 1104
' 6. 5 105 205 305 405 505 605 705 805 905 1005 1105
' 7. 6 106 206 306 406 506 606 706 806 906 1006 1106
' 8. 7 107 207 307 407 507 607 707 807 907 1007 1107
' 9. 8 108 208 308 408 508 608 708 808 908 1008 1108
' 10. 9 109 209 309 409 509 609 709 809 909 1009 1109
' 11. 10 110 210 310 410 510 610 710 810 910 1010 1110
' 12. 11 111 211 311 411 511 611 711 811 911 1011 1111
' 13. 12 112 212 312 412 512 612 712 812 912 1012 1112
' 14. 13 113 213 313 413 513 613 713 813 913 1013 1113
' 15. 14 114 214 314 414 514 614 714 814 914 1014 1114
' 16. 15 115 215 315 415 515 615 715 815 915 1015 1115
' 17. 16 116 216 316 416 516 616 716 816 916 1016 1116
' 18. 17 117 217 317 417 517 617 717 817 917 1017 1117
' 19. 18 118 218 318 418 518 618 718 818 918 1018 1118
' 20. 19 119 219 319 419 519 619 719 819 919 1019 1119
' 21. 20 120 220 320 420 520 620 720 820 920 1020 1120
' 22. 21 121 221 321 421 521 621 721 821 921 1021 1121
' 23. 22 122 222 322 422 522 622 722 822 922 1022 1122
' 24. 23 123 223 323 423 523 623 723 823 923 1023 1123
' 25. 24 124 224 324 424 524 624 724 824 924 1024 1124
' 26. 25 125 225 325 425 525 625 725 825 925 1025 1125
' 27. 26 126 226 326 426 526 626 726 826 926 1026 1126
' 28. 27 127 227 327 427 527 627 727 827 927 1027 1127
' 29. 28 228 328 428 528 628 728 828 928 1028 1128
' 30. 29 229 329 429 529 629 729 829 929 1029 1129
' 31. 30 230 430 630 730 930 1130
이전 예제에서는 For...Next
루프를 사용하여 요소별로 가변 배열에 값을 할당합니다. 중첩된 배열 리터럴을 사용하여 가변 배열의 요소에 값을 할당할 수도 있습니다. 하지만 중첩된 배열 리터럴(예: Dim valuesjagged = {{1, 2}, {2, 3, 4}}
)을 사용하려고 시도하면 컴파일러 오류 BC30568이 발생합니다. 오류를 수정하려면 내부 배열 리터럴을 괄호로 묶습니다. 다음 예제와 같이 괄호는 배열 리터럴 식이 계산되도록 강제하며, 결과 값이 외부 배열 리터럴과 함께 사용됩니다.
Module Example
Public Sub Main()
Dim values1d = { 1, 2, 3 }
Dim values2d = {{1, 2}, {2, 3}, {3, 4}}
Dim valuesjagged = {({1, 2}), ({2, 3, 4})}
End Sub
End Module
가변 배열은 요소에 배열이 포함된 1차원 배열입니다. 따라서 Array.Length 속성과 Array.GetLength(0)
메서드는 1차원 배열의 요소 수를 반환하고, Array.GetLength(1)
는 가변 배열이 다차원 배열이 아니므로 IndexOutOfRangeException을 throw합니다. 각 하위 배열의 Array.Length 속성 값을 검색하여 각 하위 배열의 요소 수를 결정합니다. 다음 예제에서는 가변 배열의 요소 수를 결정하는 방법을 보여줍니다.
Module Example
Public Sub Main()
Dim jagged = { ({1, 2}), ({2, 3, 4}), ({5, 6}), ({7, 8, 9, 10}) }
Console.WriteLine($"The value of jagged.Length: {jagged.Length}.")
Dim total = jagged.Length
For ctr As Integer = 0 To jagged.GetUpperBound(0)
Console.WriteLine($"Element {ctr + 1} has {jagged(ctr).Length} elements.")
total += jagged(ctr).Length
Next
Console.WriteLine($"The total number of elements in the jagged array: {total}")
End Sub
End Module
' The example displays the following output:
' The value of jagged.Length: 4.
' Element 1 has 2 elements.
' Element 2 has 3 elements.
' Element 3 has 2 elements.
' Element 4 has 4 elements.
' The total number of elements in the jagged array: 15
길이가 0인 배열
Visual Basic은 초기화되지 않은 배열(값이 Nothing
인 배열)과 길이가 0인 배열 또는 빈 배열(요소가 없는 배열)을 구분합니다. 초기화되지 않은 배열은 차원화되지 않았거나 할당된 값이 있는 배열입니다. 예를 들면 다음과 같습니다.
Dim arr() As String
길이가 0인 배열은 -1의 차원으로 선언됩니다. 예를 들면 다음과 같습니다.
Dim arrZ(-1) As String
다음과 같은 경우 길이가 0인 배열을 만들어야 할 수도 있습니다.
NullReferenceException 예외가 발생할 위험 없이 코드에서 Length 또는 Rank와 같은 Array 클래스의 멤버에 액세스하거나 UBound와 같은 Visual Basic 함수를 호출해야 하는 경우.
Nothing
을 특별한 경우로 확인할 필요가 없도록 하여 코드를 보다 간단하게 유지하려는 경우.코드가 하나 이상의 프로시저에 길이가 0인 배열을 전달해야 하거나 하나 이상의 프로시저에서 길이가 0인 배열을 반환하는 API(애플리케이션 프로그래밍 인터페이스)와 상호 작용하는 경우
배열 분할
경우에 따라 단일 배열을 여러 배열로 분할해야 할 수 있습니다. 여기에는 배열을 분할할 지점을 식별한 다음 배열을 두 개 이상의 개별 배열에 삽입하는 작업이 포함됩니다.
참고
이 섹션에서는 일부 구분 기호를 기반으로 단일 문자열을 문자열 배열로 분할하는 것에 대해서는 설명하지 않습니다. 문자열 분할에 대한 자세한 내용은 String.Split 메서드를 참조하세요.
배열 분할에 대한 가장 일반적인 기준은 다음과 같습니다.
배열의 요소 수입니다. 예를 들어 지정된 개수 이상의 요소 배열을 거의 같은 수의 부분으로 분할할 수 있습니다. 이를 위해 Array.Length 또는 Array.GetLength 메서드에 의해 반환된 값을 사용할 수 있습니다.
배열을 분할해야 하는 위치를 나타내는 구분 기호 역할을 하는 요소의 값입니다. Array.FindIndex 및 Array.FindLastIndex 메서드를 호출하여 특정 값을 검색할 수 있습니다.
배열을 분할해야 하는 인덱스를 결정한 후에는 Array.Copy 메서드를 호출하여 개별 배열을 만들 수 있습니다.
다음 예제에서는 배열을 거의 같은 크기의 두 배열로 분할합니다. (배열 요소의 총 수가 홀수이면 첫 번째 배열에는 두 번째 배열보다 요소가 하나 더 있습니다.)
Module Example
Public Sub Main()
' Create an array of 100 elements.
Dim arr(99) As Integer
' Populate the array.
Dim rnd As new Random()
For ctr = 0 To arr.GetUpperBound(0)
arr(ctr) = rnd.Next()
Next
' Determine how many elements should be in each array.
Dim divisor = 2
Dim remainder As Integer
Dim boundary = Math.DivRem(arr.GetLength(0), divisor, remainder)
' Copy the array.
Dim arr1(boundary - 1 + remainder), arr2(boundary - 1) as Integer
Array.Copy(arr, 0, arr1, 0, boundary + remainder)
Array.Copy(arr, boundary + remainder, arr2, 0, arr.Length - boundary)
End Sub
End Module
다음 예제에서는 값이 배열 구분 기호 역할을 하는 “zzz”인 요소의 존재에 따라 문자열 배열을 두 개의 배열로 분할합니다. 새 배열에는 구분 기호가 포함된 요소가 포함되지 않습니다.
Module Example
Public Sub Main()
Dim rnd As New Random()
' Create an array of 100 elements.
Dim arr(99) As String
' Populate each element with an arbitrary ASCII character.
For ctr = 0 To arr.GetUpperBound(0)
arr(ctr) = ChrW(Rnd.Next(&h21, &h7F))
Next
' Get a random number that will represent the point to insert the delimiter.
arr(rnd.Next(0, arr.GetUpperBound(0))) = "zzz"
' Find the delimiter.
Dim location = Array.FindIndex(arr, Function(x) x = "zzz")
' Create the arrays.
Dim arr1(location - 1) As String
Dim arr2(arr.GetUpperBound(0) - location - 1) As String
' Populate the two arrays.
Array.Copy(arr, 0, arr1, 0, location)
Array.Copy(arr, location + 1, arr2, 0, arr.GetUpperBound(0) - location)
End Sub
End Module
배열 조인
여러 배열을 더 큰 단일 배열로 결합할 수도 있습니다. 이를 위해 Array.Copy 메서드를 사용할 수도 있습니다.
참고
이 섹션에서는 문자열 배열을 단일 문자열로 조인하는 것에 대해 설명하지 않습니다. 문자열 배열 조인에 대한 자세한 내용은 String.Join 메서드를 참조하세요.
각 배열의 요소를 새 배열로 복사하기 전에 먼저 배열의 크기가 새 배열을 수용할 수 있을 정도가 되도록 배열을 초기화해야 합니다. 이 작업은 다음 두 가지 방법 중 한 가지로 수행할 수 있습니다.
- 새 요소를 추가하기 전에
ReDim Preserve
문을 사용하여 배열을 동적으로 확장합니다. 이 방법은 가장 쉬운 방법이지만 큰 배열을 복사할 때 성능이 저하되고 메모리 소비가 과도하게 발생할 수 있습니다. - 새 큰 배열에 필요한 요소의 총 수를 계산한 다음 각 원본 배열의 요소를 추가합니다.
다음 예제에서는 두 번째 방법을 사용하여 각각 10개의 요소가 있는 4개의 배열을 단일 배열에 추가합니다.
Imports System.Collections.Generic
Imports System.Threading.Tasks
Module Example
Public Sub Main()
Dim tasks As New List(Of Task(Of Integer()))
' Generate four arrays.
For ctr = 0 To 3
Dim value = ctr
tasks.Add(Task.Run(Function()
Dim arr(9) As Integer
For ndx = 0 To arr.GetUpperBound(0)
arr(ndx) = value
Next
Return arr
End Function))
Next
Task.WaitAll(tasks.ToArray())
' Compute the number of elements in all arrays.
Dim elements = 0
For Each task In tasks
elements += task.Result.Length
Next
Dim newArray(elements - 1) As Integer
Dim index = 0
For Each task In tasks
Dim n = task.Result.Length
Array.Copy(task.Result, 0, newArray, index, n)
index += n
Next
Console.WriteLine($"The new array has {newArray.Length} elements.")
End Sub
End Module
' The example displays the following output:
' The new array has 40 elements.
이 경우 원본 배열은 모두 작기 때문에 각 새 배열의 요소를 추가할 때 배열을 동적으로 확장할 수도 있습니다. 다음 예제에서는 해당 작업을 수행합니다.
Imports System.Collections.Generic
Imports System.Threading.Tasks
Module Example
Public Sub Main()
Dim tasks As New List(Of Task(Of Integer()))
' Generate four arrays.
For ctr = 0 To 3
Dim value = ctr
tasks.Add(Task.Run(Function()
Dim arr(9) As Integer
For ndx = 0 To arr.GetUpperBound(0)
arr(ndx) = value
Next
Return arr
End Function))
Next
Task.WaitAll(tasks.ToArray())
' Dimension the target array and copy each element of each source array to it.
Dim newArray() As Integer = {}
' Define the next position to copy to in newArray.
Dim index = 0
For Each task In tasks
Dim n = Task.Result.Length
ReDim Preserve newArray(newArray.GetUpperBound(0) + n)
Array.Copy(task.Result, 0, newArray, index, n)
index += n
Next
Console.WriteLine($"The new array has {newArray.Length} elements.")
End Sub
End Module
' The example displays the following output:
' The new array has 40 elements.
배열의 대안으로 사용되는 컬렉션
배열은 고정된 개수의 강력한 형식 개체를 만들고 작업하는 데 가장 유용합니다. 컬렉션은 개체 그룹에 대해 작업하는 보다 유연한 방법을 제공합니다. ReDim
문을 사용하여 배열의 크기를 명시적으로 변경해야 하는 배열과 달리 컬렉션은 애플리케이션의 요구 사항이 변경되면 동적으로 확장 및 축소됩니다.
배열을 다시 조정하는 데 ReDim
을 사용하는 경우 Visual Basic은 새 배열을 만들고 이전 배열을 해제합니다. 이 경우 실행 시간이 걸립니다. 따라서 작업하는 항목 수가 자주 변경되거나 필요한 항목의 최대 수를 예측할 수 없는 경우 컬렉션을 사용하여 성능을 개선할 수 있습니다.
일부 컬렉션의 경우 키를 사용하여 개체를 신속하게 검색할 수 있도록 컬렉션에 추가하는 모든 개체에 키를 할당할 수 있습니다.
컬렉션에 단일 데이터 형식의 요소만 포함된 경우 System.Collections.Generic 네임스페이스의 클래스 중 하나를 사용할 수 있습니다. 제네릭 컬렉션은 다른 데이터 형식을 추가할 수 없도록 형식 안전성을 적용합니다.
항목 컬렉션에 대한 자세한 내용은 컬렉션을 참조하세요.
관련 항목
용어 | 정의 |
---|---|
Array Dimensions in Visual Basic | 배열의 차수 및 차원을 설명합니다. |
방법: Visual Basic에서 배열 변수 초기화 | 배열에 초기 값을 채우는 방법을 설명합니다. |
방법: Visual Basic에서 배열 정렬 | 배열의 요소를 사전순으로 정렬하는 방법을 보여 줍니다. |
방법: 한 배열에 다른 배열 할당 | 다른 배열 변수에 배열을 할당하는 규칙 및 단계를 설명합니다. |
배열 문제 해결 | 배열에서 작업할 때 발생할 수 있는 몇 가지 일반적인 문제를 설명합니다. |