【问题标题】:How to use cast in C?如何在 C 中使用强制转换?
【发布时间】:2015-03-14 10:24:10
【问题描述】:

我想比较任何数据类型,但我不知道如何使用变量或常量,例如:

if ( *(var)v > *(var)(v+sizeof(int)) )
    //some instructions...

代替:

if ( *(int*)v > *(int*)(v+sizeof(int)) )
    //some instructions...

其中var 可以是int*float*char* 或其他任何东西,v 被声明为

void* v;

【问题讨论】:

  • 您要比较指针还是它们指向的值?你知道(无类型的)void 指针真正指向什么吗?
  • 我想比较他们指向的值。 v 指向 int 或 float 或 structs,我知道函数调用时的类型,上面的代码在哪里。
  • 别这样,演员阵容是邪恶的。如果你不明白你在做什么,他们甚至更多。如果您真的需要,请深入了解 C 的类型系统。

标签: c variables pointers casting void


【解决方案1】:

你不能在纯 C 中做到这一点,没有“类型推断”。您可以将任何地址(int、float 等)类型转换为void*,仅此而已。任何void* 指向的内容的比较取决于指向的数据 - 而您想要做的是:在不考虑数据类型的情况下比较两件事。

例如,当您要比较以下两个字节(二进制表示法)时:

1000 0000

0000 0001

你的结果应该是什么?这是不可能的。如果它们是有符号的 8 位值 (char),那么第一个值为 -1,第二个值为 1(因此第二个值“更大”)。但如果它们是无符号值 (unsigned char),那么第一个是 255(这样会“更大”)。

在执行比较之前,您必须包含一些类型提示。例如,有一次将 twovoid*s 转换为 char*,或者在另一种情况下将其转换为 unsigned char*

【讨论】:

    【解决方案2】:

    使用指向函数的指针并强制转换为 char * 进行指针运算,就像 qsort 所做的那样:

    #include <stdio.h>
    
    int cmpint(const void *pa, const void *pb)
    {
        int a = *(int *)pa;
        int b = *(int *)pb;
    
        if (b > a) return -1;
        else return (a > b);
    }
    
    int cmpfloat(const void *pa, const void *pb)
    {
        float a = *(float *)pa;
        float b = *(float *)pb;
    
        if (b > a) return -1;
        else return (a > b);
    }
    
    
    void fn(void *v, size_t size, int (*cmp)(const void *, const void *))
    {
        if (cmp(v, (char *)v + size) == 1) {
            /* some  instructions */
            puts("v is greater than v + 1");
        }
    }
    
    int main(void)
    {
        int iarr[] = {5, 6};
        float farr[] = {7.f, 6.f};
    
        fn(iarr, sizeof(int), cmpint);
        fn(farr, sizeof(float), cmpfloat);
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      根据比较的类型简单调度:

      switch (type) {
          case int_type: {
              int* v1 = p1;
              int* v2 = p2;
              return *v1 < *v2;
          }
          case float_type: {
              float* v1 = p1;
              float* v2 = p2;
              return *v1 < *v2;
          }
      }
      

      这应该让您了解如何比较这些类型。使用检查不同类型并添加一些const 来扩展它。顺便说一句:这里没有使用演员表,恕我直言。虽然有从void*int*float* 的隐式转换。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-21
        • 1970-01-01
        • 2010-10-19
        • 1970-01-01
        相关资源
        最近更新 更多