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

Начал осваивать списки. Не работает вывод на экран. - C++

Восстановить пароль Регистрация
 
Kirill Losev
3 / 3 / 0
Регистрация: 01.10.2011
Сообщений: 249
30.04.2012, 23:59     Начал осваивать списки. Не работает вывод на экран. #1
Вот такой пример нашел в интернете:

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
37
38
39
40
41
42
#include <iostream>
using namespace std;
 
struct Item
{
    int info;
    int count;
    Item *next;
};
 
int main()
{
    Item *first = 0;
    Item *n;
    int i;
    int c = 1;
    while(1)
    {
    cout << "Введите следующий элемент списка: ";
    cin >> i;
    if(i == 0)
        break;
    n = new Item;
    n->info = i;
    n->next = first;
    first = n;
    n->count = c;
    }
    cout << "Какой элемет по счету выводить?\n"
           << "Ответ: ";
    int y = 0;
    cin >> y;
    n = first;
    while(n)
    {
    n = n->next;
    cout << n->info << " ";
    if(n->count == y)
        cout << "Элемент списка под номером " << y << ": " << n->info << endl;
    }
    return 0;
}
Получается ввести данные, но когда хочу вывести то, что я ввел на экран и заданный элемент списка, то программа либо просто аварийно завершается, либо ничего не выводит.

Прошу помочь мне в этом разобраться.

Заранее спасибо!
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IFree Host
Заблокирован
01.05.2012, 00:11     Начал осваивать списки. Не работает вывод на экран. #2
Вообще-то работать оно не должно, так как создано по образцу стека а обращение как к массиву.
А к стеку так обращаться нельзя

и к тому же first ссылается на нуль а ты пытаешься к нему обратиться
Kirill Losev
3 / 3 / 0
Регистрация: 01.10.2011
Сообщений: 249
01.05.2012, 00:18  [ТС]     Начал осваивать списки. Не работает вывод на экран. #3
IFree Host, спасибо. а как исправить?

Добавлено через 56 секунд
Может есть где-нибудь статья хорошая или видео?
IFree Host
Заблокирован
01.05.2012, 02:34     Начал осваивать списки. Не работает вывод на экран. #4
А все зависит от того, что ты хочешь получить.
Если стек то немного замарочено. Если просто массив структуры, то совсем просто
C++
1
2
3
4
5
6
7
struct Example{
   int info;
   char word[10];
   float number;
}
 
Example massiv[100];
Потом можешь к нему обращаться как к объекту
C++
1
2
3
massiv[25].info = 2;
massiv[25].word = "coloboc";
massiv[25].number = 3.89234F;
Добавлено через 2 часа 7 минут
А кстати про структуры полезно вот это узнать:

Структуры синтаксически очень похожи на классы, но существует принципиальное отличие, которое заключается в том, что класс – является ссылочным типом (reference type), а структуры – значимый класс (value type). А следовательно, классы всегда создаются в, так называемой, “куче” (heap), а структуры создаются в стеке (stack). Цитата из комментария: "Имхо, главное отличие структур и классов: структуры передаются по значению (то есть копируются), объекты классов - по ссылке. Именно это является существеннейшим различием в их поведении, а не то, где они хранятся. Примечание: структуру тоже можно передать по ссылке, используя модификаторы out и ref."

Ключевой момент статьи: Чем больше Вы будете использовать структуры вместо небольших (наверное, правильнее будет сказать – маленьких) классов, тем менее затратным по ресурсам будет использование памяти. Смею предположить, что не требуется объяснения почему… “куча”, “сборщик мусора”, “неопределенные временные интервалы прохода”, сложность “ручного” управления кучей и сборщиком мусора. Все ключевые моменты уже перечислены.

Так же как и классы, структуры могут иметь поля, методы и конструкторы. Хотя про конструкторы надо поговорить подробнее (будет дальше по теме), ибо это есть очень важное понятие при сравнивании классов и структур.

Структуры всегда с Вами

