2013-02-23 5 views
1

У меня есть небольшой вопрос о том, как работают указатели и функции. Я хочу видеть, как функция выглядит как qsort(), но мне нужно использовать мою собственную функцию для замены элементов и сравнения элементов. Я очень удивлен, узнав, что моя функция не поменять местами данные ...C/C++, проблемы с указателями и функциями

Мой код:

//prototypes file: other.h 

void Sort(char* pcFirst, int nNumber, int size, void (*Swap)(void*, void*), int (*Compare)(void*, void*)); //sorts any arrays 
void SwapInt(void* p1, void* p2); // swap pointers 
int CmpInt(void* p1, void* p2); // compare poineters 

//realisation file: other.cpp 

#include "other.h" 
void Sort(char* pcFirst, int nNumber, int size, 
    void (*Swap)(void*, void*), int (*Compare)(void*, void*)) 
{ 
    int i; 
    for(i = 1; i < nNumber; i++) 
     for(int j = nNumber - 1; j >= i; j--) 
     { 
      char* pCurrent = pcFirst + j * size; 
      char* pPrevious = pcFirst + (j - 1) * size; 
      if((*Compare)(pPrevious, pCurrent) > 0)// if > 0 then Swap 
      { 
       (*Swap)(pPrevious, pCurrent); 
      } 
     } 
} 

void SwapInt(void* p1, void* p2) 
{ 
    int * ptmp1 = static_cast<int*>(p1); 
    int * ptmp2 = static_cast<int*>(p2); 
    int * ptmp = ptmp1; 
    ptmp1 = ptmp2; 
    ptmp2 = ptmp; 
} 

int CmpInt(void* p1, void* p2) 
{ 
    int nResult; 
    int * ptmp1 = static_cast<int*>(p1); 
    int * ptmp2 = static_cast<int*>(p2); 
    nResult = (*ptmp1 - *ptmp2); 
    return nResult; 
} 

//main file: lab.cpp 
#include <tchar.h> 
#include <iostream> 
#include <cstdio> 
#include <cmath> 
#include "other.h" 

int _tmain() 
{ 
int nAr[] = {33,44,55,22,11}; //array for sort 
    int nTotal = sizeof(nAr)/sizeof(int); //number of elements 
for (int i = 0; i < nTotal; i++) 
    { 
     printf("%d ",nAr[i]); // result of cycle is 33 44 55 22 11 
    } 
    Sort(reinterpret_cast<char*>(&nAr[0]), nTotal, sizeof(int), SwapInt, CmpInt); 
for (int i = 0; i < nTotal; i++) 
    { 
     printf("%d ",nAr[i]); // result of cycle is 33 44 55 22 11 too =(
    } 
} 

Почему массив не изменится?

В отладчике я вижу, что все указатели изменяются и получают правильные значения, но в main мой массив не изменяется.

+1

Ваш код только поменять местами указатели, а не то, что они указывают. –

ответ

0

Вы можете посмотреть на различных комбинациях, как это .....

#include<iostream> 
#include<stdio.h> 
#include<malloc.h> 
//Call by Address 
    void SwapIntAddr(int* ptmp1, int* ptmp2) 
    { 
     int ptmp; 
     ptmp = *ptmp1; 
     *ptmp1 = *ptmp2; 
     *ptmp2 = ptmp; 
    } 

//Call by Reference 

    void SwapIntRef(int& ptmp1, int& ptmp2) 
    { 
     int ptmp; 
     ptmp = ptmp1; 
     ptmp1 = ptmp2; 
     ptmp2 = ptmp; 
    } 
//Call by Reference but in pointer level 
    void SwapPtrRef(int*& ptmp1, int*& ptmp2) 
    { 
     int* ptmp; 
     ptmp = ptmp1; 
     ptmp1 = ptmp2; 
     ptmp2 = ptmp; 
    } 

//Call by Address but in Pointer level. 

    void SwapPtrAddr(int** ptmp1,int** ptmp2) 
    { 
     int** ptmp = (int**) malloc(sizeof(int*)); 
     *ptmp = *ptmp1; 
     *ptmp1 = *ptmp2; 
     *ptmp2 = *ptmp; 
    } 


int main(){ 
    int a = 3, b= 5; 
    int* p1 = &a; 
    int* p2 = &b; 

    SwapIntAddr(p1,p2); 
    printf("%d %d\n",*p1,*p2); 

    SwapIntRef(*p1,*p2); 
    printf("%d %d\n",*p1,*p2); 

    SwapPtrRef(p1,p2); 
    printf("%d %d\n",*p1,*p2); 

    SwapPtrAddr(&p1,&p2); 
    printf("%d %d\n",*p1,*p2); 

    return 0; 
} 
+0

у вас попытались скомпилировать это –

+0

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

+0

Да, я изменил код и скомпилировал его сейчас, и он сработал. –

0

Ваш SwapInt функция своп некоторых указателей, а не int s. Поскольку все эти указатели являются локальными для SwapInt, он не имеет фактического эффекта. Возможно, вы хотели что-то сделать с int s *ptmp1 и *ptmp2.

3

указатели указывают на объекты

код

int * ptmp = ptmp1; 
ptmp1 = ptmp2; 
ptmp2 = ptmp; 

изменяет некоторые значения указателей локально в функции, и это все.

для того, чтобы обменять значения двух объектов, передавать их по ссылке:

void swap_values_of(int& a, int& b) 
{ 
    int const original_a = a; 
    a = b; 
    b = original_a; 
} 

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

, но для целей обучения, за исключением, используйте std::swap вместо


не просили, но ... если вы измените текущий Microsoft конкретных

int _tmain() 

только стандартный

int main() 

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

только кончик

+0

большое спасибо! – sesega

+0

решены.Я просто использовал: \t int tmp = * ptmp1; \t * ptmp1 = * ptmp2; \t * ptmp2 = tmp; – sesega

0

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

void SwapInt(void* p1, void* p2) 
{ 
    int * ptmp1 = static_cast<int*>(p1); 
    int * ptmp2 = static_cast<int*>(p2); 
    int ptmp = *ptmp1; 
    *ptmp1 = *ptmp2; 
    *ptmp2 = ptmp; 
} 
+0

спасибо =) использовал это и работает! – sesega