如何写未知参数的排序无法无效迭代* /

问题描述

在此void* ic = b + j * sz;和此void* jc = ic - sz;行中,写表达式必须是指向完整类型的指针。我需要wright函数,它可以对所有内容进行排序,因此我使用void *。我现在不怎么用void *进行迭代。如何访问元素void* base之类的数组。

UPD pcharToInt是错误的。我首先将void*投射到char*上, 原来是心脏符号。比我尝试与void*合作。

#include <iostream>

using namespace std;

typedef int (*CFT) (const void*,const void*);

int pcharToInt(char* a);
int cmp1(const void* a,const void* b);
void insort(void* base,size_t n,size_t sz,CFT cmp);

int main() {
    int arr[] = { 9,3,5,7,9,4 };
    void* a = arr;
    char* b = static_cast<char*>(a);
    return 0;
}

int pcharToInt(char* a) {
    int b = 0;
    char* tmp = a;
    while (*a) {
        b *= 10;
        b += (*a++ - '0');
    }
    a = tmp;
    return b;
}

int cmp1(const void* a,const void* b) {
    int n1 = 0;
    int n2 = 0;
    n1 = pcharToInt((char*)a);
    n2 = pcharToInt((char*)b);
    if (n1 > n2) return 1;
    else return 0;
}

void insort(void* base,CFT cmp) {
    void* b = base;
    for (int i = 1; i < n; i++)
    {
        for (int j = i; j > 0; j--)
        {
            void* ic = b + j * sz;
            void* jc = ic - sz;
            if (cmp1(jc,ic)) {
                for (int k = 0; k < sz; k++) {
                    char tmp = jc[k];
                    jc[k] = ic[k];
                    ic[k] = tmp;
                }
            }
            break;
        }
    }
}

UPD2其旧代码为char

char* b = static_cast<char*> (base);
    for (int i = 1; i < n; i++)
    {
        for (int j = i; j > 0; j--)
        {
            char* ic = b + j * sz;
            char* jc = ic - sz;
            if (cmp1(jc,ic)) {
                for (int k = 0; k < sz; k++) {
                    char tmp = jc[k];
                    jc[k] = ic[k];
                    ic[k] = tmp;
                }
            }
            break;
        }
    }

UPD3 我在将void*投射到char*时遇到了麻烦。结果是哪里没有正确的符号。示例代码中必须是数字。

解决方法

如果您试图模仿C标准库中qsort()的操作,则需要根据要排序的元素的类型和排序顺序(升序或降序)来定制比较功能。比较比较时使用类型为const void *的指针参数进行调用,因为qsort()设计为可与任何类型的数组一起使用,并且void *是最通用的对象指针类型。

对于比较int元素的特定情况,应将const void *参数转换为const int *并取消引用以获取要比较的int元素的值。比较函数应返回负值,零值或正值,以指示要比较的两个元素的相对顺序。为了按升序对int类型的元素进行排序,下面是一个合适的比较函数:

int cmp1(const void *a,const void *b)
{
    int aa = *(const int *)a; // convert pointer a and dereference
    int bb = *(const int *)b; // convert pointer b and defererence

    if (aa < bb)
        return -1;
    if (aa > bb)
        return 1;
    return 0;
}

用于按降序对int元素进行排序的比较函数与上面的类似,但是交换了-11返回值。

您的insort()函数需要与比较函数不同的返回值,返回0而不是负值。为了与您的insort()函数兼容,需要对该函数进行如下修改:

int cmp1(const void *a,const void *b)
{
    int aa = *(const int *)a; // convert pointer a and dereference
    int bb = *(const int *)b; // convert pointer b and defererence

    return (aa > bb);
}

对于标准C(和C ++?),不允许在void *上使用指针算法,因为仅在指向 complete 对象类型的指针上使用指针算法,而void是根据定义为不完整对象类型。某些编译器(例如GCC)允许将指针void *作为C标准的扩展,就指针算法而言,它与char *相同。可移植代码应避免对void *使用指针算术。您的insort()函数可以进行以下修改以实现可移植性:

void insort(void* base,size_t n,size_t sz,CFT cmp) {
    char* b = (char*)base;
    for (int i = 1; i < n; i++)
    {
        for (int j = i; j > 0; j--)
        {
            char* ic = b + j * sz;
            char* jc = ic - sz;
            if (cmp1((void*)jc,(void*)ic)) {
                for (int k = 0; k < sz; k++) {
                    char tmp = jc[k];
                    jc[k] = ic[k];
                    ic[k] = tmp;
                }
            }
            break;
        }
    }
}
,

在C ++中,您不会丢弃类型信息。

代替

{
  "errors": [
    {
      "debugMessage": "Call to a member function articles() on null","message": "Internal server error","extensions": {
        "category": "internal"
      },"locations": [
        {
          "line": 6,"column": 3
        }
      ],"path": [
        "createArticle"
      ],

你应该在写

typedef int (*CFT) (const void*,const void*);
void insort(void* base,CFT cmp);
int cmp1(const void* a,const void* b);

请注意,您忽略了第一个元素,而template<typename T> using CFT = bool(*)(const T *,const T *); template<typename T> void insort(T* base,CFT<T> cmp) { for (T* i = base + 1; i < base + n; i++) { for (T* j = i; j > base; j--) { if (cmp(j,i)) { std::swap(*j,*i) } break; } } } int cmp1(const int * a,const int * b) { return *a > *b; } 似乎可疑。当发现不规则的东西时,通常需要移动多个元素。

正确的插入排序(adapted from here

break