c - 如何使用具有相同名称的不同类型的指针?

标签 c pointers

我在减少 for 循环的数量方面遇到了问题。他们对不同的类型做同样的事情。

我应该使用 void 指针还是其他东西。

是否可以减少代码量?

  void smt(int nb, int iform, void *ptr)//example function
  {
      int *ipt;// pointers definitions
      float *fpt;
      double *dpt;
      if( iform == 1 )
      {
          ipt = (int *) ptr;
          for( int i = 0; i < nb; i++ )
              ipt[i]=i;
      }
      else if( iform == 2)
      {
          fpt  = (float *)ptr;
          for( int i = 0; i < nb; i++)
              fpt[i] = 2.71;
      }
      else
      {
          dpt = (double *)ptr;
          for( int i = 0; i < nb; i++)
              dpt[i] = i*3.14159;
      }
   } 
   int main(void)
   {
       int nb = 5;
       float iform = 2;
       float *a = malloc(nb*sizeof(float)); //allocate memory 
       float *fpt;
       //there should be double *dpt and so on  
       smt(nb, iform, a );
       if( iform == 1)
       {
           for( int i = 0; i < nb; i++)
               printf("a = %d\n", a[i]);
       }
       else if( iform  == 2)
       {
           for( int i = 0; i < nb; i++)
               printf("a = %f\n", a[i]);
       }
       else
       {
           for( int i = 0; i < nb; i++)
               printf("a = %f\n", a[i]);
       }            
            return 0;
   }

最佳答案

如果你分配内存

float *a = malloc(nb*sizeof(float));

你可以使用指针a作为一个 float 组。编译器知道 float 有多大用于计算数组元素a[i]的地址.

如果将指针转换为不同的类型,则数组元素的大小可能会不同,从而导致不同的地址。与 i != 0使用 a[i] 时,您会将数据存储在不同的地址或 ((double*)a)[i] .

要在数组中存储不同的类型,我建议使用 union .而不是 iform 的魔数(Magic Number)我建议使用枚举类型(或 #define s)。要减少 for 循环的数量,您可以移动 iform 的比较。进入循环体。

union data {
    int intVal;
    float floatVal;
    double doubleVal;
};

enum dataType {
    INT_DATA = 1,
    FLOAT_DATA = 2,
    DOUBLE_DATA = 3
}

void smt(int nb, enum dataType iform, union data *ptr)//example function
{
    for( int i = 0; i < nb; i++ )
    {
        switch( iform )
        {
        case INT_DATA:
            ptr[i].intVal = i;
            break
        case FLOAT_DATA:
            ptr[i].floatVal = 2.71;
            break;
        case DOUBLE_DATA:
        default:
            ptr[i].doubleVal = i*3.14159;
            break;
        }
    }
} 

int main(void)
{
    int nb = 5;
    enum dataType iform = FLOAT_DATA;
    union data *a = malloc(nb*sizeof(union data )); //allocate memory 

    smt(nb, iform, a );
    for( int i = 0; i < nb; i++)
    {
        switch( iform )
        {
        case INT_DATA:
            printf("a = %d\n", a[i].intVal);
            break
        case FLOAT_DATA:
            printf("a = %f\n", (double)a[i].floatVal);
            break;
        case DOUBLE_DATA:
        default:
            printf("a = %f\n", a[i].doubleVal);
            break;
        }
   }            
   return 0;
}

可以使用 void 指针进行强制转换,但您必须使用最大数据类型的指针,而不是将指针强制转换为数组的开头 a yopu 必须转换数组元素的地址。假设 double是您可以执行类似操作的最大数据类型。

double *a = malloc(nb*sizeof(*a)); //allocate memory 

int *ipt = (int*)&(a[i]);
*ipt = i;

但我不推荐这样做。

关于c - 如何使用具有相同名称的不同类型的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54289858/

相关文章:

c++ - 隐式构建规则: GNU Make Multiple Makefiles Multiple Directories

c++ - 如何在 C++ 中交叉包含类?

c - int 和 char 指针如何影响我在此处的打印?

c++ - C 简单指针示例

c++ - 如何将二维字符串数组传递给另一个类的函数

c - 在 Debian 上使用 gcc 4.7.2-5 无效释放/删除,而在 Ubuntu/Linaro 上使用 gcc 4.8.1 一切正常

为 C 编写标准 unix 程序时的命令行参数 "−"

c - 使用 malloc() 作为唯一指针

c++ - Webassembly - 尝试编译代码缓冲区并通过 EM_JS 通过 C 执行它

c - C 中的 SHA1 错误实现