2013-02-23 114 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

你的代碼只交換指針,而不是它們指向的東西。 – 2013-02-23 17:11:28

回答

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

你試過編譯這個 – 2013-02-23 17:20:42

+0

把這個void放到一邊並且不會編譯,如果你看看函數的名字,應該很清楚,他的意圖是交換整數,而不是指針本身。 – Slava 2013-02-23 17:22:32

+0

是的,我已經改變了代碼,現在編譯並運行。 – 2013-02-23 17:53:14

0

你的SwapInt函數交換了一些指針,而不是int s。由於所有這些指針都是SwapInt的本地指針,因此它沒有實際效果。可能你打算用int*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代替


沒有要求,但是......如果你改變微軟特有的電流

int _tmain() 

只是標準

int main() 

那麼代碼將(更有可能)在例如Linux操作系統。

只是一個提示

+0

非常感謝你! – sesega 2013-02-23 17:19:06

+0

解決了。我剛剛使用:\t int tmp = * ptmp1; \t * ptmp1 = * ptmp2; \t * ptmp2 = tmp; – sesega 2013-02-23 17:19:45

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 2013-02-23 17:21:31