Не хочется думать, что следующая информация, для Вас сюрпризом. В языке C# примитивные числовые типы int, long, float являются альясами для структур System.Int32, System.Int64 и System.Single соответственно. Эти структуры имеют поля и методы. Вы обычно вызываете методы у переменных данных типов. Например, каждая из перечисленных структур имеет метод ToString. Также у перечисленных структур есть статичные поля, например, Int32.MaxValue или Int32.MinValue. Получается, что Вы уже в повседневной "программной" жизни используете структуры, а значит знакомы с ними.

Таблица классов и структур в Microsoft. NET Framework

В таблице указаны альясы и соответствующие им типы, а также дана информация о представляющем типе (структура или класс).Keyword Type equivalent Class or structure
bool System.Boolean Structure
byte System.Byte Structure
decimal System.Decimal Structure
double System.Double Structure
float System.Single Structure
int System.Int32 Structure
long System.Int64 Structure
object System.Object Class
sbyte System.SByte Structure
short System.Int16 Structure
string System.String Class
uint System.UInt32 Structure
ulong System.UInt64 Structure
ushort System.UInt16 Structure
Объявление структур

Для объявления структуры используется зарезервированное слово struct, следом наименование структуры и фигурные скобки:
C++
1
2
3
4
   1:  struct Time
   2:  {
   3:     public int hours, minites, seconds;
   4:  }
В отличие от классов, использование публичных полей в структурах в большинстве случаев не рекомендуется, потому что не существует способа контролирования значений в них. Например, кто-либо может установит значение минут или секунд более 60. Более правильный вариант в данном случае - использовать свойства, а в конструкторе осуществить проверку:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   1:  struct Time  
   2:  {  
   3:      public Time(int hh, int mm, int ss)  
   4:      {  
   5:          hours = hh % 24;  
   6:          minutes = mm % 60;  
   7:          seconds = ss % 60;  
   8:      }  
   9:    
  10:      public int Hours()  
  11:      {  
  12:          return hours;  
  13:      }  
  14:      ...  
  15:      private int hours, minutes, seconds;  
  16:  }
Кстати, …

По умолчанию, Вы не можете использовать некоторые общие операторы в Ваших структурах. Например, Вы не можете использовать оператор сравнения (==) и противоположные ему (!=) на своих структурах. Однако, Вы можете явно объявить и реализовать операторы для своих структур.
И в чем же разница между структурами и классами

рассмотрим пример, в котором уже заложена ошибка:
C++
1
2
3
4
5
   1:  struct Time  
   2:  {  
   3:      public Time() { ... } // compile-time error  
   4:      ...  
   5:  }
Причина возникновении ошибки в том, что Вы не можете использовать конструктор по умолчанию (без параметров) для структуры, потому что компилятор всегда генерирует его сам. Что же касается класса, то компилятор создает конструктор по умолчанию, только в том случае, если Вы его не создали. Сгенерированный конструктор для структуры всегда устанавливает поля в 0, false или null – как и для классов. Поэтому Вы можете быть уверенными в том, что созданная структура всегда будет вести себя “адекватно” в соответствии со значениями по умолчанию в используемых типах. Если Вы не хотите использовать значения по умолчанию, Вы можете инициализировать поля своими значениями в конструкторе с параметрами для инициализации. Однако, если в этом конструкторе не будет инициализировано какое-нибудь значение, компилятор не будет его инициализировать за Вас и покажет ошибку.
C++
1
2
3
4
5
6
7
8
9
10
   1:  struct Time  
   2:  {  
   3:      private int hours, minutes, seconds; 
   4:      ... 
   5:      public Time(int hh, int mm)   
   6:      {  
   7:          this.hours = hh;  
   8:          this.minutes = mm;  
   9:      }   // compile-time error: seconds not initialized  
  10:  }
Первое правило Структуры: Всегда все переменные должны быть инициализированы!

