Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.11.2011, 22:35   #21
Caged
Пользователь
 
Регистрация: 10.10.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от SteAlzzer Посмотреть сообщение

Иначе у вас в ф-ии main значение first не меняется.
так first же не должно меняться.. это ж голова списка.. или я что-то не понимаю?
Caged вне форума Ответить с цитированием
Старый 02.11.2011, 22:39   #22
Caged
Пользователь
 
Регистрация: 10.10.2011
Сообщений: 33
По умолчанию

Цитата:
Сообщение от SteAlzzer Посмотреть сообщение
Вы в add_item либо должны использовать ссылку, либо возвращать значение.
новый элемент списка возвращать надо, что ли?
Caged вне форума Ответить с цитированием
Старый 02.11.2011, 22:56   #23
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

Код:
 listI *item = new listI;
вы уверены, что все поля нового обьекта listI проинициализировались так, как вы ожидаете? не факт ведь что указатель link будет нулем.

Есть тонкость между записями:
Цитата:
listI* item1 = new listI;
listI* item2 = new listI();
Помоему эта тонкость начинает работать для POD структур без конструкторов и прочих ф-ий (как раз ваш случай). Какое-то наследие С. Т.к. я всех тонкостей дефолтной инициализации переменных не помню, всегда инициализирую их явно.

И еще глюк: вы в ф-ию add_item отдаете нулевой указатель и пытаетесь обратиться к мебмеру. в ф-ии main нужно создать first.

Кстати, listI - дурацкое имя для структуры. Общепринятым является "узел списка" (Node или ListNode). Вот всзязанные между собой узлы как раз и образуют список.

Последний раз редактировалось _Ч_; 02.11.2011 в 23:00.
_Ч_ вне форума Ответить с цитированием
Старый 03.11.2011, 23:58   #24
SteAlzzer
Пользователь
 
Аватар для SteAlzzer
 
Регистрация: 11.10.2011
Сообщений: 60
По умолчанию

Caged, а что за ошибка-то? Текст приведите, пожалуйста

Да, возвращать значение нужно. Смотрите, вы вначале инициализируете переменную first как NULL. Она ни на что не указывает. (Только не удаляйте данную инициализацию, можете покрушить данные и систему).
Дальше, при первом вызове add2list вы выделаете память, пихаете туда значение, присваиваете его first. Но first в функции main не поменяет своего значения.
SteAlzzer вне форума Ответить с цитированием
Старый 04.11.2011, 01:45   #25
itnomad
Новичок
Джуниор
 
Регистрация: 03.11.2011
Сообщений: 1
По умолчанию

у меня похожая задача, но на Си: напишите программу, выполняющую конкатенацию двух связанных списков символов. программа должна включать функцию concatenate, которой в качестве аргументов передаются указатели на оба списка и она присоединяет второй список к первому.

вот что наваял:
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
 
struct listNode{
        char data;
        listNode *nextPtr;
};
 
typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;
 
//funktsia obiedinenia spiskov
void concatenate(LISTNODEPTR , LISTNODEPTR );
//funktsia pechati spiska
void printList(LISTNODEPTR);
//funktsia vvoda bukv v spisok
void insert(LISTNODEPTR *, char);
 
void main(){
        clrscr();
        char item;
        LISTNODEPTR startPtr=NULL;
        LISTNODEPTR startPtr2=NULL;
        //vvodim 3 bukvi v pervii spisok
        for(int i=0;i<3;i++){
           printf("Enter a character list1: \n");
           scanf("%s", &item);
           insert(&startPtr, item);
           printList(startPtr);
        }
       //vvodim 3 bukvi vo vtoroi spisok
        for(i=0;i<3;i++){
           printf("Enter a character list2: \n");
           scanf("%s", &item);
           insert(&startPtr2, item);
           printList(startPtr2);
        }
        //obiedinenie
        concatenate(startPtr,startPtr2);
        printf("\nConcatenate list(1+2): \n");
        printList(startPtr);
        getch();
}
 
