Консультации по курсу ООП 2011

Задавайте здесь свои вопросы

Модератор: Преподаватели

Консультации по курсу ООП 2011

Сообщение Telnov » 05 сен 2011, 10:57

Учебные материалы и задания по курсу ООП находятся здесь.
На этом форуме можно задавать вопросы и обмениваться мнениями по изучаемому курсу (лекции, лабораторный практикум, прочее).
По мере сил буду отвечать.
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Консультации по курсу ООП

Сообщение Strelitsyn » 24 сен 2011, 09:07

Здравствуйте.
При запуске программы выскакивает сообщение "Нарушение прав доступа при чтении", указывает на strcmp из функции FindItem. Не могу понять, в чём ошибка. Вот часть кода:

Код: выделить все
#include "stdafx.h"
#define N 5
#define S 20

struct item
{
   char key[S];
   item* next;
};

void AddItem(item*&, char*);
item* FindItem(item*, char*);
void PrintList(item*);


int _tmain(int argc, _TCHAR* argv[])
{
   item* L=0;
   AddItem(L,"a");
   AddItem(L,"b");
   AddItem(L,"c");
   PrintList(L);

   item* P;
   P=FindItem(L,"b");

   getch();
   return(0);
}



item* FindItem(item* pFirst, char* s)
   //Поиск элемента, равного строке s
   //Возвращает указатель на этот элемент
{
   item* P = pFirst;
   while (strcmp(P->key, s) != 0 || P != 0)
      P = P->next;
   return P;
}


void AddItem(item*& pFirst, char* s)
   //Добавление в список нового элемента
{
   if (pFirst == 0)
   {
      pFirst = new item;
      strcpy(pFirst->key, s);
      pFirst->next = 0;
   }
   else
   {
      item* P1 = new item;
      strcpy(P1->key, s);
      P1->next=0;
      item* P2 = pFirst;
      while (P2->next != 0)
         P2 = P2->next;
      P2->next = P1;
   }
}

void PrintList(item* pFirst)
   //Вывод на экран всех элементов списка
{
   item* P = pFirst;
   while (P != 0)
   {
      puts(P->key);
      P = P->next;
   }
}
Аватар пользователя
Strelitsyn
Студент
 
Сообщений: 5
Зарегистрирован: 06 сен 2011, 19:24
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: выскакивает сообщение "Нарушение прав доступа ...

Сообщение Telnov » 24 сен 2011, 14:56

Не прогоняя ваш код на компьютере, выскажу предположение о причинах ошибки.
Это ошибка адресации. Обращаетесь к памяти, которая вам не принадлежит, либо при создании списка затираете свой собственный код.
Происходит это вот почему.
При создании элемента списка операторами вида pFirst = new item вы, очевидно, предполагаете, что память вам будет выделена не только под структуру типа item, но и под строку char key[S] в этой структуре.
Это не так. Память под строку char key[S] нужно каждый раз получать явно, опять оператором new.
Имя массива символов key есть синоним адреса первого элемента массива. После создания в динамической памяти объекта типа item поле key содержит "мусор".
Поэтому, когда вы пишите в строку strcpy(pFirst->key, s), вы пишите неизвестно куда. Возможно, даже на свой собственный код.
Далее с вашим кодом может происходить всё, что угодно. Последствия непредсказуемы.

Корректный пример создания списка смотрите в лекции "ООП Тема 04. С++ Структуры, препроцессор, динамическая память", "Пример: ввод строк в динамическую память и выдача их в обратном порядке".
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Консультации по курсу ООП

Сообщение starovoitov » 10 окт 2011, 21:38

Здравствуйте Виктор Петрович! Я написал лаб. работу по теме "кольцевой односвязный список", прошу вас высказать свои замечания. Заранее извиняюсь за то, что описания функций объявлены перед главной функцией, я это исправлю.
Код: выделить все
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>

#define N 70


struct Node{

int d;            //ключ, номер элемента в списке
char s[N];        //строка произвольной длины
Node* next;       // указатель на следующий элемент

};

Node* First( int d ){         //cоздание первого элемента
   Node* pv=new Node;      //в функцию в качестве аргумента передаётся номер первого элемента
     pv->d = d;              //возвращает указатель на созданный элемент
    pv->next = pv;
 return pv;
 }





  Node* Find( Node* const pbeg, int d, int i ){    //поиск по ключу, продолжается не больше чем есть элементов
   if(pbeg == NULL){
      printf("the list is empty");
      return 0;
   }                                           // в списке, так как конец замкнут на первый элемент
 Node *pv = pbeg;                                  //аргументы функции: неизменяемый указатель на начало списка pbeg
                                                 //i - количество элементов списка
 for(i; i>0; i--){                               //функция возвращает указатель на найденный элемент               
   if(pv->d == d)break;
   pv = pv->next;
   }
    return pv;
    }


     int Add( Node** pend, int d, Node* pbeg, int i ){      // добавляет cледующий элемент в конец
  Node* pv = new Node;                                       //при этом изменяется значение указателя на конечный элемент
                                                           
  pv->d = d;
  pv->next = pbeg;
  (*pend)->next = pv;
  *pend = pv;


  return i+1;                        //возвращает количество элементов после добавления                                                                 
  }


  void RenumberKey( Node* pbeg, int i ){  //перенумерует ключи по порядку
           Node* pv = new Node;
            pv = pbeg;
       for(int u = 1; u <= i; u++){
         pv->d = u;
       pv = pv->next;
     }
   }


    int Insert( Node** pend, int d, Node** pbeg, int i ){      // вставка элемента по ключу
  Node* pv = new Node;                              //при этом меняется указатель на конечный элемент
  Node* pv1 = new Node;                            //может измениться и указатель на начало
  pv1 = Find( *pbeg, d, i );                 
  if( d == 1 ){          //случай вставки в начало   

  printf("\n");
//int j;

 RenumberKey( *pbeg, i+1 );

 pv1 = *pbeg;

  pv->d = 1;
  pv->next = pv1;
  *pbeg = pv;

   (*pend) = Find(*pbeg, i, i);


  (*pend)->next=pv;


  }
if( d != 1 && d != i){  //вставка в середину

  pv1->d = d+1;


  pv1 = pv1->next;

  pv1 = Find(*pbeg, d+1, i);
   pv->d = d;
   pv->next = pv1;
    pv1 = Find(*pbeg, d-1, i);
      pv1->next = pv;

  *pend = Find(*pbeg, i, i);

  RenumberKey(*pbeg, i+1);
 }

  if( d == i ){                 //вставка в конец
while( pv1->d != 1)
{

  pv1->d = d++;
   pv1 = pv1->next;

  }

   pv->d  = d;
   pv->next = pv1;
    pv1 = Find(*pbeg, d-1, i);
     pv1->next = pv;
      *pend = Find(*pbeg, i+1, i+1);

   }
  return i+1;         //количество элементов увеличивается на 1
  }


  int Remove(Node** pbeg, Node** pend, int d, int i){    //удаления выбранного по ключу элемента
                                                          //при этом могут измениться указатели на начало и конец
 Node* pkey = Find(*pbeg, d, i); //вспомогательный указатель для обхода

   if( pkey->d ==1 ){   //удаления начального
 
      *pbeg = pkey->next;
   (*pend)->next = *pbeg;

   }


else  if ( pkey->d == d && d !=1 ){ //любого другого
    Node* pkey1 = Find(*pbeg, d-1, i);
   pkey1->next = (pkey1->next)->next;
      if(pkey == *pend) *pend = pkey1;   
   }
   delete pkey; //удаление вспомогательного указателя, освобождение памяти
 
   return i-1;  // количество элементов уменьшается на 1
      }

 void PrintNext(Node* pbeg, int i){ //печать списка вперёд

    if(pbeg == NULL){
      printf("the list is empty");
   
   }           
 for(int j = i; j>0; j--){
printf(" %d %s", pbeg->d, pbeg->s);
pbeg = pbeg->next;
 }
  }