В классах Вы можете инициализировать значение полей непосредственно в месте их объявления. В структурах такого сделать не получиться, и поэтому данный код вызовет ошибку при компиляции:
C++
1
2
3
4
5
6
7
   1:  struct Time  
   2:  {  
   3:      private int hours = 0; // compile-time error  
   4:      private int minutes;  
   5:      private int seconds;  
   6:      ... 
   7:  }
Второе правило Структуры: Нельзя инициализировать переменные в месте их объявления!

Данная таблица в некотором роде подытоживает всё вышесказанное и отображает основные отличия между классами и структурами.
Вопрос Структура Класс
И какого же типа экземпляр объекта? Структура значимый (value) тип Класс ссылочный (reference) тип
А где “живут” экземпляры этих объектов? Экземпляры структуры называют значениями и “живут” они в стеке (stack). Экземпляры классов называют объектами и “живут” они в куче (heap).

Можно ли создать конструктор по умолчанию? Нет
Если создается свой конструктор будет ли компилятор генерировать конструктор по умолчанию? Да
Если в своём конструкторе не будут инициализированы некоторые поля, будут ли они автоматически инициализированы компилятором? Нет
Разрешается ли инициализировать переменные в месте их объявления? Нет

Использование структур как переменных

После того как Вы создали структуры, Вы можете использовать ее также как классы и другие типы. Например, создав структуру Time, я могу использовать ее в классе:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
   1:  struct Time   
   2:  {   
   3:      private int hours, minutes, seconds; 
   4:      ... 
   5:  }  
   6:    
   7:  class Example  
   8:  {  
   9:      private Time currentTime; 
  10:   
  11:      public void Method(Time parameter)   
  12:      {  
  13:          Time localVariable;  
  14:          ...  
  15:      }  
  16:  }
Кстати, …

Вы можете создавать nullable версию переменной типа структуры использую модификатор “?” и потом присвоить ей значение null:

C++
1
Time? currentTime = null;
Инициализация структур

В статье я не раз говорил, что поля структуры могут быть инициализированы при использования конструктора, причем не важно какого “собственного” или “по умолчанию”. К особенностям структур можно отнести еще и тот факт, что вследствие того, что структуры являются значимым типом, то можно создать структуру без использования конструктора, например:
C++
1
  1:  Time now;
В таком случае, переменная создается, но поля не будут инициализированы в соответствии параметрами конструктора.
grizlik78
Эксперт С++
 Аватар для grizlik78
1884 / 1416 / 102
Регистрация: 29.05.2011
Сообщений: 2,961
01.05.2012, 02:54     Начал осваивать списки. Не работает вывод на экран. #5
Исправленная версия:
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
37
38
39
40
41
42
43
#include <iostream>
 
using namespace std;
 
struct Item
{
    int info;
    int count;
    Item *next;
};
 
int main()
{
    Item *first = 0;
    Item *n;
    int i;
    int c = 1;
    while(1)
    {
        cout << "Введите следующий элемент списка: ";
        cin >> i;
        if(i == 0)
            break;
        n = new Item;
        n->info = i;
        n->next = first;
        first = n;
        n->count = c++;
    }
    cout << "Какой элемет по счету выводить?\n"
         << "Ответ: ";
    int y = 0;
    cin >> y;
    n = first;
    while(n)
    {
        cout << n->info << " ";
        if(n->count == y)
            cout << "Элемент списка под номером " << y << ": " << n->info << endl;
        n = n->next;
    }
    return 0;
}
Раньше не увеличивался счётчик элементов (строка 28) и переход к следующему элементу стоял в начале цикла, а надо в конце (стр. 37 -> 40).
Kirill Losev
3 / 3 / 0
Регистрация: 01.10.2011
Сообщений: 249
01.05.2012, 12:34  [ТС]     Начал осваивать списки. Не работает вывод на экран. #6
IFree Host, Спасибо огромное за такую статью. буду разбираться.

grizlik78, спасибо!
Yandex
Объявления
01.05.2012, 12:34     Начал осваивать списки. Не работает вывод на экран.
Ответ Создать тему
Опции темы

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