Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Глюк с выводом связного списка 
:(
    Опции темы
nikitao
Дата 1.10.2005, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


Профиль
Группа: Завсегдатай
Сообщений: 1206
Регистрация: 30.8.2005
Где: Спб

Репутация: 1
Всего: 26



Добрый <время суток>Вот программа:

Код

#include <iostream>
using namespace std;
template <class X> class ochered{
  ochered *next;
  ochered *head;
  ochered *tail;
  X i;
  public:
    ochered(){head=tail=next=NULL;}
    void add(X a){
    ochered *temp;
    temp=new ochered;
    if (!temp)
    {
      cerr<<"Oshibka vidilenia pamati";
      exit(1);
    }
    temp->next=NULL;
    temp->i=a;
    if (!head){
      head=temp;
      tail=head;}
    else
    {
      tail->next=temp;
      tail=temp;
    }
    }
    X vivod()
    {
      X temp;
      temp=head->i;
      head=head->next;
      return temp;
    }
};
int main()
{
  ochered<int> ob1;
  ob1.add(30);
  ob1.add(239);
  ob1.add(566);
  cout<<ob1.vivod()<<'  '<<ob1.vivod()<<'  '<<ob1.vivod()<<'\n';
  system("PAUSE");
  return 0;
}


Здесь реализуется связный список с помощью создания шаблона(это не суть дела).
Лично я перед компиляцией ожидал увидеть в окне такую строку
"30 239 566"
но увидел:
"566 239 30"
Почему так произходит до меня не доходит.
Если прописать вместо
Код

cout<<ob1.vivod()<<'  '<<ob1.vivod()<<'  '<<ob1.vivod()<<'\n';

строку
Код

cout<<ob1.vivod();

или
Код

cout<<ob1.vivod();
  cout<<ob1.vivod();
  cout<<ob1.vivod();

То все работает нормально.Пыталя посмотреть в отладки:поставил точку останова и посмотрел выдаваемое значание в ochered::vivod();.Все выдает нормально ,а в окне глюк такой.
Зарание спасибо. smile


--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
LPBOY
Дата 1.10.2005, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Инструкция:
Код

cout<<ob1.vivod()<<'  '<<ob1.vivod()<<'  '<<ob1.vivod()<<'\n';


трансформируется в:

Код

std::operator<<(operator<<(operator<<(cout, ob1.vivod()), ob1.vivod()), ob1.vivod());


если нигде не опечатался. Но суть в том что компилятору разрешается производить вычисления своих аргументов в любом порядке - т.н. неспецифицированное поведение. Кроме того здесь судя по всему вступает в действие правило о разделении модификаций объекта точками следования. У тебя получается аж три модификации объекта и ни одной точки следования между ними. - Это приводит к неопределенному поведению, например MSVC 7.1 выдает полный бред.
Добавлено @ 22:01
А вообще что ты реализуешь? Очередь или двусвязный список? И какой компилятор?
Ты после выделения памяти проверяешь на ноль. Вообще-то компилятор должен бросать исключение, хотя старые действительно возвращают ноль...
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
nikitao
Дата 1.10.2005, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


Профиль
Группа: Завсегдатай
Сообщений: 1206
Регистрация: 30.8.2005
Где: Спб

Репутация: 1
Всего: 26



Цитата
А вообще что ты реализуешь? Очередь или двусвязный список? И какой компилятор?
Ты после выделения памяти проверяешь на ноль.

Реализую я очередь,но это не важно.IDE C++BuilderX v 1.0 а компелятор Borland Win32.
Вобще ,как я понял надо быть осторожнее с выводом.
Цитата

Вообще-то компилятор должен бросать исключение, хотя старые действительно возвращают ноль...

Пока еще не научился обрабатывать исключения,поэтому по старинке проверяю(вроде все работает).

LPBOY,спасибо.
ЗЫ А что такое точка следования???

Это сообщение отредактировал(а) nikitao - 1.10.2005, 22:31


--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
bilbobagginz
Дата 1.10.2005, 22:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 3
Всего: 317



выкури man fflush
пока.



--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
LPBOY
Дата 1.10.2005, 23:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



В общем правило такое: если несколько раз модифицируешь одну и ту же переменную (в твоем примере функция vivod каждый раз модифицирует ob1), то модификации должны отделяться точками следования. Точки следования это:
- точка с запятой
- оператор запятая
- оператор ?:
- операторы && и ||
- а также перед началом выполнения некоторой функции и в самом конце ее выполнения

В твоем примере можно испольовать точку с запятой, т.е. как ты сам сказал:

Код

cout<<ob1.vivod();
cout<<ob1.vivod();
cout<<ob1.vivod();

--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
LPBOY
Дата 1.10.2005, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 228
Регистрация: 12.7.2005

Репутация: 20
Всего: 20



Это я тебе рассказал - почему у меня выдается мусор (неопределенное поведение) ;)
Теперь расскажу - почему у тебя они выходят в обратном порядке (не специфицированное поведение). Я тут поэкспериментировал, написал такой код:

Код

#include <iostream>

int func()
{
static int val;
++val;
return val;
}

int main()
{
    std::cout << func() << ' ' << func() << ' ' << func(); 
    return 0;
}


он выдал:

Цитата

3 2 1


Как видишь компилятор вычисляет параметры функции operator<< так как ему нравится. То что именно справа налево видимо связано с конвенцией __cdecl.

Это сообщение отредактировал(а) LPBOY - 1.10.2005, 23:44
--------------------
Каждый человек по-своему прав, а по-моему нет...
PM MAIL   Вверх
nikitao
Дата 2.10.2005, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кот-программист
***


Профиль
Группа: Завсегдатай
Сообщений: 1206
Регистрация: 30.8.2005
Где: Спб

Репутация: 1
Всего: 26



Угу,понятно,разьяснил. smile


--------------------
Жизнь - печальная штука.
PM MAIL ICQ Skype GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0655 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.