Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/34: Рейтинг темы: голосов - 34, средняя оценка - 4.53
22 / 22 / 7
Регистрация: 26.05.2011
Сообщений: 256
.NET 4.x

Как заполнить динамический массив?

18.12.2016, 19:41. Показов 6919. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет!
Сразу к делу. Есть код:

VB.NET Скопировано
1
2
3
4
5
6
7
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim StrMas() As String = Nothing
 
        For i As Integer = 0 To 99 Step 1
            StrMas(i) = CStr(i)
        Next i
    End Sub
По нажатию на кнопку – получим вылет в виде исключения.
Если в коде не дописывать "= Nothing", то компилятор заранее предупредит, мол, переменная используется до присвоения ей значения. Дописывая это, мы лишь обманываем компилятор, но не решаем проблему.

Как быть в такой ситуации, если цифру 99 мы никак не знаем наперед?
Спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.12.2016, 19:41
Ответы с готовыми решениями:

Как создать глобальный динамический массив и заполнить его
Всем привет! Мне нужно каким-то образом создать глобальный динамический массив и заполнить его. но когда я пишу вот так Module...

Как объявить динамический двумерный массив и заполнить его
Здравствуйте,не могли бы вы еще кое-чем помочь.У меня есть есть матричный массив,с неуказанным кол-вом элементов. Dim Files(,) As String ...

Как записать значение в динамический двумерный массив
Здравствуйте у меня такой вопрос вот есть динамический массив Dim (,) ListBox1.Items.Add(" матрица") Randomize() ...

12
 Аватар для Sklifosofsky
1082 / 912 / 213
Регистрация: 29.09.2015
Сообщений: 1,015
18.12.2016, 19:48
Ну во первых массив должен перед вставкой размечен
VB.NET Скопировано
1
2
3
Dim StrMas() As String = New String(99){}
или 
Dim StrMas(99) As String
Еcли мы не знаем размерность наперед, то лучше использовать класс List(Of String)
Или на худой конец

VB.NET Скопировано
1
2
3
4
5
6
7
8
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim StrMas() As String = Nothing
 
        For i As Integer = 0 To 99 Step 1
            ReDim Preserve StrMas(i)
            StrMas(i) = CStr(i)
        Next i
    End Sub
1
22 / 22 / 7
Регистрация: 26.05.2011
Сообщений: 256
18.12.2016, 19:58  [ТС]
Sklifosofsky, а чем класс List лучше ReDim Preserve?
И как бы Вы его использовали?
0
 Аватар для Sklifosofsky
1082 / 912 / 213
Регистрация: 29.09.2015
Сообщений: 1,015
18.12.2016, 20:33
Лучший ответ Сообщение было отмечено Stass48 как решение

Решение

VB.NET Скопировано
1
2
3
4
5
Dim strList As New List(Of String)
For i As Integer = 0 To 99
strList.Add(CStr(i))            
Next i
Dim strMas() As String = strList.ToArray()
В Redim Preserve каждый раз идет перераспределение памяти, а в List данные добавляются в конец коллекции, не трогая остальное
1
22 / 22 / 7
Регистрация: 26.05.2011
Сообщений: 256
19.12.2016, 22:45  [ТС]
Sklifosofsky, следует отметить, что этот класс как-то странно себя ведет! В смысле что вроде добавляет туда данные, но считать эти данные по индексу получается, увы не всегда!

Я КАТЕГОРИЧЕСКИ НЕ РЕКОМЕНДУЮ использовать этот класс! Если уж используете, то смотрите в оба и все тщательно проверяйте на работоспособность.

P. S.: В итоге решил свою проблему обычной переменной типа String, в которую помещал данные, разделяя их vbNewLine, а потом. Короче вот так:
VB.NET Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Private Function GetChannelNames() As String()
Dim Info As New ChannelInfoType 'В эту переменную возвращается из функции полная коллекция информации о канале
Dim ChCounter As Integer = 0 'Номер канала, о котором надо получить информацию и счетчик
Dim strChannelData As String = String.Empty 'Сюда сформируется список имен каналов, каждый с новой строки
Dim strDataArr() As String
 
While SomeFunction(ChCounter, Info) = True 'Пока каналы существуют, функция будет возвращать положительный ответ
   If ChCounter = 0 Then 'Если это будет первая строка в списке, то нам не за чем перескакивать на новую строку
      strChannelData = "Channel #" & CSTR(ChCounter) & ": " & Info.Name 'Формируем первую строку списка с именем канала
   Else
      strChannelData &= vbNewLine & "Channel #" & CSTR(ChCounter) & ": " & Info.Name 'Перескакиваем на новую строку и добавляем новые данные с именем канала
   End If
   ChCounter += 1 'Увеличиваем счетчик и номер канала для последующего сканирования
