URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 6983
[ Назад ]

Исходное сообщение
"Создание динамичных переменных в C++"

Отправлено siegerstein , 28-Ноя-07 17:38 
Привет всем!

Возникла проблема создания динамичных переменных в C++.

К примеру, имееться переменная "value" типа char*, и имееться переменная "i" типа int.
Значение "i" не постоянное, и может меняться.
Нужно в цикле присоеденять значение "i" и названию переменной "value"

То есть должно выйти: value1, value2, value3...

for ( int i = 0; i < somevalue; i++ ) {
// Должно выйти соединение названий переменных

типа value + i;
или как на Perl $value$i

}

Зарание списибо за ответ.



Содержание

Сообщения в этом обсуждении
"Создание динамичных переменных в C++"
Отправлено Michelnok , 28-Ноя-07 18:06 
>Возникла проблема создания динамичных переменных в C++.

C++ - компилируемый язык, а не интерпретируемый.


"Создание динамичных переменных в C++"
Отправлено siegerstein , 28-Ноя-07 18:33 
>>Возникла проблема создания динамичных переменных в C++.
>
>C++ - компилируемый язык, а не интерпретируемый.

Но решить эту проблему все же как-то возможно ?!?


"Создание динамичных переменных в C++"
Отправлено Michelnok , 28-Ноя-07 20:19 
>Но решить эту проблему все же как-то возможно ?!?

Конечно. Используй массив char *values[N].


"Создание динамичных переменных в C++"
Отправлено elvenic , 28-Ноя-07 19:10 
>Привет всем!
>
>Возникла проблема создания динамичных переменных в C++.

Это не совсем то что понимается под "динамичными переменными".

Вам просто нужно превратить число в строку и приписать к другой строке. Если это C++, то проще всего где-то так:


for ( int i = 0; i < somevalue; i++ ) {

    std::stringstream strm;
    strm << value << i;
    std::string newValue = strm.str();

    // do something with newValue
    // ...

}

То есть, создаете обьект класса stringstream который занимается форматированием строк (value может быть или char *, или std::string), а потом из этого обьекта получаете уже результирующую строку newValue.



"Создание динамичных переменных в C++"
Отправлено siegerstein , 29-Ноя-07 07:18 
>[оверквотинг удален]
>    std::string newValue = strm.str();
>
>    // do something with newValue
>    // ...
>
>}
>
>То есть, создаете обьект класса stringstream который занимается форматированием строк (value может
>быть или char *, или std::string), а потом из этого обьекта
>получаете уже результирующую строку newValue.

Задача стоит не в конкатенации переменных а в создании переменной из имен, то есть есть к примеру переменная value, нужно поочередно прилиплять к примеру числа от 1..10 так, чтобы создавались переменные value1, value2, value3 и т.д.

И чтобы к этой переменной можно было нормально обратиться как к другим переменным.

Вот про что я говорил.

А этот пример по всей видимости соединяет значение одной переменной с другой.
Но реальной переменной он не создает.

Он создает к примеру переменную newValue которая имеет значение value + i, а нужно было создать переменную value + i.

Смотрел как это реализовать, можно TCL + C++ или писать на Java.

Есть идеи как реализовать штатными средствами C++?

Масивы не подходять.


"Создание динамичных переменных в C++"
Отправлено elvenic , 29-Ноя-07 13:44 
>[оверквотинг удален]
>
>Но реальной переменной он не создает.
>
>Он создает к примеру переменную newValue которая имеет значение value + i,
>а нужно было создать переменную value + i.
>
>Смотрел как это реализовать, можно TCL + C++ или писать на Java.
>
>
>Есть идеи как реализовать штатными средствами C++?

Да, извините, теперь я понял вопрос.

Нет, штатными средствами C++ - нельзя. Дело в том, что на этапе выполнения программы откомпилированной из исходного текста C++, информация об именах переменных уже утеряна. Eсли у вас есть набор простых переменных

    int value1;
    ...
    int value10;

для программы их имена ничего не значат, программа манипулирует просто их адресами в памяти. Даже если вы думаете об использовании RTTI - в C++ он очень ограничен.

Java, будучи по сути "вещь в себе", тянет за собой намного больше информации чем C++ на этап выполнения - что и позволяет использовать reflection чтобы получить доступ к именам переменных (да и то, я не уверен что reflection позволяет обратиться к локальным переменным).