//funktia vvoda bukv v spisok
void insert(LISTNODEPTR *sPtr, char value){
        LISTNODEPTR newPtr, prevPtr, curPtr;
        newPtr=(LISTNODEPTR)malloc(sizeof(LISTNODE));
        if(newPtr!=NULL){
           newPtr->data=value;
           newPtr->nextPtr=NULL;
           prevPtr=NULL;
           curPtr=*sPtr;
           while(curPtr!=NULL&&value>curPtr->data){
              prevPtr=curPtr;
              curPtr=curPtr->nextPtr;
           }
           if(prevPtr==NULL){
              newPtr->nextPtr=*sPtr;
              *sPtr=newPtr;
           }
           else{
              prevPtr->nextPtr=newPtr;
              newPtr->nextPtr=curPtr;
           }
        }
        else
           printf("%c  not inserted. No memory avaible\n", value);
}
 
//funktia raspechatki spiska
void printList(LISTNODEPTR curPtr){
        if(curPtr==NULL)
           printf("List is empty\n");
        else{
           printf("The list is: \n");
           while(curPtr!=NULL){
              printf("%c-> ", curPtr->data);
              curPtr=curPtr->nextPtr;
           }
           printf("NULL\n\n");
        }
}
 
//funktia obiedinenia dvuh spiskov
void concatenate(LISTNODEPTR startPtr, LISTNODEPTR startPtr2){
        LISTNODEPTR curPtr;
        curPtr=startPtr;
        while(curPtr!=NULL){
           printf("%c-> ", curPtr->data);
           curPtr=curPtr->nextPtr;
        }
        if(curPtr->nextPtr==NULL) {
           curPtr->nextPtr=startPtr2;
        }
}
В программе все работает, но
проблема, мне кажется в функции объединения списков concatenate.
функция получает два указателя на начало первого списка (startPtr)и на начало второго списка (startPtr2).
Дальше в while я дохожу до конца первого списка, т.е. до указателя последнего узла первого списка, который равен NULL и в if присваиваю ему указатель на начало второго списка:
curPtr->nextPtr=startPtr2;

Присваивание происходит, т.к.проверял, распечатывается второй список.
Т.е., если я правильно понимаю, связывание двух списков произошло.

Потом в main запускаю функцию печати списка с параметром указателем на начало списка printList(startPtr) - печатается только первый список, а второй присоединенный -нет!

вот в этом и загвоздка. не могу понять почему.
itnomad вне форума Ответить с цитированием
Старый 04.11.2011, 11:54   #26
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

У вас ошибка в конкатенации списков

Код:
void concatenate(LISTNODEPTR startPtr, LISTNODEPTR startPtr2)
{
  LISTNODEPTR curPtr;
  curPtr=startPtr;
  while (curPtr!=NULL)
  {
    printf("%c-> ", curPtr->data);
    curPtr=curPtr->nextPtr;
  }
  // раз мы тут, то условие для while не выполнилось. Т.е. curPtr==NULL.
  // Но дальше идет обращение по этому указателю (выделено жирным).
  // Лечится исправлением условия: while (curPtr->nextPtr != NULL) {...}
  if (curPtr->nextPtr==NULL) // этот if после исправления не нужен.
  {
     curPtr->nextPtr=startPtr2;
  }
}
Второй вариант и более устойчивый к передаче в ф-ию нулевых указателей - это засунуть иф в тело цикла while c выходом из цикла при срабатывании условия в ифе:
Код:
void concatenate(LISTNODEPTR startPtr, LISTNODEPTR startPtr2)
{
  LISTNODEPTR curPtr;
  curPtr=startPtr;
  while(curPtr!=NULL)
  {
    printf("%c-> ", curPtr->data);
    if(curPtr->nextPtr==NULL)
    {
       curPtr->nextPtr=startPtr2;
       break;
    }
    curPtr=curPtr->nextPtr;
  }
}
_Ч_ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамические списки Ольчик Паскаль, Turbo Pascal, PascalABC.NET 4 15.01.2012 14:33
Динамические списки. Светусик Паскаль, Turbo Pascal, PascalABC.NET 0 22.12.2010 17:50
динамические списки tricksler Помощь студентам 0 10.12.2010 21:15
Динамические списки Saawa Помощь студентам 4 02.12.2009 18:35
Динамические списки lubafffka Паскаль, Turbo Pascal, PascalABC.NET 6 17.12.2008 21:59