Страницы: Пред. 1 2 3 4 5 6 7 След.
RSS
Возможности разработки взаимодействия с БД (выбор инструментов), Javascript ИЛИ VBScript
 
JeyCi, по ссылке, один чел, которому 16 лет, он учит четыре языка, два из которых знает на уровне джуна, спрашивает что такое указатели, а публика, видимо таких же, отвечает какую-то то ересь. Зайдите на проф. форум и почитайте нормальные ответы. Про массив я вообще не понял, видимо чел с ними не умеет вообще работать. Какое копирование, зачем, при чем здесь указатели?
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал: Какое копирование, зачем, при чем здесь указатели?
насколько я понимаю - при работе с массивами выгоднее использовать указатели, с точки зрения и памяти и скорости (я бы даже сказала)... например (или особенно) при передаче массива в функцию... моё имхо
p.s.
именно в этом и суть - не копировать в памяти массив...
Изменено: JeyCi - 16.07.2019 14:47:49
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, это происходит от незнания, что такое массив в С++.
Вот, можно почитать, к примеру, здесь: Массивы в С++
Кратко: в С++ имя массива является указателем, и передать массив по значению нельзя, не сделав определенные специальные для этого действия, а именно выделив вручную память и вручную же переписав данные. Причем все это все равно происходит через имя/указатель. А как можно работать с массивом без указателя? Расскажите? )
Можно сделать статистический массив, не в куче, а на стеке, все равно имя массива - есть указатель. Можно работать с массивами, очередями, списками, коллекциями из стандартной библиотеки std:: контейнеры С++, там под капотом те же указатели.

Поэтому, когда человек пишет: "перебираете в цикле десятки сотен тысяч массивов с тысячами элементами, и каждый раз проц берет и по одному копирует каждый элемент массива в новый. И вот ваша генерация жрет 5 минут и 10 гигабайт ОЗУ, вместо 10 секунд и 50 мегабайт" - значит говнокод лютый, азов не знает, еще кого-то учит, что еще страшнее. Перебрать по указателям сотни миллионов строк это секунды! нукуда ничего не надо копировать, что за треш. Куда и что брать в С++ указывает программист, компилятор всегда думает, что программист всегда прав, какую он ахинею бы не написал. Этот язык не для таких "профессионалов".

Немного матчасти:
Указатели и массивы
Указатели и массивы
Указатели, ссылки и массивы в C и C++: точки над i
Изменено: bedvit - 16.07.2019 16:26:20
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал:
JeyCi , это происходит от незнания, что такое массив в С++.
Привет, Виталий.
Эк как прорвало :)  Я уже боюсь что-нибудь отвечать JeyCi - иначе на разбор потока времени уходит много. К стати, может как-нибудь встретимся, пива попьём?
 