void PrintPrev(Node* pbeg, int i){//печать назад
   if(pbeg == NULL){
      printf("the list is empty");
   }           
Node* pv = new Node;
 printf("\n");

for(int k=i; k>0; k--){   
 
   pv = Find(pbeg, k, i);
 printf(" %d %s", pv->d, pv->s);

  }
   }

int RemoveEqual(Node* pbeg, Node* pend, int i){ //удаляет одинаковые элементы

   Node *pv1 = new Node; //два вспомогательный указателя для обхода
    Node *pv2 = new Node;

pv1 = pbeg;
pv2 = pbeg->next;
for(int j=i; j>1; j--){ //обход
   while(pv2->d != 1){
       if(strcmp(pv1->s, pv2->s) == 0){
       i=Remove(&pbeg, &pend, pv2->d, i);
    }
pv2 = pv2->next;
 }
pv1 = pv1->next;
pv2 = pv1->next;
}
return i;
}


void SortList(Node* pbeg, int i){ //сортировка пузырьком строк по алфавиту
   Node *pv1 = new Node; //указатели для обхода
   Node *pv2 = new Node;

pv1 = pbeg;
pv2 = pbeg->next;

char str[N];        //буферная строковая переменная
for(int j = i; j > 0; j--){

 while(pv2->d != 1){

   if(strcmp(pv1->s, pv2->s) > 0){     //сортировка
            strcpy(str, pv1->s);
            strcpy(pv1->s, pv2->s);
            strcpy(pv2->s, str);
                    }
  pv2 = pv2->next;

 }
pv1 = pv1->next;
pv2 = pv1->next;
}

}

int ReadFile(Node** pend, Node* pbeg, FILE *fin, const char* filename, int i){//считывание из текстового файла
   char str[N];                                                               //pbeg и pend показывают кудаа размещать список
   if((fin = fopen(filename,"rt")) == 0)
   printf("Error when open input file\n");
   else {

while(fgets(str, N, fin)){  //чтение идет построчно, прочитанная строка преобразуется в структуру


(*pend)->d = atoi(&str[0]);
strncpy((*pend)->s, &str[2],78);
i = Add(&(*pend), i, pbeg,i);

 }
(*pend) = Find(pbeg, i, i);
 }
    fclose(fin);

return i; //возвращает количество прочитанных элементов

}

int RemoveAll(Node** pbeg, Node** pend, int i){      //удаляет все элементы, обнуляет счётчик

    while(i)i = Remove(&(*pbeg), &(*pend), (*pend)->d, i);
 return i;
 }

 void WrightFile(FILE* fout, const char* filename, int i, Node* pbeg){//записывает список в текстовый файл
    Node* pv=new Node;//указатель для обхода
    pv=pbeg;
    fout=fopen(filename,"at");

   for(int j=i; j>0; j--){
 fprintf(fout,"%d %s",pv->d,pv->s);
pv=pv->next;
}

    fclose(fout);
}


Node* CopyLists(Node* pbeg, int i, Node** pend2, Node** pbeg2){//копирует список в выбранный участок памяти,
 *pbeg2 = First(1);                                              //определяемый pbeg2,pend2
 strcpy((*pbeg2)->s, pbeg->s);
 *pend2 = *pbeg2;

      for(int j = 2; j <= i; j++){
      Add(&(*pend2), j, *pbeg2, i);
      strcpy((*pend2)->s, pbeg->next->s);
      pbeg=pbeg->next;
      }


 return *pbeg2; //возвращает указатель на созданную копию
}



