Форум программистов, компьютерный форум CyberForum.ru

Как обычную переменную на время сделать константой? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.67
BigLow
55 / 55 / 2
Регистрация: 07.07.2013
Сообщений: 345
14.07.2013, 10:32     Как обычную переменную на время сделать константой? #1
Как обычную переменную на время сделать константой?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
14.07.2013, 13:54     Как обычную переменную на время сделать константой? #21
C++
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
//вот так тоже забавно:
#include <iostream>
 using namespace std;
//если 0 по умолчанию не устраивает
 int foo2(int ai){
int first_inisializer = -1;//не обязательно -1, можно всё что угодно, NAN например, лишь бы a 
//не могла принимать это значение естественным путём))
static int prevA;//инициализируется нулём до первого вызова, но тепрь это неважно
static int count_of_callings;//то же с нуля 
if( count_of_callings==0 ) prevA = first_inisializer;
if( prevA ==  first_inisializer ) prevA = ai;
const int a = prevA;// :)
//далее работаем с переменной a 
 
 
 
if(count_of_callings<100)//защита от переполнения
count_of_callings++;//делаем невозможной переустановку в first_inisializer
else count_of_callings = 1;
return a;
 }
 
int main()
{  
for(int i=6; i<9; ++i) cout<<foo2(i)<<" ";//6 6 6 то есть не меняется значение в функции
    cout<<endl;  
    system("pause");
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
14.07.2013, 17:53     Как обычную переменную на время сделать константой? #22
Уважаемый IGPIGP!
А можно ли решить задачу сохранения значения переменной с использование только одной функции main ()?
Т.е. без применения функции int foo2()?
Как я уже писал, у меня только одна функция и применить две я не могу по условиям использования библиотеки.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
14.07.2013, 18:19     Как обычную переменную на время сделать константой? #23
Цитата Сообщение от kotgav Посмотреть сообщение
у меня только одна функция
//далее работаем с переменной a
То есть, в Вашей же функции и сделайте. Имя подберите на свой вкус, добавьте аргументов по усмотрению, измените тип и возвращаемое значение (в foo2 оно для демонстрации равно a)). Волшебное число 100 можно изменить на INT_MAX или на двойку ( вряд ли найдёте платформу, где int меньше). То есть отнеситесь творчески. Главное идея.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
14.07.2013, 18:35     Как обычную переменную на время сделать константой? #24
Пока не понял как буду передавать значение переменной в рамках одной функции, но примусь за создание тренировочной программы.
Спасибо за советы и примеры!
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
14.07.2013, 18:41     Как обычную переменную на время сделать константой? #25
Цитата Сообщение от kotgav Посмотреть сообщение
Пока не понял как буду передавать значение переменной в рамках одной функции
У меня аналогично. Не понятно о какой функции идёт речь. Если это Ваша пользовательская функция, то вариантов Вам предложили достаточно. Даже мой подойдёт. Если библиотечная, - вызывайте внутри своей. Это называется "обёртка". Как ещё сказать не знаю.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
14.07.2013, 19:12     Как обычную переменную на время сделать константой? #26
Да, вариантов и информации много, поле для деятельности есть.
Если вернуться ко второму примеру, то мне надо "заморозить" значение переменной в функции foo2() и не вызывать ее из функции main(). В моем случае программа - это библиотека для приложения к Windows, из ее главной функции DLLmain функция foo2() напрямую не вызывается.
В общем, пока только в общих чертах понимаю, как это сделать в foo2(), не прибегая к main(). Буду тренироваться.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
14.07.2013, 20:53     Как обычную переменную на время сделать константой? #27
Цитата Сообщение от kotgav Посмотреть сообщение
В моем случае программа - это библиотека для приложения к Windows, из ее главной функции DLLmain функция foo2() напрямую не вызывается.
А какая вызывается? Может объясните подробнее. Есть подозрение, что то что Вам нужно это не то, что Вы спросили.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
14.07.2013, 21:04     Как обычную переменную на время сделать константой? #28
В библиотеке DLL есть стандартный файл dllmain.cpp, который автоматически сформирован при создании проекта:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// dllmain.cpp: определяет точку входа для приложения DLL.
#include "stdafx.h"
 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
