簡體   English   中英

C中具有空指針的動態類型變量(最終是動態類型轉換)

[英]dynamic type variable with void pointer (eventuelly dynamic typecasting) in C

我只是問動態類型的變量(不是真正的動態,但應該在運行時確定),情況是這樣的:

我有一個函數,它接受一個雙精度數組,將其轉換為整數並寫入文件,該整數可以具有不同的Bitlength,例如8、16和32。由於它是一個數組,我想使用一個指針來訪問最終值。結果(數組)。 因此,我現在將空指針與malloc和switch case一起使用,但是當我嘗試訪問或修改此數組時,需要在每個地方添加switch case,我的問題是,有沒有更好的方法呢?

當前代碼如下:

void foo(double * arr, int len, int iBits, FILE *fh)
{
      void * newArr;
      int iBytePerElement, iBase,i;

      iBytePerElement = iBits / 8;
      iBase = (1 << (iBits - 1)) - 1;

      switch (iBytePerElement)
      {
             case 1:
                  {
                         newArr = (int8_t *) malloc(sizeof(int8_t)*len);
                         break;
                  }
             case 2:
                  {
                         newArr = (int16_t *) malloc(sizeof(int16_t)*len);
                         break;
                  }
             case 4:
                  {
                         newArr = (int32_t *) malloc(sizeof(int32_t)*len);
                         break;
                  }
      }

      for (i = 0; i < len; ++i)
      {
              switch (iBitPerElement)
              {
                     case 1:
                          {
                                ((int8_t *)newArr)[i] = (int8_t)(arr[i]*iBase);
                                 break;
                          }
                     case 2:
                          {
                                ((int16_t *)newArr)[i] = (int16_t)(arr[i]*iBase);
                                 break;
                          }
                     case 4:
                          {
                                ((int32_t *)newArr)[i] = (int32_t)(arr[i]*iBase);
                                 break;
                          }
              }
      }
      fwrite(newArr, iBytePerElement, iBytePerElement*len,fh);
}

對未定義的示例代碼(注釋)可能意味着什么做一些假設,這是我的處理方法:

#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
void *foo(double * arr, int len, int iBits)  //should return the malloced array not void
{
      void * newArr;
      int iBytePerElement, iBase, i;

      iBytePerElement = iBits / 8;
      iBase = (1 << (iBits - 1)) - 1;

      if(NULL==(newArr = malloc(iBits/CHAR_BIT))) return NULL; //replace the first switch
      //which obviously meant to alloc sizeof(int16_t)*len in the case 2 branch (not (sizeof(int8_t)*len) etc

      for (i = 0; i < len; ++i) {
          switch(iBytePerElement){
          break; case 1: ((int8_t *)newArr)[i] = arr[i]*iBase; 
          break; case 2: ((int16_t *)newArr)[i] = arr[i]*iBase;
          break; case 4: ((int32_t *)newArr)[i] = arr[i]*iBase;
          }
      }
      return newArr;
}

基本上,您只需要第二個開關。

如果您想擺脫第二個開關,可以用一些函數指針播放代替它。 例如:

#include <stdint.h>
#include <stdlib.h>
#include <limits.h>

#define MK_FN(Bits) \
void to##Bits(void *newArr, double const*arr, int len) \
{ \
    int i; for(i=0; i < len; i++) ((int##Bits##_t *)newArr)[i] = arr[i]*((1<<(Bits-1)-1));  \
} 
MK_FN(8)
MK_FN(16)
MK_FN(32)



void *foo(double * arr, int len, int iBits)  //should return the malloced array not void
{
      void * newArr;
      int iBytePerElement = iBits / 8;

      if(NULL==(newArr = malloc(iBits/CHAR_BIT))) return NULL;
      ((void (*[])(void *,double const*, int)){ [1]=to8, [2]=to16, [4]=to32, })[iBits](newArr,arr,len);
      return newArr;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM