Часовой пояс: UTC + 3 часа




Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 1730 • Страница 68 из 87<  1 ... 65  66  67  68  69  70  71 ... 87  >
  Пред. тема | След. тема 
В случае проблем с отображением форума, отключите блокировщик рекламы
Автор Сообщение
 

Member
Статус: Не в сети
Регистрация: 06.05.2009
Спс, теперь все работает.



Партнер
 

Junior
Статус: Не в сети
Регистрация: 26.01.2008
Откуда: Ukraine
Вопрос по шаблонам STL: необходимо реализовать сложение двух матриц с помощью шаблона. Можете пожалуйста подкинуть информацию по данной теме, а то в интернете ничего толкового найти пока не могу :insane:


 

Member
Статус: Не в сети
Регистрация: 10.12.2007
Откуда: Санкт-Петербург
Всем доброго времени суток.
Функция находит остаток от деления 2 многочленов. В самой ф-и он находится верно, но происходит 1 неприятная вещь.
Код:
int *remaind(int * const p, int len1, int *p22, int len2, int *rem, int &len3){
   int *p1 = new int [len1];
   int *p2 = new int [len2];
   int k= len1-1;
   for (int i=0; i<len1; i++)
      p1[i] = p[i];
   for (int i=0; i<len2; i++)
      p2[i] = p22[i];
   for (int i=0; i<len1/2; i++)
   {
      int temp = p1[i];
      p1[i] = p1[k-i];
      p1[k-i] = temp;
   }
   k = len2-1;
   for (int i=0; i<len2/2; i++)
   {
      int temp = p2[i];
      p2[i] = p2[k-i];
      p2[k-i] = temp;
   }
   int *ptr1;
   ptr1 = p1;
   int ii=0;
   while (len1>=len2)
   {
      int del = (int)(*ptr1/ *p2);
      for (int i=0; i<len2; i++)
         *(ptr1+i) -= del * p2[i];
      len1--;
      ptr1++;
   }
   rem = ptr1;
   len3 = len1;
   delete [] p1;
   delete [] p2;
   return rem;
}

Стоит только освободить память из-под p2, как удаляется все, что было в rem, но так быть не должно. Значит, p2 и rem в этот момент имеют одинаковые значения адреса. А вот как это исправить, не знаю :weep:

_________________
Семь бед, один Reset. 95, 98 - это количество багов. В пpоцентах...
DCN - наше все


 

Advanced member
Статус: Не в сети
Регистрация: 30.08.2003
Откуда: Санкт-Петербург
manya
1) в таких функциях лучше ничего не return'ить, а возвращать значения через аргументы-указатели. И возвращают обычно код ошибки (вроде как 0 - все ОК, остальное - конкретные коды) или кол-во возвращаемых элементов.
2)
Цитата:
Стоит только освободить память из-под p2, как удаляется все, что было в rem, но так быть не должно.

что-то напутано с указателями
Цитата:
Значит, p2 и rem в этот момент имеют одинаковые значения адреса.

не факт.
Цитата:
А вот как это исправить, не знаю :weep:

в дебаггере (отладчике) для начала запустить. И внимательно следить за указателями. Легко может оказаться, что один указатель налезает на пространство, адресуемое другим.

_________________
{:€ дед в законе :-) нородный окодемег
почетный пользователь OpenSuSE 11.3
Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad


 

Member
Статус: Не в сети
Регистрация: 10.12.2007
Откуда: Санкт-Петербург
Цитата:
Легко может оказаться, что один указатель налезает на пространство, адресуемое другим.
. Так и есть. Дело в том, что указатель ptr1 ходит по массиву и всегда внутри него, а значит освобождая память из под p1, я убиваю rem, что совершенно мне не нужно. Можно было бы копировать нужный измененный кусок p1, а потом возвращать на него указатель, но вот только тогда получится, что я буду возвращать указатель на локальную переменную из функции, что тоже не есть хорошо

Добавлено спустя 20 минут 22 секунды:
В этом-то и весь вопрос

_________________
Семь бед, один Reset. 95, 98 - это количество багов. В пpоцентах...
DCN - наше все


 

Member
Статус: Не в сети
Регистрация: 07.01.2010
ты просто не совсем понимаешь, где и как память выделяется

вот для такой конструкции
Код:
int *p1 = new int [len1];

на самом деле происходит сразу 2 выделения памяти: из кучи выделяется len1 байт данных, и в стеке размещается непосредственно указатель, и занимает там sizeof(int*) байт, 4 для 32битных систем и 8 для 64битных.
когда ты в конце функции делаешь return стек сворачивается и значения всех локальных переменных, которые были там размещены, ессно, портится, значения входных переменных тоже портятся. НО! при этом кучу никто не трогает. как у тебя было выделено len1 байт - так они и остались выделенными, и всё, что там было записано никуда не пропадает. даже если будет уничтожен последний указатель на эту область данных - она останется выделенной до тех пор, пока процесс не помрёт.
поэтому, в твоём случае надо просто выделить ещё один кусок длины len3 для rem и скопировать туда значения. а потом, в той функции, откуда позвали remaind(), не забыть эту память подчистить.

почитай на тему heap, malloc, new, new[] (последние 3 делают примерно одно и то же), ну и ещё про стандарт вызова процедур stdcall, чтобы картина стала совсем понятной.

Добавлено спустя 2 минуты 10 секунд:
ну и ответ на вопрос: в своей функции ты возвращаешь не локальную переменную, а указатель на кусок памяти, который выделен в куче.


 

Member
Статус: Не в сети
Регистрация: 10.12.2007
Откуда: Санкт-Петербург
ToSHiC, Root спасибо :-)

_________________
Семь бед, один Reset. 95, 98 - это количество багов. В пpоцентах...
DCN - наше все


 

Junior
Статус: Не в сети
Регистрация: 26.01.2008
Откуда: Ukraine
Помогите пожалуйста с векторами. Надо инициализировать двумерные вектора в классе. Но у меня не получается, юзал поиск, ничего найти не смог. Смог найти только про одномерные вектора, но про двумерные ничего нет. Заранее спасибо.


Код:
#include <iostream>
#include <vector>
#include <conio.h>
using namespace std;


class Addition{
protected:
int M;
int N;
int A;
int B;
int i;
int j;


public:

   Addition(){
   };

   void create_matrix() {
   
   vector <vector <int> > matrix1(N,vector<int>(M));
   vector <vector <int> > matrix2(B,vector<int>(A));
   vector <vector <int> > matrix3(B,vector<int>(A));
   
   };

   int input_sizes(){
   
   cout<<"Введите размерность первой матрицы:"<<endl;
   cin>>M>>N;

   cout<<"Введите размерность второй матрицы:"<<endl;
   cin>>A>>B;
   
   if(A!=M || B!=N){
      cout<<"Матрицы складывать нельзя, потому что они не одинаковой размерности."<<endl;
      return 1;
   }
   else
   return 0;

   };

   void input_matrix(){
   
   cout<<"Ввведите элементы первой матрицы: "<<endl;

   for(i=0;i<M;i++){
   for(j=0;j<N;j++)

      cin>>matrix1[i][j];

   }

   cout<<"Ввведите элементы второй матрицы: "<<endl;

   for(i=0;i<A;i++){
   for(j=0;j<B;j++)

      cin>>matrix2[i][j];

   }
   
   };


   void show_matrix(){
   
   cout<<"Исходные матрицы имеют вид: "<<endl;

   cout<<"Первая матрица: "<<endl;

   for(i=0;i<M;i++){
   for(j=0;j<N;j++)

      cout<<matrix1[i][j]<<" ";
      cout<<endl;
   }


   cout<<"Вторая матрица: "<<endl;

   for(i=0;i<M;i++){
   for(j=0;j<N;j++)

      cout<<matrix2[i][j]<<" ";
      cout<<endl;
   }
   
   };


   void addition(){
   
   for(i=0;i<M;i++){
   for(j=0;j<N;j++)
      matrix3[i][j]=matrix1[i][j]+matrix2[i][j];
   }


   cout<<"Просуммированная матрица имеет вид: "<<endl;

   for(i=0;i<M;i++){
   for(j=0;j<N;j++)

      cout<<matrix3[i][j]<<" ";
      cout<<endl;

   }

   };



};

void main()
{

int r;

setlocale(LC_ALL,".1251");

Addition y;
r=y.input_sizes();

if(r==0){

y.create_matrix();
y.input_matrix();
y.show_matrix();
y.addition();
getch();
}

getch();

}


 

Member
Статус: Не в сети
Регистрация: 15.08.2007
BMWM3GTR писал(а):
Помогите пожалуйста с векторами. Надо инициализировать двумерные вектора в классе. Но у меня не получается, юзал поиск, ничего найти не смог. Смог найти только про одномерные вектора, но про двумерные ничего нет. Заранее спасибо.


http://www.google.ru/search?q=vector+%3 ... int%3E+%3E

http://www.daniweb.com/forums/thread38527.html


не понял только, что именно у тебя не получается

ps
кстати в boost'е уже есть готовые матрицы
http://www.boost.org/doc/libs/1_43_0/li ... matrix.htm


 

Junior
Статус: Не в сети
Регистрация: 26.01.2008
Откуда: Ukraine
progn
Проинициализировать двумерный вектор в классе. Именно в классе, как просто инициализировать я нашел до этого, спасибо, но в классе такая инициализация не работает. :(


 

Member
Статус: Не в сети
Регистрация: 15.08.2007
BMWM3GTR
так ты выражайся точнее и правильнее, тебе похоже нужны matrix1,... не как локальные переменные в функции create_matrix, а как члены класса

определи
vector <vector <int> > matrix1;

как член класса

а инициализировать можно в конструкторе, в списке инициализации

Addition(int N, int M)
: matrix1(N,vector<int>(M))
{
}

или в ручками, в любом методе

matrix1->resize(N);
for (int i = 0; i < N; i++)
matrix1[i].resize(M);


там кстати по ссылке был похожий способ, только через push_back
for ( int i = 0; i < 5; i++ ) {
items.push_back ( vector<int>() );

ps
дизайн программы у тебя кривой, правильнее сделать класс матрица, переопределить операцию "+" (при неподходящем размере операндов она выбрасывает exception (можно просто std::runtime_error), а также ввод, вывод в поток.


 

Junior
Статус: Не в сети
Регистрация: 06.01.2008
Может при вставках кода (например больше 3 строк) использовать например: http://dpaste.com , http://paste.org.ru , http://pastebin.ca
Чтобы пользователи знали где размещать код ссылки на них прикрепить в первый топик и сделать, чтобы он он на каждой странице отображался.


 

Junior
Статус: Не в сети
Регистрация: 26.01.2008
Откуда: Ukraine
progn
Да, именно так. Именно то что нужно. Спасибо, работает. :-)

п.с. Согласен что так лучше, но это просто задание с обязательным использованием STL, поэтому...вот так сделал. Хотя за идею переопределения "+" спасибо. :-)


 

Member
Статус: Не в сети
Регистрация: 20.03.2009
Откуда: Санкт-Петербург
Приветствую. Помогите пожалуйста с "небольшой" проблемой. Ситуация вот какая: дома стоит visual studio 2008 PE, а там,где сдаю лабы -VS 6.0. Она настолько древняя,что не работают дружественные функции. В смысле программа ругается,что мол пытаетесь получить доступ к закрытым членам класса.
Вот описание класса
Код:
class IntSet {
   int *maselm;
   int kolelm;
public:
   IntSet();
   IntSet(char*);
   IntSet(const IntSet &tmp);
   ~IntSet();
   void vvod(char*);
   void vuvod();
   IntSet operator=(IntSet);
   IntSet operator+(IntSet);
   IntSet operator+(int);
   IntSet operator-(IntSet);
   IntSet operator-(int);
   void operator+=(IntSet);
   void operator-=(IntSet);
   int operator==(IntSet);
   int operator!=(IntSet);
   int operator>(IntSet);
   int operator<(IntSet);
   int operator>=(IntSet);
   int operator<=(IntSet);
   IntSet operator*(IntSet);
   ostream &func(ostream &stream);
   ostream &operator<<(ostream &stream);
//   friend ostream &operator<<(ostream &stream,const IntSet tmp);
//   friend istream &operator>>(istream &stream,IntSet &tmp);
private:
   int check_to_add(int number);
   void add_to_mas(int number);
   void del_from_mas(int);
};


Помогите прегрузить операторы вывода <<. Ввод я надеюсь сам уж тогда смогу.
Вот обычная функция вывода
Код:
void IntSet::vuvod(){
   for(int i=0;i<kolelm;i++)
      cout<<maselm[i]<<" ";
   cout<<"kolelm= "<<kolelm<<endl;
}


Пробывал так
Ф-я элемент класса
Код:
ostream &IntSet::func(ostream &stream){
   for(int i=0;i<kolelm;i++)
      stream<<maselm[i]<<" ";
   stream<<"kolelm= "<<kolelm<<endl;
   return stream;
}

Она вызывается в ф-ии перегрузки,которая элементом класса не является:
Код:
ostream& operator<<(ostream &stream,IntSet p){
   p.func(stream);
   return stream;
}

Но при компиляции конструкция типа cout<<p не работает. Пишется бинарный '<<': не найден оператор, принимающий правый операнд типа 'IntSet' (или приемлемое преобразование отсутствует)
Я тока начал разбираться с с++, с уже вроде как знаю. Не пинайте сильно, если есть нелепая ошибка :-)

_________________
Задачи бывают простыми и очень простыми...


 

Member
Статус: Не в сети
Регистрация: 15.08.2007
Цитата:
Она настолько древняя,что не работают дружественные функции


да ну, это везде работает, даже в самых древних компиляторах типа bc++ 3.0


почему описан friend:
friend ostream &operator<<(ostream &stream,const IntSet tmp);

а в реализации:

ostream& operator<<(ostream &stream,IntSet p){

должно быть одинаково, и по хорошему const IntSet &tmp


 

Member
Статус: Не в сети
Регистрация: 20.03.2009
Откуда: Санкт-Петербург
Вот реализация этой friend ф-ии
Код:
/*ostream& operator<<(ostream& stream,const IntSet tmp){
   for(int i=0;i<tmp.kolelm;i++)
      stream<<tmp.maselm[i]<<" ";
   stream<<"kolelm="<<tmp.kolelm<<endl;
   return stream;
}*/


Про одинаково и & я догадываюсь,просто когда уже :-x пытался по-разному. В настоящий момент пытаюсь реализовать всё без friend ф-ии, и в связи с этим они закомментированы. Так что вопрос в силе, как перегрузить <<, не используя дружественные ф-ии.

Добавлено спустя 3 часа 2 минуты 15 секунд:
Вопрос снят) Всё сделал. Завтра сдавать буду :D

_________________
Задачи бывают простыми и очень простыми...


 

Junior
Статус: Не в сети
Регистрация: 07.07.2008
подскажите,плз, как можно средствами C++ менять размер консоли? это просто делается например в VC++(для СLR приложений), но надо сделать это в GCC(IDE Netbeans)


 

Advanced member
Статус: Не в сети
Регистрация: 30.08.2003
Откуда: Санкт-Петербург
iliax
Стандартными средствами C++ - никак.
В остальном - нужно искать стандартную виндовую ф-цию для управления консольным окном. MSDN в помощь
См. также http://www.cplusplus.com/forum/beginner/1481/

_________________
{:€ дед в законе :-) нородный окодемег
почетный пользователь OpenSuSE 11.3
Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad


 

Member
Статус: Не в сети
Регистрация: 15.02.2009
Откуда: Лангепас
iliax писал(а):
это просто делается например в VC++(для СLR приложений), но надо сделать это в GCC(IDE Netbeans)


Под что пишем, то? если под Linux, то кажется никак...


 

Member
Статус: Не в сети
Регистрация: 15.08.2007
можно и в линуксах, точно так же как и в винде, находишь исковое окно и меняешь размер. Но это глупость и извращение, во первых никакого окна оконной системы может и не быть, а во вторых это неправильно идеологически, сама идея консольных приложений в их отвязанности от GUI, в том что стандартные потоки можно переопределять и можно соединять несколько приложений пайпами (вывод одного, на ввод другого).

Если вообще возникла такая потребность, то надо было писать оконное приложение.

Еще в случае винды можно поменять свойство ярлыка.


Показать сообщения за:  Поле сортировки  
Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 1730 • Страница 68 из 87<  1 ... 65  66  67  68  69  70  71 ... 87  >
-

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB | Kolobok smiles © Aiwan