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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.10.2011, 12:43   #21
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

Ну и наверно последний вопрос по этой теме
вот написал две функции первая увеличивает размер массива на заданную величину. Вторая функция уменьшает размер массива на еденицу, уничтожается ячейка с последним номером.
посмотрите так правильно будет?
Код:
#include <iostream>

//функция увеличивает разерность массива
//s1 первоночальный размер, s2 новый размер
void v_s_a (int a[], int s1, int s2)
{
    int* temp;
    temp = new int [s1];//временный массив

    //переписываем во временный массив
    for (int i = 0; i <= (s1 - 1); i++)
    {
        temp[i] = a [i];
    }
    //очищаем память массива
    delete[] a;
    //выделяем память
    a = new int [s2];
    if (s1 <= s2)
    {
        //переписываем значения ИЗ временного массива
        for (int i = 0; i <= (s1 - 1); i++)
        {
            a[i] = temp[i];
        }
    }
    //очищаем память временного массива
    delete[] temp;
}
//функция уменьшает размер массива на еденицу
//s -первоночальный размер
void v_s_a (int a[], int s)
{
    int* temp;
    temp = new int[s];
    for (int i = 0; i <= (s - 1); i++)
    {
        temp[i] = a[i];
    }
    delete[] a;
    a = new int[s - 1];
    for (int i = 0; i <= (s - 2); i++)
    {
        a[i] = temp[i];
    }

    delete[] temp;
}

using namespace std;

int main()
{
    int size = 10;
    int* array;
    array = new int[size];

    //увеличиваем размер
    v_s_a(array, size, 15);

    //уменьшаем размер
    v_s_a(array, 15);

    delete[] array;
    return 0;
}
SAMOUCHKA вне форума Ответить с цитированием
Старый 20.10.2011, 13:17   #22
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

SAMOUCHKA

посмотрите так правильно будет?

неправильно. при выходе из программы (а возможно и раньше) словим крэш :D
подробнее объяснять лень, пусть лучше кто-нибудь другой сделает (Ж, но вкраце, функция уничтожает переданный указатель, а новое значение не возвращает.

а уменьшать массив вообще смысла не имеет, тем более как у тебя - чтобы уменьшить на 1, в системе пусть и кратковременно, выделяется памяти 2 * N
Rififi вне форума Ответить с цитированием
Старый 20.10.2011, 16:00   #23
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
Ну и наверно последний вопрос по этой теме
вот написал две функции первая увеличивает размер массива на заданную величину. Вторая функция уменьшает размер массива на еденицу, уничтожается ячейка с последним номером.
посмотрите так правильно будет?
Код:
#include <iostream>

//функция увеличивает разерность массива
//s1 первоночальный размер, s2 новый размер
void v_s_a (int a[], int s1, int s2)
{
    int* temp;
    temp = new int [s1];//временный массив

    //переписываем во временный массив
    for (int i = 0; i <= (s1 - 1); i++)
    {
        temp[i] = a [i];
    }
    //очищаем память массива
    delete[] a;
    //выделяем память
    a = new int [s2];
    if (s1 <= s2)
    {
        //переписываем значения ИЗ временного массива
        for (int i = 0; i <= (s1 - 1); i++)
        {
            a[i] = temp[i];
        }
    }
    //очищаем память временного массива
    delete[] temp;
}
//функция уменьшает размер массива на еденицу
//s -первоночальный размер
void v_s_a (int a[], int s)
{
    int* temp;
    temp = new int[s];
    for (int i = 0; i <= (s - 1); i++)
    {
        temp[i] = a[i];
    }
    delete[] a;
    a = new int[s - 1];
    for (int i = 0; i <= (s - 2); i++)
    {
        a[i] = temp[i];
    }

    delete[] temp;
}

using namespace std;

int main()
{
    int size = 10;
    int* array;
    array = new int[size];

    //увеличиваем размер
    v_s_a(array, size, 15);

    //уменьшаем размер
    v_s_a(array, 15);

    delete[] array;
    return 0;
}
Во-первых, совершенно не понятно, зачем создавать две функции, когда проще создать одну функцию, в которой проверять новый размер больше или меньше старого размера и в соответствии с этим выполнять необходимые действия. Дело в том, что код у ваших двух функций во многом совпадает, так зачем его дублировать?!

Во-вторых, у вас происходит утечка памяти. Вызывающая программа ничего не будет знать о том, что вы в функциях выделяете память. Дело в том, что ваш массив, который описан в виде параметра передается по значению. То есть аргумент в виде массива, который вы задаете при вызове ваших функций (или указатель) преобразуется в указатель, который является локальным для ваших функций. И при завершении работы функции этот локальный указатель удаляется. То есть вы очевидно думаете, что ваш аргумент, который вы передаете в функцию в качестве параметра int a[], получает новое значение, а на самом деле это не так, так как функция имеет дело с копией вашего аргумента.

Кроме того, касаясь дизайна функции, нет никакой необходимости во временном масииве. Он просто лишний. Фактически, вы два раза вызываете delete вместо одного раза.

Вам нужно переопределить функцию таким образом, чтобы она возвращала не void, а указатель на вновь выделенную память.
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 20.10.2011, 18:45   #24
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Можно и ничего не возвращать, если указатель будет передаваться по ссылке:
Код:
void v_s_a (int* &a, int s1, int s2)
{
....
}
void v_s_a (int* &a, int s)
{
....
}
An1ka вне форума Ответить с цитированием
Старый 21.10.2011, 00:25   #25
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

ну две функции или одна не в этом суть, тем более что функция перегруженная. скажите лучше как без временного массива обойтись???.
SAMOUCHKA вне форума Ответить с цитированием
Старый 21.10.2011, 04:33   #26
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
ну две функции или одна не в этом суть, тем более что функция перегруженная. скажите лучше как без временного массива обойтись???.
Очень просто. По логике вещей:
1. Создаем новый массив.
2. Копируем из старого массива в новый.
3. Уничтожаем старый.
4. В указатель на старый массив записываем адрес нового массива.
An1ka вне форума Ответить с цитированием
Старый 21.10.2011, 10:38   #27
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

Цитата:
Сообщение от An1ka Посмотреть сообщение
Очень просто. По логике вещей:
1. Создаем новый массив.
2. Копируем из старого массива в новый.
3. Уничтожаем старый.
4. В указатель на старый массив записываем адрес нового массива.
ну а чем это лучше?
приведите пример. код функции.
а вообще этот массив будет являтся полем класса, по этому без функции, не обойтись. поле-то находится в блоке private и воздествовать на него можно только посредством метода
SAMOUCHKA вне форума Ответить с цитированием
Старый 21.10.2011, 17:39   #28
An1ka
C++,DirectX/OpenGL
Форумчанин
 
Регистрация: 09.01.2011
Сообщений: 422
По умолчанию

Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
ну а чем это лучше?
приведите пример. код функции.
Уже ведь говорили... тем что временный массив не нужен !
Код:
void v_s_a (int* &a, unsigned int s1, unsigned int s2)
{
    if (s1 < s2)
    {
        //выделяем память
        int *a2 = new int [s2];
        //переписываем значения ИЗ старого массива
        for ( unsigned int i = 0; i < s1 ; i++)
        {
            a2[i] = a[i];
        }
	//очищаем память старого массива
	delete[] a;
	a = a2;
    }
}
Цитата:
Сообщение от SAMOUCHKA Посмотреть сообщение
поле-то находится в блоке private и воздествовать на него можно только посредством метода
Не только, для доступа к закрытым полям класса можно использовать дружественную функцию:
Код:
#include <iostream>

 class B;

 class A 
{
   int i;
   friend int sum( A a, B b);
public:
   A ( int i) : i(i){}
};

 class B 
{
   int i;
   friend int sum( A a, B b);
public:
   B ( int i) : i(i){}
};

 int sum( A a, B b)
{
   return a.i + b.i;
}

int main( ) {
   A a = 1;
   B b = 3;
   std::cout << sum ( a, b);
   return 0;
}
http://liveworkspace.org/code/664fef...52270a269192ac
Методы класса так же можно делать друзьями другого класса
An1ka вне форума Ответить с цитированием
Старый 21.10.2011, 23:51   #29
SAMOUCHKA
Форумчанин
 
Регистрация: 07.08.2011
Сообщений: 576
По умолчанию

на счет класса вы не так поняли, или я плохо объяснил.
я имел в виду что поле класса есть динамический массив и менять его размерность можно только посредством метода. этот метод пренадлежит етому-же классу
Код:
class main_class
{
public:
    main_class (int size)// конструктор
    {
          s = size;
          p = new int [s];
    }
    ~main_class ()
    {
         delete [] p;
    }
    void v_s_a (int s1, int s2);//метод меняет размерность массива p
private:
    int* p;
    int s;
}
вот что-то вроде этого. про метод v_s_a я и спрашивал. как-бы мне его лучше описать

Последний раз редактировалось SAMOUCHKA; 21.10.2011 в 23:53.
SAMOUCHKA вне форума Ответить с цитированием
Старый 22.10.2011, 00:06   #30
БалаШагаЛ
Форумчанин
 
Регистрация: 11.02.2011
Сообщений: 131
По умолчанию

Для динамического изменения размерности массива нужны связанные списки. Вот самый простой пример, где при добавлении в список он сортируется по возрастанию. Не знаю, конечно, насколько это понятно, но разобраться можно.
Код:
#include <iostream>

enum {kIsSmaller,kIsLarger,kIsSame};

class Data
{
    public:
      Data(int val):myValue(val){}
      ~Data(){}
      int Compare(const Data &);
      void Show(){std::cout << myValue << "\n";}
    private:
      int myValue;
};

int Data::Compare(const Data & theOtherData)
{
    if (myValue<theOtherData.myValue)
    {
        return kIsSmaller;
    }
    if (myValue>theOtherData.myValue)
    {
        return kIsLarger;
    }
    return kIsSame;
}

class Node;
class HeadNode;
class TailNode;
class InternalNode;

class Node
{
    public:
      Node(){}
      virtual ~Node(){}
      virtual Node* Insert(Data *theData)=0;
      virtual void Show()=0;
};

class InternalNode : public Node
{
    public:
      InternalNode(Data *theData,Node *next):
      myData(theData),
      myNext(next)
      {}
      ~InternalNode()
      {
          delete myData;
          delete myNext;
      }
      virtual Node* Insert(Data *theData)
      {
          int result=myData->Compare(*theData);
          switch(result)
          {
              case kIsSame:
              case kIsLarger:
              {
                  InternalNode *dataNode=new InternalNode(theData,this);
                  return dataNode;
              }
              case kIsSmaller:
              myNext=myNext->Insert(theData);
              return this;
          }
          return this;
      }
      virtual void Show()
      {
          myData->Show();
          myNext->Show();
      }
    private:
      Data *myData;
      Node *myNext;
};

class TailNode : public Node
{
    public:
      TailNode(){}
      ~TailNode(){}
      virtual Node* Insert(Data *theData)
      {
          Node *dataNode=new InternalNode(theData,this);
          return dataNode;
      }
      virtual void Show(){}
};

class HeadNode : public Node
{
    public:
      HeadNode()
      {
          myNext=new TailNode;
      }
      virtual ~HeadNode()
      {
          delete myNext;
      }
      virtual Node* Insert(Data *theData)
      {
          myNext=myNext->Insert(theData);
          return this;
      }
      virtual void Show()
      {
          myNext->Show();
      }
    private:
      Node *myNext;
};

class ListengList
{
    public:
      ListengList()
      {
          myHead=new HeadNode;
      }
      ~ListengList()
      {
          delete myHead;
      }
      virtual void Insert(Data *theData)
      {
          myHead->Insert(theData);
      }
      virtual void ShowAll()
      {
          myHead->Show();
      }
    private:
      Node *myHead;
};

int main()
{
    int a;
    std::cout << &a << "\n";
    int val;
    ListengList ll;
    Data *pData;
    while(1)
    {
        std::cin >> val;
        if (!val)
        {
            break;
        }
        pData=new Data(val);
        ll.Insert(pData);
    }
    std::cout << "\n------\n\n";
    ll.ShowAll();
}
Вся суть в том, что создаётся класс, в котором есть два параметра - указатель на следующую и предыдущую ячейку. Также есть "голова" и "хвост" списка. В начале создания класса создаётся по одному экземпляру каждого из них, причём указатели в пункте указывают на "голову" и "хвост". При добавлении новых пунктов происходит смена указателей.
БалаШагаЛ вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Изменение всего массива RedStorm Microsoft Office Excel 2 10.04.2011 12:54
C++ - изменение размера массива kefir Помощь студентам 1 19.06.2010 11:42
Задание размерности 2мерного массива Bernarditto Общие вопросы C/C++ 2 18.06.2010 17:04
Конструктор для изменения размерности массива and277 Общие вопросы C/C++ 2 10.08.2009 20:47
увеличение размерности массива Лучик_света Общие вопросы .NET 3 25.10.2008 04:36