int Сoncatenation(Node* pbeg, Node* pbeg2, int i, int i2, Node** pbeg3, Node** pend3){ //конкатенация 2 списков в выбранные указатели pend3 и pbeg3
int i3=i2+i; //количество элементов у результата
  Node* pbegt1=new Node;  //вспомогательные указатели для склеивания копий списков
  Node* pbegt2=new Node;
CopyLists(pbeg, i, &(pbegt1), &(*pbeg3));

CopyLists(pbeg2, i2, &(*pend3), &(pbegt2));

(pbegt1)->next = pbegt2;
(*pend3)->next = (*pbeg3);


return i3; //количество элементов у результата
}


 int Union(Node** pbeg3, Node** pend3, Node* pbeg2, Node* pbeg, int i, int i2){//операция объединения
CopyLists(pbeg, i, &*pend3, &*pbeg3);
Сoncatenation(pbeg, pbeg2, i, i2, &*pbeg3, &*pend3); //конкатенация
    int i3=i2+i;
    RenumberKey(*pbeg3,i3);

i3=RemoveEqual(*pbeg3, *pend3, i3); //удаление одинаковых
     RenumberKey(*pbeg3, i3);
 
  return i3; //количество элементов результата
 }

 int Intersection(Node** pbeg3, Node** pend3, Node* pbeg2, Node* pbeg, int i, int i2){//пересечение
CopyLists(pbeg, i, &*pend3, &*pbeg3);
int i3 = Сoncatenation(pbeg, pbeg2, i, i2, &*pbeg3, &*pend3); //конкатенация
 RenumberKey(*pbeg3, i3);

                      //удаление элементов, не принадлежащих обим операндов
Node* pv1 = new Node;  //указатели для обхода
Node* pv2 = new Node;
pv1 = *pbeg3;
pv2 = pv1->next;

Node* pv3 = new Node;
Node* pv4 = new Node;
pv3=First(1);
pv4=pv3;

int count = 0;


for(int j=2; j<i3; j++){
   while(pv2->d != 1){
       if(strcmp(pv2->s , pv1->s)==0){
       strcpy(pv4->s,pv1->s);
       Add(&pv4,j,pv3,j);
       count++;
    }
pv2 = pv2->next;
 }
pv1 = pv1->next;
pv2 = pv1->next;
}


*pbeg3 = pv3;
*pend3 = Find(*pbeg3, count,i3);
(*pend3)->next = *pbeg3;
  return count;  //количество элементов результата

   }

   ///////////////////////////////////////////////////////////////////

 void main(){//cчитывает из текстовых файлов два списка, выполняет их пересечение. Потом сортирует второй и
              //выводит в обратном порядке,удаляет результат пересечения. Отсортированный список записывает в текстовый файл
 int i=0;        //вставляет в первый список элемент с ключом 3
 int i2=0;


FILE* fin,* fout;

Node *pend=First(1);
Node *pbeg=pend;
Node *pend2=First(1);
Node *pbeg2=pend2;


i=ReadFile(&pend,pbeg,fin,"c:\\temp\\fin.txt",i);
i2=ReadFile(&pend2,pbeg2,fin,"c:\\temp\\fin2.txt",i2);

 Node* pbeg3=new Node;
 Node* pend3=new Node;
 
 printf("The first list:\n");
 PrintNext(pbeg,i);
 printf("\n");

   printf("\n");
    printf("The second list:\n");
  PrintNext(pbeg2,i2);
   printf("\n");

   
int i3 = Intersection(&pbeg3,&pend3,pbeg2,pbeg,i,i2);//Union(&pbeg3,&pend3,pbeg2,pbeg,i,i2);


printf("\n");
 
  // RemoveAll(&pbeg3,&pend3,i3);
printf("The intersection list:\n");
  PrintNext(pbeg3,i3);
  i = Insert( &pend, 3, &pbeg, i );
  SortList(pbeg2, i2);
 PrintPrev(pbeg2,i2);
   printf("\ncount of intersection elements:%d\n",i3);
   PrintNext(pbeg,i);
   
    printf("\nsorting list:%d\n",i2);
   SortList(pbeg2, i2);
 PrintPrev(pbeg2,i2);

   WrightFile(fout, "c:\\temp\\fin.txt", i2,  pbeg2);
      RemoveAll(&pbeg3,&pend3,i3);
  getch();
        }
Аватар пользователя
starovoitov
Студент
 
Сообщений: 2
Зарегистрирован: 07 сен 2011, 08:39
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

... по теме "кольцевой односвязный список"

Сообщение Telnov » 10 окт 2011, 23:02

Очень хорошо. Ваш код посмотрел.
Вопрос такой: а как ваш софт взаимодействует с пользователем? Ведь он должен выполнять ряд операций над списками (см. задание).
Пожалуйста, подумайте над этим. Параллельно готовьте отчет по лаб. работе.
Обсудить работу можно будет завтра, после лекции.
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Односвязный список

Сообщение Strelitsyn » 16 окт 2011, 22:30

Виктор Петрович, возникли проблемы с записью/чтением текстовых файлов. Я читал, что при записи в текстовый файл происходит преобразование символов '\0' -> '\n'. Однако у меня в программе такого не происходит, символ '\0' теряется, все строчки соединяются в одну. Более того, при чтении файла, созданного в блокноте и состоящего из нескольких строчек, вместо одного переноса строки появляется два.

Код: выделить все
#include <stdio.h>
#include <tchar.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

const int STR_LEN = 20;
const int FN_LEN = 20;
const int DIR = 1;
const int BACK = -1;

struct item
{
   char* key;
   item* next;
};

void AddItem(item*&, char*);
item* CopyList(item*);
int DeleteItem(item*&, item*&);
int FindItem(item*, item*&, char*);
void PrintList(item*, int);
void DeleteDblItems(item*);
int CountItems(item*);
item* DirectIterator(item*);
void SortList(item*&);
item* LinkLists(item*, item*);
item* SubtrLists(item*, item*);
item* CrossLists(item*, item*);
int SaveList(item*, FILE*);
int OpenList(item*&, FILE*);
void Menu1();
void Menu2(item*);
void Menu3(item*, item*);

int _tmain(int argc, _TCHAR* argv[])
{
   Menu1();
   return(0);
}

void DeleteList(item*& pFirst)
   //Удаление всего списка
{
   while (pFirst != 0)
      DeleteItem(pFirst, pFirst);
}

void AddItem(item*& pFirst, char* Str)
   //Добавление в начало списка нового элемента
{
   item* P = new item;
   P->key = new char[strlen(Str)];
   strcpy(P->key, Str);
   P->next = pFirst;
   pFirst = P;
}

item* CopyList(item* pFirst)
   //Возвращает указатель на копию списка
{
   item* pNewFirst = 0;
   item* P = pFirst;
   while (P != 0)
   {
      AddItem(pNewFirst, P->key);
      P = P->next;
   }
   return pNewFirst;
}

int FindItem(item* pFirst, item*& pResult, char* Str)
   //Поиск элемента, равного строке Str
   //pResult - указатель на результат поиска
   //0 - элемент найден
   //1 - список пуст
   //2 - элемент не найден
{
   if (pFirst == 0)
      return 1;
   pResult = pFirst;
   while (pResult != 0 && strcmp(pResult->key, Str) != 0)
      pResult = pResult->next;
   if (pResult == 0)
      return 2;
   return 0;
}

