| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Struct, array |
| Автор: deBuger 14.11.2002, 23:15 |
| Ламерский вопрос. Есть рабочий код: struct settings { char *element; }; int main(int argc, char ** argv) { settings *ss; char *a; char *b; a = "La-La-La\n"; b = "element"; ss -> element = a; printf(ss->element); return 0; } Хочется присваивать значение для члена (MEMBER) структуры не по конкретному названию (как ss -> element), а через переменную, ну типа ss -> b, а b содержит соответственно имя название "element", ну как в примере. Вот такая дурь. |
| Автор: neutrino 14.11.2002, 23:27 | ||
Не понял. Как это? Если у тебя определена struct{char* element}, то нельзя обращаться как ss->а или ss->b. |
| Автор: deBuger 14.11.2002, 23:35 |
| Неверное не так выразился. Можно ли вместо явного указания члена структуры, каким либо образом, указать , что его имя надо взять из переменной. |
| Автор: AntonSaburov 15.11.2002, 00:39 |
| Просто так в лоб - не получится. Можно переопределить оператор и его использовать, но это как-то странно выглядит. Или тогда уже просто Map использовать. |
| Автор: Fantasist 15.11.2002, 12:36 | ||
В общем случае это так:
|
| Автор: deBuger 15.11.2002, 15:32 |
| Продолжаем разговор. Может я че-то недогоняю, или мысли не могу выразить. Но вот не в тему код на РНР (синтаксис как в С): $a = "I'am A"; $b= "a"; printf($$b); который выводит I'am A а как такое-же сделать на С. |
| Автор: AntonSaburov 16.11.2002, 00:26 |
| Что-то я не понял, в чем суть. Ну вот так вот можно. И будет работать на ура #include <stdio.h> int main() { char* a = "I am Bill"; char* b = a; printf("%s\n\r",a); printf("%s\n\r",b); return 0; } |
| Автор: man2002ua 16.11.2002, 00:54 |
| вопрос вовсе не ламерский... (просто непонятно ДЛЯ ЧЕГО ЭТО НАДО?) Естественный выход (если ты хочешь сделать это как в PHP-примере) - это классы. Классы в к-х переопределены все операции (=,-,+,... и т.д.) и для каждой переменной - задается имя и значение. Что-то вроде Variant в D5. Но это хороший кусок программного кода, чтобы делать нахрапом. |
| Автор: Fantasist 16.11.2002, 07:35 | ||
Ага не ламерский, а просто не понятный. Но до меня кажись дошло в чем суть (благодаря примеру на PHP) - он хочет обращаться к переменной по ее имени. |
| Автор: man2002ua 16.11.2002, 18:06 |
| никогда не использовал <map> и не собираюсь впредь. Может я извращенец, но для меня легче что-то подобное написать самому. |
| Автор: HexoGenus 17.11.2002, 02:24 | ||||||
Хммммм.... задачка приобрела зловещий смысл В свое время я пытался создать искусственный интелект используя Basic (вот умора) потом то же самое на паскале (вот долбежу то...) Вобщем с треском провалилась тогда моя затея (может лет через 5 снова попробую Вопрос вас удивил Все очень даже просто Представте у вас есть процесс выполняющийся на данной машине, или на сервере, вас интересует возможность не прерывая его в любой момент отследить значение любой его переменной, но количество этих самых переменных в вашем проекте растет не по часам а по минутам... А вы очень любопытные ... хочется то значение одной переменной узнать то другой... (Вобщем свитч на 400 переменных вам писать совсем не хочется а какие переменные вас заинтересуют через три минуты вы сами не знаете) Навел на мысль как это просто было бы реализовать если была бы возможность узнать значение переменной по имени? У вас есть функция которую вы можете вызывать из другого процесса и передавать ей имя переменной а эта программулька тут же вернет значение... И это только один из вариантов применения этой функции... Кстати говоря вопрос который очень похож на этот очень часто поднимается в разных форумах: "Как выполнить функцию по ее имени?" Ответы которые я встречал: 1. Невозможно так как после компиляции к функциям идет обращение по их адресам а не по именам... 2. Можно замутить огромный свитч который будет по имени возвращать функцию... 3. Можно все функции научить проверять имя по которому к ним обращаются и если оно не соответствует их собственному передавать управление по цепочке следующей ... (что то типа: я не Вася а ты 4. Способ который лежит в часто задаваемых вопросах на этом сайте : В Builder C++ задача получения адреса функции по ее символьному имени решается не просто, а очень просто. Правда с одним ограничением: эта функция должна быть опубликованным методом класса.
естественно, возможен обратный процесс получения символьного имени по адресу. Например, определим как называется функция, которая в данный момет является обработчиком события Button->OnClick;
А теперь сравните в первом случае сказали что это невозможно а в четвертом сказали что это очень просто.... Так может и к переменным по именам обращаться можно очень даже просто Вобщем если кто найдет способ то я с удовольствием занесу его в свою копилочку на будущее |
| Автор: Fantasist 17.11.2002, 05:47 | ||||||||
Что-о-о?? Но посуществу, если ты хочешь стать проффессиональным программистом на С++, то с STL придется разобраться.
Для этого существуют отладчики и отладачная информация. Но это по большому счету роли не играет - обычно использования глобальных переменных не велико, а локальные переменные существуют то недолгое время, пока не кончится соответсвующий контекст выполнения. И в разных контекстах я могу использовать одно и то же имя.
Это уже использование RTTI(Run-Time Type Information) в Builder. Реально такое очень редко применяется. Это слишком дорого и это просто не правильно. Так никто не делает.
Можно так же просто. Делаешь published property и сможешь обращаться к нему по имени. Но все это ерунда. |
| Автор: HexoGenus 17.11.2002, 06:25 | ||||||
Попробуй при помощи отладчика отследи как выполняется приложение на машине в другой части города А насчет малого числа переменных... как бы не так на каждой форме их может быть тьма... и на время существования формы они очень даже существуют
Да просто задача редкая мало кто пишет не просто алгоритмы а алгоритмы-интерпритаторы входящих команд, что ты предложишь самому все написать?
Хмммммм..... Разве к свойствам можно обращаться по имени в ходе выполнения программы |
| Автор: Fantasist 17.11.2002, 10:14 | ||||||||||||
Вполне. Если есть соответствующий доступ по сети. Но это очень редкий случай.
Это совсем, НЕ глобальные переменные. Сама форма может быть глобальной переменной, но я могу написать отдельный класс формы, и использовать там те же имена для переменных. Какое тогда имя выбирать? Внутри функций я тоже могу те же имена использовать.
Ага. Что-то за супер задача у тебя? Тогда вот что - пиши лучше сразу новый язык и интерпритатор/компилятор к нему. Будет он делать все что ты захочешь. А что такое "алгоритмы-интерпритаторы входящих команд" непонял.
Примерно так же как методов. Смотри модуль Classes - TWriter::WriteProperties. Eще раз повторю, если уж захотел извращений, то сделай их по нормальному. примерно так:
Потом и добавляй где-нибудь:
|
| Автор: man2002ua 18.11.2002, 20:47 |
| 2 Fantasist - ВОТ ЭТО МОЁ - смотри как это сделать на BCB5... На С++ можно тоже запросто (Delphi труднее). Оценивай... TStringList *VALS; typedef struct vINT{ int vVAL; }vINT, *LPvINT; int& V(char *s) { if(!VALS) VALS = new TStringList; int idx = VALS->IndexOf(s); if(idx == -1) idx = VALS->AddObject(s,(TObject*)(new LPvINT)); return LPvINT(VALS->Objects[idx])->vVAL; } void __fastcall TForm1::Button1Click(TObject *Sender) { V("hello") = 5; V("gotta") = 10; V("all") = V("hello") + V("gotta"); Caption = IntToStr(V("all")); } повторяю тебя - "лучше использовать свои мозги, чем чужой бредовый код" |
| Автор: HexoGenus 18.11.2002, 23:32 | ||||||
Алгоритмы-интерпритаторы входящих команд Например программка администрирования другого компа работающая по сети в режиме приема команд с удаленной консоли... >>Попробуй при помощи отладчика отследи как выполняется приложение на ?>>машине в другой части города
Еще раз убеждаюсь что многие вопросы рождаются от недостатка академических знаний... ну не пользуюсь я отладчиком... знаю что полезная штука... но обычно встраиваю свои следящие функции которые мне текущие значения переменных и различные состояния программы на разных этапах ее выполнения сообщают... Я даже и не подозревал что можно программу запустить на другом компьютере и пользуясь отладчиком прямо со своего компьютера отследить ход ее выполнения ...
:-) Да кто говорит обо всех переменных... Мы тут немножко на разных языках говорим ... Ты пытаешься мне объяснить что есть море переменных имя которых вообще не имеет значения так как само существование этих переменных может быть мгновенным ... кто же спорит ... А я хотел бы больше узнать о тех переменных к которым можно было бы обратится по их относительному имени например Form1->intMyDay (Насколько я помню в Билдере можно кое-что в ходе выполнения программы заставить идентифицировать себя <например можно у Edit1 выпытать что он помещен на Form32>... т.е. сообщить свое имя... может и с переменными которые регистрируются в классе компонента тоже так Почему мне интересен вопрос о публичных свойствах компонентов... Хотелось бы иметь возможность получить список имен публичных свойств компонентов в процессе выполнения программы, тогда можно было бы написать что то вроде собственного инспектора объектов который будет обновляться по таймеру в ходе выполнения программы, и что бы этому инспектору достаточно было сообщить имя отслеживаемого компонента а он все остальное уже выискивал бы сам... Большое спасибо за код который ты привел... возьму кружку кофе побольше и сяду сегодня разбираться.... |
| Автор: man2002ua 18.11.2002, 23:55 |
| для гурманов, к-е будут использовать подобный код далее - с Variant работать прикольнее (использовать все возможности C++ и BCB по максимуму): TStringList *VALS; typedef struct vINT{ Variant vVAL; }vINT, *LPvINT; Variant& V(char *s) { if(!VALS) VALS = new TStringList; int idx = VALS->IndexOf(s); if(idx == -1) idx = VALS->AddObject(s,(TObject*)(new LPvINT)); return LPvINT(VALS->Objects[idx])->vVAL; } void __fastcall TForm1::Button1Click(TObject *Sender) { V("hello") = "XpeH "; V("gotta") = "BaM"; V("all") = V("hello") + V("gotta"); Caption = V("all"); } |
| Автор: Fantasist 19.11.2002, 05:22 | ||||||||||||||
Ну, сам попросил.
Неправда. Вместо std::map ты использовал VCL-ный TStringList. Простенькая процедурка, которую ты написал не тянет на написание собственного контейнера. Довольно забавно, что ты утверждаешь, что STL - это "чужой глючный код", а VCL - это "свои мозги".
Неправильно - в стандартной библиотеке C++ нет TStringList. А значит так можно отлько в Builder'e.
Зачем это извращение для int? Для int можно вообще написать:
Хотя теоретически это непереносимо - размер указателя и размер int на некоторых платформах различаются. Хотя не слышал о таком, чтобы указателя не хватило для хранения int. Если для чего-то по более чем int, то можно было так:
Далее - код абсолютно не инкапсулирован. Непонятно, когда надо удалять VALS, кто это должен делать. Переменную VALS нетяжело случайно запортить, так как она открыта всем. Использование глобальных переменных и функций в таком деле просто не допустимо. Если ты попробуешь написать нормальную программу при таком подходе(как минимум с десяток отдельных модулей и 10000 строк в сумме - считается небольшой проект), быстро поймешь о чем я говорю. ООП как раз придумали, чтобы так не делать. Код очень не эффективен. Ты ведь даже не потрудился создать список отсортированным, для ускорения поиска. С типизацией плохо. Если я захочу сделать такую вещь для разных типов, придется создавать несколько переменных и функций. Если сделать Variant станет не намного лучше. Операции с variant достадочно долгие и занимает она много места. Что за данные хранятся там по коду сказать тяжело - читабельность падает, использование усложняется. Уж не говоря о том, что в С++ нету variant - это извращения Borland'a. Как бы это могло выглядеть:
Хотя, конечно, по функциональности и эффективности до std::map все-равно далеко. Не говоря уж о не переносимости. Так что лучше использовать свои мозги. И если их использовать, то они тебе подскажут, что труд умнейших людей в течении нескольких лет, и признание и использование этого труда во всем мире, стоят очень не мало. |
| Автор: Fantasist 19.11.2002, 05:38 | ||
То есть ты хочешь сделать удаленный инспектор объектов времени исполнения? Хм... Идея интересная. |
| Автор: man2002ua 19.11.2002, 18:56 |
Речь шла не об удобстве, скорости, оптимальности, а о возможности это сделать...Причем TStringList я для себя уже давно сделал на C++ (вот тут и сортировка и оптимизация и отдельная библиотека). Этот же код не пригодится (пока), чтобы его оптимизировать или формировать класс для него. |
| Автор: Vyacheslav 19.11.2002, 22:45 | ||||
Без проблем. Правда могут быть ошибки. Пишу влет, без проверки Итак получение списка опубликованных свойств из серии " Не просто - а очень просто". Неужели я это забыл вставить в FAQ?
Да , небольшое замечание. Это работает в 5-ом Builder , в 6--ом линкер отругается на GetPropList (баг). Его можно обойти, если вызов GetPropList обернуть в паскалевскую функцию |
| Автор: dim 19.11.2002, 23:17 | ||
2 man2002ua
Напиши пару более менее серьезных проектов, требующих хорошей устойчивости и сопроводимости и ты поймешь о чем говорил Fantasist. |
| Автор: man2002ua 19.11.2002, 23:23 |
| dim, при написании vxd устойчивость и надежность прежде всего... Большие проекты я тоже писал (правда на С и др.языке, а не VС++). Что я должен понять? |
| Автор: Vyacheslav 19.11.2002, 23:27 |
| Ай-яй-яй. Кое-кто FAQ читать не умеет. А я уж испугался. http://www.forum.vingrad.ru/cgi-bin/newforum/ikonboard.cgi?act=ST;f=37;t=1261 |
| Автор: Fantasist 20.11.2002, 01:38 | ||||
Так я же говорю, открываешь исходник TWriter.WriteComponentProperties, там-то должно быть без ошибок. Или исходники VCL на паскале и для Builder'a?
Ага, а я думал у нас это только в FAQ по Делфи есть. А оно интересно там есть? Кстати, RTTI не генерируется по умолчанию для классов наследуемых от TObject. Для не наследуемых... Да а вот и нтересно, как Borland совмещает свою RTTI с С++-шной? |
| Автор: Fantasist 20.11.2002, 02:11 | ||||
Нет. Во-первых, речь шла о том, что ты все напишишь сам целиком - этого мы не увидели. Во-вторых, речь шла о том, что ты сам можешь сделать это лучше, чем стандартная библиотека - этого тоже не было. А сделать-то, конечно, возможно, как-то глупо об этом было бы спорить после того,как мы имеем столько готовых библиотек. Но сделать еще не достадочно, важно как сделать. Чтобы это можно было использовать.
Давай покажи. Ты все-таки считаешь, что сумел сделать это лучше, чем люди которые этим занимаются много лет? Уверен, что нет. |
| Автор: man2002ua 20.11.2002, 02:23 |
| может я и погарячился, сказав, что чужой код глючный (то что мой лучше - я точно не говорил!), имел ввиду, что в своем коде легче найти ошибку, чем в чужом. |