TCL + C++ - наверно вы имеете в виду использование переменных TCL, а не C++, и доступаться к ним путем вызова какой-то функции среды TCL?

Тогда эквивалентное по эффективности средство - std::map с ключами типа "value1" ... "valueN":

    std::map myMap;

    for ( int i = 0; i < somevalue; i++ ) {

        std::stringstream strm;

        // Create a key for the map.
        strm << "value" << i;
        std::string key = strm.str();

        // Clear the stingstream.
        strm.rdbuf()->str("");

        // Create value.
        strm << "a" << i;
        std::string val = strm.str();

        // Create a value in the map.
        myMap[key] = val;

    }

Теперь доступ к таким "переменным" - myMap["value1"], myMap["value2"] и т. д.



"Создание динамичных переменных в C++"
Отправлено siegerstein , 29-Ноя-07 16:33 
>[оверквотинг удален]
>        std::string val = strm.str();
>
>
>        // Create a value
>in the map.
>        myMap[key] = val;
>
>    }
>
>Теперь доступ к таким "переменным" - myMap["value1"], myMap["value2"] и т. д.

Ура! Работает! Спасибо elvenic!

Вот рабочий пример:

#include <iostream>
#include <sstream>
#include <map>

std::map <std::string, std::string> myMap;

int main() {

    for ( int i = 0; i < 10; i++ ) {

         std::stringstream strm;

        // Create a key for the map.
         strm << "value" << i;
         std::string key = strm.str();

        // Clear the stingstream.
         strm.rdbuf()->str("");

        // Create value.
         strm << "a" << i;
         std::string val = strm.str();

        // Create a value in the map.
         myMap[key] = val;

     }
    
     std::cout << myMap["value1"] << std::endl;
     std::cout << myMap["value2"] << std::endl;
     std::cout << myMap["value3"] << std::endl;

     return 0;
}


"Создание динамичных переменных в C++"
Отправлено Alu , 29-Ноя-07 06:26 
//Вариант без STL:

for(int i = 0; i < somevalue; i++)
{
    char TempBuff[TEMP_BUFF_SOME_LENGTH];
    snprintf(TempBuff, TEMP_BUFF_SOME_LENGTH, "%s %d\0", value, i);
}


"Создание динамичных переменных в C++"
Отправлено siegerstein , 29-Ноя-07 07:21 
>//Вариант без STL:
>
>for(int i = 0; i < somevalue; i++)
>{
>    char TempBuff[TEMP_BUFF_SOME_LENGTH];
>    snprintf(TempBuff, TEMP_BUFF_SOME_LENGTH, "%s %d\0", value, i);
>}

То же случай вроде. В C не очень...


"Создание динамичных переменных в C++"
Отправлено phpcoder , 29-Ноя-07 10:34 
Ну и в чем у вас затруднение? Как число в строку превратить? Вариантов, как минимум, три (boost::lexical_cast, s[n]printf, и что-то там с потоками). Ищите в гугле.



"Создание динамичных переменных в C++"
Отправлено DeadMustdie , 29-Ноя-07 11:18 
Состав переменных программы на языке C++ фиксируется на этапе компиляции и по определению не может зависеть от (вообще говоря, изменяемого в процессе исполнения программы) количества итераций цикла. Некий синтаксический сахар подобного рода можно изготовить с помощью макросов, но это - убогий костыль, не более.

Таким образом, в поставленной форме проблема не решается. Основная причина - на уровне конструкций языка C++ нет средств по манипулированию конструкциями языка. Фокус тут не в интерпретируемости/компилируемости, а в отсутствии встроенного в runtime-среду кодового генератора. Скажем, Java - среда компилируемая, но там есть Reflection API.

Исходная проблема, честно говоря, непонятна. Для манипулирования *данными* в C++ есть все необходимое плюс еще чуть-чуть, а потребность "на лету" управлять составом переменных сродни соревнованиям по бегу в мешках.


"Создание динамичных переменных в C++"
Отправлено f00l , 30-Ноя-07 07:38 

Зачем такие сложности.

Создай двух мерный массив.
char  ** value;
int i;
value = new ( char *)[i];

