C++ 带指针的冒泡排序函数

C++ bubble sort function with pointers

我想编写一个程序,在函数内包含带指针的冒泡排序。 这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

void rendez(int* t, int n){
    for(int i=0; i<n-1; i++){
        for(int j=i+1; j<n; j++){
            if(*t+i<*t+j){
                int temp = *t+i;
                *t+i = *t+j;
                *t+j = temp;
            }
        }
    }
}

int main(){

    setlocale(LC_ALL,"");

    int t[10] = {2,3,4,5,6,7,8,9,10,11};

    rendez(&t,sizeof(t)); 

    printf("\n");
    system("pause");
}

它给我这些错误:

C:\Users\metal\gyakorlás1211.cpp    In function 'void rendez(int*, int)':
C:\Users\metal\gyakorlás1211.cpp    [Error] lvalue required as left operand of assignment
C:\Users\metal\gyakorlás1211.cpp    [Error] lvalue required as left operand of assignment
C:\Users\metal\gyakorlás1211.cpp    In function 'int main()':
C:\Users\metal\gyakorlás1211.cpp    [Error] cannot convert 'int (*)[10]' to 'int*' for argument '1' to 'void rendez(int*, int)'

谢谢!

你需要做两处改变

      if(*(t+i)<*(t+j)){
            int temp = *(t+i);
            *(t+i) = *(t+j);
            *(t+j) = temp;
        }

还有

rendez(t,sizeof(t)/sizeof(t[0])); 

现在看看你之前做了什么,首先你的编译器一定已经爆出很多警告了。

&tint (*)[10] 这不是你想要的。

相反,您只是想传递最终会衰减为指针的数组,然后您所做的任何更改都会反映到数组中。

早些时候你的 *t+i 正在做这样的事情,(*t)+i 这就是你想要的吗?而且 t 当时是 int(*)[10] 所以你基本上是在添加 ij 到它。这是不对的。您正在处理地址,但您想处理值。

函数的第二个参数,您想传递数组的大小,但不是字节数而是元素数。

sizeof (arr) 基本上是说 10*sizeof(int) 因为它包含 int。但这是你想要的吗?不,您要传递 int 个元素的数量。所以只需将它除以每个 int 的大小。这就是我们在 sizeof(t)/sizeof(t[0]).

中所做的

当您在参数中发送 &t 时,您实际上并不是在发送数组的首地址,而是整个数组的地址。

Let's understand this thing
Let's say the array is allocated as 1000, 1004, 1008. . . so, the address of the first element will be 1000 as when you add 1 in it, it will give you 1004. and the address of the whole array will be 1000 as when you add 1 in it, it will give the next address of the last element in the array.

t 是指向第一个元素的指针,&t 是指向数组的指针。 因此,要将数组传递给另一个函数,只需在参数中发送 t

现在,sizeof 运算符不是 return 数组的长度,而是它分配的大小。

阅读 this 并将您的函数调用编写为。

rendez(t, sizeof(t)/sizeof(t[0]));


现在关于 lvalue 错误。

*+ 具有更高的优先级,因此 * 首先执行。 所以像这样写 *t + i 会给你从数组的第一个元素开始的第 i 个下一个地址。
所以你需要这样写 *(t + i)在赋值操作中。

这次通话

rendez(&t,sizeof(t)); 

是错误的,因为表达式 &t 的类型是 int (*)[10] 而不是函数 rendez 的第一个参数的类型 int *

你应该像这样调用函数

rendez( t, sizeof(t) / sizeof( *t ) ); 

函数的第二个参数的类型应该是size_t.

同样在函数内 this if 语句

        if(*t+i<*t+j){
            int temp = *t+i;
            *t+i = *t+j;
            *t+j = temp;
        }

也是错误的。

一定要像

        if( *( t + i ) < *( t + j ) ){
            int temp = *( t + i );
            *( t + i ) = *( t + j );
            *( t + j ) = temp;
        }

考虑到冒泡排序算法比较相邻元素。

您的函数实现看起来像是一种低效的选择排序。

如果您只想使用指针,那么该函数可以像演示程序中显示的那样

#include <iostream>

void rendez( int *a, int n )
{
    for ( int *first = a, *swapped = a, *last = a + n; !( last - first < 2 ); first = a, last = swapped )
    {
        swapped = a;
        while ( ++first != last )
        {
            if ( *( first - 1 ) < *first )
            {
                swapped = first;
                int tmp = *first;
                *first = *( first - 1 );
                *( first - 1 ) = tmp;
            }
        }
    }        
}


int main() 
{
    int a[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    rendez( a, sizeof( a ) / sizeof( *a ) );

    for ( int x : a ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

它的输出是

2 3 4 5 6 7 8 9 10 11 
11 10 9 8 7 6 5 4 3 2 

该函数确实实现了冒泡排序算法。