代码之家  ›  专栏  ›  技术社区  ›  Dean Movy

如何通过两个void指针参数交换2个未知确切类型的数字?

c
  •  1
  • Dean Movy  · 技术社区  · 7 年前

    我需要编写一个函数来替换2个未知类型的“数字”。

    我不知道确切的类型,我只能使用2个参数。

    这就是我所尝试的:

    void swap(void *p1, void *p2)
    {
        char p;
        char * q1 = (char *)p1;
        char * q2 = (char *)p2;
        for (int i = 0; i < sizeof(long double); i++)
        {
            p = q1[i];
            q1[i] = q2[i];
            q2[i] = p;
        }
    }
    

    用法:

    double a = 100123000000.2;
    double b = 100065450000.3;
    printf("a: %1f, b: %1f\n", a, b);
    swap(&a, &b)
    printf("a: %1f, b: %1f\n", a, b);
    

    这很好,但我的问题是,如果 number 那就更大了 long double (或者没有人……)
    我的解决方案可以吗?

    2 回复  |  直到 6 年前
        1
  •  2
  •   chux    7 年前

    这很好,但我的问题是,如果我的数字更大(?)
    我的解决方案可以吗?

    除非代码知道确切的大小,否则它会有问题。所以,不,OP的解决方案不好。
    以某种方式 void swap() 需要知道要交换的数据的大小。

    我只能使用2个参数。

    代码可以欺骗并将所有数据放入 1. 参数作为 复合文字 ,自C99起。

    typedef struct {
      void *a;
      void *b;
      size_t sz;
    } swap_T;
    
    // Only 1 parameter!!
    void swap(swap_T sw) {
      unsigned char * q1 = sw.a;
      unsigned char * q2 = sw.b;
      while (sw.sz > 0) {
        sw.sz--;
        unsigned char p = q1[sw.sz];
        q1[sw.sz] = q2[sw.sz];
        q2[sw.sz] = p;
      }
    }
    
    int main(void) {
      double a = 100123000000.2;
      double b = 100065450000.3;
      printf("a: %g, b: %g\n", a, b);
      swap(((swap_T ) { &a, &b, sizeof a } ));  // Compound literal
      printf("a: %g, b: %g\n", a, b);
      return 0;
    }
    

    输出

    a: 1.00123e+11, b: 1.00065e+11
    a: 1.00065e+11, b: 1.00123e+11
    

    代码可以包装 swap(((swap_T ) { &a, &b, sizeof a } )) 在看起来像函数调用2的宏中

    #define SWAP(a,b) (swap(((swap_T ) { &(a), &(b), sizeof (a) } )))
    ...
    SWAP(a,b);
    

    只要 a 不是具有 可变逻辑阵列 (VLA)并且有副作用,宏应该可以正常工作。

    当然,如果 a,b 类型相同。

        2
  •  2
  •   John Doe    7 年前

    您的程序应该尝试检索 sizeof 要知道要交换多少字节的参数,可能作为第三个参数,否则无法判断参数有多大。使用当前函数,您将覆盖内存,这将导致糟糕的结果-尤其是在更大的程序中。例如,考虑以下程序。

    #include <stdio.h>
    int main() {
        int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
        swap(&a[0], &a[4]);
        for (int i = 0; i < 8; i++) {
            printf("%d\n", a[i]);
        }
    }
    

    它将返回5、6、7、8、1、2、3、4-这显然不是预期的-只应交换第0个和第4个数组元素。

    如果需要,可以将获取大小隐藏在宏后面。

    #define SWAP(a, b) swap(&(a), &(b), sizeof(a))