Привет Андрей! да уж, ввязался в бой :) Сам на грабли наступал не раз, думаю если бы мне помогли бы сразу, не было бы некоторых выстрелов в ногу. Пришлось все самому осваивать, в боевых условиях, так сказать. Сам вот столкнулся с одним вопросом, довольно специфичным, до сих пор не решил, вот бы здесь кто бы помог, но сомневаюсь, мало проф форумов по данному вопросу.
Встретится я всегда ЗА! Планируется командировка?
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал: Перебрать по указателям сотни миллионов строк это секунды!
ну так об этом же и речь!.. вместо того, чтобы копировать массив в память снова для перебора его...
(если есть ответ на вопрос Зачем мне знакомиться с новым и меня убеждает этот ответ ДЛЯ моих целей ИЛИ же я старыми знакомыми способами смогу справиться - отсюда и принимается выбор в пользу распределения времени или изучения или разработки... должна ведь быть какая-то мативация ... мои сомнения были: стоит ли пользоваться указателями [незнакомыми мне], или подрядить какой более знакомый ход других контейнеров)
p.s.
понятно, что поднимать тему с нуля неблагодарное занятие на первых порах - но главное правильно сориентироваться и самое главное - определить Edge того или иного языка, тех или иных путей разработки... и максимально профитно утилизировать этот Edge... или выбирать др. яз - более профитный... ценю профитность C++ по скорости (замечено благодаря вам) - но причину скорости (помимо того, что это машинный код после компиляции) , заключающуюся в рабочих фишках алгоритмов и языка в целом - тоже ведь интересно нащупать... чтобы принимать решение ударяться в этот язык или иной... т.н. чтобы прикинуть "кривую изучения"
p.p.s.
например, понравилась книга (беглым взглядом) - Принципы, паттерны и методики гибкой разработки на языке C#  Р.С. Мартин, М.Мартин(по плюсам у него тоже что-то есть) - хоть на хабре и виделось что-то вроде критики, но в книге хорошо описана логика разбиения проекта на компоненты и классов по этим компонентам - для  easy-to-use  в дальнейшей разработке - рекомендации и их цель, кажутся очень заслуживающими внимания... поскольку разрабатывать изначально корректно логично - лучше, чтобы потом доделывать (если придётся), чем писать всё с нуля снова по той же задаче... мне понравились идеи о независимости компонентов - поскольку, чем больше разрастается проект - тем сложнее проводить изменения с первоисточника по всему коду проекта - но если правильно разбить классы и интерфейсы по компонентам - то доработки будут сводиться к минимуму при изменениях первоисточника... он ведь не мой (первоисточник) :) а сторонний
p.p.p.s
за матчасть спасибо! спасибо, что задаёте вектор движения... - сразу же встречается хороший совет - Классы в С++
Цитата
Совет. Создавайте классы, используя средства своей IDE:
В MVS в меню Проект->Мастер классов или Проект->Добавить класс
В Code::Blocks в меню File->New->Class
В Dev-C++ слева выбрать закладку Классы и правой кнопкой в контекстном меню выбрать Новый класс
В QTCreator в меню Новый файл или проект, в разделе Файлы и классы выбрать C++ и соответственно Класс C++
-- и жизнь кодера в IDE кажется проще  8)
а с учётом количества примеров по линку - разработку вообще можно свести к собиранию конструктора согласно своей логике  ;)  
Благодарю!
===
как правило google не помощник - когда googl'ит новичок в теме...
Изменено: JeyCi - 17.07.2019 16:26:18
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
всё-таки VBA мне больше напоминает процедурное программирование с его процедурами...
а ООП ещё надо проникнуться - Объектно-ориентированное мышление - Мэтт Вайсфельд
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
создание и использование DLL, по примеру отсюда (только .h надо задать одинаковый и в проекте dll, и в проекте приложения), - работает при компиляции в Ultimate++ v11873 (C++ v11)...
в DEV C++ - какие-то проблемы бывают с компиляцией - v5.4.x - там есть свои нюансы... - здесь ... а может эта IDE уже и отжила своё...
но встречены пояснения по коду объявлений для создания dll - по ATTACH/DETACH, а THREAD - это, видимо, про потоки (если надо)...
===
вобщем, пощупать DLL удалось скромненько... а интерес в создании своих dll обусловлен удобством систематизации новых функций, классов и интерфейсов - для удобства работы со своими наработками в дальнейшем... [хм, хотя встречала где-то, что интерфейс лучше делать на клиенте, не на сервере]
===
а вот надстройки COM, насколько поняла, отличается от dll - их структурой, которая реализует взаимодействие библ и утилизирующего её приложения по принципу Сервер-Клиент через созданный интерфейс (причём можно задать взаимодействие с разными языками программирования)... полагаю, тоже залог скорости... имхо (если не права - правьте с лёгкостью)
... пока такие выводы...
Изменено: JeyCi - 25.07.2019 12:38:21
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал: а вот надстройки COM, насколько поняла, отличается от dll - их структурой, которая реализует взаимодействие библ и утилизирующего её приложения по принципу Сервер-Клиент через созданный интерфейс
точнее способом реализации взаимодействия с клиентом...
* для DLL нужно реализовать статическую или динамическую загрузку её; также задаются жёсткие требования к клиенту,  если она (dll) написана на C++, в dll.h  - который и не позволяет взаимодействовать с библ (dll) из любого языка (=> невозможно эти dll использовать, например, из VisualBasic и Delphi)
* возможность взаимодействия с др. языками для COM обоснована её ООП-природой и обеспечивается созданием типов библиотек  (классов, методов, интерфейсов) во время её разработки, который взаимодействуют с Внешним интерфейсом, который в свою очередь взаимодействует с клиентом... поэтому, насколько понимаю, можно для взаимодействия с COM просто переписать логику библиотек типов этого внешнего интерфейса, чтобы законнектить его на др. язык клиента... как впрочем и один внеш. интерфейс можно направить и на разные серверы (серверная часть COM - это, как правило, dll, но может быть и exe [если есть на то основания])... и при создании COM создаётся свой .h, содержащий шаблон класса, применяемый для создания Экземпляра Класса (т.е. объекта) для использования его на клиенте.. [важно: delete его (этого объекта) с клиента - не делать, т.к. к объекту на сервере могут иметь доступ и др. клиенты; просто release()]... но т.к. COM - это бинарник - то нет необходимости в поиске заголовочного файла сервера (да и написан сервер может быть на любом яз. прогр., поддерживающем COM, не только на C++)... - а т.к. заголовочный файл даёт указания компилятору для определения переменных... а компилировать уже не надо COM... а определения всё-таки нужны - для задания взаимодействия с люб. др. яз. прогр-ия, на котором создан клиент... - то тут и нужно, как понимаю, something like "propagation(распространение/расширение) of библиотеки типов"... что и достигается путём использования typedef или на клиенте или в том заголовочном файле серверА (если он вдруг всё-таки имеется, если у вас есть доступ к исходнику COM-проекта, если он на C++))...
кстати,  (полагаю, речь об этом внешнем интерфейсе)
Цитата
COM-интерфейсы работают с таблицей виртуальных методов, которая отображает размещение функций объектов в памяти и представляет собой способ стандартизации организации и порядка объявленных интерфейсов, чтобы их могли использовать различные языки программирования, и позволяет обеспечить независимость от языков программирования и бинарную совместимость с COM
p.s.
резюмировала главу книги (насколько поняла)  Borland C++ Builder 6. Холингворт и др - полистала...  8)
===
с typedef'ом мне ещё разобраться бы - как его юзать... а в общем, ОО-природа COM'а даёт более универсальный способ подрядить библу, чем просто написание и использование DLL...
Хотя кто его знает - может в VS библы, подключаемые, так и подключаются, как COM-объекты при разработке проектов??... и не надо напрягаться разработкой сервера COM'a (aka сама dll) и его внешнего интерфейса для взаимодействия с клиентом... и только клиентика смастерить... хотя понятное дело, своя библа всегда ближе к делу...
===
просто вот думала, как, например, JSON.NET законнектить на Excel (чтобы не парсить через PQ, а своим ходом)... глядишь и скорости прибавилось бы для парсинга json'ов-исходников для загрузки в БД... думала, как вариант xll (созданный в Excel DNA) ?? - но всё равно свою dll надо делать... а вот если эта vs'ная библа поддерживает COM - то просто интерфейс наваять для её взаимодействия с excel, или даже просто из тект-файлов, в каком виде они берутся с web-сервера (чтобы не подряжать промежуточную прогу, aka excel, в это простое действие - загрузить данные из txt json-структуры в БД)... вобщем разминка для мозга в свободное время, где его нет...
хотя конечно быстрее, чем json-функции самого MS SQL Server 2016, всё равно не будет...
но просто интересно сделать быстро и доступно по памяти для настольных пк... а так в принципе и не обязательно с JSON.NET (он же Newtonsoft.dll) для c#-проектов (мне так показалось) - хотя если он COM - то и где на др яз можно использовать - знать бы его внутренности и природу...
но и свой С++ вариант парсинга json, оптимизированный для своих баранов ! (хоть библы для работы с json и есть уже на C++) - тоже интересная задумка...
Изменено: JeyCi - 30.07.2019 07:36:28
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал: JSON.NET (он же Newtonsoft.dll)... - знать бы его внутренности и природу...
в принципе на github, наверно, можно найти многое... в исходниках...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
хороший ликбез по COM - в комментах здесь
Использование COM/ActiveX библиотек без регистрации в реестре
В качестве демонстрации платформо-независимости COM - #118
===
всё-таки удобно создавать dll -  и интерфейс для её использования в разных языках... может пригодиться
===
за линки спасибо to bedvit
Изменено: JeyCi - 31.07.2019 10:48:43
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, да, это линки из темы Подключить библиотеку dll. И обсуждения блога Длинная арифметика (Bignum arithmetic) c COM-интерфейсом и C API Functions для Excel на библиотеках MPIR. С/С++. Довольно интересный состоялся разговор.
Про использованиее СОМ без регистрации в реестре, у меня так и не вышло, по причине "много чего допиливания", в сравнении со стандартной регистрацией. А именно нужно:  использовать манифест. Чтобы использовать его динамически (т.е.) как в случае VBA нужно использовать контекст активации, там прописывается местоположение библиотеки, CLSID, PROGID, ProxyStub и т.д. те же ключи реестра. Есть, конечно, уже автоматизированные приложения создающие такой манифест. Мне показалось это сложным и громоздким. Там ещё были какие-то ньюансы, читайте по ссылке выше.
Если у вас получится, поделитесь реализацией
Изменено: bedvit - 31.07.2019 12:24:08
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал: стандартной регистрацией
полагаю, как обычно:
Пуск - Выполнить - cmd - (Enter)
а в коммандной строке: regsvr32 "C:\..pathFolder..\primer.dll"
[оставила линк - там и для отмены регистрации - если в процессе разработки надо вернуть систему в исходное состояние]
===
Цитата
bedvit написал: СОМ без регистрации в реестре,... манифест... прописывается местоположение библиотеки, CLSID, PROGID, ProxyStub и т.д. те же ключи реестра.
спасибо, что предупредили... ok, если всё-таки полезу в нюансы - конечно, выложу - если получится
Изменено: JeyCi - 01.08.2019 15:38:43
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал: и при всех наворотах Visual Studio - всё-таки
даже старый добрый Borland C++ Builder уже помог нарисовать кнопку на форме и !привязать AccessTable к DataGrid... через TADODataSet... (осталось выгрузить в файл - но для этого пробежать циклом до "EOF" на C++ и, наверно, ещё понять BSTR для лучшего начального знакомства с C++  8) )... в общем, комфортно и не грузит оператив... на небольшие несложные моменты автоматизации - есть свои плюсы (по линку)... имхо  :)
===
и здесь - Применение ADO для работы с БД (C++ Builder)
Цитата
Использование так называемых RAD-систем, т.е. систем мгновенной разработки приложений, значительно ускоряет процесс разработки и является более простым и выгодным способом, нежели использование иных сред. К примеру, возьмем Microsoft Visual Studio 2005. В ней реализовано как использование готовых компонентов (MFC) и добавление своих, так и создание приложений с нуля, т.е. программисту придется вручную предусматривать обработку сообщений операционной системы, создавать GUI интерфейс вручную на основе WinAPI функций. Видите насколько тяжелым становиться разработка конечного проекта! Поэтому применение RAD-систем оправданно с точки зрения времени создания проекта, а также простоты разработки.
... хотя, конечно, с появлением NET.Framework и его WPF уже не актуальны MFC-проблемы...
Изменено: JeyCi - 09.08.2019 13:52:29
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал:
ещё понять BSTR для лучшего начального знакомства с C++
BSTR это больше к COM или VB или C#.NET.  В С++ строки это std::string или СИ-шные char. Но можно и BSTR, если хочется.
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал: BSTR это больше к COM или VB или C#.NET.
ой, спасибо за наводку резкости моего зрения...
Цитата
bedvit написал: В С++ строки это std::string
насколько поняла, удобный строковый класс - можно конкатенировать строки и др действия с ними
Цитата
bedvit написал: СИ-шные char.
а вот, как с этими обращаться пока не вижу их плюсы... да и способы - удобство записи в файл, и удобство их природы - массив символов...
p.s.
:) дошла до EOF DataSet'a и  strInfo сформировала из всех полей через + (конкатенацию) по каждой одной строке (record)... сейчас думаю, как в .txt закидывать - построчно? или всё считывать в одну большую строку (чтобы потом кидать в файл)? - есть ли ограничения на размер строки?..  и ЧТО быстрее??
Изменено: JeyCi - 10.08.2019 16:52:37
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал:
ЧТО быстрее??
Чаще всего написать код, подготовить тестовый пример, провести тестирование быстрее, чем дождаться того, кто такое уже проделывал и проделает вместо вас :)  А как же опыт, что сын ошибок трудных, предполагаете приобретать и полезные шишки и мозоли зарабатывать? :)
Изменено: Андрей VG - 10.08.2019 17:20:29
 