End While
strDataArr = Split(strChannelData, vbNewLine) 'По завершению, режем весь текст по строкам и отправляем каждую строку в массив
Return strDataArr
End Function
0
 Аватар для Sklifosofsky
1082 / 912 / 213
Регистрация: 29.09.2015
Сообщений: 1,015
19.12.2016, 22:52
Цитата Сообщение от Stass48 Посмотреть сообщение
класс как-то странно себя ведет!
Пример в студию. Это надежный класс...

Цитата Сообщение от Stass48 Посмотреть сообщение
P. S.: В итоге решил свою проблему обычной переменной типа String, в которую помещал данные, разделяя их vbNewLine
Если очень много будет данных - окажется в итоге самым тормознутым вариантом
0
22 / 22 / 7
Регистрация: 26.05.2011
Сообщений: 256
19.12.2016, 23:33  [ТС]
Sklifosofsky, вот пример где не работает.

VB.NET Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Private Function GetChannelNames() As String()
Dim Info As New ChannelInfoType 'В эту переменную возвращается из функции полная коллекция информации о канале
Dim ChCounter As Integer = 0 'Номер канала, о котором надо получить информацию и счетчик
Dim ChInfo_List As New List(Of ChannelInfoType) 'Сюда сформируется список имен каналов
 
While SomeFunction(ChCounter, Info) = True 'Пока каналы существуют, функция будет возвращать положительный ответ
   ChInfo_List.Add(Info)
   'MsgBox(ChInfo_List.Item(ChCounter).Name)
   ChCounter += 1 'Увеличиваем счетчик и номер канала для последующего сканирования
End While
 
'MsgBox(ChInfo_List.Item(0).Name)
'MsgBox(ChInfo_List.Item(1).Name)
'MsgBox(ChInfo_List.Item(2).Name)
'MsgBox(ChInfo_List.Item(3).Name)
'MsgBox(ChInfo_List.Item(4).Name)
 
Dim strDataArr(ChCounter - 1) As String
 
For i As Integer = 0 To ChCounter Step 1
   strDataArr(i) = ChInfo_List.Item(i).Name
Next i
 
Return strDataArr
End Function
Поясню. В первом закомментированном MsgBox внутри While все хорошо, то есть каждую новую итерацию цикла он нам отображает уникальную актуальную информацию о текущем канале.

В следующих пяти MsgBox, которые находятся между циклами уже полная фигня! В каждом из них уже находится информация только о последнем канале!!!
Соответственно, после второго цикла, в выходном массиве мы получаем тупо дубликаты данных последнего канала!

Объясните, как такое возможно?

Добавлено через 13 минут
Цитата Сообщение от Sklifosofsky Посмотреть сообщение
Если очень много будет данных - окажется в итоге самым тормознутым вариантом
Разве только у Вас будет звуковая карта на миллион каналов
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
17898 / 13994 / 5345
Регистрация: 17.03.2014
Сообщений: 28,652
Записей в блоге: 1
19.12.2016, 23:34
Лучший ответ Сообщение было отмечено Stass48 как решение

Решение

Stass48, насколько я понимаю ChannelInfoType это класс, а метод SomeFunction(ChCounter, Info) принимает второй аргумент как ByRef. Это означает что он модифицирует одно и то же значение которое и добавляется в List(Of ChannelInfoType). Также это означает что тип List(Of T) работает правильно. Причина ошибки в твоем непонимании работы ссылочных типов.

Исправить можно так:
VB.NET Скопировано
1
2
3
4
5
While SomeFunction(ChCounter, Info) = True 'Пока каналы существуют, функция будет возвращать положительный ответ
   ChInfo_List.Add(Info)
   Info = New ChannelInfoType
   ChCounter += 1 'Увеличиваем счетчик и номер канала для последующего сканирования
End While
1
22 / 22 / 7
Регистрация: 26.05.2011
Сообщений: 256
19.12.2016, 23:43  [ТС]
OwenGlendower, тогда почему так?

Цитата Сообщение от Stass48 Посмотреть сообщение
В первом закомментированном MsgBox внутри While все хорошо
Ведь если верить Вашему ходу мыслей, тогда бы новые данные не вывелись бы в этом сообщении. Но выводятся же! Почему?

Добавлено через 1 минуту
Цитата Сообщение от OwenGlendower Посмотреть сообщение
насколько я понимаю ChannelInfoType это класс, а метод SomeFunction(ChCounter, Info) принимает второй аргумент как ByRef. Это означает что он модифицирует одно и то же значение которое и добавляется в List(Of ChannelInfoType).
Все верно понимаете
0
 Аватар для Sklifosofsky
