Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/56: Рейтинг темы: голосов - 56, средняя оценка - 4.54
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443

Быстрый старт в изучении C++ для относительно опытных программистов Basic

18.04.2020, 16:11. Показов 14337. Ответов 253

Студворк — интернет-сервис помощи студентам
В этой ветке предлагаю обсуждать сходства и различия между C++ и Visual Basic.
Ну хотя бы для упрощения процесса изучения параллельного (дополнительного) языка для тех, кто уже относительно неплохо знаком с Visual Basic.
Ну просто как-то "не вкусно" начинать изучение совсем уж с нуля, когда, в принципе, уже и без того много знаешь (циклы, ветвления, указатели, видимость переменных ... ).

На самом деле, начал сейчас просмортр на ютубе курса по C++. Дядька очень толково и понятно всё объясняет, явно есть у него талант хорошего преподавателя.

Самые первые отличия, которые бросились в глаза, это:
- комменты обозначают двумя косыми чертами вместо апострофа,
- в конце каждой строки точка с запятой,
- все процедуры, функции, "тела" циклов ... в фигурных скобках,
- вложенные циклы можно описывать одной строкой,
- если переменная объявлена, но ей не присвоено значение, то она содержит случайный "мусор" из памяти, а не как у нас в бейсике, где сразу получает значение ноль или пустую строку,
- массивы с квадратными скобками вместо круглых,
- область видимости переменных ограничена фигурными скобками и причём неважно функция это, цикл или "тело" функции IF, а не как у нас область видимости переменных ограничена только функциями и процедурами.

Ветка открытая, пишите кто хочет.
Особенно приветствуются советы опытных специалистов, уже овладевших несколькими языками.
Ну уж им-то гораздо виднее, в чём сходство и различие разных языков.

Сказать по правде, лично мне сейчас C++ и его младший брат нужны, главным образом, для удобства изучения материалов MSDN.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.04.2020, 16:11
Ответы с готовыми решениями:

предложение для опытных программистов
добрый день уважаемые госпда программисты - необходима помощь по выполнению лабораторных по предмету Операционные Системы. Ищу человека...

Быстрый старт и софт для Modicon TM251MESE (Schneider Electric)
Так сложилась ситуация, что в скором времени предстоит познакомиться с ПЛК TM251MESE от Sneider Electric. Начал интересоваться как...

Книги или справочники для опытных(или проффесиональных) программистов!
Пожалуйста, Подскажите книги или справочники для опытных и проффесиональных программистов! Особенно хотелось бы найти: 1) полный...

253
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
29.04.2020, 15:36
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от locm Посмотреть сообщение
Нет, я просто прошу рабочий код. Что сложного написать? Вы лучше знаете VB чем я.
Я уже написал этот код. cObj.ptr = LocalAlloc(...). Из любого места я могу обратится через ссылку на этот объект и на указатель который по ссылке. Аналогично если бы это была переменная PVOID, и я бы ссылался на нее через сырой указатель в C как PVOID *ppvMyPtr = pvMemory.

Цитата Сообщение от locm Посмотреть сообщение
Возможно что вы мягко говоря "пошутили" написав что ссылки и указателя аналогичны.
Нет я не пошутил и привел примеры как заменяются небезопасные указатели на безопасные ссылки. Ты же меня пытался убедить что сырые указатели и работа с памятью безопасна, на что я приводил тебе примеры что это не так и никакой инструмент не поможет. Я приводил примеры где это небезопасно, но у тебя все-равно какие-то отговорки, что тут я тест поменял, тут я специально что-то сделал и т.п. Ладно, проехали. Потом ты попросил привести примеры безопасных API, я привел примеры безопасных API, но тебя и тут что-то не устраивает. Эти API - не API, неправильные декларации и т.п. Мне честно надоело это уже, это не дискуссия - это троллинг меня.
0
Эксперт по электронике
6876 / 3299 / 340
Регистрация: 28.10.2011
Сообщений: 12,951
Записей в блоге: 7
29.04.2020, 16:01
Цитата Сообщение от The trick Посмотреть сообщение
Я уже написал этот код. cObj.ptr = LocalAlloc(...).
Не компилируется. Быстрый старт в изучении C++ для относительно опытных программистов Basic

Цитата Сообщение от The trick Посмотреть сообщение
Нет я не пошутил
Тогда что мешает привести полный код, который можно скомпилировать?

Цитата Сообщение от The trick Посмотреть сообщение
привел примеры как заменяются небезопасные указатели на безопасные ссылки.
Вы написали что ссылки и указатели аналогичны.

Цитата Сообщение от The trick Посмотреть сообщение
Ты же меня пытался убедить что сырые указатели и работа с памятью безопасна
Где я такое написал? Я писал что если код написан по всем правилам, проблем не возникнет.

Цитата Сообщение от The trick Посмотреть сообщение
Потом ты попросил привести примеры безопасных API, я привел примеры безопасных API, но тебя и тут что-то не устраивает.
В документации функция SHCreateStreamOnFile требует указатель в 3 аргументе, а не так как в вашем коде.
Цитата Сообщение от The trick Посмотреть сообщение
Эти API - не API, неправильные декларации и т.п.
Согласитесь, согласно документации от MS у функции SHCreateStreamOnFile 3 параметра и третий это указатель на объект. Функция возвращает статус работы, а не ссылку на объект. Или это не так и в документации ошибка?