Цитата
Андрей VG написал: А как же опыт... шишки и мозоли зарабатывать?
а как же суровая реальность? если у строковой переменной есть ограничения на размер? - это  узнавать когда-нибудь не хочется - чтобы потом перекраивать проект... а сейчас тестить все случаи - всё равно от всего не застрахуешься... вот и спросила, если кто в курсе о максимально оптимальных подходах к работе со строками... зачем чтобы все люди делали одни и те же ошибки, чтобы научиться?.. я всегда за share knowledge -
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
тестово сделала через ADO на форме с Кнопкой
connection настроила вручную и выставила пока TADODataSet в Active=true
по коду как-то так -- работает через Run, но Build пока выдает ошибку (не хватает какого-то dbrtl60.bpl файла, видимо, самой IDE - у меня portable версия без install) - надо разобраться с компилятором или прописать header file как-то правильно?... да и вообще всё сделать по уму ООП, полагаю... хотя для простых шагов, которые нужны мне - пока не вижу смысла создавать классы и т.д.... да и пока тестово...
код обработки нажатия кнопки

p.s.
но вопрос о приоритетных подходах в работе со строками в C++ - конечно же ещё на повестке дня!?.... (или хотя бы впечатления об этом?)
Изменено: JeyCi - 12.08.2019 09:35:33
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал:
у строковой переменной есть ограничения на размер? -
размер вашей памяти :)
В Си-строках нет (не знаю о таком)
В С++ в зависимости от архитектуры, смотреть так:
Код
std::string::max_size() 