А в файле исходных кодов подключен файл инструментов приложения:
#include "..\..\inc\gauges.h"
в котором все типовые функции и описаны. В том числе и данная функция обратного вызова, о которой идет речь.
Мне остается действовать в рамках типовых инструментов приложения с использование соответствующих API функций и отсюда все мои проблемы.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
14.07.2013, 21:29     Как обычную переменную на время сделать константой? #29
Цитата Сообщение от kotgav Посмотреть сообщение
Мне остается действовать в рамках типовых инструментов приложения
Не такого мне хотелось объяснения. Единственное, что удалось понять, это то, что Вам не позавидуешь.
Попробую воспользовавшись приведенным Вами ранее фрагментом "вслепую", то есть не понимая, где он и как работает. Пусть это фрагмент многократно вызываемой Вами функции:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
......
       FLOAT64  time_var = pelement->source_var.var_value.n;          // получаем текущее значение секунд от 0 до 59 с частотой 1 Гц
       FLOAT64  time_double = modf(time_var/10, &time_int)*10;        // получаем единицы и десятки секунд
//вставка
int first_inisializer = -1;//не обязательно -1, можно всё что угодно, NAN например, лишь бы a 
//не могла принимать это значение естественным путём))
static int time_int_begin;//инициализируется нулём до первого вызова, но тепрь это неважно
static int count_of_callings;//time_int_begin с нуля 
if( count_of_callings==0 ) time_int_begin = first_inisializer;
if( time_int_begin ==  first_inisializer ) time_int_begin = time_int;// замораживаем десятки секунд 
if(count_of_callings<100)//защита от переполнения
count_of_callings++;//делаем невозможной переустановку в first_inisializer
else count_of_callings = 1;
//конец вставки
time_double_secondomer = time_double-time_double_begin;    // текущее время секундомера, единицы секунд
.......
}
Угадал?
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
15.07.2013, 17:10     Как обычную переменную на время сделать константой? #30
Извините, что заставил Вас угадывать, не хотел.
В Вашем коде есть два момента, которые я не использовал в предлагаемом виде.
Первый - это блок:
C++
1
2
3
if(count_of_callings<100)//защита от переполнения
count_of_callings++;//делаем невозможной переустановку в first_inisializer
else count_of_callings = 1;
Его я исключил полностью, т.к. библиотека используется не консольным приложением.
Второй момент - это статичные переменные:
C++
1
2
static int time_int_begin;//инициализируется нулём до первого вызова, но теперь это неважно
static int count_of_callings;//time_int_begin с нуля
Я сделал изменения в функции, но заменил переменную десятков секунд time_int_begin на переменную единиц секунд time_double_begin.
Результат неутешительный - при работе программы они не сохраняют свои значения, а меняют их при всяком обращении к функции на значение time_double, как это написано в программе. Поэтому значение секундомера всегда равно 0. Программа не работает.

Я уже пытался использовать static и static const, но "заморозить" значения после первого обращения к функции не получается:
- статические значения в 0 или заданные при инициализации значения не устанавливаются при первом обращении к функции, как это написано в книжках, а принимают всякий раз произвольные значения. Например, при установленном значении -1 они принимают значения 7, при втором цикле 19, потом еще чего-нибудь;
- при каждом обращении к функции статические переменные принимают новые значения текущего счетчика времени.
Собственно задача сводится к замораживанию первого значения переменной static. А оно не замораживается.
Мне уже подсказали, что использовать static для замораживания нельзя, нужно использовать для этих целей глобальную переменную.
Применил глобальную - тоже не замораживается.

Добавлено через 13 минут
Постараюсь пояснить работу функции.
Есть макрос, таблица переменных которого такова:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MAKE_ICON
(
    GTX328_zastavka_icon,                    // имя макроса статического изображения
    IDB_BITMAP2,                             // ID ресурса (идентификатор bmp рисунка заставки)
    GTX328_digital_icon_list,                // следующие макросы - цифры кода транспондера 
    GTX328_fail,                             // Отказы
    IMAGE_USE_ERASE,                         // режим использования рисунка
    0,                                       // флаг ASI_FLAGS
    0,0,                                     // координаты верхнего левого угла рисунка
    CLOCK_SECOND,GTX328_Zastavka_icon_cb,
    NULL,                   // переключателя иконок нет
    1,                      // Количество иконок
    0,
    0,
)
Этот макрос делает видимыми картинки в приложении, к которому создается библиотека. Приложение - не консольное, это авиасимулятор. В этом макросе я могу устанавливать только свои имена параметров и все. Работа макроса определена инструментами, неподвластными пользователю.
Первая строчка - это имя макроса. Вторая - имя первой картинки, которых может быть много. Порядок показа картинок определяет специальный параметр макроса.
Строчка CLOCK_SECOND,GTX328_Zastavka_icon_cb, содержит имя переменной, которая генерирует секунды и имя функции обратного вызова, которая срабатывает при обновлении значения секунд.
Каждой картинке соответствует свой номер.
В функции обратного вызова я читаю текущее значение секунд, присваиваю соответствующий ему номер картинки и возвращаю в макрос. Картинка выводится.
Для текущего времени эта задача решается просто и такие часы у меня работают.
Для секундомера мне надо знать начальное значение секунд, чтобы затем постоянно его вычитать из текущего значения и получать относительное время.
Вот задачу "замораживания" начального времени я и не могу решить.