int DeleteItem(item*& pFirst, item*& pCur)
   //Удаление элемента, на который указывает pCur
   //0 - удаление успешно
   //1 - список пуст
   //2 - элемент не найден или не существует
{
   if (pFirst == 0)
      return 1;
   if (pCur == 0)
      return 2;   
   item* P;
   if (pCur == pFirst)
   {
      P = pCur;
      pFirst = pFirst->next;
      pCur = pFirst;
      delete P;
      return 0;
   }
   P = pFirst;
   while (P->next != pCur)
   {
      P = P->next;
      if (P == 0)
         return 2;
   }
   P->next = pCur->next;
   P = pCur;
   pCur = pCur->next;
   delete P;
   return 0;
}

item* DirectIterator(item* pFirst)
   //Проход в прямом направлении
   //Возвращает указатель на последний элемент
{
   item* pResult = pFirst;
   if (pResult != 0)
      while (pResult->next != 0)
      {
         pResult = pResult->next;
      }
   return pResult;
}

void PrintList(item* pFirst, int Direction)
   //Вывод на экран всех элементов списка
   //Direction - выбор направления:
   //DIR - в прямом направлении
   //BACK - в обратном направлении
{
   if (Direction == BACK)
   {
      if (pFirst != 0)
      {
         PrintList(pFirst->next, BACK);
         puts(pFirst->key);
      }
   }
   else
   {
      item* P = pFirst;
      while (P != 0)
      {
         puts(P->key);
         P = P->next;
      }
   }
}

void DeleteDblItems(item* pFirst)
{
   item* P1 = pFirst;
   item* P2;
   while (P1 != 0)
   {
      //чтобы избежать лишних итераций
      //рассматриваем только часть списка после P1
      P2 = P1;
      while (P2->next != 0)
      {
         if (strcmp(P1->key, P2->next->key) == 0)
            DeleteItem(P1, P2->next);
         else
            P2 = P2->next;
      }
      P1 = P1->next;
   }
}

int CountItems(item* pFirst)
   //Возвращает количество элементов
{
   item* P = pFirst;
   int i = 0;
   while (P != 0)
   {
      i++;
      P = P->next;
   }
   return i;
}

void SortList(item*& pFirst)
{
   //пустой или из 1 элемента:
   if (pFirst == 0 || pFirst->next == 0) return;

   //сортируем по алгортиму выбора,
   //пропуская первый элемент

   item* pNew = 0;
   item* P;
   item* pMin;
   item* pPrev; //предшествующий минимальному элементу
   
   while (pFirst->next != 0)
   {
      P = pFirst->next;
      pPrev = pFirst;
      while (P->next != 0)
      {
         if (strcmp(pPrev->next->key, P->next->key) < 0)
            pPrev = P;
         P = P->next;
      }
      P = pPrev;
      pMin = pPrev->next;
      P->next = P->next->next;
      pMin->next = pNew;
      pNew = pMin;
   }

   //теперь ставим первый элемент на нужное место
   //по методу вставки
   pFirst->next = pNew;
   P = pFirst;
   if (strcmp(pFirst->key, pFirst->next->key) < 0)
      return; //pFirst - минимальный
   do
      P = P->next;
   while (P->next != 0 && strcmp(P->next->key, pFirst->key) < 0);
   pPrev = P->next; //pPrev в качестве промежуточной переменной
   P->next = pFirst;
   pFirst->next = pPrev;
   pFirst = pNew;
}

item* LinkLists(item* pFirst1, item* pFirst2)
   //Объединение списков
{
   item* pCFirst1 = CopyList(pFirst1);
   item* pCFirst2 = CopyList(pFirst2);
   item* pCLast1 = pCFirst1;
   if (pCLast1 != 0)
   {
      while (pCLast1->next != 0)
         pCLast1 = pCLast1->next; //доходим до конца списка
      pCLast1->next = pCFirst2;  //связываем списки
   }
   else
      pCFirst1 = pCFirst2;
   return pCFirst1;
}

item* SubtrLists(item* pFirst1, item* pFirst2)
   //Возвращает указатель на результат вычитания списка pFirst2 из списка pFirst1
{

   item* pNewFirst = 0;
   item* P1 = pFirst1;
   item* P2;
   while (P1 != 0)
   {
      if (FindItem(pFirst2, P2, P1->key) != 0)
         AddItem(pNewFirst, P1->key);
      P1 = P1->next;
   }
   return pNewFirst;
}

item* CrossLists(item* pFirst1, item* pFirst2)
   //Возвращает указатель на результат пересечения списка pFirst2 и списка pFirst1
{

   item* pNewFirst = 0;
   item* P1 = pFirst1;
   item* P2;
   while (P1 != 0)
   {
      if (FindItem(pFirst2, P2, P1->key) == 0)
         AddItem(pNewFirst, P1->key);
      P1 = P1->next;
   }
   return pNewFirst;
}

int SaveList(item* pFirst, FILE* F)
   //Сохранение списка в файл
{
   int l;
   if (pFirst == 0)
      return 1;
   item* P = pFirst;
   while (P != 0)
   {
      fputs(P->key, F);
      P = P->next;
   }
   return 0;
}

int OpenList(item*& pFirst, FILE* F)
   //загрузка списка из файла
{
   if (F == 0)
      return 1;
   char strBuf[STR_LEN];
   
   //считываем первую строку,
   //чтобы впоследствии не потерять указатель pFirst
   pFirst = new item;
   fgets(strBuf, STR_LEN, F);
   pFirst->key = new char [strlen(strBuf)];
   strcpy(pFirst->key, strBuf);
   item* P = pFirst;
   P->next = 0;
   
   //считываем остальные строки
   while (!feof(F))
   {
      fgets(strBuf, STR_LEN, F);
      P->next = new item;
      P = P->next;
      P->key = new char [strlen(strBuf)];
      strcpy(P->key, strBuf);
      P->next = 0;
   }
   return 0;
}