на Х64 это 9223372036854775807 символов.
BSTR (это COM или VB или C#.NET) - по-моему 2^31
Цитата
Андрей VG написал:
как с этими обращаться пока не вижу их плюсы... да и способы - удобство записи в файл, и удобство их природы - массив символов...
Си-строки самые быстрые. С ними можно напрямую работать в памяти. Вот результат. Чем удобнее, тем меньше производительность. впрочем это видимо и к языкам относится (низкого, высокого уровня).
Цитата
JeyCi написал:
вопрос о приоритетных подходах в работе со строками в C++
обычно под строками С++ подразумевают std::string. Вполне удобный вариант. А вообще зависит от ваших задач. Нет универсального решения.
«Бритва Оккама» или «Принцип Калашникова»?
 
спасибо!..  :) хоть не 256 символов...
Цитата
bedvit написал: Си-строки самые быстрые. С ними можно напрямую работать в памяти
ну это, наверно, потому что массив символов... а на него указателями... вобщем, ковырять ещё эту тему мне надо - ищу прример - вижу, что всегда важно количество символов в строке (чтобы потом эту строку легче обрабатывать) - иногда и пишут в файл это число символов в довесок к строке... хотя, наверно, можно и взять sizeof и задавать массив на это количество символов... или в многострочном: отдельно массив (вектор) одномерных массивов каждый по строке и отдельно массив sizeof'в... просто пока не вижу удобный алгоритм...
... и, честно говоря, заинтриговал меня ваш алгоритм отсюда - в кодировке Unicode...
вобщем ищу способ оптимальный для скорости и универсальности, как стартовую точку... имхо
Изменено: JeyCi - 11.08.2019 16:49:21
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал:
вобщем ищу способ оптимальный для скорости и универсальности,
Способ для решения какого вопроса?
«Бритва Оккама» или «Принцип Калашникова»?
 
выяснила, что тормоза даёт использование ORDER BY в Access - хочу выполнять сортировку не на стороне сервера, а на стороне клиента... честно говоря, понимаю, что сложность возникает, когда надо отсортировать по 2-м и более полям... но допустим, даже если по одному (первому) - то можно взять строки, которые вытягиваю из ADODataSet... дальше думать о сортировке или искать алгоритм в std или stl (где-то)... а по двум полям сортировать вообще муторно (sorry за выражение)...
p.s.
** кстати, как вариант в написании массива символов на C - возможно, стоит использовать структуру (в которую поместить 2 массива: один - массив массивов строк, второй массив sizeof этих строк (хотя, думала, что у каждого типа данных есть свой size и обычно пишется как есть, char-size умножить на количество символов?)... чтобы всегда знать, какой длины массив строк и не измерять каждый раз sizeof...  :qstn:
** если же помимо "полей"-членов-структуры ещё нужны и методы для работы с ними - то лучше создавать класс, насколько понимаю
** опять же возникает вопрос: может придётся создать даже ещё и др. класс, наследуемый из первого (если он нуждается в свойствах и методах из первого класса, и при этом если надо переопределить немного поведение старого класса [чтобы не дублировать создание однотипных классов - например для сортировки по разным полям])... тут уж в пору задумываться об архитектуре клиента... [наверно, мне пока от клиента иного и не надо будет]...
p.s.
клиент для загрузки из json (или даже из web), в принципе, можно и другой отдельный потом делать... имхо... когда постигну основы...
p.p.s
есть ли идеи об алгоритме для сортировки массива строк по нескольким полям?..  
:qstn: - или/и пару ювелирных красивых строк (способов) выделить память для массива строк на C (потом, насколько понимаю, буду ходить по ним указателями или ссылками) .... а то в i'net'e примеров много, а лучших пока не могу отличить др от др - чувства вкуса в новом языке у меня ещё не очень развито...
p.p.s
** с ссылками поосторожнее (чтобы компилятор не выполнил swap по своему взгляду на ссылку при операции над переменной в функции, чтобы ф-ция не могла изменить параметр переданный по ссылке лучше параметры, которые не должны изменяться, опр-ть словом const, ДА И при несовпадении типов передаваемого в функцию аргумента и принимаемого функцией - происходит неявное преобразование типов, а для ссылок оно идёт через созд-е промежуточной переменной - вот тут компилятор и выполняет swap -- и можно получить совсем не то, что хотелось )...поскольку она (ссылка) определяет новое имя переменной, не создаёт её копии, а просто лишь явл-ся др именем переменной... чаще всего в ней возникает потребность при перегрузке операций - насколько поняла... вобщем указатель надёжнее... хотя в моём случае, если создавать класс сортировки и из него наследование в классы для сортировки разных полей (точнее разных типов их)... то вот тут как раз и перегрузка появляется  :D (хорошее слово в новом языке)... а может какой Template перегруженный для сортировки  уже и есть в stl, да я пока не знаю ??  :qstn:
просто не хочу на первых порах всё очень усложнять, но найти простые и действенные способы - и хотелось бы не тормознутые... имхо... в поисках... и при этом хочу понимать, чтО пишу и писать по-простому, чтобы въезжать в язык ;)... !C... (у С++ как-то попроще со строками)
Изменено: JeyCi - 12.08.2019 10:26:30
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
В С++ std::sort
«Бритва Оккама» или «Принцип Калашникова»?
 