1082 / 912 / 213
Регистрация: 29.09.2015
Сообщений: 1,015
19.12.2016, 23:47
Лучший ответ Сообщение было отмечено Stass48 как решение

Решение

Сейчас вы узнаете о чем вы и не подозревали
Объект класса передается в лист как ссылка и если вы меняете содержание уже ранее отправленного класса в List, то и соответственно в List'e в объекте отразятся эти изменения.

Есть 3 варианта решения этой проблемы
1. Если ваш класс использует примтивы типа число, строка то можно его переделать в структуру
2. В класс добавить функцию
VB.NET Скопировано
1
2
3
        Public Function Clone() As Object
            Return Me.MemberwiseClone()
        End Function
И в лист добавлять List.Add(Info.Clone())
3. В вашем коде трудно извернуться. Но это выглядит следящим образом: перед каждым добавлением в лист следует создавать новый экземпляр вашего класса и копировать в него все данные поочередно (не самый ахти способ)

Добавлено через 1 минуту
OwenGlendower, как раз 3 способ описал =)
1
Администратор
Эксперт .NET
 Аватар для OwenGlendower
17898 / 13994 / 5345
Регистрация: 17.03.2014
Сообщений: 28,652
Записей в блоге: 1
19.12.2016, 23:55
Цитата Сообщение от Stass48 Посмотреть сообщение
Ведь если верить Вашему ходу мыслей, тогда бы новые данные не вывелись бы в этом сообщении. Но выводятся же! Почему?
Потому что внутри цикла идет вывод одного текущего значения.

Добавлено через 5 минут
Чтобы лучше понять что происходит подумай над следующим примером
VB.NET Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Sub Main
 
Dim list As New List(Of TheTest)
Dim item As New TheTest
 
For I = 0 To 5
    item.Name = "Name #" & i
    Console.WriteLine(item.Name)
    list.Add(item)
Next
 
Console.WriteLine("----------------")
For I = 0 To 5
    Console.WriteLine(list(i).Name)
Next
 
End Sub
 
 
Class TheTest
    Public Name As String
End Class
1
22 / 22 / 7
Регистрация: 26.05.2011
Сообщений: 256
20.12.2016, 00:03  [ТС]
OwenGlendower, Я понял, но блин, это дебилизм какой-то... Я то считаю что если это список, то и добавляются туда данные, а не ссылки на класс... Мда уж........ Я вчера полдня убил на это все в недоумении

А оно вон какое хитрое...

Добавлено через 6 минут
OwenGlendower, Я прекрасно "прохавал" уже в чем фигня и почему так))

Но посмотрите на код, который дали с примером получения каналов BassAsio.dll на VB:
Visual Basic Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Dim di As BASS_ASIO_DEVICEINFO
    Dim a As Long
    a = 0
    While BASS_ASIO_GetDeviceInfo(a, di)
        With txtList
            .Text = .Text & "dev " & a & ": " & VBStrFromAnsiPtr(di.name) & vbCrLf
            .Text = .Text & "driver: " & VBStrFromAnsiPtr(di.driver) & vbCrLf
            BASS_ASIO_Init(a, 0)
 
            Dim i As BASS_ASIO_CHANNELINFO, b As Long, name_ As String
            b = 0
            While BASS_ASIO_ChannelGetInfo(1, b, i)
                name_ = Mid(i.name_, 1, InStr(1, i.name_, Chr(0)) - 1)
                .Text = .Text & vbTab & "in " & b & ": " & name_ & " (group " & i.group & ", format " & i.format_ & ")" & vbCrLf
                b = b + 1
            Wend
            b = 0
            While BASS_ASIO_ChannelGetInfo(0, b, i)
                name_ = Mid(i.name_, 1, InStr(1, i.name_, Chr(0)) - 1)
                .Text = .Text & vbTab & "out " & b & ": " & name_ & " (group " & i.group & ", format " & i.format_ & ")" & vbCrLf
                b = b + 1
            Wend
        End With
        Call BASS_ASIO_Free
        a = a + 1
    Wend
VB получается почему-то не парил мозги с Null-исключениями и использованиями переменных до их присвоения... А тут при переделке на VB.NET началось... Понимаешь что надо что-то присвоить... А что присваивать в непонятно какой тип и главное ЗАЧЕМ, ведь на деле это нужно только ради наполнения самой переменной, чтобы была не Null... Вот и пришлось писать слово New. А дальше уже понеслись проблемы....
0
Администратор
Эксперт .NET
 Аватар для OwenGlendower