void Menu1()
{
   const char* MENU_1 =
"______\n\n \
1 - New list\n \
2 - Open list\n \
Esc - Exit\n";

   char Key;
   char FileName[FN_LEN];
   item* pL1;
   FILE* F;

   for(;;)
   {
      system("cls");
      puts(MENU_1);
      pL1 = 0;
      Key = getch();
      switch (Key)
      {
      case '1':
         {
            Menu2(pL1);
            break;
         }
      case '2':
         {
            system("cls");
            printf("Enter the name of file: \n");
            gets(FileName);
            F = fopen(FileName,"r");
            if (!F)
            {
               printf("Error open file");
               break;
            }
            OpenList(pL1, F);
            fclose(F);
            Menu2(pL1);
            break;
         }
      case 27:
         {
            return;
         }
      default:
         {
            printf("Wrong instruction");
            break;
         }
      }
   }
}

void Menu2(item* pL1)
{
   const char* MENU_2 =
"______\n\n \
1 - Save list\t\t 7 - Change print direction\n \
2 - Add item\t\t 8 - Link with other list\n \
3 - Find item\t\t 9 - Cross with other list\n \
4 - Count items\t 0 - Subtract other list\n \
5 - Sort list\t\t Esc - Close list\n \
6 - Delete double items\n";

   item* pL2;
   item* pL3;
   item* pCur;
   char Key, FileName[FN_LEN], strBuf[STR_LEN];
   int Direction = DIR;
   FILE* F;

   for(;;)
   {
      system("cls");
      PrintList(pL1, Direction);
      puts(MENU_2);
      Key = getch();
      switch (Key)
      {
      case '1':
         {
            system("cls");
            printf("Enter the name of file: \n");
            gets(FileName);
            F = fopen(FileName, "w");
            if (!F)
            {
               printf("Error open file");
               break;
            }
            SaveList(pL1, F);
            fclose(F);
            break;
         }
      case '2':
         {
            system("cls");
            printf("Enter the string: \n");
            gets(strBuf);
            AddItem(pL1, strBuf);
            break;
         }
      case '3':
         {
            system("cls");
            printf("Enter the string: \n");
            gets(strBuf);
            switch (FindItem(pL1, pCur, strBuf))
            {
            case 1:
               {
                  system("cls");
                  printf("Empty list");
                  getch();
                  break;
               }
            case 2:
               {
                  system("cls");
                  printf("No such item");
                  getch();
                  break;
               }
            default:
               Menu3(pL1, pCur);
            }
            break;
         }
      case '4':
         {
            system("cls");
            printf("%i items", CountItems(pL1));
            getch();
            break;
         }
      case '5':
         {
            SortList(pL1);
            break;
         }
      case '6':
         {
            DeleteDblItems(pL1);
            break;
         }
      case '7':
         {
            Direction = -(Direction);
            break;
         }
      case '8':
         {
            printf("Enter the name of file: \n");
            gets(FileName);
            F = fopen(FileName, "r");
            if (!F)
            {
               printf("Error open file");
               break;
            }
            OpenList(pL2, F);
            fclose(F);
            pL3 = LinkLists(pL1, pL2);
            DeleteList(pL2);
            Menu2(pL3);
            break;
         }
      case '9':
         {
            printf("Enter the name of file: \n");
            gets(FileName);
            F = fopen(FileName, "r");
            if (!F)
            {
               printf("Error open file");
               break;
            }
            OpenList(pL2, F);
            fclose(F);
            pL3 = CrossLists(pL1, pL2);
            DeleteList(pL2);
            Menu2(pL3);
            break;
         }
      case '0':
         {
            printf("Enter the name of file: \n");
            gets(FileName);
            F = fopen(FileName, "r");
            if (!F)
            {
               printf("Error open file");
               break;
            }
            OpenList(pL2, F);
            fclose(F);
            pL3 = SubtrLists(pL1, pL2);
            DeleteList(pL2);
            Menu2(pL3);
            break;
         }
      case 27:
         {
            DeleteList(pL1);
            return;
         }
      default:
         {
            printf("Wrong instruction");
            break;
         }
      }
   }
}

void Menu3(item* pL1, item* pCur)
{
   const char* MENU_3 =
"______\n\n \
1 - Delete item\n \
Esc - Back\n";

   char Key;

   for(;;)
   {
      system("cls");
      puts(pCur->key);
      puts(MENU_3);
      Key = getch();
      switch (Key)
      {
      case '1':
         {
            DeleteItem(pL1, pCur);
            return;
         }
      case 27:
         {
            return;
         }
      default:
         {
            printf("Wrong instruction");
            break;
         }
      }
   }
}
Аватар пользователя
Strelitsyn
Студент
 
Сообщений: 5
Зарегистрирован: 06 сен 2011, 19:24
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: проблемы с записью/чтением текстовых файлов

Сообщение Telnov » 17 окт 2011, 00:06

При чтении строк функция fgets() преобразует '\n' -> '\0'.
Насколько я помню, когда fputs() записывает в поток содержимое строки, преобразования символов '\0' -> '\n' не происходит. Более того, и сам символ '\0' в поток не записывается. Нужно самостоятельно позаботиться о разделении строк.

Вообще, с управляющими символами следует обращаться осторожно. Если поток открыт в текстовом режиме, при записи могут произойти преобразования некоторых управляющих символов. Это значит, что однозначного отображения строки в файл может и не быть. Однако если поток открыт в двоичном режиме, никаких преобразований символов не будет и строка отобразится в файл "один к одному".
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Домашнее задание 1

Сообщение Strelitsyn » 26 окт 2011, 13:44

Вопрос по номеру 17. Функция одно общее число всех этих символов, или три числа отдельно для каждого символа?

Стрелицын, выражайтесь, пожалуйста, яснее. С трудом понял суть вашего вопроса.
Ответ: как вам будет угодно.

В.Тельнов
Аватар пользователя
Strelitsyn
Студент
 
Сообщений: 5
Зарегистрирован: 06 сен 2011, 19:24
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Консультации по курсу ООП

Сообщение Strelitsyn » 16 ноя 2011, 13:54

Возник вопрос по второй лабораторной:
Я использовал пример полиморфного контейнера из лекции и создал в проекте файл Polymorph.h. Как указать в методе get() класса CString, что нужно вывести поле S в textBox1? Я делал так:
Код: выделить все
CString& get() { textBox1->Text = S; return *this; }

Компилятор пишет, что textBox1 - необъявленный идентификатор, хотя подключен файл Form1.h.
Аватар пользователя
Strelitsyn
Студент
 
Сообщений: 5
Зарегистрирован: 06 сен 2011, 19:24
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: ... необъявленный идентификатор, хотя подключен файл For

Сообщение Telnov » 16 ноя 2011, 19:21

1. Для целей вашего проекта лучше подходит объект ListBox, а не TextBox. Он как раз предназначен для выдачи массивов строк.
2. При занесении данных в виджет лучше пользоваться методами объекта (см. метод AppendText), а не писать данные напрямую в объект.

Теперь по существу вашего вопроса.
Видимо, в вашем проекте функция get() и указатель textBox1 оказались в разных пространствах имен. Внимательно разберитесь со структурой проекта и самостоятельно найдите решение для вашей ситуации. Это одна из целей лабораторной работы.

К сожалению, в помощь вам у меня сейчас нет под рукой образца проекта, аналогичного вашему, на C++.
Поэтому во вложении к посту смотрите решение на C#, где аналогичная проблема с пространствами имен решена.
Там используется общее пространство имен namespace КлиентСервер.
Программное решение включает в себя пять проектов, и моделирует на локальной машине работу распределенного сетевого приложения.
Пример вполне рабочий, для выдачи данных использует как раз ListBox.
Если будете его пробовать - не запускайте процесс "Машина 8", там код ещё не дописан.

Я не буду возражать, если всю Лабораторную №2 вы выполните на C#. Это даже интереснее.
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Консультации по курсу ООП 2011

Сообщение Tohin » 24 мар 2012, 12:36

Здравствуйте, Виктор Петрович.
Посмотрите, пожалуйста, корректно ли реализована функция извлечения элемента слева?!
p.s. функция работает.

dek* Extract_Left(pdek &begin) //извлечение элемента из начала
{
while(begin!=end) //пока не останется 1 элемент в контейнере
{
pdek extr=new dek; //выделяем память
extr=begin;
printf("izvlechenniy element: ");
printf("%s", extr->mean); //выводим значение первого элемента
begin=extr->next;
delete extr; //очищаем память
begin->prev=NULL;
return begin;
}
pdek extr=new dek; //выделяем память
extr=begin;
printf("izvlechenniy element: ");
printf("%s", extr->mean); //выводим значение первого элемента
begin=NULL;
delete extr; //очищаем память
printf("Konteiner pust \n");
}
Назаркин Антон, ВТ-С09
Аватар пользователя
Tohin
Студент
 
Сообщений: 4
Зарегистрирован: 06 сен 2011, 18:16
Откуда: Обнинск
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Консультации по курсу ООП 2011

Сообщение MadeInUSSR » 24 мар 2012, 17:04

Вопрос по второй лабораторной работе. На сайте msdn вычитал , что и ArrayList и List реализуют интерфейс доступа к эдементу через индекс (Ilist вроде бы), но List быстрее. У меня задание реализовать динамический массив, какой класс лучше использовать??
Особенности производительности

Делая выбор между классами List<T> и ArrayList, предлагающими сходные функциональные возможности, следует помнить, что класс List<T> в большинстве случаев обрабатывается быстрее и является потокобезопасным. Если в качестве типа T класса List<T> используется ссылочный тип, оба класса действуют идентичным образом. Однако если в качестве типа T используется тип значений, необходимо принять во внимание особенности, связанные с реализацией и упаковкой.
Аватар пользователя
MadeInUSSR
Студент
 
Сообщений: 4
Зарегистрирован: 06 сен 2011, 17:35
Благодарил (а): 1 раз.
Поблагодарили: 0 раз.

Re: Делая выбор между классами List и ArrayList

Сообщение Telnov » 24 мар 2012, 18:20

List и ArrayList - насколько я помню, в Visual Studio 2010 оба шаблона классов реализованы на базе динамических массивов, и принципиальных различий между ними в плане производительности нет.
С точки зрения вашей лабораторной работы, выбор между этими двумя шаблонами классов - дело вкуса, не более того.
В.Тельнов

За это сообщение автора Telnov поблагодарил:
MadeInUSSR (24 мар 2012, 22:46)
Рейтинг: 25%
 
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Корректно ли реализована функция извлечения элемента?

Сообщение Telnov » 24 мар 2012, 18:37

Корректно ли реализована функция извлечения элемента слева? - насколько можно уяснить из приведенного фрагмента кода, реализована кошмарно, не грани фола.
Огорчаться не надо, при обучении первый код часто получается корявым.
Сейчас пространных замечаний не будет. Если этот код у вас хоть как-то работает, готовьте лабу к сдаче.
Содержательное обсуждение будет при очном разговоре.
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Консультации по курсу ООП 2011

Сообщение Strelitsyn » 01 апр 2012, 20:48

Виктор Петрович, посмотрите пожалуйста диаграмму прецедентов по ЛР №3 "Книжный магазин", выскажите замечания.

Сейчас очень занят, но чуть позже обязательно внимательно посмотрю и отвечу.
В.Тельнов
Аватар пользователя
Strelitsyn
Студент
 
Сообщений: 5
Зарегистрирован: 06 сен 2011, 19:24
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Консультации по курсу ООП 2011

Сообщение starovoitov » 04 апр 2012, 00:00

Здравствуйте! Я использую список STL для добавления в него полиморфного контейнера CPolymorph. Для этого я создаю указатель на абстрактный объект этого класса, присваиваю ему при помощи метода SET некое значение в виде строки, введенной с консоли и отправляю его в конец списка. Действие происходит в цикле. После этого я вывожу список на экран при помощи метода get. Выводится несколько раз значение элемента, которого я последним отправил в список. Вопрос состоит в том, как тогда это сделать правильно, чтобы в списке состояли все введенные элементы?
Объекты, которые отправляются в список - структуры, у которых одно поле целых чисел и одно поле строк.
Код: выделить все
#include <list>
#include<conio.h>
#include<iostream>
#include <fstream>
#include <string>
#include<stdio.h>

using namespace std;


class CPolymorph{                   //класс-предок
   
public:
virtual CPolymorph& get()=0;
virtual CPolymorph& set(int X, char *S) =0;
virtual CPolymorph& SET(char *buf) = 0;
virtual int getInt() = 0;
virtual char *getString() = 0;
};


class CStruct: public CPolymorph                //класс-потомок

{
   
   int I;
   char *S;
   
   
public:
   
   CStruct(){}
   CStruct(int i, char *s){    
      I = i;
       S = new char[strlen(s)+1];strcpy(S,s);

   }
   
   
   

    CStruct& get(){
      cout<<"Object CStruct:"<<I << " "<<S<<" "<<endl;   
   return *this;
   }
 
   
    CStruct& set(int i, char *s){   
       I = i;
       S = new char[strlen(s)+1];strcpy(S,s);
       return *this;
    }
   
    int getInt(){return I;}
    char* getString(){return S;}
     CStruct& SET(char *buf){
        char *BUF = new char[strlen(buf)+1];
        char BUF1[100];
       for(int i = 0; i < strlen(buf)+1; i++)
       {
         
          if (!isdigit((unsigned char)buf[i]))
             BUF1[i] = buf[i];
          else strcpy(&BUF1[i] , " ");
      
       }
        set(atoi(buf), BUF1);
        return *this;
     }

      
       friend ostream& operator<< (ostream& out, CStruct& C){
      return out <<C.getInt() <<" "<< C.getString()<<endl;
}

      friend istream& operator>> (istream& in, CStruct& C){
       in>> C.I  >> C.S;
      return in;
    }

   

   const CStruct& operator = (CStruct &P){
         if(this!= &P){
         CStruct *assignment = new CStruct;
         strcpy(assignment->S,P.S);
         assignment->I = P.I;
         return *assignment;
         }
      }


   bool operator< (const CStruct &P){
      if(strcmp(S,P.S)>0)
      return true;
   }
      bool operator> (const CStruct &P){
      if(strcmp(S,P.S)<0)
      return true;
   }
      bool operator== (const CStruct &P){
      if(strcmp(S,P.S)==0)
      return true;
   }

   
};





void main(){

CStruct l; 
list <CPolymorph*> c;      //создаю полиморфный контейнер
   
c.push_front(&l);
   
char buffer[256];       //буфер для введенной строки
char *S;
CPolymorph *p;             //указатель на абстрактный объект
   
   int j = 3;
   while(j){
   p = &l;              //пытаюсь так присвоить ему значение адреса объекта l
  std::cin>> buffer;
  S = new char[strlen(buffer)+1];
  strcpy(S, buffer);
  p->SET(S);
  c.push_back(p);
      j--;
   }


for (list <CPolymorph*>::iterator i = c.begin(); i!=c.end(); ++i)      //вывод на экран
    (*i)->get();

   getch();
}

Аватар пользователя
starovoitov
Студент
 
Сообщений: 2
Зарегистрирован: 07 сен 2011, 08:39
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Выводится несколько раз значение элемента

Сообщение Telnov » 04 апр 2012, 08:52

"... я вывожу список на экран при помощи метода get" - предполагаю, что вы опять наступаете на старые грабли. Если выводите список "вручную" - нужно использовать итератор, а не get.
А вообще-то, любой виджет сам себя всегда отображает на экране в актуальном состоянии.

Чтобы справиться с вашими проблемами, предлагаю следующий пошаговый алгоритм работы:

1. Самостоятельно и очень внимательно выполняете пример из лекций. Добиваетесь того, чтобы: а) он у вас работал; б) чтобы вы понимали, как он работает.
2. Добавляете в этот пример виджет Listbox, и выводите контейнер через него. Добиваетесь того, чтобы: а) это у вас работало; б) чтобы вы понимали, как это работает.
3. Вместо полиморфного контейнера из лекций используете готовый контейнер из STL. Опять добиваетесь того, чтобы: а) это у вас работало; б) чтобы вы понимали, как это работает.
Всё, лаба сделана.
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Консультации по курсу ООП 2011

Сообщение puncher » 07 апр 2012, 14:05

Виктор Петрович, можно ли воспользоваться динамическим преобразованием типов, во второй лабораторной работе, чтобы была возможность обратиться к свойствам и методам объекта-наследника? Если такое решение нельзя использовать, посоветуйте другое.
Аватар пользователя
puncher
Студент
 
Сообщений: 2
Зарегистрирован: 06 апр 2012, 11:48
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: воспользоваться динамическим преобразованием типов ...

Сообщение Telnov » 08 апр 2012, 09:52

Если говорить отвлеченно, динамическим преобразованием типов можно пользоваться всегда и везде, где это не запрещено синтаксисом языка. При этом нужно помнить, что преобразование типов - очень капризный искусственный приём, который при неосторожном использовании может привести к неприятным последствиям.

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

В случае, если проблема останется - выкладывайте фрагмент кода, попробую вам помочь.
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Консультации по курсу ООП 2011

Сообщение puncher » 08 апр 2012, 13:53

Вопрос задан в виде комментария в коде.
Код: выделить все
#include "stdafx.h"


#include <iostream>
#include <string>
#include <stdio.h>
#include <list>

using namespace std;

class CPolymorf
{
public:
   virtual CPolymorf& get() = 0;
};

class CInt: public CPolymorf
{
public: int X;
public:
   CInt();
   CInt(int x = 0){X = x;}
   CInt& get()
   {
      return *this;
   }
};

class CStr: public CPolymorf
{
public: string S;
public:
   CStr(string s){this->S = s;}
   CStr& get()
   {
      return *this;
   }
};


int main()
{
   list <CPolymorf*> c;
   list <CPolymorf*>::iterator it;
    string str;
   cin >> str;
   int val = 0;
   cin >> val;
   CStr* I = new CStr(str);
   CInt* S = new CInt(val);
   c.push_back(I);
   c.push_back(S);
   
   for(it = c.begin();it != c.end(); it++)
   {     
                //Как обратиться к свойствам объекта класса-потомка, которые не представлены в классе CPolymorf?
      (*it)->get();
   }
   return 0;
}
Аватар пользователя
puncher
Студент
 
Сообщений: 2
Зарегистрирован: 06 апр 2012, 11:48
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Как обратиться к свойствам объекта класса-потомка

Сообщение Telnov » 08 апр 2012, 15:31

В рамках данного упрощённого примера - напрямую никак не обратитесь, если у предка этих свойств не было.
Мудрить с преобразованием типов крайне не рекомендую.

Существует множество отработанных технологических приемов для решения задач такого рода. Они называются паттерны проектирования ПО. Изучаются на кафедре КССТ на 5-м курсе и в магистратуре.
Загляните, например, в Учебные материалы, курс "Программные средства САПР", лекция "Паттерны проектирования ПО (структурные)". Обозначенная вами задача может быть грамотно решена применением паттернов Адаптер, Мост, Декоратор, Фасад, и некоторых других.

Однако, мне по-прежнему неясно происхождение ваших проблем. Зачем такие сложности? Для лабораторного практикума 3-го курса ничего этого не требуется.
В.Тельнов
Аватар пользователя
Telnov
Преподаватель
 
Сообщений: 324
Изображения: 5
Зарегистрирован: 05 сен 2011, 00:19
Благодарил (а): 1 раз.
Поблагодарили: 10 раз.

Re: Консультации по курсу ООП 2011

Сообщение Tohin » 19 апр 2012, 12:32

Здравствуйте, Виктор Петрович!
Посмотрите, пожалуйста, отчет Владимира Борботько (ВТ-С09).
Вы говорили можно выложить, поскольку сегодня не было лабораторной работы!

Борботько - Л.р. №1 зачтена в ПТ.
В.Тельнов
Назаркин Антон, ВТ-С09
Аватар пользователя
Tohin
Студент
 
Сообщений: 4
Зарегистрирован: 06 сен 2011, 18:16
Откуда: Обнинск
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Консультации по курсу ООП 2011

Сообщение MadeInUSSR » 19 апр 2012, 19:42

Виктор Петрович при здаче второй лабораторной работы были заданы 2 вопроса: обертки, и как работает метод Sort. На первый вопрос ответил на л.р. Тут попытаюсь ответить на второй, по данному куску кода:
Код: выделить все
{
            Vector1.Sort(delegate(MyClassPolymorph Item1, MyClassPolymorph Item2)
            {
                return Item1.Info.CompareTo(Item2.Info);
            });
            binding1.ResetBindings(false);
        }


Функция Sort требует некий предикат в качестве аргумента. Предикатом в данном случае является анонимный метод, заключающийся в конструкции delegate{ }.
Вектор Vector1 состоит из объектов класса MyClassPolymorph. Каждый экземпляр класса ItemX имеет член Info, который является типом System.String. Метод CompateTo сравнивая 2 строки, возвращает некий результат . Он может иметь значение, которое сообщает о том, какая из сравнимаемых строк Больше. В зависимости от полученного результата сортировщик принимает решение о том, как именно должны быть упорядочены объекты. Иными словами предикат - это критерий, по которому вы говорите сортировщику, как должны быть упорядочены элементы контейнера Vector1.

Прилагаю проект, отчет, и задание.

А как это будет работать, если сравниваются не строки, а структуры?
В.Тельнов


В классе структур перегужен член info, структура приводиться к виду строки, и сравниваются как строки.
public override string Info
{
get
{
return (S + Separator + X.ToString());
}
set
{
if (FSM.Test(value) != FSM.StructState)
throw new MyException("\"" + value + "\" не является структурой");
if ((S = value.Split(new String[] { Separator }, StringSplitOptions.RemoveEmptyEntries)[0]).Length > 20)
throw new MyException("Слишком длинная строка");
X = Convert.ToInt32(value.Split(new String[] { Separator }, StringSplitOptions.RemoveEmptyEntries)[1]);
}
}

Хорошо. Для зачета по этой Л.р. ответьте ещё на один вопрос.
Раз уж вы использовали в языке C# конструкцию delegate - что является её аналогом в языке C++ ?
В.Тельнов

Делегат в C# - это аналог указателя на функцию в C++.

ОК. Выбирайте себе проект по Л.р. №3.
В.Тельнов
Аватар пользователя
MadeInUSSR
Студент
 
Сообщений: 4
Зарегистрирован: 06 сен 2011, 17:35
Благодарил (а): 1 раз.
Поблагодарили: 0 раз.

Re: Консультации по курсу ООП 2011

Сообщение Bichlander » 06 май 2012, 20:15

Здравствуйте, Виктор Петрович!
Мне был задан вопрос по поводу использования gcnew в приложении Windows Forms.
Вот мой ответ:

При компиляции в управляемый код компилятор преобразует исходный код в промежуточный язык Microsoft Intermediate Language (MSIL), представляющий собой независимый от процессора набор инструкций.
Когда компилятор создает код MSIL, одновременно создаются метаданные.
Код и метаданные помещаются в "управляемую сборку".
Перед выполнением код MSIL необходимо преобразовать в код для конкретного процессора, обычно с помощью JIT-компилятора,предоставляемого
CLR(Common Language Runtime(общеязыковая среда выполнения)).
При JIT-компиляции язык MSIL преобразуется в машинный код во время выполнения приложения по требованию, когда загружается и исполняется
содержимое сборки.
Среда CLR подключает средства сборки мусора(garbage collection (откуда притсавка gc в gcnew)),управление ресурсами а так же подключает классы из библиотеки классов .NET Framework.
Windows Forms является частью .NET Framework,реализуется в рамках пространства имён System.Windows.Forms.
Таким образом для создания объектов .NET используется gcnew,а не new. Такой объект не нужно удалять, об этом позаботится сборщик мусора.

,Панюков Антон

Хорошо. Ваш ответ принят. Приводите в порядок отчёт по этой лабе и сдавайте его.
Срочно выполняйте остальные работы по лабораторному практикуму.

В.Тельнов
Аватар пользователя
Bichlander
Студент
 
Сообщений: 1
Зарегистрирован: 11 окт 2011, 18:04
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.

Re: Консультации по курсу ООП 2011

Сообщение Grom Zadira » 13 май 2012, 17:06

Виктор Петрович, посмотрите пожалуйста диаграммы прецедентов и классов по ЛР №3 "Лифт".

Эти материалы вам следует распечатать и на ближайшем занятии подойти с ними для уточненной постановки задачи.
В.Тельнов
Аватар пользователя
Grom Zadira
Студент
 
Сообщений: 4
Зарегистрирован: 24 мар 2012, 15:45
Благодарил (а): 1 раз.
Поблагодарили: 0 раз.

След.

Вернуться в Консультации онлайн

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6