Добавлено через 1 час 25 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//ну очень смешное решение))
#include <iostream>
 using namespace std;
 int foo1(int ai){
static int prevA;//инициализируется нулём до первого вызова
if(prevA == 0) prevA = ai;
const int a = prevA;//если хотите для самодисциплины
//далее работаем с переменной a, 
 
 
return a;
 }
 
 
 
int main()
{
    setlocale(LC_ALL, "Russian");
for(int i=6; i<9; ++i) cout<<foo1(i)<<" ";//6 6 6 то есть не меняется значение в функции
 
    system("pause");
    return 0;
}
Прорешал первый пример в консольном приложении. Работает отлично! Это и понятно, здесь применена передача значения переменной из функции foo1() в функцию main().

Переделал пример для использования только одной функции - main().
C++
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
// Sht_Example_StaticVar.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <iostream>
using namespace std;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "Russian");
    
    static int prevA = -1;   //инициализируется нулём до первого вызова, переменная счетчика циклов обращения
    int ant = 0;
 
if(prevA == 0)      // Если первый цикл
    prevA = ant;        
cout << "Выводим ant" << ant;
    system("pause");
const int a = prevA;   //если хотите для самодисциплины
//далее работаем с переменной a, 
 
    for(int i=1; i<5; ++i)
        cout << a << "  Это значение а ";    //6 6 6 то есть не меняется значение в функции
 
    system("pause");
    return 0;
}
Как и ожидал, замораживания переменной a не происходит, ее значение меняется так же, как и значение переменной ant.
Так что для одной функции этот вариант не подходит.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
15.07.2013, 17:21     Как обычную переменную на время сделать константой? #31
kotgav, скажу честно, мало что понятно. То есть библиотека получает время самостоятельно, как я понял. Тогда и не нужно пытаться его останавливать. Поставьте вопрос так: -" Что мне нужно остановить во времени?" Если доступ к работе библиотеки у Вас есть только через установку номера картинки, то возвращайте прежний номер всё время пока Вам нужно.
Не взыщите если и это не в тему.
А вообще, лучше бы Вам сформулировать вопрос как-то иначе. Например: работаю в MVS, в проекте MFC, с внешней библиотекой такой-то..., вопрос в следующем...
Может кто-то и скажет.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
15.07.2013, 17:28     Как обычную переменную на время сделать константой? #32
Можно так сказать, что библиотека получает время самостоятельно из приложения. Точнее значения переменной с частотой 1 герц, т.е. каждую секунду абсолютное значение секунд: 0, 1, 2 и т.д. А я могу включиться в процесс в любой момент времени, например, когда значение этой переменной равно 43. Вот его мне и надо запомнить.
Не останавливать бег переменной, а запомнить то значение, которое было у переменной в момент запуска библиотеки.
Похоже, для данного случая, задача не решаемая.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
15.07.2013, 17:30     Как обычную переменную на время сделать константой? #33
Цитата Сообщение от kotgav Посмотреть сообщение
Как и ожидал, замораживания переменной a не происходит, ее значение меняется так же, как и значение переменной ant.
Так что для одной функции этот вариант не подходит.
Мне в силу недостатка опыта непонятно, почему из функции нельзя вызвать функцию (вынести часть кода в функцию) или наоборот: почему нельзя код вызова библиотечной функции (или установки управляющих переменных, для событийно-управляемой модели) обернуть функцией. Попробуйте всё же переформулировать вопрос (см. предыдущий пост).
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
15.07.2013, 17:34     Как обычную переменную на время сделать константой? #34
А кстати, это идея! Попробую сделать совсем другую функцию и объявить глобальные переменные. При первом обращении к функции обратного вызова вызвать новую функцию и в ней присвоить начальные значения.
Может быть и получится, кто его знает.
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
15.07.2013, 17:37     Как обычную переменную на время сделать константой? #35
Цитата Сообщение от kotgav Посмотреть сообщение
Вот его мне и надо запомнить.
Вы то его запомните. Хоть в глобальной переменной. Однако непонятно, что Вы хотите. Чтобы библиотека это сделала? Смотрите документацию, можно ли и как это сделать. Может оказаться, что в соответствии с предлагаемыми возможностями это и не нужно, а можно иначе.

Добавлено через 1 минуту
Цитата Сообщение от kotgav Посмотреть сообщение
При первом обращении к функции обратного вызова вызвать новую функцию и в ней присвоить начальные значения.
Рад это слышать. Напишите что вышло.
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
15.07.2013, 17:38     Как обычную переменную на время сделать константой? #36
Напишу, спасибо за помощь!
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
16.07.2013, 17:55     Как обычную переменную на время сделать константой? #37
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//ну очень смешное решение))
#include <iostream>
 using namespace std;
 int foo1(int ai){
static int prevA;//инициализируется нулём до первого вызова
if(prevA == 0) prevA = ai;
const int a = prevA;//если хотите для самодисциплины
//далее работаем с переменной a, 
 
 
return a;
 }
 
 
int main()
{
    setlocale(LC_ALL, "Russian");
for(int i=6; i<9; ++i) cout<<foo1(i)<<" ";//6 6 6 то есть не меняется значение в функции
 
    system("pause");
    return 0;
}
Проработал еще раз пример и переделал его для лучшего понимания, как мне показалось.
Пример наглядный. Принцип сохранения значения в качестве временной константы основан на использовании const в вызываемой функции.
А со своей функцией обратного вызова продолжаю работать.
C++
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
#include "stdafx.h"
#include <iostream>
using namespace std;
 
// Вспомогательная (вызываемая) функция
int foo1(int ai)
{
    static int prevA;        // вспомогательная переменная, инициализируется нулём до первого вызова
    if(prevA == 0)           // проверяем, если 0 - то значение первое, иначе возвращаем старое значение аргумента
        prevA = ai;          // если значение первое, то присваиваем вспомогательной переменной полученное значение из вызывающей функции
    const int a = prevA;     //если хотите для самодисциплины, "замораживаем" значение аргумента функции foo1()
//далее работаем с переменной a 
return a;   // возвращаем "замороженное" значение переменной
}
 
 
// Главная (вызывающая) функция
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "Russian");
    int i = 0;
    int b = 0;
    int c = 0;
 
    for(int i=1; i<5; ++i)
    {
        b = foo1(i);     // присваиваем "замороженное" переменной b, которая выполняет роль временной константы в вызывающей функции
        c = i-b;         // текущая разность
 
        cout << "i= "<< i << " а= " << b << " c= " << c << "\n";;    // вывод текущего i и "замороженного foo1(i)" значений 
        system("pause");
    }
 
    system("pause");
    return 0;
}
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
16.07.2013, 18:07     Как обычную переменную на время сделать константой? #38
Цитата Сообщение от kotgav Посмотреть сообщение
Принцип сохранения значения в качестве временной константы основан на использовании const в вызываемой функции.
Не-а, на основе использования static основан. Конст можно и не использовать, но если функция большая, вполне уместно.
Второй пример с инициализирующим значением (дополнительной статической переменной) лучше подходит. Нет же гарантии, что 0 не получите потом. Это нормальное значение секунд на каждой 61-й секунде предыдущей минуты, другими словами. Успеха!
kotgav
2 / 2 / 0
Регистрация: 13.07.2013
Сообщений: 62
16.07.2013, 18:10     Как обычную переменную на время сделать константой? #39
Цитата Сообщение от IGPIGP Посмотреть сообщение
Не-а, на основе использования static основан. Конст можно и не использовать, но если функция большая, вполне уместно.
Второй пример с инициализирующим значением (дополнительной статической переменной) лучше подходит. Нет же гарантии, что 0 не получите потом. Это нормальное значение секунд на каждой 61-й секунде предыдущей минуты, другими словами. Успеха!
Да, пожалуй, что static. Но и const здесь нелишним поставлен, для надежности.
Второй пример тоже изучил, применил у себя. Но пока не присваивается начальное значение, а все время остается этот -1, который был даден ему при инициализации. Разбираюсь.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.07.2013, 19:06     Как обычную переменную на время сделать константой?
Еще ссылки по теме:

Как сделать, чтобы "*" принимали как обычную переменную? C++
Как сделать уже созданную переменную ссылкой C++
C++ Как сделать переменную строковой C++

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

Или воспользуйтесь поиском по форуму:
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6166 / 2895 / 282
Регистрация: 04.12.2011
Сообщений: 7,695
Записей в блоге: 3
16.07.2013, 19:06     Как обычную переменную на время сделать константой? #40
Цитата Сообщение от kotgav Посмотреть сообщение
Второй пример тоже изучил, применил у себя. Но пока не присваивается начальное значение, а все время остается этот -1, который был даден ему при инициализации. Разбираюсь.
Дык, положите кода столько сколько нужно. Может и увидим чего.
Yandex
Объявления
16.07.2013, 19:06     Как обычную переменную на время сделать константой?
Ответ Создать тему
Опции темы

Текущее время: 02:53. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru