在C中记录不同的数据类型

时间:2015-03-10 11:58:52

标签: c pointers void

我正在为数据记录类型函数编写一些C代码。从变量中获取值,执行简单操作,并将数据推送到另一个变量中。

这里的关键是在数据上容纳如此多的不同数据类型和操作。我尝试使用void指针来处理所有不同的变量。然后我为每个调用相同的函数。

看一下这个功能。你会看到我正在为每种不同的数据类型反复重写代码。

    /***********************************************************/
    static void GenData(USHORT data_type,
                         USHORT operation,
                         void *var_p,
                         void *data_p)
    /***********************************************************/
   {
      switch (data_type)
      {
      case (DATA_INT):
        switch (operation) {
        case (OP_ONE_SHOT):
          *(int*)data_p = *(int*)var_p;
          break;
        case (OP_COUNTER):
          *(int*)data_p += 1;
          break;
        case (OP_CURR_TIME):
          *(int*)data_p = (int)sytime;
        case (OP_ELAPSED_TIME):
          *(int*)data_p += delta_tick_time;
          break;
        case (OP_MIN):
          if (*(int*)data_p > *(int*)var_p) {
            *(int*)data_p = *(int*)var_p;
          }
          break;
        case (OP_MAX):
          if (*(int*)data_p < *(int*)var_p) {
            *(int*)data_p = *(int*)var_p;
          }
          break;
        case (OP_ADD_ITSELF):
          *(int*)data_p += *(int*)data_p;
          break;
        default:
          break;
        }
        break;

      case (DATA_BYTE):
        switch (operation) {
        case (OP_ONE_SHOT):
          *(BYTE*)data_p = *(BYTE*)var_p;
          break;
        case (OP_COUNTER):
          *(BYTE*)data_p += 1;
          break;
        ...
        ...

      case (DATA_SHORT):
        ...and so on...
    }

C中的void指针的算术无效。我不确定这意味着我不能让这个功能变得更好。有没有办法可以写这个,所以我不必一遍又一遍地重写“mathy”部分?

一如既往,感谢您花时间和精力提供帮助。

3 个答案:

答案 0 :(得分:2)

使用宏创建样板代码相对容易...

#define CASE(DATA_TYPE, TYPE) \
  case (DATA_TYPE): \
    switch (operation) { \
    case (OP_ONE_SHOT): \
      *(TYPE*)data_p = *(TYPE*)var_p; \
      break; \
    case (OP_COUNTER): \
      *(TYPE*)data_p += 1; \
      break; \
    case (OP_CURR_TIME): \
      *(TYPE*)data_p = (int)sytime; \
    ...etc...

static void GenData(USHORT data_type,
                     USHORT operation,
                     void *var_p,
                     void *data_p)
{
  switch (data_type)
  {
    CASE(DATA_INT, int)
    CASE(DATA_BYTE, BYTE)
    CASE(DATA_SHORT, short)
    ...etc...
  }
}

答案 1 :(得分:2)

另一种解决方案是将两个参数都转换为支持所有必需操作的单一类型,并容纳您支持的最长类型(例如,long int)。然后你可以执行操作并将结果转换回你需要的类型:

static long DoOperation(USHORT operation, long var, long data)
{
    switch(operation) {
        case(OP_ONE_SHOT):
            return data;
        case (OP_COUNTER):
            return data+1;
        [...etc...]
    }
}
static void GenData(USHORT data_type,
                     USHORT operation,
                     void *var_p,
                     void *data_p)
{
    switch(data_type) {
        case (DATA_INT):
            *(int*)data_p = (int)DoOperation(operation, *(int*)var_p, *(int*)data_p);
            break;
        case (DATA_BYTE):
            *(BYTE*)data_p = (BYTE)DoOperation(operation, *(BYTE*)var_p, *(BYTE*)data_p);
            break;
        [...etc...]
    }

}

当然,不能保证存在这种类型。

答案 2 :(得分:0)

如果问题是算术运算无效,你可以使用一些正确类型的局部变量,转换指针以在局部变量上赋值,然后对局部变量执行操作,最后复制新的值回到指针......

/***********************************************************/
static void GenData(USHORT data_type,
                     USHORT operation,
                     void *var_p,
                     void *data_p)
/***********************************************************/
{
  int int_data, int_var;      

  switch (data_type)
  {
  case (DATA_INT):
    switch (operation) {
    case (OP_ONE_SHOT):
      *(int*)data_p = *(int*)var_p;
      break;
    case (OP_COUNTER):
      //*(int*)data_p += 1;
      int_data = *(int*)data_p;
      int_data +=1;
      *(int*)data_p= int_data;
      break;
    case (OP_CURR_TIME):
      *(int*)data_p = (int)sytime;
    case (OP_ELAPSED_TIME):
      //*(int*)data_p += delta_tick_time;
      int_data = *(int*)data_p;
      int_data += delta_tick_time;
      *(int*)data_p= int_data;
      break;
      //...and so on...