C语言 转换void* 指针

dy1byipe  于 2023-10-15  发布在  其他
关注(0)|答案(1)|浏览(112)

当我尝试在C lang上通用排序库中使用compelx结构时,我的代码中出现了一个问题:(你可以找到完整的代码https://github.com/Tramontz/ASD_2023
我有一个二进制合并插入排序,它可以输入一个空指针(数组的第一个元素),并且可以处理int和string的数组(所有统一测试通过)。
现在我尝试使用它与数组:

struct record{
  int id;
  char* string_field_1;
  int integer_field_2;
  double float_field_3;
};

存储在另一个结构中

struct _StructArray{
  void**array;
  unsigned long el_num;
  unsigned long array_capacity;
};

我必须命令记录的void**数组。
这是从csv文件中获取的数据的示例
<POSIZION:0,ID:0,String:诺托,字符串:233460,Float:32209.073312 >
<POSIZION:1,ID:1,String:piangea,字符串:4741192,Float:81176.622633 >
<POSITIZION:2,ID:2,String:spenti!,电话:1014671,浮点数:4476.013614 >
<POSIZION:3,ID:3,String:misericordia,String:496325,Float:61628.929334 >
排序模式由

switch (field) {
      case 1://struct_array_get(array,0) return the first element of the array
          merge_binary_insertion_sort(struct_array_get(array,0), struct_array_size(array), sizeof(struct record), k, precedes_record_string_field);

所以基本上我用一个循环把所有数据存储在structArray中的record * 数组中。
数组被正确加载,因为打印函数

for(unsigned long i=0;i<el_num;i++){
    array_element = (struct record *)struct_array_get(array, i);
    printf("<POSIZION:%d, ID:%d, String:%s, Integer:%d, Float:%lf >\n",i,array_element->id,array_element->string_field_1,array_element->integer_field_2,array_element->float_field_3); 
  }

可以显示数组中的所有记录。
所以当调用sorting函数时出现问题:

void bin_insertion_sort(void *arr, int n, size_t elementSize, CompareFunction compare) {
        int i, loc, j;
        void *selected = malloc(elementSize);
        if (selected == NULL) {
          fprintf(stderr, "Errore nell'allocazione di memoria per 'selected'\n");
           exit(EXIT_FAILURE);
         }
        for (i = 1; i < n; ++i) {
            j = i - 1;
            memcpy(selected, arr + i * elementSize, elementSize);

            // Find location where selected should be inserted
            loc = binary_search(arr, selected, 0, j, compare, elementSize);

我存储在void * 中,选中了我想在数组中查找位置的项,并调用二分查找

int binary_search(void *arr, void *item, int low, int high, CompareFunction compare, size_t elementSize) {
        if (high <= low){
            return (compare(item, arr + low * elementSize) > 0) ? (low + 1) : low ;

我们只能集中在binary_search中,问题是:当我调用**return(compare(item,select + low * elementSize)> 0)时,(低+ 1):low ;**用于记录的数组,使用此比较函数

static int precedes_record_string_field(const void* r1_p, const void* r2_p) {
    if (r1_p == NULL || r2_p == NULL) {
        fprintf(stderr, "precedes_record_string_field: one of the parameters is a null pointer\n");
        exit(EXIT_FAILURE);
    }

    const struct record* rec1_p = (const struct record*)r1_p;
    const struct record* rec2_p = (const struct record*)r2_p;

    printf("Record 1: ID=%d, String=%s, Integer=%d, Float=%f\n", rec1_p->id, rec1_p->string_field_1, rec1_p->integer_field_2, rec1_p->float_field_3);
    sleep(1);
    printf("Record 2: ID=%d, String=%s, Integer=%d, Float=%f\n", rec2_p->id, rec2_p->string_field_1, rec2_p->integer_field_2, rec2_p->float_field_3);
sleep(5);

    return strcmp(rec1_p->string_field_1, rec2_p->string_field_1);
}

它打印rec 2数据,但不打印rec 1数据,所以我假设它可以转换void + low * elementSize指针,但不能转换我通过compare(item,void + low * elementSize)传递并存储在rec 1(item)和rec 2(void + low * elementSize)中的void* item指针。
我在内存地址管理中做错了什么?也许我用item来寻址所有的structArray,而不是record* 数组的第二个元素?
我卡住了,因为我所有的单一,空,和多字符串和整数数组的统一测试工作正常。
谢谢你们

yjghlzjz

yjghlzjz1#

你的写作方式看起来非常非常复杂。

Maybe you could test the functions first...

I will show you a methodical way of writing his,
using your `struct` and `qsort`,
that you can easily adapt...

编辑:增加了第二部分,第二部分,下面。我添加了代码来使用下面相同的方法对void**数组进行排序,然后像原来的问题中那样对StructArray进行排序,作为一种分离容器,方法和算法的方法的示例。这是一个大量使用复制和粘贴:这些变化只在比较函数(每行2行)和一个函数添加到StructArray(4行),以提取指针数组的基址。

把东西分开

typedef struct
{
    int    id;
    char*  string;
    int    i_field;
    double d_field;
} Target;

int cmp_1(const void*, const void*);
int cmp_2(const void*, const void*);
int cmp_3(const void*, const void*);
int cmp_4(const void*, const void*);

int so_show(unsigned, Target[], const char*);

在这里,我们有您的数据记录,4个必需的功能和一个功能,以显示结果
使用封装并围绕数据编写代码。
看这个:

Target some_value[] = {
        [0] =
            {.id      = 42,
             .string  = "value 33",
             .i_field = 4242,
             .d_field = 42.42},
        [1] =
            {.id      = 4,
             .string  = "stack",
             .i_field = 42,
             .d_field = 42.242},
        [2] =
            {.id      = 342,
             .string  = "overflow",
             .i_field = 4,
             .d_field = 142.42},
        [3] =
            {.id      = 412,
             .string  = "take the survey",
             .i_field = 2,
             .d_field = 2142.42},
};

这是测试你所有功能的数据。

'main用于测试#

这里:

  • 数组被打印为声明的
  • 数组按每个条件排序并显示
so_show(4, some_value, "\nBefore sort:\t");

    qsort(some_value, 4, sizeof(Target), cmp_1);
    so_show(4, some_value, "\nAfter sort by id:\t");

    qsort(some_value, 4, sizeof(Target), cmp_2);
    so_show(
        4, some_value, "\nAfter sort by string field:\t");

    qsort(some_value, 4, sizeof(Target), cmp_3);
    so_show(
        4, some_value, "\nAfter sort by integer field:\t");

    qsort(some_value, 4, sizeof(Target), cmp_4);
    so_show(
        4, some_value, "\nAfter sort by double field:\t");

输出

Before sort:    4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|   42 | "            value 33" |     4242 |      42.4200 |
|    4 | "               stack" |       42 |      42.2420 |
|  342 | "            overflow" |        4 |     142.4200 |
|  412 | "     take the survey" |        2 |    2142.4200 |
|=========================================================|

After sort by id:       4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|    4 | "               stack" |       42 |      42.2420 |
|   42 | "            value 33" |     4242 |      42.4200 |
|  342 | "            overflow" |        4 |     142.4200 |
|  412 | "     take the survey" |        2 |    2142.4200 |
|=========================================================|

After sort by string field:     4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|  342 | "            overflow" |        4 |     142.4200 |
|    4 | "               stack" |       42 |      42.2420 |
|  412 | "     take the survey" |        2 |    2142.4200 |
|   42 | "            value 33" |     4242 |      42.4200 |
|=========================================================|

After sort by integer field:    4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|  412 | "     take the survey" |        2 |    2142.4200 |
|  342 | "            overflow" |        4 |     142.4200 |
|    4 | "               stack" |       42 |      42.2420 |
|   42 | "            value 33" |     4242 |      42.4200 |
|=========================================================|

After sort by double field:     4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|    4 | "               stack" |       42 |      42.2420 |
|   42 | "            value 33" |     4242 |      42.4200 |
|  342 | "            overflow" |        4 |     142.4200 |
|  412 | "     take the survey" |        2 |    2142.4200 |
|=========================================================|

看起来还不错。
这样更容易:首先测试所有功能。
既然你说代码已经可以处理整数,那么只要确保排序代码确实抽象了数据记录。一般来说,这只是编写正确的交换函数的情况。特别注意导航过程...

C完整代码

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

typedef struct 
{
    int    id;
    char*  string;
    int    i_field;
    double d_field;
}  Target;

int cmp_1(const void*, const void*);
int cmp_2(const void*, const void*);
int cmp_3(const void*, const void*);
int cmp_4(const void*, const void*);

int so_show(unsigned, Target[], const char*);

int main(void)
{
    Target some_value[] = {
        [0] =
            {.id      = 42,
             .string  = "value 33",
             .i_field = 4242,
             .d_field = 42.42},
        [1] =
            {.id      = 4,
             .string  = "stack",
             .i_field = 42,
             .d_field = 42.242},
        [2] =
            {.id      = 342,
             .string  = "overflow",
             .i_field = 4,
             .d_field = 142.42},
        [3] =
            {.id      = 412,
             .string  = "take the survey",
             .i_field = 2,
             .d_field = 2142.42},
    };

    so_show(4, some_value, "\nBefore sort:\t");

    qsort(some_value, 4, sizeof(Target), cmp_1);
    so_show(4, some_value, "\nAfter sort by id:\t");

    qsort(some_value, 4, sizeof(Target), cmp_2);
    so_show(
        4, some_value, "\nAfter sort by string field:\t");

    qsort(some_value, 4, sizeof(Target), cmp_3);
    so_show(
        4, some_value, "\nAfter sort by integer field:\t");

    qsort(some_value, 4, sizeof(Target), cmp_4);
    so_show(
        4, some_value, "\nAfter sort by double field:\t");

};  // main

int cmp_1(void* one, void* other)
{
    Target* a = one;
    Target* b = other;
    if (a->id < b->id) return -1;
    if (a->id == b->id) return 0;
    return 1;
};

int cmp_2(void* one, void* other)
{   // now for the string
    Target* a = one;
    Target* b = other;
    return strcmp(a->string, b->string);
};

int cmp_3(void* one, void* other)
{
    Target* a = one;
    Target* b = other;
    if (a->i_field < b->i_field) return -1;
    if (a->i_field == b->i_field) return 0;
    return 1;
};

int cmp_4(void* one, void* other)
{
    Target* a = one;
    Target* b = other;
    if (a->d_field < b->d_field) return -1;
    if (a->d_field == b->d_field) return 0;
    return 1;
};
int so_show(unsigned N, Target r[], const char* msg)
{
    if (r == NULL) return -1;
    if (msg != NULL) printf("%s", msg);
    printf("%d records\n", N);
    const char* l0 =
        "\
|  id  |           string value |  integer |       double |";
    const char* l1 =
        "\
|=========================================================|";
    printf("%s\n%s\n%s\n", l1,l0,l1);
    for ( unsigned u=0;u<N;u+=1)
        printf(
            "| %4d | \"%20s\" | %8d | %12.4f |\n", r[u].id,
            r[u].string, r[u].i_field, r[u].d_field);
    printf("%s\n\n",l1);
    return 0;
}

第二部分

第二个例子是main.c

int main(void)
{
    Target some_value[] = {
        [0] =
            {.id      = 42,
             .string  = "value 33",
             .i_field = 4242,
             .d_field = 42.42},
        [1] =
            {.id      = 4,
             .string  = "stack",
             .i_field = 42,
             .d_field = 42.242},
        [2] =
            {.id      = 342,
             .string  = "overflow",
             .i_field = 4,
             .d_field = 142.42},
        [3] =
            {.id      = 412,
             .string  = "take the survey",
             .i_field = 2,
             .d_field = 2142.42},
    };

    const N = sizeof(some_value) / sizeof(some_value[0]);

    test_with_struct_array(
        N, some_value,
        "\n\n\t***** using an array of structs *****\n\n");
    test_with_voidp_array(
        N, some_value,
        "\n\n\t***** using a 'void**' *****\n\n");
    test_with_Struct_Array(
        N, some_value,
        "\n\n\t***** using an original 'StructArray' "
        "*****\n\n");

    return 0;
};  // main

test_with_struct_array()是原始程序。第二个函数将相同的数组排序到void**数组中,以便单独测试机制,第三个函数使用作者的原始StructArray-稍作修改,请参见下面的代码。

使用void**

这是使用原始数据构建数组的代码:

Target** base = malloc(n * sizeof(Target*));
    for (unsigned i = 0; i < n; i += 1)
        base[i] = &some_value[i];

比较函数都是不同的,因为有一个新的间接级别来访问实际数据。新函数是cmp_[1234]中的cmp_[5678],这里有一对,比较了Target中的i_field

int cmp_3(const void* one, const void* other)
{
    Target* a = (Target*)one;
    Target* b = (Target*)other;
    if (a->i_field < b->i_field) return -1;
    if (a->i_field == b->i_field) return 0;
    return 1;
};

int cmp_7(const void* one, const void* other)
{
    Target* a = (Target*)*((const void**)one);
    Target* b = (Target*)*((const void**)other);
    if (a->i_field < b->i_field) return -1;
    if (a->i_field == b->i_field) return 0;
    return 1;
};

不同之处在于获取数据地址。由于StructArray也是一个void**的东西,这些函数也在那里使用。
添加了姐妹函数来显示来自不同来源的数据,因此输出与预期完全相同。

int so_show_one(Target*);
int so_show(
    unsigned, Target[], int (*show)(void*), const char*);
int so_show_from_StructArray(
    StructArray*, int (*show)(void*), const char*);
int so_show_from_voidp_array(
    unsigned, void**, int (*show)(void*), const char*);

第一个函数显示单个数据记录,因此可以被所有3种格式使用。它作为一个参数传递,因此如果需要,可以很容易地为每个测试使用备用显示。

StructArray的变化

void* struct_array_get_base(StructArray* x)
{
    if (x == NULL) return NULL;
    return &(x->array)[0];
}

添加此函数是为了从StructArray内部获取基址

关于使用StructArray作为容器

int test_with_Struct_Array(
    unsigned n, Target some_value[], const char* msg)
{
    if (msg != NULL) printf("%s", msg);

    StructArray* tgt = struct_array_create();
    for (size_t i = 0; i < n; i += 1)
        struct_array_add(tgt, &some_value[i]);
    fprintf(
        stderr, "\n\t%u values inside target StructArray\n",
        struct_array_size(tgt));

    so_show_from_StructArray(
        tgt, so_show_one,
        "\n    With data inside StructArray:\t");

    // this is the base for sort
    void*  array_base = struct_array_get_base(tgt);
    size_t size       = struct_array_size(tgt);
    qsort(array_base, size, sizeof(void*), cmp_5);
    so_show_from_StructArray(
        tgt, so_show_one, "\n\tAfter sort by id:\t");

这就是在测试函数开始时如何抽象容器进行排序的。这应该适用于void*连续数组上的任何排序算法。
希望它能帮助

第二个示例的代码

#pragma pack(push, 1)
#pragma pack(show)

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

#include "struct_array.h"

typedef struct
{
    int    id;
    char*  string;
    int    i_field;
    double d_field;
} Target;

int cmp_1(const void*, const void*);
int cmp_2(const void*, const void*);
int cmp_3(const void*, const void*);
int cmp_4(const void*, const void*);

int cmp_5(const void*, const void*);
int cmp_6(const void*, const void*);
int cmp_7(const void*, const void*);
int cmp_8(const void*, const void*);

int so_show_one(Target*);
int so_show(
    unsigned, Target[], int (*show)(void*), const char*);
int so_show_from_StructArray(
    StructArray*, int (*show)(void*), const char*);
int so_show_from_voidp_array(
    unsigned, void**, int (*show)(void*), const char*);

int test_with_struct_array(unsigned, Target[], const char*);
int test_with_voidp_array(unsigned, Target[], const char*);
int test_with_Struct_Array(unsigned, Target[], const char*);

int main(void)
{
    Target some_value[] = {
        [0] =
            {.id      = 42,
             .string  = "value 33",
             .i_field = 4242,
             .d_field = 42.42},
        [1] =
            {.id      = 4,
             .string  = "stack",
             .i_field = 42,
             .d_field = 42.242},
        [2] =
            {.id      = 342,
             .string  = "overflow",
             .i_field = 4,
             .d_field = 142.42},
        [3] =
            {.id      = 412,
             .string  = "take the survey",
             .i_field = 2,
             .d_field = 2142.42},
    };

    const N = sizeof(some_value) / sizeof(some_value[0]);

    test_with_struct_array(
        N, some_value,
        "\n\n\t***** using an array of structs *****\n\n");
    test_with_voidp_array(
        N, some_value,
        "\n\n\t***** using a 'void**' *****\n\n");
    test_with_Struct_Array(
        N, some_value,
        "\n\n\t***** using an original 'StructArray' "
        "*****\n\n");

    return 0;
};  // main

int cmp_1(const void* one, const void* other)
{  // compare ids
    Target* a = (Target*)one;
    Target* b = (Target*)other;
    if (a->id < b->id) return -1;
    if (a->id == b->id) return 0;
    return 1;
};

int cmp_2(const void* one, const void* other)
{  // now for the string
    Target* a = (Target*)one;
    Target* b = (Target*)other;
    return strcmp(a->string, b->string);
};

int cmp_3(const void* one, const void* other)
{
    Target* a = (Target*)one;
    Target* b = (Target*)other;
    if (a->i_field < b->i_field) return -1;
    if (a->i_field == b->i_field) return 0;
    return 1;
};

int cmp_4(const void* one, const void* other)
{  // for doubles
    Target* a = (Target*)one;
    Target* b = (Target*)other;
    if (a->d_field < b->d_field) return -1;
    if (a->d_field == b->d_field) return 0;
    return 1;
};

int cmp_5(const void* one, const void* other)
{
    Target* a = (Target*)*((const void**)one);
    Target* b = (Target*)*((const void**)other);
    if (a->id < b->id) return -1;
    if (a->id == b->id) return 0;
    return 1;
};

int cmp_6(const void* one, const void* other)
{  // now for the string
    Target* a = (Target*)*((const void**)one);
    Target* b = (Target*)*((const void**)other);
    return strcmp(a->string, b->string);
};

int cmp_7(const void* one, const void* other)
{
    Target* a = (Target*)*((const void**)one);
    Target* b = (Target*)*((const void**)other);
    if (a->i_field < b->i_field) return -1;
    if (a->i_field == b->i_field) return 0;
    return 1;
};

int cmp_8(const void* one, const void* other)
{  // sort as double
    Target* a = *((void**)one);
    Target* b = *((void**)other);
    if (a->d_field < b->d_field) return -1;
    if (a->d_field == b->d_field) return 0;
    return 1;
};

int so_show(
    unsigned N, Target r[], int (*show)(void*),
    const char* msg)
{
    if (r == NULL) return -1;
    if (msg != NULL) printf("%s", msg);
    printf("%d records\n", N);
    const char* l0 =
        "\
|  id  |           string value |  integer |       double |";
    const char* l1 =
        "\
|=========================================================|";
    printf("%s\n%s\n%s\n", l1, l0, l1);
    for (unsigned u = 0; u < N; u += 1) show(r + u);
    printf("%s\n\n", l1);
    return 0;
}

int so_show_one(Target* one)
{
    printf(
        "| %4d | \"%20s\" | %8d | %12.4f |\n", one->id,
        one->string, one->i_field, one->d_field);
    return 0;
}

int so_show_from_StructArray(
    StructArray* A, int (*show)(void*), const char* msg)
{
    if (A == NULL) return -1;
    if (show == NULL) return -2;
    if (msg != NULL) printf("%s", msg);
    unsigned long N = struct_array_size(A);
    printf("%u records\n", N);
    const char* l0 =
        "\
|  id  |           string value |  integer |       double |";
    const char* l1 =
        "\
|=========================================================|";
    printf("%s\n%s\n%s\n", l1, l0, l1);
    for (unsigned u = 0; u < N; u += 1)
        show((Target*)struct_array_get(A, u));
    printf("%s\n\n", l1);
    return 0;
}

int so_show_from_voidp_array(
    unsigned N, void** base, int (*show)(void*),
    const char* msg)
{
    if (base == NULL) return -1;
    if (show == NULL) return -2;
    if (N <= 0) return -3;
    if (msg != NULL) printf("%s", msg);
    printf("%u records\n", N);
    const char* l0 =
        "\
|  id  |           string value |  integer |       double |";
    const char* l1 =
        "\
|=========================================================|";
    printf("%s\n%s\n%s\n", l1, l0, l1);
    for (unsigned u = 0; u < N; u += 1)
        show((Target*)base[u]);
    printf("%s\n\n", l1);
    return 0;
}

int test_with_struct_array(
    unsigned n, Target some_value[], const char* msg)
{
    if (msg != NULL) printf("%s", msg);

    so_show(
        n, some_value, so_show_one, "\n    Before sort:\t");

    qsort(some_value, n, sizeof(Target), cmp_1);
    so_show(
        n, some_value, so_show_one,
        "\n    After sort by id:\t");

    qsort(some_value, n, sizeof(Target), cmp_2);
    so_show(
        n, some_value, so_show_one,
        "\n    After sort by string field:\t");

    qsort(some_value, n, sizeof(Target), cmp_3);
    so_show(
        n, some_value, so_show_one,
        "\n    After sort by integer field:\t");

    qsort(some_value, n, sizeof(Target), cmp_4);
    so_show(
        n, some_value, so_show_one,
        "\n    After sort by double field:\t");

    return 0;
}

int test_with_voidp_array(
    unsigned n, Target some_value[], const char* msg)
{
    if (msg != NULL) printf("%s", msg);

    Target** base = malloc(n * sizeof(Target*));

    for (unsigned i = 0; i < n; i += 1)
        base[i] = &some_value[i];

    so_show_from_voidp_array(
        n, base, so_show_one, "\tbefore sort: ");

    size_t sz_one = sizeof(Target*);
    qsort(&base[0], n, sz_one, cmp_5);
    so_show_from_voidp_array(
        n, base, so_show_one, "\tsorted by id field: ");

    qsort(&base[0], n, sz_one, cmp_8);
    so_show_from_voidp_array(
        n, base, so_show_one, "\tsorted by double field: ");

    qsort(&base[0], n, sz_one, cmp_7);
    so_show_from_voidp_array(
        n, base, so_show_one,
        "\tsorted by integer field: ");

    qsort(&base[0], n, sz_one, cmp_6);
    so_show_from_voidp_array(
        n, base, so_show_one, "\tsorted by string field: ");
    return 0;
}

int test_with_Struct_Array(
    unsigned n, Target some_value[], const char* msg)
{
    if (msg != NULL) printf("%s", msg);

    StructArray* tgt = struct_array_create();
    for (size_t i = 0; i < n; i += 1)
        struct_array_add(tgt, &some_value[i]);
    fprintf(
        stderr, "\n\t%u values inside target StructArray\n",
        struct_array_size(tgt));

    so_show_from_StructArray(
        tgt, so_show_one,
        "\n    With data inside StructArray:\t");

    // this is the base for sort
    void*  array_base = struct_array_get_base(tgt);
    size_t size       = struct_array_size(tgt);
    qsort(array_base, size, sizeof(void*), cmp_5);
    so_show_from_StructArray(
        tgt, so_show_one, "\n\tAfter sort by id:\t");

    qsort(array_base, size, sizeof(void*), cmp_6);
    so_show_from_StructArray(
        tgt, so_show_one,
        "\n\tAfter sort by string field:\t");

    qsort(array_base, size, sizeof(void*), cmp_7);
    so_show_from_StructArray(
        tgt, so_show_one,
        "\n    After sort by integer field:\t");

    qsort(array_base, size, sizeof(void*), cmp_8);
    so_show_from_StructArray(
        tgt, so_show_one,
        "\n    After sort by double field:\t");

    return 0;
}

第三次测试的输出

不感兴趣,因为它是相同的数据3次,但由从相同的原始数据构建的容器生成。

***** using an original 'StructArray' *****

        4 values inside target StructArray

    With data inside StructArray:       4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|    4 | "               stack" |       42 |      42.2420 |
|   42 | "            value 33" |     4242 |      42.4200 |
|  342 | "            overflow" |        4 |     142.4200 |
|  412 | "     take the survey" |        2 |    2142.4200 |
|=========================================================|

        After sort by id:       4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|    4 | "               stack" |       42 |      42.2420 |
|   42 | "            value 33" |     4242 |      42.4200 |
|  342 | "            overflow" |        4 |     142.4200 |
|  412 | "     take the survey" |        2 |    2142.4200 |
|=========================================================|

        After sort by string field:     4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|  342 | "            overflow" |        4 |     142.4200 |
|    4 | "               stack" |       42 |      42.2420 |
|  412 | "     take the survey" |        2 |    2142.4200 |
|   42 | "            value 33" |     4242 |      42.4200 |
|=========================================================|

    After sort by integer field:        4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|  412 | "     take the survey" |        2 |    2142.4200 |
|  342 | "            overflow" |        4 |     142.4200 |
|    4 | "               stack" |       42 |      42.2420 |
|   42 | "            value 33" |     4242 |      42.4200 |
|=========================================================|

    After sort by double field: 4 records
|=========================================================|
|  id  |           string value |  integer |       double |
|=========================================================|
|    4 | "               stack" |       42 |      42.2420 |
|   42 | "            value 33" |     4242 |      42.4200 |
|  342 | "            overflow" |        4 |     142.4200 |
|  412 | "     take the survey" |        2 |    2142.4200 |
|=========================================================|

相关问题