17898 / 13994 / 5345
Регистрация: 17.03.2014
Сообщений: 28,652
Записей в блоге: 1
20.12.2016, 00:13
Stass48, ничего хитрого здесь. Нужно всего лишь понимать как работают ссылочные типы. Советую заполнить этот пробел в своих знаниях т.к. это фундаментальная вещь. Вот хорошая статья по теме - Reference Types, Value Types, ByVal, ByRef. Плюс советую прочитать книгу Джеффри Рихтера CLR via C#. Программирование на платформе Microsoft.NET Framework 4.5 на языке C#. Всю книгу сразу читать не обязательно. Достаточно несколько первых глав где он подробно объясняет внутреннее устройство .NET.

Добавлено через 2 минуты
Stass48, VB и VB.NET это два совершенно разных языка. Единственное что их объединяет это слова Visual Basic в названии.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.12.2016, 00:13
Помогаю со студенческими работами здесь

Как заполнить двумерный динамический массив?
вот я создал двумерный динамический массив (правильно надеюсь): int row=2; for (int i=0; i<dl; i++){if ('!'==str){row+=1;}}; int...

Как заполнить двумерный динамический массив?
Кто может объяснить , как создать динамический двумерный массив и записать в него элементы из файла, при этом подсчитав количество строк и...

Как заполнить одномерный динамический массив Integer?
Пробую заполнить одномерный динамический массив Integer. Не получается. Как заполнить одномерный динамический массив Integer? ...

Как создать динамический массив и заполнить его с клавиатуры
Как это реализовать на c# подскажите пожалуйста, смотрел в других темах, как то невнятно объяснено. Я думаю, что программа должна...

Как создать динамический двумерный массив и самому его заполнить?
Как создать динамический двумерный массив и самому его заполнить?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Результаты исследования от команды MCM (март 2025 г.)
Programma_Boinc 07.04.2025
Результаты исследования от команды MCM (март 2025 г. ) В рамках наших текущих исследований мы продолжаем изучать гены, которые имеют наибольшую вероятность развития рака легких, выявленные в рамках. . .
Рекурсивные типы в Python
py-thonny 07.04.2025
Рекурсивные типы - это типы данных, которые определяются через самих себя или в сочетании с другими типами, которые в свою очередь ссылаются на исходный тип. В мире программирования такие структуры. . .
C++26: Объединение и конкатенация последовательностей и диапазонов в std::ranges
NullReferenced 07.04.2025
Работа с последовательностями данных – одна из фундаментальных задач, с которой сталкивается каждый разработчик. C++ прошел длинный путь в эволюции средств для манипуляции коллекциями – от. . .
Обмен данными в микросервисной архитектуре
ArchitectMsa 06.04.2025
Когда разработчики начинают погружаться в мир микросервисов, они часто сталкиваются с парадоксальным правилом: "два сервиса не должны делить один источник данных". Эта мантра звучит повсюду в. . .
PostgreSQL в Kubernetes: Автоматизация обслуживания с CNPG
Mr. Docker 06.04.2025
Администраторы баз данных сталкиваются с целым рядом проблем при обслуживании PostgreSQL в Kubernetes: как обеспечить правильную репликацию данных, как настроить автоматическое переключение при. . .
Async/await в TypeScript
run.dev 06.04.2025
Асинхронное программирование — это подход к разработке программного обеспечения, при котором операции выполняются независимо друг от друга. В отличие от синхронного выполнения, где каждая последующая. . .
Многопоточность в C#: Синхронизация потоков
UnmanagedCoder 06.04.2025
Многопоточное программирование стало неотъемлемой частью разработки современных приложений на C#. С появлением многоядерных процессоров возможность выполнять несколько задач параллельно значительно. . .
TypeScript: Классы и конструкторы
run.dev 06.04.2025
TypeScript, как статически типизированный язык, построенный на основе JavaScript, привнес в веб-разработку новый уровень надежности и структурированности кода. Одним из важнейших элементов этой. . .
Многопоточное программирование: Rust против C++
golander 06.04.2025
C++ существует уже несколько десятилетий и его поддержка параллелизма постепенно наращивалась со временем. Начиная с C++11, язык получил стандартную библиотеку для работы с потоками, а в последующих. . .
std::vector в C++: от основ к оптимизации производительности
NullReferenced 05.04.2025
Для многих программистов знакомство с std::vector происходит на ранних этапах изучения языка, но между базовым пониманием и подлинным мастерством лежит огромная дистанция. Контейнер std::vector. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер