2011-11-29 15 views
7

Hice un typedef para las matrices de flotación, así:Typedef una red de flotadores sin restricciones en C

typedef float fooType[]; 

De modo que pueda declarar e inicializar arrays de flotación estática como esto:

fooType myArray = {1.0, 2.0, 3.0} 

Eso funciona multa. Puedo decir myArray[2] sin problemas y generalmente uso mi fooType como me gustaría. En el contexto de mi programa, está muy claro que fooType es un tipo de matriz (en realidad es una tabla de búsqueda gigante) por lo que no estoy simplemente haciendo typedef float fooType.

¿Cómo declaro y uso una variable para señalar a bar y acceder a los elementos de bar? No puedo declarar una variable simple como esto:

fooType bar = myArray; 

Dado que los errores con invalid initializer; No esperaba que funcionara porque el compilador no sabe cuánta memoria asignar. He intentado algunas cosas con punteros:

fooType *bar = myArray; 

Esto da una advertencia: initialization from incompatible pointer type y errores cuando accedo a los elementos con bar[1] .. Esto declara bien, como me esperaba que ya que los tipos coinciden ahora:

fooType *bar = &myArray; 

Pero por encima de los errores de compilación con un invalid use of array with unspecified bounds cuando digo bar[1].

Esto funciona:

float *bar = myArray; 
float val = bar[3]; 

Pero yo no quiero porque pierdo la legibilidad de mi typedef.

He estado enterrado durante mucho tiempo en un tierno mundo de OO (Java), así que espero entender de esto lo idiomático en C en esta situación. Estoy bastante preparado para cambiar mi uso del typedef para adecuarme a la convención si no hay una solución directa. Tengo la sensación de que sí lo hay, y no es complicado.

Gracias

+0

La conclusión es que ** no ** quieres hacer typedefs para matrices ... Puedes, pero luego te enfrentas a todos esos "problemas". Por ejemplo, esta cosa 'fooType myArray = {1.0, 2.0, 3.0}; fooType bar = myArray; 'significa' float myArray [] = {1.0, 2.0, 3.0}; barra de flotación [] = myArray; '¿Es legible? :) Otro "rompecabezas" es cuando defines un prototipo de función que toma 'fooType' como _output_ argument. (Similar a 'memset', etc.) – debleek63

+0

Eso ya está claro @ debleek63. Gracias. –

Respuesta

5

El problema que se encuentra aquí es el hecho de que las matrices no son punteros en C, sino más bien decaen a punteros al primer elemento cuando se utilizan en el lado derecho del operador de asignación.Por lo tanto, si se declara un array como

fooType myArray = {1.0, 2.0, 3.0} 

del tipo de myArray es float[3] y & miMatriz es (*float)[3], o "puntero a una matriz de 3 flotadores". Por lo tanto no se puede simplemente decir

fooType *bar = myArray; 

El tipo fooType* no es un puntero a un flotador ... por lo tanto se trata de un tipo de puntero incompatible. Haciendo

fooType* bar = &myArray; 

funciona, pero el problema que está encontrando es que bar[1] no es un elemento de la matriz myArray, ya bar sí mismo es un puntero. Debería desreferenciar bar como (*bar)[1] para acceder a un elemento en myArray. Por ejemplo:

typedef float fooType[]; 
fooType myArray = {1.0, 2.0, 3.0} 
fooType* bar = &myArray; 
(*bar)[1] = 5.0; 

Por último, tenga en cuenta que con C, no se puede asignar una matriz a otra matriz ... para que can'd hacer algo como:

fooType bar = myArray; 

Esto se remonta a todo el asunto de las matrices y su descomposición en indicadores para el primer elemento, y el hecho de que el tipo de la matriz en sí no es el mismo que el tipo del primer elemento en la matriz.

Puede al final simplemente querer escribir la matriz, y luego digitar los tipos de elementos de la matriz desde el uso de float para que cualquiera que use su código sepa qué tipo de elemento pertenece con el otro.

+0

Gracias Jason. Eso es un poco más claro ahora. No puedo usar el typedef entonces, parecería, ya que su tipo es ... 'float []'? ¿Debo usar 'float * bar = myArray' en su lugar? No es tan legible pero funciona. –

+0

Sé el tamaño de las matrices en tiempo de compilación, por lo que su segunda opción funcionaría, pero ambas sugerencias han ayudado mucho. Gracias. –

+0

Por cierto, cambié mi respuesta un poco ... parece que hubo un error de sintaxis que lo bloqueó de una de sus soluciones. – Jason

1

que haya mezclado con Java C.

intenta cambiar su typedef a

typedef float *fooType; 

Posteriormente, sin embargo, no será capaz de inicializar una variable de tipo fooType como

fooType myArray = {1.0, 2.0, 3.0}; 

porque fooType es un puntero ahora.

+0

Ocultar un tipo de puntero detrás de un 'typedef' generalmente se considera una mala práctica ... –

+0

@OliCharlesworth oops. Gracias. Solo quería que el código de OP funcione. – Beginner

+0

Gracias Roman, Oli. Funciona como lo escribí: puedo inicializar mis matrices y usarlas directamente. Necesito poder inicializar en la declaración como en la pregunta. Lo único que aún no puedo hacer es declarar otras variables que los señalen. –

0

Utilizando Visual Studio 2013 encontré que puede usar construcciones como en este ejemplo. Esto también parece funcionar con Visual Studio 2015.

en cuenta que el uso de malloc() para crear una matriz de fooType requiere un puntero sin referencia de tipo pfooType en lugar del tipo de fooType o *pfooType para compilar. Cambié el typedef de float a double y el sizeof(*p2) cambió de 4 a 8 bytes como se esperaba.

#include <malloc.h> 

typedef float fooType[], *pfooType; 

int xxmain2(void) 
{ 
    fooType myArray = { 1.0, 2.0, 3.0 }; // define the array with its elements 
    pfooType p = myArray; // get a pointer to the array. 
    int i; 
    int nElements = sizeof(myArray)/sizeof(*p); // determine number of elements in the array. 

    pfooType p2 = malloc(sizeof(*p2) * 5); // malloc() an array of 5 elements. 

    for (i = 0; i < 5; i++) p2[i] = (float)i * 10.0; // initialize my malloced array. 
    myArray[0] = *p;  // dereference pointer 
    myArray[1] = p[1];  // use array subscripting with pointer 

    for (i = 0, p = myArray; i < nElements; i++) *p++ = 0; // increment the pointer to traverse the array. 

    free(p2); 
    return 0; 
} 

También encontré que no podía crear un tamaño especificado de una matriz con algo así como fooType myRay2[10]; (error de compilación de "error C2087: 'myRay2': subíndice perdido") o algo similar. Y fooType myRay2; da un error de compilación de "error C2133: 'myRay2': tamaño desconocido".

Así que la única manera parece ser utilizar la inicialización para dimensionar la matriz o usar malloc() para crear una matriz de un tamaño particular que luego requiere free().