Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > переменная счетчик в циклах i - неадекват


Автор: Notreg 11.8.2008, 17:08
Пошагово отлаживаю и тут раз и i  присваивается нереально большое занчение(i = 9604034)! притом в предыдущем операторе так же используется i и нормально а тут раз и все! И сообственно с i то никаких манипуляций не происходит нет операторов присваивания, кроме тех которые выполняет оператор цикла собственно. Че может быть, а главное как выявить от куда прирост такой берется?

Автор: THandle 11.8.2008, 17:12
Notreg, интересно было бы глянуть на код...

Автор: Notreg 11.8.2008, 17:48
вот например в обработчике отжатия мыши! всегда в одном и том же месте: MyCards[i] = -1; 

Код

//---------------------------------------------------------------------------
void __fastcall TMainForm::FormMouseUp(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
        //мышка на карте?
        for (i = 0; i < 6; i += 1)
        {
                if (MouseOnCard[i] == true && MyCards[i] != -1)
                {
                        //фиксируем уход карты
                        GoCards[i] = true;
                        CardsForGlasses[n] = MyCards[i];
                        //ставим карту в центр
                        MoveCards[n] = ArrayCards[MyCards[i]];
                        if (FirstCard == -1)
                        {
                                FirstCard = MyCards[i];
                        }
                        if (Suit[FirstCard] == Suit[CardsForGlasses[n]] || Suit[CardsForGlasses[n]] == 0)
                        {
                                if (Weight[PreviousCard] > Weight[CardsForGlasses[n]])
                                {
                                        BribeWinner = 0;
                                        PreviousCard = CardsForGlasses[n];
                                }
                        }
                        MyCards[i] = -1;//вот! здесь! i - принимает большое значение
                        //следующий
                        n += 1;
                        //запрещаем текущего
                        PlayerGo[Player] = false;
                        //следующий
                        Player += 1;
                        if (Player > 3)
                        {
                                //переход в начало
                                Player -= 4;
                        }
                        //разрешаем следующего
                        PlayerGo[Player] = true;
                        //запуск следующего
                        PlayNext();
                }
        }

        //PaintGame();
}
//---------------------------------------------------------------------------

Автор: fridkaratel 11.8.2008, 22:11
Судя по твоему коду, у тебя переменная i глобально объявлена... ;)

Автор: mrbrooks 12.8.2008, 07:40
Цитата(fridkaratel @ 11.8.2008,  22:11)
Судя по твоему коду, у тебя переменная i глобально объявлена... ;)

с чего ты взял - она описана и инициализована в цикле. 

умиляют эти строчки кода  smile 
Код

n += 1;
...
Player += 1;

Автор: fridkaratel 12.8.2008, 08:25
Цитата(mrbrooks @ 12.8.2008,  15:40)
с чего ты взял - она описана и инициализована в цикле.


Цитата(Notreg @ 12.8.2008,  01:48)
for (i = 0; i < 6; i += 1)


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

Автор: volvo877 12.8.2008, 08:26
Цитата(mrbrooks @  12.8.2008,  07:40 Найти цитируемый пост)
она описана и инициализована в цикле. 
Можешь назвать номер строки, в которой она описана в цикле? Или эта строка почему-то не вошла в исходник?

Автор: fridkaratel 12.8.2008, 08:26
[DELETE]

Автор: mrbrooks 12.8.2008, 08:59
Цитата(volvo877 @ 12.8.2008,  08:26)
Цитата(mrbrooks @  12.8.2008,  07:40 Найти цитируемый пост)
она описана и инициализована в цикле. 
Можешь назвать номер строки, в которой она описана в цикле? Или эта строка почему-то не вошла в исходник?

факмоймозг. мой косяк. smile 

Автор: Notreg 12.8.2008, 11:18
Цитата(mrbrooks @  12.8.2008,  07:40 Найти цитируемый пост)
умиляют эти строчки кода


что там такого? пояснишь?



Цитата
Судя по твоему коду, у тебя переменная i глобально объявлена... ;)



типа это косяк? почему же он проявляется тока в одно и том же месте? короче зачем объявлять локально?


Автор: mrbrooks 12.8.2008, 11:28
использовать глобальные переменные - плохой стиль. надо стараться их избегать. например сиглинтоном. тебе достаточно будет локальной переменной. к примеру 
Код

static int i;
 

по поводу умиления:

Код

n ++;
...
Player ++;

Автор: fridkaratel 12.8.2008, 11:29
Вообще, в твоем случае лучше:
Код

for (int i = 0; i < 6; i++)
{
  <...>
}

Автор: Notreg 12.8.2008, 12:04
Цитата

по поводу умиления:


да ладно, если шаг = 2, два раза чтоль писать или 4 плюса, а если 10, и шаг вообще может быть переменной,чтоб оперативно изменять шаг пишу так..

Цитата

например сиглинтоном


а это че?




Автор: fridkaratel 12.8.2008, 12:10
а что за массивы используешь? Например,  MyCards[i] - это AnsiString, int, char?

И какая у них длина?

Автор: mrbrooks 12.8.2008, 12:27
Цитата(Notreg @ 12.8.2008,  12:04)
Цитата

по поводу умиления:


да ладно, если шаг = 2, два раза чтоль писать или 4 плюса, а если 10, и шаг вообще может быть переменной,чтоб оперативно изменять шаг пишу так..

Цитата

например сиглинтоном


а это че?

1. Это если, а у тебя не если
2. В гугл
3. Присоединяюсь к fridkaratel - выложи полный код со своими глобальными переменными. Не боись. Врятли кто нарушит твои авторские права. smile 

Автор: Notreg 12.8.2008, 14:02
гугл не занет, что это - сиглинтон =)

int MyCards[24];