Язык Си в примерах/Сортировка
Алгоритмы сортировок
Parallel Sorting - здесь линк
p.s.
:) а нашёлся и BCB - Сортировка ADODataSet1->Sort... как я не подумала сразу про сортировку dataset'a? ... или здесь
===
в мой код выше - до цикла формирования строки-выгрузки:
Код
ADODataSet1->Sort = "CategoryID ASC, ProductName ASC";
Изменено: JeyCi - 12.08.2019 17:10:41
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
на всякий случай у bedvit есть COM - Библиотека COM (OLE Automation). Часть 2 - ArraySort
обсуждение здесь (правда vba)...
ещё не смотрела COM-версию... но про запас  8) ... не уверена, что dll c Visual Studio можно подключить в Borland C++ Builder Project... но надо подумать когда-нибудь на досуге...
спасибо
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
а про строки в С - всё-таки думаю, надо задавать максимально возможный размер фиксированный в char - тоже про запас  8)  ... и не отвлекаться вечным пересчётом sizeof строки... чтобы на скорую руку
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Цитата
JeyCi написал:
на всякий случай у bedvit есть COM -  Библиотека COM (OLE Automation). Часть 2 - ArraySort обсуждение здесь (правда vba)... ещё не смотрела COM-версию... но про запас   ... не уверена, что dll c Visual Studio можно подключить в Borland C++ Builder Project...
Это не секрет.
Вот код. Есть конечно, что оптимизировать еще. Плюс нужно тестирование на разных массивах с разными параметрами для выявления слабых сторон.
Код
#include "stdafx.h"
#include "VBA.h"
#include <atlsafe.h>
#include <vector>
#include <algorithm>
#include <array> 
#include <numeric>
#include <ppl.h>
#include <string>
#include <iostream>
#include "comdef.h"

// CVBA
struct str_index
{
   size_t index;
   BSTR wstr;
   friend bool operator<(const str_index& l, const str_index& r);
   friend bool operator==(const str_index& l, const str_index& r);
   friend bool operator!=(const str_index& l, const str_index& r) { return !(l == r); }
   friend bool operator>(const str_index& l, const str_index& r);
};

bool operator<(const str_index& l, const str_index& r)
{
   if (l.wstr == nullptr) return false;// r.wstr != nullptr;
   if (r.wstr == nullptr) return true;
   return wcscmp(l.wstr, r.wstr) < 0;
}

bool operator==(const str_index& l, const str_index& r)
{
   return l.wstr == r.wstr ||
      l.wstr != nullptr && r.wstr != nullptr && wcscmp(l.wstr, r.wstr) == 0;
}

bool operator>(const str_index& l, const str_index& r)
{
   if (l.wstr == nullptr) return false;
   if (r.wstr == nullptr) return true;
   return wcscmp(l.wstr, r.wstr) > 0;
}

   bool comparestring1(BSTR lhs, BSTR rhs)    {
      if (lhs == NULL) return false;
      if (rhs == NULL) return true;
      return wcscmp(lhs, rhs) < 0;
   }
   bool comparestring2(BSTR lhs, BSTR rhs)    {
      if (lhs == NULL) return false;
      if (rhs == NULL) return true;
      return wcscmp(lhs, rhs) > 0;
   }

   bool comparestring3(BSTR lhs, BSTR rhs) {
      if (lhs == NULL && rhs == NULL) return true;
      if (lhs == NULL || rhs == NULL) return false;
      return wcscmp(lhs, rhs) == 0;
   }


STDMETHODIMP CVBA::ArraySort(VARIANT* array_in_out, VARIANT_BOOL sort_order, LONG key_1, LONG key_2, LONG key_3, LONG sort_orientation, VARIANT_BOOL delete_duplicates, VARIANT_BOOL out_array_index, VARIANT* index_array_out)
{
   if (array_in_out->vt != 8200) { return E_INVALIDARG; }
   if (sort_orientation <0 || sort_orientation > 3) { return E_INVALIDARG; } //границы метода
   if (sort_orientation >1 && out_array_index) { return E_INVALIDARG; } //массив мндексов выводится для первых двух методов сортировки 
   long cDims = array_in_out->parray->cDims;
   if (cDims > 2) { return E_INVALIDARG; }
   long lLbound_0 = array_in_out->parray->rgsabound[0].lLbound;
   long cElements_0 = array_in_out->parray->rgsabound[0].cElements;
   long lLbound_1 = 0;
   long cElements_1 = 0;
   if (cDims == 2) {
      lLbound_1 = array_in_out->parray->rgsabound[1].lLbound;
      cElements_1 = array_in_out->parray->rgsabound[1].cElements;
   }
   if (lLbound_0 < 0 || lLbound_1 < 0) { return E_INVALIDARG; } //если границы массивы ниже 0
   if (cDims == 2 && delete_duplicates) { return E_INVALIDARG; } //&&-и
   if(sort_orientation == 0) {
      if (key_1 > cElements_0 + lLbound_0 || (key_1<lLbound_0 && key_1>-1)) { return E_INVALIDARG; }
      if (key_2 > cElements_0 + lLbound_0 || (key_2<lLbound_0 && key_2>-1)) { return E_INVALIDARG; }
      if (key_3 > cElements_0 + lLbound_0 || (key_3<lLbound_0 && key_3>-1)) { return E_INVALIDARG; }
      if (out_array_index && delete_duplicates) { return E_INVALIDARG; } //&&-и
   }
   else if (sort_orientation == 1) {
      if (key_1 > cElements_1 + lLbound_1 || (key_1<lLbound_1 && key_1>-1)) { return E_INVALIDARG; } 
      if (key_2 > cElements_1 + lLbound_1 || (key_2<lLbound_1 && key_2>-1)) { return E_INVALIDARG; } 
      if (key_3 > cElements_1 + lLbound_1 || (key_3<lLbound_1 && key_3>-1)) { return E_INVALIDARG; } 
      if (out_array_index && delete_duplicates) { return E_INVALIDARG; } //&&-и
   }

   HRESULT hr; 
   BSTR HUGEP *pbstr;//в с-массив
   hr = SafeArrayAccessData(array_in_out->parray, (void HUGEP**)&pbstr); //открываем массив для редактирования
   if (FAILED(hr)) return hr;

   if (cDims == 1 && !out_array_index && !delete_duplicates) {  //если сортировать одномерный массив без вывода индексов и без удаления
      if (!sort_order) concurrency::parallel_buffered_sort(pbstr, pbstr + cElements_0, comparestring1); //0.21 сек
      else concurrency::parallel_buffered_sort(pbstr, pbstr + cElements_0, comparestring2);
      hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
      if (FAILED(hr)) return hr;
   }
   else if (cDims == 1 && !out_array_index){ //если одномерный массив и не выгружаем индексы, просто сортируем, удаляем
      std::vector <BSTR> vBSTR(pbstr, pbstr + cElements_0); //передаем в вектор
      if (!sort_order) concurrency::parallel_buffered_sort(vBSTR.begin(), vBSTR.end(), comparestring1); //0.23(0.30) сек
      else concurrency::parallel_buffered_sort(vBSTR.begin(), vBSTR.end(), comparestring2);
      if (delete_duplicates) { 
         vBSTR.erase(unique(vBSTR.begin(), vBSTR.end(), comparestring3), vBSTR.end());
      } //удаляем дубликаты 
      for (long i = 0; i < vBSTR.size(); i++) pbstr[i] = vBSTR[i]; //записываем обратно в массив 
      hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
      if (FAILED(hr)) return hr;
      if (delete_duplicates) {
         array_in_out->parray->rgsabound[0].cElements = vBSTR.size(); //меняем количество элементов
         hr = SafeArrayRedim(array_in_out->parray, &array_in_out->parray->rgsabound[0]); //удаляем лишние
         if (FAILED(hr)) return hr;
      }
   }
   else if (cDims == 1) { //если одномерный массив и выгружаем индексы
      //Pair parallel_sort New - 0.26 (0.28?) сек
      std::vector<str_index> pairs1(cElements_0);
      for (size_t i = 0; i < cElements_0; ++i) pairs1[i] = str_index{ i+ lLbound_0, pbstr[i] };
      if (!sort_order) {
         concurrency::parallel_buffered_sort(pairs1.begin(), pairs1.end());
      }
      else {
         concurrency::parallel_buffered_sort(pairs1.begin(), pairs1.end(),
            []( str_index & l, str_index & r)
         {return l > r; });
      }
      std::vector<long> out1(pairs1.size());
      std::transform(pairs1.begin(), pairs1.end(), out1.begin(), [](const str_index& i) { return i.index; });
      hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
      if (FAILED(hr)) return hr;
      CComSafeArray <long> outArray1(out1.size(), lLbound_0);
      for (long i = 0; i < out1.size(); i++) outArray1[i+ lLbound_0] = out1[i];
      CComVariant varOut(outArray1);
      varOut.Detach(index_array_out);
   }
   else if (sort_orientation == 2) {//сортировка по всему двухмерному  массиву строки/столбцы
      if (!sort_order) concurrency::parallel_buffered_sort(pbstr, pbstr + cElements_0* cElements_1, comparestring1); //0.21 сек
      else concurrency::parallel_buffered_sort(pbstr, pbstr + cElements_0 * cElements_1, comparestring2);
      hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
      if (FAILED(hr)) return hr;
   } 
   else if (sort_orientation == 3) { ////сортировка по всему двухмерному массиву столбцы/строки
      long cElements_full = cElements_0 * cElements_1;
      std::vector <BSTR> vBSTR(pbstr, pbstr + cElements_full); //передаем в вектор
      if (!sort_order) concurrency::parallel_buffered_sort(vBSTR.begin(), vBSTR.end(), comparestring1); //0.23(0.30) сек
      else concurrency::parallel_buffered_sort(vBSTR.begin(), vBSTR.end(), comparestring2);
      //for (long i = 0; i < vBSTR.size(); i++) pbstr[i] = vBSTR[i]; //записываем обратно в массив 
      long iTmp = 0;
      for (long i = 0; i < cElements_1; i++) {
         for (long j = 0; j < cElements_full; j=j+cElements_1) {
            pbstr[j+i] = vBSTR[iTmp++];//iTmp++;
         }
      }
      hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
      if (FAILED(hr)) return hr;
   } 
   else if ((key_2 == -1 && key_3 == -1)||((key_1 == key_2) && (key_2 == key_3))) { //если одно условие
      if (sort_orientation == 0) { //если сортировка по строкам
         if (key_1 == -1) key_1 = lLbound_0;
         long offset = (key_1 - lLbound_0)*cElements_1; //сдвигаем на заданную размерность 
         std::vector<str_index> pairs2(cElements_1);
         for (size_t i = 0; i < cElements_1; ++i) pairs2[i] = str_index{ i, pbstr[i+ offset] }; //сдвигаем на заданную размерность 
         if (!sort_order) {
            concurrency::parallel_buffered_sort(pairs2.begin(), pairs2.end());
         }
         else {
            concurrency::parallel_buffered_sort(pairs2.begin(), pairs2.end(),
               [](str_index & l, str_index & r)
            {return l > r; });
         }
         std::vector<long> out2(pairs2.size());
         std::transform(pairs2.begin(), pairs2.end(), out2.begin(), [](const str_index& i) { return i.index; });
         if (out_array_index) { //выводим индексы
            CComSafeArray <long> outArray2(out2.size(), lLbound_1);
            for (long i = 0; i < out2.size(); i++) outArray2[i + lLbound_1] = out2[i]+ lLbound_1;
            CComVariant varOut(outArray2);
            varOut.Detach(index_array_out);
         }
         else { //сортируем двухмерный массив поодному из измерений (столбец - сортировка строк)
            long cElements_full2 = cElements_0 * cElements_1;
            std::vector <BSTR> vBSTR(pbstr, pbstr + cElements_full2); //передаем в вектор
            for (long i = 0; i < cElements_0; i++) {
               for (long j = 0; j < cElements_1; j++) {
                  pbstr[j + i * cElements_1] = vBSTR[out2[j] + i * cElements_1];
               }
            }
         }
         hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
         if (FAILED(hr)) return hr;
      }
      else if (sort_orientation == 1) { //если сортировка по столбцам
         if (key_1 == -1) key_1 = lLbound_1;
         long offset = (key_1 - lLbound_1); //сдвигаем на заданную размерность 
         std::vector<str_index> pairs2(cElements_0);
         for (size_t i = 0; i < cElements_0; ++i) pairs2[i] = str_index{ i, pbstr[i*cElements_1 + offset] }; //сдвигаем на заданную размерность 
         if (!sort_order) {
            concurrency::parallel_buffered_sort(pairs2.begin(), pairs2.end());
         }
         else {
            concurrency::parallel_buffered_sort(pairs2.begin(), pairs2.end(),
               [](str_index & l, str_index & r)
            {return l > r; });
         }
         std::vector<long> out2(pairs2.size());
         std::transform(pairs2.begin(), pairs2.end(), out2.begin(), [](const str_index& i) { return i.index; });
         if (out_array_index) { //выводим индексы
            CComSafeArray <long> outArray2(out2.size(), lLbound_0);
            for (long i = 0; i < out2.size(); i++) outArray2[i + lLbound_0] = out2[i] + lLbound_0;
            CComVariant varOut(outArray2);
            varOut.Detach(index_array_out);
         }
         else { //сортируем двухмерный массив поодному из измерений (столбец - сортировка строк)
            long cElements_full2 = cElements_0 * cElements_1;
            std::vector <BSTR> vBSTR(pbstr, pbstr + cElements_full2); //передаем в вектор
            for (long i = 0; i < cElements_1; i++) {
               for (long j = 0; j < cElements_0; j++) {
                  pbstr[i + j * cElements_1] = vBSTR[out2[j] * cElements_1 + i];
               }
            }
         }
         hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
         if (FAILED(hr)) return hr;
      }
         
   }
   ///////////////////////////////////////////////////////////////////////////////////////////////
   else if ((key_2 > -1 || key_3 > -1)) { //если больше условий 
      if (sort_orientation == 0) { //если сортировка по строкам
         if (key_1 == -1) key_1 = lLbound_0;
         long offset1 = (key_1 - lLbound_0)*cElements_1; //сдвигаем на заданную размерность 
         long offset2 = (key_2 - lLbound_0)*cElements_1; //сдвигаем на заданную размерность 
         long offset3 = (key_3 - lLbound_0)*cElements_1; //сдвигаем на заданную размерность 

         std::vector<str_index> pairs2(cElements_1);
         for (size_t i = 0; i < cElements_1; ++i) {
            CComBSTR CComBSTRtmp(pbstr[i + offset1]);
            CComBSTRtmp.AppendBSTR(pbstr[i + offset2]);
            CComBSTRtmp.AppendBSTR(pbstr[i + offset3]);
            pairs2[i] = str_index{ i, CComBSTRtmp.Detach()};
         }//сдвигаем на заданную размерность 
         if (!sort_order) {
            concurrency::parallel_buffered_sort(pairs2.begin(), pairs2.end());
         }
         else {
            concurrency::parallel_buffered_sort(pairs2.begin(), pairs2.end(),
               [](str_index & l, str_index & r)
            {return l > r; });
         }
         std::vector<long> out2(pairs2.size());
         std::transform(pairs2.begin(), pairs2.end(), out2.begin(), [](const str_index& i) { return i.index; });
         if (out_array_index) { //выводим индексы
            CComSafeArray <long> outArray2(out2.size(), lLbound_1);
            for (long i = 0; i < out2.size(); i++) outArray2[i + lLbound_1] = out2[i] + lLbound_1;
            CComVariant varOut(outArray2);
            varOut.Detach(index_array_out);
         }
         else { //сортируем двухмерный массив поодному из измерений (столбец - сортировка строк)
            long cElements_full2 = cElements_0 * cElements_1;
            std::vector <BSTR> vBSTR(pbstr, pbstr + cElements_full2); //передаем в вектор
            for (long i = 0; i < cElements_0; i++) {
               for (long j = 0; j < cElements_1; j++) {
                  pbstr[j + i * cElements_1] = vBSTR[out2[j] + i * cElements_1];
               }
            }
         }
         hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
         if (FAILED(hr)) return hr;
      }
      else if (sort_orientation == 1) { //если сортировка по столбцам
         if (key_1 == -1) key_1 = lLbound_1;
         long offset1 = (key_1 - lLbound_1); //сдвигаем на заданную размерность 
         long offset2 = (key_2 - lLbound_1); //сдвигаем на заданную размерность 
         long offset3 = (key_3 - lLbound_1); //сдвигаем на заданную размерность 
        //long offset = (key_1 - lLbound_1); //сдвигаем на заданную размерность 
         std::vector<str_index> pairs2(cElements_0);
         for (size_t i = 0; i < cElements_0; ++i) {
            CComBSTR CComBSTRtmp(pbstr[i*cElements_1 + offset1]);
            CComBSTRtmp.AppendBSTR(pbstr[i*cElements_1 + offset2]);
            CComBSTRtmp.AppendBSTR(pbstr[i*cElements_1 + offset3]);
            pairs2[i] = str_index{ i, CComBSTRtmp.Detach() };
         }//сдвигаем на заданную размерность 
         if (!sort_order) {
            concurrency::parallel_buffered_sort(pairs2.begin(), pairs2.end());
         }
         else {
            concurrency::parallel_buffered_sort(pairs2.begin(), pairs2.end(),
               [](str_index & l, str_index & r)
            {return l > r; });
         }
         std::vector<long> out2(pairs2.size());
         std::transform(pairs2.begin(), pairs2.end(), out2.begin(), [](const str_index& i) { return i.index; });
         if (out_array_index) { //выводим индексы
            CComSafeArray <long> outArray2(out2.size(), lLbound_0);
            for (long i = 0; i < out2.size(); i++) outArray2[i + lLbound_0] = out2[i] + lLbound_0;
            CComVariant varOut(outArray2);
            varOut.Detach(index_array_out);
         }
         else { //сортируем двухмерный массив поодному из измерений (столбец - сортировка строк)
            long cElements_full2 = cElements_0 * cElements_1;
            std::vector <BSTR> vBSTR(pbstr, pbstr + cElements_full2); //передаем в вектор
            for (long i = 0; i < cElements_1; i++) {
               for (long j = 0; j < cElements_0; j++) {
                  pbstr[i + j * cElements_1] = vBSTR[out2[j] * cElements_1 + i];
               }
            }
         }
         hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
         if (FAILED(hr)) return hr;
      }
   }
   else {
   hr = SafeArrayUnaccessData(array_in_out->parray); //закрываем массив
   if (FAILED(hr)) return hr;
   }

   return S_OK;
}