Вот у тебя массив динамических переменных.


"Создание динамичных переменных в C++"
Отправлено siegerstein , 30-Ноя-07 17:36 
>
>Зачем такие сложности.
>
> Создай двух мерный массив.
> char  ** value;
> int i;
> value = new ( char *)[i];
>
> Вот у тебя массив динамических переменных.

Спасибо, пробывал работает.
Но вот в Qt4 не работает.

Сильно спростил, чтобы показать суть:

QLCDNumber **lcd = new QLCDNumber *[10];
...
for ( int i = 0; i < 10; ++i ) {
...
   lcd[i] -> setNumDigits ( 3 );
...
}

Вылетает в кору (Ошибка сегментирования)

Как только я хочу применить к объекту какой-то метод ( в данном случае setNumDigits ) - приложение падает даже не запустившись.

Не знаете почему?


"Создание динамичных переменных в C++"
Отправлено siegerstein , 30-Ноя-07 17:44 
>[оверквотинг удален]
>   lcd[i] -> setNumDigits ( 3 );
>...
>}
>
>Вылетает в кору (Ошибка сегментирования)
>
>Как только я хочу применить к объекту какой-то метод ( в данном
>случае setNumDigits ) - приложение падает даже не запустившись.
>
>Не знаете почему?

Вот это глюк. На сайте показывает lcd -> setNumDigits ( 3 ); а должно быть lcd <квадратная скобка> i <квадратная скобка> -> setNumDigits ( 3 );
На почте и при ответе все нормально...


"Создание динамичных переменных в C++"
Отправлено Michelnok , 30-Ноя-07 17:47 
>[оверквотинг удален]
>for ( int i = 0; i < 10; ++i ) {
>
>...
>   lcd[i] -> setNumDigits ( 3 );
>...
>}
>
>Вылетает в кору (Ошибка сегментирования)
>
>Не знаете почему?

Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала надо сделать что-то типа
lcd[i] = new QLCDNumber();
а потом уже пытаться обращаться к lcd[i]->anything


"Создание динамичных переменных в C++"
Отправлено Michelnok , 30-Ноя-07 17:48 
>Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала
>надо сделать что-то типа
>lcd[i] = new QLCDNumber();
>а потом уже пытаться обращаться к lcd[i]->anything

Что-то покоцался текст в предыдущем посте.


"Создание динамичных переменных в C++"
Отправлено Michelnok , 30-Ноя-07 17:52 

>>Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала
>>надо сделать что-то типа
>>lcd[i] = new QLCDNumber();
>>а потом уже пытаться обращаться к lcd[i]->anything
>
>Что-то покоцался текст в предыдущем посте.

Какому [censored] пришло в голову цеплять рюшечки с курсивом на форуме технарей?


"Создание динамичных переменных в C++"
Отправлено siegerstein , 30-Ноя-07 17:55 
>>Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала
>>надо сделать что-то типа
>>lcd[i] = new QLCDNumber();
>>а потом уже пытаться обращаться к lcd[i]->anything
>
>Что-то покоцался текст в предыдущем посте.

Я про это и говорю... У меня то же ( см. выше )


"Создание динамичных переменных в C++"
Отправлено siegerstein , 30-Ноя-07 17:53 
>[оверквотинг удален]
>>}
>>
>>Вылетает в кору (Ошибка сегментирования)
>>
>>Не знаете почему?
>
>Знаем конечно. После new QLCDNumber *[10] каждый lcd[i] содержит мусор. Тебе сначала
>надо сделать что-то типа
>lcd[i] = new QLCDNumber();
>а потом уже пытаться обращаться к lcd[i]->anything

Спасибо добрый человек, работает!

Извените за ламерские вопросы, просто начинающий :)


"Создание динамичных переменных в C++"
Отправлено siegerstein , 30-Ноя-07 18:21 
И так, небольшой итог как можно решить задачу:

QLCDNumber **lcd = new QLCDNumber *[15];
lcd [ i ] = new QLCDNumber;
lcd [ i ] -> setNumDigits ( 3 );
lcd [ i ] -> display ( L );

Это пример для Qt. Конечно вместо QLCDNumber ставим нужный тип данных.
Шаблон понятный.

Темы закрыта.
БОЛЬШОЕ спасибо всем кто помогал!