2012-04-23 2 views
1

У меня есть небольшая математическая библиотека для 3d-вектора и Im, пытающаяся «унифицировать» ее.C Typedef Struct/Union auto-cast

Вместо того, чтобы несколько ЬурейиХ-структуры для vector3f, vector3i, color3, углов и т.д. ... Im пытаясь поставить все в тех же структуры, как это:

typedef struct 
{ 
    union 
    { 
      float x; 
      float r; 
      float ax; 

      int x_int; 
    }; 

    union 
    {   
      float y; 
      float g; 
      float ay; 

      int y_int; 
    }; 


    union 
    { 
      float z; 
      float b; 
      float az; 

      int z_int;     
    }; 

} vec3; 

Все работает персиковым до тех пор, как тип float, однако, когда он падает до int Im, имеющего некоторые странные значения (что понятно). Мой вопрос: есть ли способ напрямую или автоматически преобразовывать внутри определения структуры или мне нужно создавать дополнительные функции для typecast между float и int?


Из приведенных ниже ответов, может быть, я должен изменить свой первоначальный вопрос к следующему:

Каков наилучший способ «объединить» (и унифицировать я имею в виду иметь как 1 структуры), чтобы быть способен обрабатывать одновременно следующим образом:

vector3f (с плавающей точкой х, у, г) vector3i (Int х, у, г) RGB (с плавающей точкой R, G, B) RGB (символ без знака г, g, b) Угол эйлера (ax, ay, az)

Заранее спасибо!

+0

Чтобы уточнить, вы хотите написать в struct/union как 'int', но считывается из него как' float'? –

+1

Почему бы просто не держать его как float, и когда вам нужно целочисленное значение, просто введите float-член в int. –

ответ

1
#include <stdio.h> 
#include <stdlib.h> 

typedef struct genericStruct 
{ 
    void *valueOne; 
    void *valueTwo; 
}GS; 

int main() 
{ 
    GS *gs = malloc(sizeof(*gs)); 
    int valueInt = 10; 
    float valueFloat = 3.141592653589; 
    int *inputIntPtr = (int*)malloc(sizeof(int)); 
    float *inputFloatPtr = (float*)malloc(sizeof(float)); 
    void *voidPtr = NULL; 
    *inputIntPtr = valueInt; 
    *inputFloatPtr = valueFloat; 
    voidPtr = inputIntPtr; 
    gs->valueOne = voidPtr; 
    int *outputIntPtr = (int*)malloc(sizeof(int)); 
    outputIntPtr = gs->valueOne; 
    printf("Input ptr = %d\n", *inputIntPtr); 
    printf("Output ptr = %d\n", *outputIntPtr); 
    voidPtr = inputFloatPtr; 
    gs->valueTwo = voidPtr; 
    float *outputFloatPtr = (float*)malloc(sizeof(float)); 
    outputFloatPtr = gs->valueTwo; 
    printf("Input ptr = %f\n", *inputFloatPtr); 
    printf("output ptr = %f\n", *outputFloatPtr); 
    free(gs); 
    free(inputIntPtr); 
    free(inputFloatPtr); 
    free(outputIntPtr); 
    free(outputFloatPtr); 
    return 0; 
} 

И это то, что я имел в виду, используя типы пустот.

2

Если вы хотите, чтобы вы поместили '360.0f' в float z объединения и имели int z_int == 3, или наоборот, вы не можете. Это не цель объединения, а двоичное представление 3 (целое число) и 3.0 (значение с плавающей запятой) - это disimiliar.

Однако вы могли бы просто удалить int и бросить одно из поплавков в int.

-1

Или изменить все переменные на тип указателя void, а затем применить их к float или integer. Это нормально?

+0

Вы не можете назначить значение для ввода void. – delicateLatticeworkFever

+0

Вы даже не можете объявить переменную с типом void. – Anthales

+0

Если вы хотите создать общую структуру: typedef struct Abc_ { void * data1; ... void * данныеN; } Abc; на основе алгоритмов мастеринга с C Кайлом Лаудоном. – Avyakt

0

Это небольшой фрагмент кода, который я написал для you.It должен делать job.I надеюсь, что я был в состоянии сделать то, что вы просили ...

typedef struct{ 


     void *ptr1; 

     void *ptr2; 

     void *ptr3; 

}VEC; 






main(){ 

     VEC v ; 

     VEC *ptr; 

     int a = 5; 

     double b = 6; 

     float c = 7; 

     v.ptr1 = NULL; 

     v.ptr2 = NULL; 

     v.ptr3 = NULL; 


     ptr = &v; 

     v.ptr1 = (int *)&a; 

     ptr->ptr1 = (int *)&a; 

     v.ptr2 = (double *)&b; 

     ptr->ptr2 = (double *)&b; 

     v.ptr3 = (float *)&c; 

     ptr->ptr3 = (float *)&c; 

     printf("%d\n",*(int *)v.ptr1); 

     printf("%d\n",*(int *)(ptr->ptr1)); 

     printf("%lf\n",*(double *)v.ptr2); 

     printf("%lf\n",*(double *)(ptr->ptr2)); 

     printf("%f\n",*(float *)v.ptr3); 

     printf("%f\n",*(float *)(ptr->ptr3)); 

}