简体   繁体   English

C / C ++,指针和函数的麻烦

[英]C/C++, troubles with pointers and functions

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. 我想看看函数如何看起来像qsort() ,但我需要使用自己的函数来交换元素和比较元素。 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. 在调试器中,我可以看到所有指针都发生了变化,并获得了正确的值,但是在main我没有改变。

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 但除了学习目的,请改用std::swap


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 eg Linux. 那么代码(更有可能)也可以在Linux中运行。

just a tip 只是一个提示

Your SwapInt function swaps some pointers, not int s. 你的SwapInt函数交换了一些指针,而不是int Since all those pointers are local to SwapInt , it has no actual effect. 由于所有这些指针都是SwapInt本地指针,因此它没有实际效果。 Probably you meant to do something with the int s *ptmp1 and *ptmp2 . 可能你打算用int s *ptmp1*ptmp2

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;
}

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM