问题
I have a little question about understand how pointers and functions work.
I want to see how a function looks like qsort()
, but I need to use my own function to swap elements and to compare elements. I am very surprised to know that my function does not swap data...
My code:
//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 =(
}
}
Why does the array not change?
In the debugger I can see that all pointers change, and get correct values, but in main
my array is not changed.
回答1:
You may look at various combinations as these.....
#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;
}
回答2:
pointers point to objects
the code
int * ptmp = ptmp1;
ptmp1 = ptmp2;
ptmp2 = ptmp;
changes some pointer values locally in the function, and that's all.
in order to swap the values of two objects, pass them by reference:
void swap_values_of( int& a, int& b )
{
int const original_a = a;
a = b;
b = original_a;
}
you can also do that, less safely, with pointer arguments, then taking care to swap the values pointed to instead of the pointers themselves.
but except for purposes of learning, use std::swap
instead
not asked for, but... if you change the current Microsoft-specific
int _tmain()
to just standard
int main()
then the code will (much more likely) work also in e.g. Linux.
just a tip
回答3:
Your SwapInt
function swaps some pointers, not int
s. Since all those pointers are local to SwapInt
, it has no actual effect. Probably you meant to do something with the int
s *ptmp1
and *ptmp2
.
回答4:
What you are actually doing is swapping pointers. What you are trying to do is to swap values, where that pointers point to. At least that comes from your program logic. So your code could be something like this:
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;
}
来源:https://stackoverflow.com/questions/15043170/c-c-troubles-with-pointers-and-functions