Цитата(mrbrooks @  12.8.2008,  12:27 Найти цитируемый пост)
 Присоединяюсь к fridkaratel - выложи полный код со своими глобальными переменными. Не боись. Врятли кто нарушит твои авторские права.


неа, не могу, закрытый код =)  Сделал локальными, вроде работает! А как делать без глобальных, это ж туева хуча, параметров функций!

Автор: mrbrooks 12.8.2008, 14:26
факмой мозг. вот что бывает когда буковку пропускаешь
http://en.wikipedia.org/wiki/Singleton_pattern

Автор: petlyura 12.8.2008, 14:28
Цитата(Notreg @  12.8.2008,  14:02 Найти цитируемый пост)
 А как делать без глобальных, это ж туева хуча, параметров функций!


Везде, где у тебя есть 
for (i = 0; i....................)
меняй
на for (int i = 0; i....................)
иначе еще такая же хрень где-нибудь всплывет.
Глобальную i убери нафиг... Такое происходит потому, что в этот момент где-то i меняет свое значение еще.

Никакой кучи параметров не будет. Параметры ф-ции - это вот void func(int param1, char* param2, double* param3, TMyClass* param4...)
Те i, что внутри ф-ции - это всего лишь локальные переменные (будут, если ты сделаешь то, что выше написано). Они видны только внутри цикла.
Память выделяется под i внутри функции (цикла) в месте объявления и удаляется при выходе из цикла. Зато не хранится через всю программу. 
Плохой стиль программирования - потому что из-за такого стиля ошибки происходят, и трудно разобраться в происхождении, и в специфике кода.

Автор: Notreg 12.8.2008, 15:27
я имел ввиду не i , с i то я разобрался. 

Автор: mrbrooks 12.8.2008, 15:46
Цитата(Notreg @ 12.8.2008,  14:02)

неа, не могу, закрытый код =)  Сделал локальными, вроде работает! А как делать без глобальных, это ж туева хуча, параметров функций!

Я тогда пас. Из меня телепат фиговый.  smile 

Автор: petlyura 12.8.2008, 15:50
Цитата(Notreg @  12.8.2008,  15:27 Найти цитируемый пост)
я имел ввиду не i , с i то я разобрался. 

Предполагаю, что ты имеешь в виду, что делать, чтобы все необходимые переменные везде, где нужно, были доступны.
Для этого существует ООП, плюс инклюдишь файлы #include "", где они объявлены (в классах формы или собственных классах), а дальше через доступ MyClass->peremennaya. Плюс еще куча наворотов типа события, SendMessage, PostMessage и т.п.

Ну, а пишешь, ты загадочно. Всегда приходится догадываться. Ладно код не можешь выкладывать. У меня тоже самое. Но попробовать сварганить простой примерчик с использованием небольшого кусочка кода, либо даже как-нибудь внятнее объяснить. На худой конец разделители ставь. Может, предложения начинай с большой буквы. Неудобно читать-то.

Автор: Notreg 12.8.2008, 15:51
вот что я натворил

Автор: fridkaratel 12.8.2008, 16:22
Ну так что - все равно та же ошибка в том же месте?

Если да, то надо смотреть и изучать код...

Вот что я приметил:
Код

int CardsForGlasses[4]; //карты взятки для подсчета очков
/* ... */
        for (int i = 0; i < 6; i += 1)
        {
                if (MouseOnCard[i] == true && MyCards[i] != -1)
                {
                  /* ... */
                        n += 1;
                 /* ... */
                }
         }
/* ... */

Судя по коду - будет ошибка, если условие выполнится больше, чем 4 раза, т.е. n будет равно 4...

PS: когда объявляешь #define, то лучше использовать заглавные буквы, напр. #define CARD_ACE 14. Так легче и, как мне кажется, правильней, нежели #define MyAce 10... Да и отличить переменную от #define в дальнейшем коде куда легче ;)

Автор: mrbrooks 12.8.2008, 16:28
Цитата(fridkaratel @ 12.8.2008,  16:22)
Ну так что - все равно та же ошибка в том же месте?

Если да, то надо смотреть и изучать код...

PS: когда объявляешь #define, то лучше использовать заглавные буквы, напр. #define CARD_ACE 14. Так легче и, как мне кажется, правильней, нежели #define MyAce 10... Да и отличить переменную от #define в дальнейшем коде куда легче ;)

если говорить о правильности в С++ вместо #define используется const

Добавлено через 1 минуту и 35 секунд
охххххх. листинг знатный. карточная игра чтоль. блин вот здесь не плохо было бы заюзать парадигмы OOП  smile 

Автор: Notreg 12.8.2008, 16:42
Цитата(fridkaratel @  12.8.2008,  16:22 Найти цитируемый пост)
Судя по коду - будет ошибка, если условие выполнится больше, чем 4 раза, т.е. n будет равно 4...


это понятно! пока, просто, основную логику делаю.

Цитата

охххххх. листинг знатный. карточная игра чтоль. блин вот здесь не плохо было бы заюзать парадигмы OOП



по поддробнее, но не сильно углубляясь. 

Цитата

Ну так что - все равно та же ошибка в том же месте?

Если да, то надо смотреть и изучать код...


нет, ошибка ушла!

Автор: Notreg 12.8.2008, 17:02
Цитата

На худой конец разделители ставь.


Какие разделители?

Автор: Notreg 12.8.2008, 19:21
Цитата(mrbrooks @  12.8.2008,  16:28 Найти цитируемый пост)
охххххх. листинг знатный. карточная игра чтоль. блин вот здесь не плохо было бы заюзать парадигмы OOП 


Т. е. собственно ООП призвано объединить переменные и функции в рамках понятия объект? Но по отношению к функциям объекта переменные внутри объекта также будут глобальными?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)