Цитата Сообщение от The trick Посмотреть сообщение
это троллинг меня.
Вовсе нет. В свою очередь когда я прошу полный код (см. выше) и получаю вместо этого отговорки, то это троллинг меня!

А вообще, у нас разные подходы к программированию и видимо отсюда разногласие и недопонимание. Я часто работаю с памятью и т. д. что вы считаете небезопасным и редко из-за этого возникают проблемы. Если они есть, в большинстве случаев отлавливаются отладчиком.
Мне часто и много приходится работать на низком уровне не только в ПК, но и при разработке прошивок для микроконтроллеров, где нет ни ОС ни BIOS ни др. и приходится взаимодействовать непосредственно с железом. Вас похоже VB сильно разбаловал...
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
29.04.2020, 16:43
Цитата Сообщение от locm Посмотреть сообщение
Не компилируется.
Я уже объяснил как сделать.

Цитата Сообщение от locm Посмотреть сообщение
Тогда что мешает привести полный код, который можно скомпилировать?
Ничего не мешает. Что мешает написать такой код тебе?

Цитата Сообщение от locm Посмотреть сообщение
Вы написали что ссылки и указатели аналогичны.
Да. Любую задачу требующую указателей можно перевести в безопасную с использованием ссылок. Я об этом и писал, приводил примеры. Ты не согласен? Ты мне пишешь, как работать с небезопасной WinAPI GetModuleFileName которая может перезаписать мимо буфера. Я же тебе говорю что такие функции небезопасны, и вместо них нужно использовать безопасные аналоги, типа App.Path которая не может спровоцировать подобных ошибок. Вот последнее предложение перечитай 5 раз, пожалуйста.

Цитата Сообщение от locm Посмотреть сообщение
Где я такое написал? Я писал что если код написан по всем правилам, проблем не возникнет.
Никто не утверждал обратного, правильно написанный небезопасный код будет работать правильно, но это налагает на программиста определенные обязательства. Безопасный код не налагает таких обязательств. Для чего ты мне приводил тогда пример с небезопасным кодом на PureBasic если ты не хотел меня убедить в обратном?

Цитата Сообщение от locm Посмотреть сообщение
В документации функция SHCreateStreamOnFile требует указатель в 3 аргументе, а не так как в вашем коде.
Потому что мой код использует безопасную концепцию принятую в VB. Ты добавил либу? Запустил код? Почему он работает если это по твоим словам нарушает документацию?

Цитата Сообщение от locm Посмотреть сообщение
Согласитесь, согласно документации от MS у функции SHCreateStreamOnFile 3 параметра и третий это указатель на объект. Функция возвращает статус работы, а не ссылку на объект. Или это не так и в документации ошибка?
Я еще первым постом когда приводил этот пример все пояснил. Я не знаю что ответить еще. Ну думай что нарушает, а работает все это благодаря магии .

Цитата Сообщение от locm Посмотреть сообщение
Вовсе нет. В свою очередь когда я прошу полный код (см. выше) и получаю вместо этого отговорки, то это троллинг меня!
Не в коем случае, я приводил код и объяснял.

Цитата Сообщение от locm Посмотреть сообщение
А вообще, у нас разные подходы к программированию и видимо отсюда разногласие и недопонимание. Я часто работаю с памятью и т. д. что вы считаете небезопасным и редко из-за этого возникают проблемы. Если они есть, в большинстве случаев отлавливаются отладчиком.
Пойми, я не против небезопасного программирования, жаль что ты не понял о чем я тут веду речь. Я веду речь о концепции, принятой в VB6 и которая позволяет писать программы и так и так. Тут у нас при соблюдении правил таких ошибок как в PB быть не может, без небезопасного API мы вообще почти не можем "уронить" наше приложение так как это легко сделать в том же PB. Все задачи в том числе работа с памятью может быть реализована в безопасном ключе, вовсе необязательно иметь возможность писать куда попало и указывать на что попало, в реальных задачах писать нужно именно туда куда нужно, а указывать туда куда нужно, и безопасная концепция как раз позволяет делать так.

Цитата Сообщение от locm Посмотреть сообщение
Мне часто и много приходится работать на низком уровне не только в ПК, но и при разработке прошивок для микроконтроллеров, где нет ни ОС ни BIOS ни др. и приходится взаимодействовать непосредственно с железом. Вас похоже VB сильно разбаловал...
Нет. Я тоже пишу иногда прошивки для AVR, и делаю это даже не из ЯВУ, а из ассемблера. Занимаюсь реверсом (для себя )и т.п. Это тут не при чем. Я веду речь об концепции в программировании, когда мы отвязываемся от "железа" и у нас нет таких понятий как указатель на память, а есть понятие ссылка на сущность. Это не означает что я не работаю с низким уровнем, как я уже писал VB6 позволяет почти точно также работать на низком уровне.
0
Эксперт по электронике
6876 / 3299 / 340
Регистрация: 28.10.2011
Сообщений: 12,951
Записей в блоге: 7
29.04.2020, 17:28
Цитата Сообщение от The trick Посмотреть сообщение
Что мешает написать такой код тебе?
Много вы видели моих ответов в разделе VB по теме. Я не знаток VB...

Цитата Сообщение от The trick Посмотреть сообщение
Ты мне пишешь, как работать с небезопасной WinAPI GetModuleFileName которая может перезаписать мимо буфера. Я же тебе говорю что такие функции небезопасны, и вместо них нужно использовать безопасные аналоги, типа App.Path
Представьте ситуацию что в VB нет безопасных аналогов. Ни разу такого не было?

Цитата Сообщение от The trick Посмотреть сообщение
Для чего ты мне приводил тогда пример с небезопасным кодом на PureBasic если ты не хотел меня убедить в обратном?
Все началось с вашего высказывания
Цитата Сообщение от The trick Посмотреть сообщение
Любую задачу с указателями можно выполнить с использованием ссылок в VB6.
Мой ответ на это. Быстрый старт в изучении C++ для относительно опытных программистов Basic
Обсуждаем несколько страниц, а полного кода как не было так и нет.

Цитата Сообщение от The trick Посмотреть сообщение
Ты добавил либу? Запустил код?
Нет. Хз как ее добавить. В меню VB на нешел как это сделать.

Цитата Сообщение от The trick Посмотреть сообщение
Не в коем случае, я приводил код и объяснял.
Ну скиньте проект в архиве чтоли где добавлены все библиотеки и он компилируется...

Цитата Сообщение от The trick Посмотреть сообщение
веду речь о концепции, принятой в VB6 и которая позволяет писать программы и так и так.
ОК, я тоже не против, но не могу понять как ссылка может быть в роли указателя, ведь как было выяснено это невозможно (или возможно?)
Цитата Сообщение от locm Посмотреть сообщение
А это можно понимать что все что возможно с указателями, возможно с ссылками. Или как это еще понимать?
Я конечно удивился, учитывая что судя по коду ссылки это указатели на объекты, но подумал может есть какая-то лазейка позволяющая использовать их как обычные указатели.

Цитата Сообщение от The trick Посмотреть сообщение
таких ошибок как в PB быть не может, без небезопасного API мы вообще почти не можем "уронить" наше приложение так как это легко сделать в том же PB
В нем тоже возможно безопасное программирование. Вот к примеру сканирование диска с сохранением данных в древовидную структуру.
Кликните здесь для просмотра всего текста
PureBasic
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Structure FileList
  N.s ; Имя файла
  S.q ; Размер файла
EndStructure
 
Structure TreeFiles
  DN.s                ; Имя текущей папки.
  List D.TreeFiles() ; Список вложенных папок текущей папки.
  List F.FileList()  ; Список файлов текущей папки.
EndStructure
 
EnableExplicit
 
Procedure ScanDisk(*Tree.TreeFiles, Dir.s) ; Сохранение структуры указаной папки
  Protected ID, Name.s
  
  If *Tree
    
    ID = ExamineDirectory(#PB_Any, Dir, "*.*")
    If ID
      
      While NextDirectoryEntry(ID)
        
        If DirectoryEntryType(ID) = #PB_DirectoryEntry_File ; Файл
          
          If AddElement(*Tree\F())
            *Tree\F()\N = DirectoryEntryName(ID)
            *Tree\F()\S = DirectoryEntrySize(ID)
          EndIf
          
        Else ; Папка
          
          Name = DirectoryEntryName(ID)
          If Name<>"." And Name<>".."
            
            If AddElement(*Tree\D())
              *Tree\D()\DN = Name
              ScanDisk(*Tree\D(), Dir+Name+"\") ; Рекурсивный вызов процедуры
            EndIf
            
          EndIf
          
        EndIf
      Wend
      
      FinishDirectory(ID)
    EndIf
    
  EndIf
  
EndProcedure
 
Procedure SetTreeGadget(Gadget, *Tree.TreeFiles, Depth)
  
  If *Tree
    
    If *Tree\DN<>""
      AddGadgetItem(Gadget, -1, *Tree\DN, 0, Depth)
      Depth+1
    EndIf
    
    ForEach *Tree\D()
      SetTreeGadget(Gadget, *Tree\D(), Depth)
    Next
    
    ForEach *Tree\F()
      AddGadgetItem(Gadget, -1, *Tree\F()\N+"    ("+*Tree\F()\S+")", 0, Depth)
    Next
;     
  EndIf
EndProcedure
 
Define Tree.TreeFiles
 
ScanDisk(Tree, #PB_Compiler_Home)
 
If OpenWindow(0, 0, 0, 500, 300, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(0, 0, 0, 500, 300)
  SetTreeGadget(0, Tree, 0)
  ResetStructure(Tree, TreeFiles) ; Очистка структуры с освобождением всех данных.
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Нет явной работы с памятью (явно не выделяется и не освобождается). Обратите внимание на этот участок.
PureBasic
1
2
3
4
5
Structure TreeFiles
  DN.s                ; Имя текущей папки.
  List D.TreeFiles() ; Список вложенных папок текущей папки.
  List F.FileList()  ; Список файлов текущей папки.
EndStructure
Список D имеет тип структуры в которой расположен, а это значит что каждый элемент списка содержит аналогичный список D, т. е. возможна практически неограниченная вложенность. И все это безопасно.
Но в PB в отличие от VB доступна работа с памятью что во многих случаях облегчает разработку программы.

Цитата Сообщение от The trick Посмотреть сообщение
Я тоже пишу иногда прошивки для AVR
Для меня пройденный этап. Имеет смысл разве что при разработке прошивки для готового устройства. Для новых устройств беру STM32, у которых процессорное ядро мощнее (во многих аппаратно поддерживается плавающая точка), периферия функциональнее, присутствует аппаратная отладка и многое другое, а цена примерно как у AVR.

Цитата Сообщение от The trick Посмотреть сообщение
из ассемблера
Слишком низкоуровнево на мой взгляд. Для реверса других вариантов в общем нет, а для разработки с нуля, лучше ЯВУ.
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
29.04.2020, 18:34
Цитата Сообщение от locm Посмотреть сообщение
Много вы видели моих ответов в разделе VB по теме. Я не знаток VB...
А я не знаток PB, но код написал и даже провел тесты, проверил инструменты. Я не говорю о каком-то сложном коде, код элементарный.

Цитата Сообщение от locm Посмотреть сообщение
Представьте ситуацию что в VB нет безопасных аналогов. Ни разу такого не было?
А я что по этому поводу ответил уже?:
Цитата Сообщение от The trick Посмотреть сообщение
Если нужна работа с памятью именно на низком уровне - работайте, никто не запрещает, но тогда и следуйте всем тем же правилам что и в C.
Цитата Сообщение от locm Посмотреть сообщение
Обсуждаем несколько страниц, а полного кода как не было так и нет.
Потому что задача неправильно поставлена, я уже писал про это. Я написал что LocalAlloc - небезопасна. Нужно 100 байт? Используй массив. Нужно какие-то данные разместить в памяти - пожалуйста, сериализуйте. Разве я этого не писал? Но тебя ничто из этого не устраивает.

Цитата Сообщение от locm Посмотреть сообщение
Нет. Хз как ее добавить. В меню VB на нешел как это сделать.
Project->References, там жмешь обзор и выбираешь библиотеку типов. Т.к. ссылки нельзя давать на сторонние ресурсы, я дал название по которому ее легко найти. В общем я прикрепил 2 проекта.

Цитата Сообщение от locm Посмотреть сообщение
ОК, я тоже не против, но не могу понять как ссылка может быть в роли указателя, ведь как было выяснено это невозможно (или возможно?)
Как невозможно? Вот тут что по твоему? Ссылка - это безопасный указатель.

Цитата Сообщение от locm Посмотреть сообщение
есть какая-то лазейка позволяющая использовать их как обычные указатели.
А они по сути и являются обычными указателями, только работа с ними безопасна, они всегда знают на что указывают и их невозможно (в рамках безопасного программирования) адресовать на то для чего они не предназначены.

Цитата Сообщение от locm Посмотреть сообщение
В нем тоже возможно безопасное программирование. Вот к примеру сканирование диска с сохранением данных в древовидную структуру.
Это небезопасное программирование. Я даже не говорю об указателях, которые программист обязан проверять, всяких вынужденых ResetStructure и т.п. Безопасное - это когда ты не заботишься об этом, а инструмент заботится. Просто написав SetTreeGadget(0, 100, 0) в твоем примере - можно положить программу с AV. Я не говорю о более сложном коде когда указатель запросто неопытный или начинающий программист может перезаписать. В VB6 если следовать его концепции такие ситуации практически не встречаются, поскольку каждая сущность знает на что она ссылается.

Цитата Сообщение от locm Посмотреть сообщение
Список D имеет тип структуры в которой расположен, а это значит что каждый элемент списка содержит аналогичный список D, т. е. возможна практически неограниченная вложенность. И все это безопасно.
Такой же список можно сделать и на VB6. Объявляй в классе ссылку на дочерние элементы и все. Не нужно никаких

Цитата Сообщение от locm Посмотреть сообщение
Для меня пройденный этап. Имеет смысл разве что при разработке прошивки для готового устройства. Для новых устройств беру STM32, у которых процессорное ядро мощнее (во многих аппаратно поддерживается плавающая точка), периферия функциональнее, присутствует аппаратная отладка и многое другое, а цена примерно как у AVR.
Да это неважно в данном контексте.
Вложения
Тип файла: zip for locm.zip (902.3 Кб, 1 просмотров)
0
Эксперт по электронике
6876 / 3299 / 340
Регистрация: 28.10.2011
Сообщений: 12,951
Записей в блоге: 7
29.04.2020, 18:51
Цитата Сообщение от The trick Посмотреть сообщение
Это небезопасное программирование. Я даже не говорю об указателях, которые программист обязан проверять, всяких вынужденых ResetStructure и т.п. Безопасное - это когда ты не заботишься об этом, а инструмент заботится.
Ну ОК, немного изменил код.
Кликните здесь для просмотра всего текста
PureBasic
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
Structure FileList
  N.s ; Имя файла
  S.q ; Размер файла
EndStructure
 
Structure TreeFiles
  DN.s                ; Имя текущей папки.
  List D.TreeFiles() ; Список вложенных папок текущей папки.
  List F.FileList()  ; Список файлов текущей папки.
EndStructure
 
EnableExplicit
 
Procedure ScanDisk(List Tree.TreeFiles(), Dir.s) ; Сохранение структуры указаной папки
  Protected ID, Name.s
    
  ID = ExamineDirectory(#PB_Any, Dir, "*.*")
  If ID
    
    While NextDirectoryEntry(ID)
      
      If DirectoryEntryType(ID) = #PB_DirectoryEntry_File ; Файл
        
        If AddElement(Tree()\F())
          Tree()\F()\N = DirectoryEntryName(ID)
          Tree()\F()\S = DirectoryEntrySize(ID)
        EndIf
        
      Else ; Папка
        
        Name = DirectoryEntryName(ID)
        If Name<>"." And Name<>".."
          
          If AddElement(Tree()\D())
            Tree()\D()\DN = Name
            ScanDisk(Tree()\D(), Dir+Name+"\") ; Рекурсивный вызов процедуры
          EndIf
          
        EndIf
        
      EndIf
    Wend
    
    FinishDirectory(ID)
  EndIf
  
EndProcedure
 
Procedure SetTreeGadget(Gadget, List Tree.TreeFiles(), Depth)
  
  If Tree()\DN<>""
    AddGadgetItem(Gadget, -1, Tree()\DN, 0, Depth)
    Depth+1
  EndIf
  
  ForEach Tree()\D()
    SetTreeGadget(Gadget, Tree()\D(), Depth)
  Next
  
  ForEach Tree()\F()
    AddGadgetItem(Gadget, -1, Tree()\F()\N+"    ("+Tree()\F()\S+")", 0, Depth)
  Next
 
EndProcedure
 
Define NewList Tree.TreeFiles()
 
AddElement(Tree())
ScanDisk(Tree(), #PB_Compiler_Home)
 
If OpenWindow(0, 0, 0, 500, 300, "TreeGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(0, 0, 0, 500, 300)
  SetTreeGadget(0, Tree(), 0)
  ClearList(Tree()) ; Очистка списка с освобождением всех данных.
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
30.04.2020, 00:48  [ТС]
Цитата Сообщение от The trick Посмотреть сообщение
Не знаю как в PowerBasic'е. StrPtr в VB6 получает данные буфера BSTR. VarPtr к слову возвращает адрес BSTR. BSTR - это ссылочный безопасный тип строк с предпросчитанной длиной и нуль-терминалом в конце. BSTR можно передать как по ссылке, так и по значению. По ссылке передается обычно для возврата значения в этом параметре, во всех остальных случаях по значению.
Особенности работы этих функций в PowerBasic'е - на скриншотах.
По правде сказать, я даже и не знал, что в VB6 тоже есть такие функции.
Миниатюры
Быстрый старт в изучении C++ для относительно опытных программистов Basic   Быстрый старт в изучении C++ для относительно опытных программистов Basic  
0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
30.04.2020, 02:44  [ТС]
Цитата Сообщение от Power_Basic
А как отличить, когда юникодную строку просят, а когда ANSI-шную?
Цитата Сообщение от locm Посмотреть сообщение
LPCWSTR
Спасибо, понял.

Добавлено через 1 час 52 минуты
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Power_Basic, BYVAL создаёт копию, дословно передача параметра "по значению",
BYREF - по ссылке, т.е. модификация(если таковая будет внутри процедуры) затронет уже
имеющийся экземпляр данных.
FreeBASIC код, поясняющий это(любой другой бейсик должен работать сходно):
Не, ну я всё-таки достаточно продвинутая домохозяйка, чтобы быть в курсе этих тонкостей
Но за стремление помочь, всё равно, спасибо.

И от себя ещё добавлю, что во многих языках (включая VB и PowerBasic) параметры передаются по умолчанию по ссылке, то есть BYREF.

И если уж об этом зашла реччь, то иногда (хотя и очень-очень редко) встречается передача параметров "по копии" ByCopy. Это полный синоним метода ByVal или всё-таки есть какие-то различия?
0
Кормпилятор
 Аватар для Quiet Snow
5044 / 1718 / 409
Регистрация: 25.04.2010
Сообщений: 4,827
Записей в блоге: 2
30.04.2020, 15:52
Никто не утверждал обратного, правильно написанный небезопасный код будет работать правильно,
но это налагает на программиста определенные обязательства.
Да в общем-то любой код налагает.

Цитата Сообщение от Power_Basic Посмотреть сообщение
Это полный синоним метода ByVal
Лучше в справку загляни, там стопроцентно написано.

Цитата Сообщение от The trick Посмотреть сообщение
Да забей, пиши как хочешь проги.

Не по теме:

Не придаю значения этой критике(потому что необъективно). Пользователь будет прав если он
обвалит мою прогу при её работе(а не доходя до неё), а для этого нужно начать работать
с ней и дать ей нормальные данные. Это не вопрос безопасно\небезопасно это вопрос здравого смысла.
А иначе в девятку можно залить дизель и после сгоревшего движка сказать "а я думал что должно работать",
или "почему не предусмотрели блокировку и индикацию", или в болгарку поставить диск по дереву
и пытаться пилить железо и искренне быть удивлённым "почему ничего не происходит и сдох диск" и
"почему на болгарке нет индикации, ведь это плохо и небезопасно". Да миллионы вещей требуют
здравого смысла. И это не вопрос того, что могу писать как хочу, мои проги работают надёжно
и крит багов в них нет, и там, где действительно это нужно и важно - все защиты стоят, но за рамки
здравого смысла не выхожу, как и большинство нормальных тестировщиков и пользователей.
И могу всё это нормально обосновать:
1) Пользователь не может не знать что нужен *.MAP файл, т.к. в списке справа выдаются только они
с расширением, другие файлы открыть крайне сложно.
2) В описании указано файлы какого приложения оно модифицирует. Если пользователь совсем не понимает
для чего оно - то ему и гарантированно не надо.
3) Работа с каждой картой - 1 итерация, никакой потери данных нет, не начав работу невозможно
ничего потерять.

Да прога ничего не выдаёт при падении, как и сгоревший движок от неправильного топлива,
это и так вполне можно понять - это здравый смысл. А так тоже можно гадать от чего же он сгорел,
"ой а может фильтр засорился или свечи не те или электрика". Скажу даже больше если такой юзер вдруг
найдётся, ему не поможет сообщение вида "невозможно открыть файл", да формально прога не обвалится,
но конкретно ему не отличающему одно от другого - это ничем не поможет, а нормальное супер информативное
сообщение - это уже т.н. здравый смысл. Поэтому лучше определиться что важно здравый смысл
или сухие формальности. К слову человек, который сделал на проге кучу контента был приличным
тестировщиком, он бы меня с потрохами сожрал, если бы прога портила данные.
И позор мне будет, если также кого-нибудь покритикую и запишу в багоделы, не будучи реальным
пользователем софта и за какую-нибудь фигню, а не за нормальную работу с софтом.

0
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
30.04.2020, 16:42  [ТС]
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Лучше в справку загляни, там стопроцентно написано.
Заглянул. Ну, короче, как я понял, это равносильно тому, чтобы заключить параметр в скобки и передать его в таком виде по ссылке, когда от нас требуется просто передать этот параметр по ссылке. Ну то есть мы передаём ссылку на временное хранилище в памяти результата этого выражения.
Может быть имеет смысл всегда так передавать?

Добавлено через 6 минут
Конечно, за исключением тех случаев, когда мы ожидаем возврата данных в этом параметре из вызываемой функции.
0
Кормпилятор
 Аватар для Quiet Snow
5044 / 1718 / 409
Регистрация: 25.04.2010
Сообщений: 4,827
Записей в блоге: 2
30.04.2020, 17:29
Цитата Сообщение от Power_Basic Посмотреть сообщение
Ну, короче, как я понял, это равносильно тому, чтобы заключить параметр в скобки и передать его в таком виде по ссылке, когда от нас требуется просто передать этот параметр по ссылке. Ну то есть мы передаём ссылку на временное хранилище в памяти результата этого выражения.
Короче ясно, BYVAL отдаёт параметр напрямую через стек, BYREF отдаёт ссылку на оригинал,
а BYCOPY делает копию в памяти и отдаёт в процедуру на неё ссылку.

Может быть имеет смысл всегда так передавать?
Почитай по уничтожению этих копий, когда оно происходит и прими решение надо оно тебе или нет.
1
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
30.04.2020, 23:34  [ТС]
Цитата Сообщение от Quiet Snow Посмотреть сообщение
Короче ясно, BYVAL отдаёт параметр напрямую через стек, BYREF отдаёт ссылку на оригинал,
а BYCOPY делает копию в памяти и отдаёт в процедуру на неё ссылку.
Да, пожалуй так.

Цитата Сообщение от Quiet Snow Посмотреть сообщение
Почитай по уничтожению этих копий, когда оно происходит и прими решение надо оно тебе или нет.
Наверно я всё-таки погорячился

Добавлено через 3 часа 39 минут
На самом деле, передача параметров это огромная отдельная тема с кучей тонкостей и скользских мест, поэтому решил вынести обсуждение в отдельную ветку, как уже давно намеревался это сделать:
Тонкости передачи параметров в функции и процедуры
0
Модератор
10060 / 3905 / 885
Регистрация: 22.02.2013
Сообщений: 5,854
Записей в блоге: 79
01.05.2020, 09:06
Цитата Сообщение от Power_Basic Посмотреть сообщение
На самом деле, передача параметров это огромная отдельная тема с кучей тонкостей и скользских мест, поэтому решил вынести обсуждение в отдельную ветку, как уже давно намеревался это сделать:
По передаче параметров есть хороший обзор.
Как обнаружилось, семантика передачи параметров в VB (ByRef/ByVal) существенно различается в зависимости от сочетания типов формального и фактического параметров.

* С простыми типами (Boolean, Byte, Currency, Date, Double, Integer, Long, Single) всё просто: ByVal передаёт копию значения, приведённую к типу формального параметра; ByRef -- адрес значения.

Если ByVal передаётся 64-битная переменная (т.е. типа Currency, Date или Double), то она занимает в стеке две позиции. Если из функции возвращается 64-битная переменная, то она либо занимает пару регистров edx:eax (для Currency), либо передаётся на стеке сопроцессора (для Date, Double и Single).

При передаче ByRef, если передаётся переменная, типы формального и фактического параметров должны строго совпадать; если же передаётся константа, то она приводится к типу формального параметра, сохраняется во временную переменную, и затем передаётся.

* UDT можно передавать только ByRef и только при совпадении типов формального и фактического параметров. Передаётся адрес данных структуры: тут, слава богу, без неожиданностей. Когда функция возвращает UDT, её содержимое либо помещается в edx:eax (для UDT размером 8 байт и менее), либо копируется по ссылке, передаваемой в невидимом последнем параметре, во временную переменную, создаваемую вызывающей стороной.

* Массивы можно передавать только ByRef и только при совпадении типов формального и фактического параметров. Передаётся адрес 32-битной переменной, которая содержит указатель на SAFEARRAY -- т.е. ссылка на ссылку на ссылку на сами данные. ("тройной ByRef") В частности, вызываемая функция имеет право перекроить переданный массив, или даже удалить его совсем.

Когда функция возвращает массив, она помещает в eax указатель на SAFEARRAY, т.е. ссылку на ссылку на сами данные.

* Со строками интереснее. При передаче ByVal передаётся ссылка на копию строки, т.е. фактически передаётся временная переменная по ссылке. При передаче ByRef передаётся либо адрес строковой переменной ("двойной ByRef"), либо -- когда ByRef передаётся фиксированная строка -- адрес адреса временной копии строки. В последнем случае строка копируется дважды -- перед вызовом функции и после возврата из неё. Данное исследование затруднялось тем, что для фиксированной строки и StrPtr, и VarPtr возвращают ложный результат (им приходит адрес временной копии строки -- его они и возвращают).

Когда функция возвращает строку, она просто помещает в eax указатель на её данные.

* При передаче объектов ByVal передаётся ссылка на данные объекта, и функция может делать с этим объектом произвольные действия (фактически, объект передаётся по ссылке). При передаче ByRef передаётся адрес объектной переменной, т.е. адрес 32-битного указателья на данные объекта ("двойной ByRef"). В этом случае функция получает возможность очистить или переназначить объектную переменную.

Объекты -- первый из типов, для которых при передаче ByRef допускается несовпадение типов формального и фактического параметров: достаточно, чтобы оба были объектными. В этом случае передаётся адрес временной объектной переменной, в которую помещается адрес скастованного к нужному типу объекта. После возврата из функции значение, помещённое ей во временную переменную, кастуется обратно к типу исходной переменной и затем ей присваивается.

Это второй из случаев (первый -- с фиксированными строками), когда изменения формального параметра, переданного ByRef, отражаются в фактическом параметре не немедленно, а только после возврата из функции. Эта особенность может быть принципиальной, если фактический параметр -- глобальная переменная, и вызванная функция (или одна из вызываемых ей, в свою очередь, функций) использует эту глобальную переменную как через формальный параметр, так и непосредственно.

* Самый интересный тип параметров -- это Variant. При передаче ByVal все его 16 байт кладутся на стек, т.е. он занимает в нём 4 позиции. Далее, возвращаемое значение типа Variant всегда передаётся в невидимом последнем параметре -- как обычно для 16-байтной структуры.

В составе варианта можно передавать ByVal любой тип -- даже UDT и массивы, для которых передача ByVal напрямую невозможна. В этом случае внутри варианта передаётся указатель на временную копию фактического параметра. В частности, для массивов передаётся указатель на SAFEARRAY ("двойной ByRef").

Когда переменная типа Variant передаётся ByRef, на стек кладётся её адрес. Но когда формальный параметр объявлен с типом Variant, фактический параметр может иметь любой приводимый к варианту тип -- т.е. вообще любой, кроме приватного UDT. В этом случае на стек кладётся адрес временной переменной типа Variant, в которой включена "магия": установлен флаг VT_BYREF, и вместо самих данных хранится ссылка на них. Обнаружить, что переданный параметр типа Variant -- такая вот временная "магическая" переменная, непросто: функция VarType скрывает этот флаг. Кроме того, при присваивании магической переменной в обычную переменную типа Variant магия теряется, и в переменную присваивается копия переданного значения, а не копия ссылки. Однако, магический параметр можно передать как ByRef As Variant в другую функцию -- при этом его магические свойства сохранятся.

Суть магии состоит в том, что присваивание значения магической переменной сразу же действует на переданный фактический параметр. В частности, внутри функции нельзя присвоить произвольную строку параметру типа Variant, если в качестве него была передана переменная типа Long: сразу же, внутри функции, возникает ошибка несоответствия типов. Такой способ передачи параметра также можно назвать "двойным ByRef", потому что передаётся адрес варианта, содержащего ссылку на данные. Однако для ссылочных типов (строки, объекты и массивы) он оказывается "тройным ByRef", потому что ссылка в варианте указывает на переменную, являющуюся указателем на собственно данные. Конкретно для массивов ссылка в варианте указывает на указатель на SAFEARRAY, содержащий ссылку на сами данные массива ("четверной ByRef").


* Для всех типов, кроме Variant, значения необязательных параметров (если значение по умолчанию не указано явно, то используется пустое) подставляются на этапе компиляции, и функция не имеет возможности узнать, был ли ей передан фактический параметр в качестве необязательного. Если необязательный параметр передавался ByRef, то создаётся временная переменная, в которую помещается значение по умолчанию, и эта временная переменная передаётся по ссылке -- как обычно при передаче констант ByRef.

Для параметров типа Variant используется специальное значение, обозначающее пропущенный фактический параметр. Это значение имеет подтип vbError и код &H80020004=DISP_E_PARAMNOTFOUND, который при попытке использования автоматически переводится в код 448 "Named argument not found", в соответствии с недокументированной таблицей перевода кодов ошибок. (Далее это специальное значение будет условно называться varMissing) Это означает, что проверку функцией IsMissing(a) можно заменить на равносильную проверку IsError(a) And CLng(a) = 448. Однако, "сфальсифицировать" пропущенный параметр при помощи CVErr не удастся: она допускает только коды от 1 до 65535, и вместо перевода их по таблице просто добавляет &H800A0000.

Поскольку при передаче параметров в другие функции магические переменные не создаются (они создаются только при передаче переменных), то невозможно получить ни "дважды магическую" переменную, ни магическую переменную, ссылающуюся на varMissing. Проверено, что использование созданных вручную многократно-магических переменных (в пределе -- зацикленных :-D) сносит крышу VB.

* В качестве параметра ParamArray передаётся, как и для обычных массивов типа Variant, указатель на указатель на SAFEARRAY. Элементами массива являются, как и для обычных ByRef-параметров типа Variant, обычные варианты для переданных констант, магические -- для переданных переменных, и varMissing для пропущенных параметров. Если передавалась переменная типа Variant, то в массиве будет переменная с подтипом vbVariant+VT_BYREF, указывающая на неё. Это единственный случай, когда в VB может появиться вариант с подтипом vbVariant без одновременно установленного флага vbArray -- хотя VarType будет для него показывать не vbVariant, а подтип того варианта, на который этот ссылается.

Как ни обидно, при передаче магического варианта, полученного в составе ParamArray, в другую процедуру -- его магия теряется. При чтении элемента массива всегда создаётся копия его значения, даже если этот элемент был магическим.

Можно для интереса прикинуть уровень передачи по ссылке для массива, передаваемого в составе ParamArray: передаётся ссылка на ссылку на SAFEARRAY, содержащий ссылку на Variant, содержащий ссылку на ссылку на SAFEARRAY, содержащий ссылку на собственно данные. Шестикратный ByRef! И после этого кто-то ещё будет заявлять, что в VB нет ссылок? :-D

* Практический вывод такой: формирование вручную магических вариантов и передача их в качестве параметров позволит работать с указателями несравнимо более удобно, чем через одноэлементные SAFEARRAY. Предлагаю GSerg-у написать продолжение к своей статье о работе с указателями в VB :-)

--------------------
* Всё написанное относится к передаче параметров внутри модулей VB. При вызове членов классов VB всегда добавляется невидимый первый параметр объектного типа (в нём передаётся Me), и невидимый последний параметр под возвращаемое значение, если член возвращает значение. Все члены классов VB возвращают в eax свой код ошибки (к положительным кодам добавляется &H800A0000), либо 0 если ошибки не было. Ни в каком случае член класса VB не может вернуть в eax положительное значение; также невозможно вызвать через Err.Raise ошибку с кодом, большим 65535 (но можно с любым отрицательным).

Всё написанное не имеет непосредственного отношения к передаче параметров в API, объявленные в Declare либо в TLB. Как всё обстоит там, подробно (хотя и с ошибками ;-)) расписано у Аппельмана.
Источник vbstreets.
2
 Аватар для Power_Basic
46 / 25 / 0
Регистрация: 08.03.2016
Сообщений: 443
01.05.2020, 19:30  [ТС]
The trick , спасибо!
Очень полезная и своевременная информация.
Буду потихонечку вдумчиво разбираться.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.05.2020, 19:30
Помогаю со студенческими работами здесь

набор опытных C++ программистов
Большой иностранный банк проводит набор опытных C++ программистов для IT-департамента своего московского офиса. Необходимы кандидаты с...

Приглашаю На работу Опытных Программистов
Всем привет . Я ищю Хороших программистов для работы над Онлайн игрой ( в типе neverlands) От вас Требую одно хорошую ...

Нужен совет опытных программистов на C#
Всем добрый день! Я здесь абсолютно новенький! Так что прошу сразу не кидать камнями если задаю вопросы не там где нужно! :) Совсем...

Нужен совет опытных программистов
Задача: Написать систему логирования LS кода, подсчета производительности (как долго исполняется LS код) и учета ошибок. Цель: получить...

Требуется совет опытных программистов
Основы С++ более менее изучены. Что же дальше? Что учить чтоб писать хоть какие то простенькие прикладные программы?


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

Или воспользуйтесь поиском по форуму:
254
Ответ Создать тему
Новые блоги и статьи
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов, содержащихся в реализации модуля. По-умолчанию все члены модуля доступны: module Foo let x = 10 let boo () = printfn "boo" . . .
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru