2013-06-08 6 views
0

У меня есть функция, которая ожидает массив указателей, как, например:C++ с использованием ** указатель в качестве аргумента функции не работает

void SortResistance(MyClass ** pointerArray, int arraySize); 

и делает пузырьковой сортировки. Внутри этой функции я могу получить доступ к любым двум элементам массива, используя:

MyClass * item1 = *pointerArray + i; 
MyClass * item2 = *pointerArray + i + 1; 

Где я выполняю итерацию по массиву. Все идет нормально. Когда я меняю значения с помощью очень простой функции подкачки, такой как:

void Swap(MyClass ** item1, MyClass ** item2); 

Значения на указателях меняются как ожидалось.

Моя проблема в том, что я не знаю, как переназначить их обратно в pointerArray.

Это не работает:

*(pointerArray + i) = item1; 
*(pointerArray + i + 1) = item2; 

(Ну, это работает, когда я равен 0, но в противном случае он просто сдвигает pointee, а не его значение.)

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

Вот подробности о gory в простейшей возможной реализации. Большое спасибо за ваши ответы.

меня попросили, чтобы посмотреть на что-то похожее на следующие заявления и реализации:

#include <string> 
using namespace std; 

void main() 
{ 
    //TODO: instantiate an array of pointers and sort them using the below 
}; 

class MyClass 
{ 
public: 
    double value; 
    string name; 
} 

void Sort(MyClass ** myArray, int arraySize) 
{ 
    //TODO: implement bubble sort 
} 

void Swap(MyClass ** pointer1, MyClass ** pointer2) 
{ 
    MyClass *temp = *pointer1; 
    *pointer1 = *pointer2; 
    *pointer2 = temp; 
} 

Мое решение, основанное на что-то вроде следующего http://www.cplusplus.com/reference/algorithm/sort/ будет что-то вроде этого:

#include <string> 
using namespace std; 

class MyClass 
{ 
public: 
    double value; 
    string name; 
}; 

void Swap(MyClass ** pointer1, MyClass ** pointer2) 
{ 
    MyClass *temp = *pointer1; 
    *pointer1 = *pointer2; 
    *pointer2 = temp; 

} 

void Sort(MyClass ** myArray, int arraySize) 
{ 
    bool done = false; // this flag will be used to check whether we have to continue the algorithm 

    while (!done) 
    { 
     done = true; // assume that the array is currently sorted 
     for (int i = 0; i < arraySize - 1; i++) // for every element in the array 
     { 
      MyClass * p1 = *myArray + i; 
      MyClass * p2 = *myArray + i + 1; 

      //MyClass * p1 = *(myArray + i); 
      //MyClass * p2 = *(myArray + i + 1); 
      //MyClass * p1 = myArray[i]; 
      //MyClass * p2 = myArray[i + 1]; 

      if (p1->value > p2->value) // compare the current element with the following one 
      { 
       // They are in the wrong order, swap them 
      Swap(&p1, &p2); 
       //Swap(*(&myArray + i), *(&myArray + i + 1)); 
      //Swap(myArray + i, myArray + i + 1); 

      *(myArray + i) = p1; 
      *(myArray + i + 1) = p2; 

       done = false; // since we performed a swap, the array needs to be checked to see if it is sorted 
           // this is done in the next iteration of the while 
      } 
     } 
    } 
} 

void main() 
{ 
    MyClass item1; item1.name = "item1"; item1.value = 25.5; 
    MyClass item2; item2.name = "item2"; item2.value = 15.5; 
    MyClass myItems[2]; myItems[0] = item1; myItems[1] = item2; 

    MyClass * myPointerToItemArray = myItems; 
    Sort(&myPointerToItemArray, 2); 
} 

Код компилируется под VS 2010. Как вы можете видеть, все идет хорошо, пока я не переназначаю новый набор указателей на массив. Любые советы будут очень признательны. Я начинаю думать, что декларации должны быть изменены, чтобы сделать эту работу.

+0

Я отредактирую этот вопрос немного, чтобы включить полный рабочий образец. – aldosa

+0

Почему вы даже называете функцию Swap? Не работает ли 'myArray [i] = p2; myArray [i + 1] = p1;' работает? – Dirk

+0

объявления функций, если требуется. Наконец понял это. См. Мой ответ. Вы правы, за исключением того факта, что вы меняете значения, а не ссылки на указатели. – aldosa

ответ

0

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

#include <string> 
using namespace std; 

class MyClass 
{ 
public: 
    double value; 
    string name; 
}; 

void Swap(MyClass ** pointer1, MyClass ** pointer2) 
{ 
    MyClass *temp = *pointer1; 
    *pointer1 = *pointer2; 
    *pointer2 = temp; 

} 

void Sort(MyClass ** myArray, int arraySize) 
{ 
    //sorting 
    bool done = false; 

    while (!done) 
    { 
     done = true; // assume that the array is currently sorted 
     for (int i = 0; i < arraySize - 1; i++) // for every element in the array 
     { 
      if (myArray[i]->value > myArray[i + 1]->value) 
      { 
       Swap(&myArray[i], &myArray[i + 1]); 
       //MyClass temp = *myArray[i]; 
       //*myArray[i] = *myArray[i + 1]; 
       //*myArray[i + 1] = temp; 
       done = false; 
      } 

     } 

    } 

}; 

void main() 
{ 
    MyClass item1; item1.name = "item1"; item1.value = 25.5; 
    MyClass item2; item2.name = "item2"; item2.value = 15.5; 
    MyClass item3; item3.name = "item3"; item3.value = 10.5; 
    MyClass * myItems[3]; myItems[0] = &item1; myItems[1] = &item2; myItems[2] = &item3; 

    MyClass ** dp = myItems; 

    Sort(dp, 3); 

} 
0

попытки поймать значение массива в ссылке:

MyClass &* item1 = *pointerArray + i; 
MyClass &* item2 = *pointerArray + i + 1; 

то вам не нужно заново присвоить значения после факта.

EDIT: То, что вы делали, по сути делает копию указателей в item1, item2. Обмен их заменял копии, но не оригинал. Вы можете попробовать опустить копии и просто делать что-то вроде этого:

Swap(&(*pointerArray + i), &(*pointerArray + i + 1)); 
+0

Указатель ссылки не компилируется. – 0x499602D2

+0

Извините, немного ржавый с C++, прошло некоторое время с тех пор, как я испортил этот язык. Я надеюсь, что идея есть, хотя синтаксис есть. – Lochemage

+0

Первый дает мне ошибку: указатель на ошибку не разрешен. Второй вариант дает мне ошибку «выражение должно быть lvalue» – aldosa

2

Это намного проще, если рассматривать его в качестве фактического массива, а не указатель, например,

MyClass* item1 = pointerArray[i]; 
MyClass* item2 = pointerArray[i + 1]; 

и:

pointerArray[i] = item1; 
pointerArray[i + 1] = item2; 

Вам не нужно модифицировать прототипы функций, чтобы сделать это.

+0

Это решение также неверно. Та же проблема, что и ответ Lochemage. Первый член работает для i = 0, второй - недопустимый указатель. – aldosa

+0

Если второй недействительный указатель, то вы превысите границы вашего массива, и у вас есть ошибка в сортировке вашего пузыря. –

+0

См. Редактирование на мой вопрос, и проблема станет ясна. Это на самом деле плохой указатель, но не проблема границ массива. – aldosa

1

Хорошо, я сделал немного отладки в моем компиляторе ... попробуйте

MyClass * item1 = *(pointerArray + i); 
MyClass * item2 = *(pointerArray + i + 1); 

И оставить остальную часть кода то же самое.

+0

Скомпилируется правильно. Та же проблема, что и ниже. Я отредактирую вопрос, чтобы включить полный рабочий образец примерно через час. Еще раз спасибо. – aldosa

Смежные вопросы