Devo definire un tipo di dati a 24 bit. Sto usando char[3]
per rappresentare il tipo. Posso type24
typedef char[3]
su type24
? L’ho provato in un esempio di codice. Ho messo typedef char[3] type24;
nel mio file di intestazione. Il compilatore non si è lamentato di ciò. Ma quando ho definito una funzione void foo(type24 val) {}
nel mio file C, si è lamentata. Mi piacerebbe essere in grado di definire funzioni come type24_to_int32(type24 val)
invece di type24_to_int32(char value[3])
.
Il typedef sarebbe
typedef char type24[3];
Tuttavia, questa è probabilmente una pessima idea, perché il tipo risultante è un tipo di array, ma gli utenti non vedranno che si tratta di un tipo di array. Se usato come argomento di funzione, verrà passato per riferimento, non per valore, e la dimensione di esso sarà quindi errata.
Una soluzione migliore sarebbe
typedef struct type24 { char x[3]; } type24;
Probabilmente vorrete anche usare il unsigned char
invece di char
, dato che quest’ultimo ha una firma definita dall’implementazione.
Tu vuoi
typedef char type24[3];
Le dichiarazioni di tipo C sono strane in questo modo. Metti il tipo esattamente dove andrebbe il nome della variabile se dichiarassi una variabile di quel tipo.
Dalla risposta di R .. :
Tuttavia, questa è probabilmente una pessima idea, perché il tipo risultante è un tipo di array, ma gli utenti non vedranno che si tratta di un tipo di array. Se usato come argomento di funzione, verrà passato per riferimento, non per valore, e la dimensione di esso sarà quindi errata.
Gli utenti che non vedono che si tratta di un array molto probabilmente scriveranno qualcosa del genere (che fallisce):
#include typedef int twoInts[2]; void print(twoInts *twoIntsPtr); void intermediate (twoInts twoIntsAppearsByValue); int main () { twoInts a; a[0] = 0; a[1] = 1; print(&a); intermediate(a); return 0; } void intermediate(twoInts b) { print(&b); } void print(twoInts *c){ printf("%d\n%d\n", (*c)[0], (*c)[1]); }
Compilerà con i seguenti avvertimenti:
In function 'intermediate': warning: passing argument 1 of 'print' from incompatible pointer type [enabled by default] print(&b); ^ note: expected 'int (*)[2]' but argument is of type 'int **' void print(twoInts *twoIntsPtr); ^
E produce il seguente output:
0 1 -453308976 32767
Per usare correttamente il tipo di array come argomento di funzione o parametro di template, crea una struct invece di typedef, quindi aggiungi un operator[]
alla struct in modo da poter mantenere la funzionalità dell’array in questo modo:
typedef struct type24 { char& operator[](int i) { return byte[i]; } char byte[3]; } type24; type24 x; x[2] = 'r'; char c = x[2];
Le matrici non possono essere passate come parametri di funzione per valore in C.
Puoi mettere la matrice in una struttura:
typedef struct type24 { char byte[3]; } type24;
e poi lo passa per valore, ma ovviamente è meno conveniente usare: x.byte[0]
invece di x[0]
.
La tua funzione type24_to_int32(char value[3])
realtà passa per puntatore, non per valore. È esattamente equivalente a type24_to_int32(char *value)
, e il 3
viene ignorato.
Se sei felice di passare per puntatore, puoi attaccare con l’array e fare:
type24_to_int32(const type24 *value);
Questo passerà un puntatore all’array, non un puntatore al primo elemento, quindi lo usi come:
(*value)[0]
Non sono sicuro che sia davvero un guadagno, dal momento che se accidentalmente scrivi value[1]
allora succede qualcosa di stupido.