Цитата
JeyCi написал:
про строки в С - всё-таки думаю, надо задавать максимально возможный размер фиксированный в char
Это как? сразу занимать всю оперативку? )
Изменено: bedvit - 12.08.2019 17:48:42
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
bedvit написал: Это как? сразу занимать всю оперативку? )
имела ввиду max под реалии данных - если знаешь, что больше 40 символов например не будет в строке...
===
:) значит всё-таки структура! размера и массива
Код
struct str_index
{
   size_t index;
   BSTR wstr;

   friend bool operator<(const str_index& l, const str_index& r);
.....
};

спасибо за код!! - теперь есть хоть пример для изучения по BSTR...
только можно вопрос на уточнение - что передаёте в дружественные функции операторы... видимо какой-то правый и левый символ... но не вижу по коду строку, откуда передаёте в эти функции?.. или просто смотреть там где просто эти операторы (>,<,==,!=)?.. не совсем понятно, как код определяет, что это не просто его операторы, а ваши функции?.. или он не думает о своих таких операторах, а просто использует ваши автоматически... а r и l - это наверно, правый и левый симол от этого оператора (любого из них)??.. правильно ли понимаю?..
thanks a lot за публикацию кода и ваш труд в написании этого кода...%
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
JeyCi, здесь реализована перегрузка стандартных операторов. Больше, меньше, равно и не равно.
Цитата
JeyCi написал:
не совсем понятно, как код определяет, что это не просто его операторы, а ваши функции?
Компилятор различает разные значения оператора, проверяя типы его операндов.
Перегрузка операторов в C++
«Бритва Оккама» или «Принцип Калашникова»?
Страницы: Пред. 1 2 3 4 5 6 7 След.
Наверх