En C, es posible typedef una matriz, usando esta construcción:
typedef int table_t[N];
Aquí, table_t ahora se define como una matriz de N int . Cualquier variable declarada como table_t t; ahora se comportará como una matriz normal de int .
El objetivo de tal construcción es usarse como un tipo de argumento en una función, como:
int doSomething(table_t t);
Un prototipo de función relativamente equivalente podría haber sido:
int doSomething(int* t);
El mérito de la primera construcción es que impone N como el tamaño de la mesa. En muchas circunstancias, es más seguro hacer cumplir esta propiedad, en lugar de confiar en el programador para averiguar correctamente esta condición.
Ahora todo está bien, excepto que, para garantizar que el contenido de la tabla no se modificará, es necesario usar el calificador const .
La siguiente declaración es relativamente fácil de entender:
int doSomething(const int* t);
Ahora, doSomething garantiza que no modificará el contenido de la tabla pasada como puntero. Ahora, ¿qué pasa con esta construcción casi equivalente? :
int doSomething(const table_t t);
¿Qué es const aquí? el contenido de la tabla, o el puntero a la tabla? Si es el puntero el que es const , ¿hay otra forma (compatible con C90) de retener la capacidad de definir el tamaño de la tabla y decir que su contenido será const ?
Tenga en cuenta que a veces también es necesario modificar el contenido de la tabla, por lo que la propiedad const no se puede incrustar en la definición de typedef.
[ Editar ] Gracias por las excelentes respuestas recibidas hasta ahora. Para resumir :
const también se comportará igual que si fuera un puntero (en marcado contraste con un typedef a un tipo de puntero, como lo subraya @random a continuación)Primero, te equivocas, los prototipos de funciones
int doSomething(table_t t); int doSomething(int* t);son exactamente equivalentes. Para los parámetros de función, la primera dimensión de la matriz siempre se reescribe como un puntero. Por lo tanto, no hay garantía del tamaño de la matriz que se recibe.
const -calificación en matrices siempre se aplica al tipo base de la matriz, por lo que las dos declaraciones
const table_t a; int const a[N];son equivalentes, y para los parámetros de las funciones tenemos
int doSomething(const table_t t); int doSomething(int const* t);El contenido de la tabla será constante. Comprobado fácilmente con este código.
#include<stdio.h> typedef int table_t[3]; void doSomething(const table_t t) { t++; //No error, it's a non-const pointer. t[1]=3; //Error, it's a pointer to const. } int main() { table_t t={1,2,3}; printf("%d %d %d %ld",t[0],t[1],t[2],sizeof(t)); t[1]=5; doSomething(t); return 0; }Los tipos de matriz y los tipos de puntero no son 100 % equivalentes, incluso en este contexto en el que finalmente obtiene un tipo de puntero para el parámetro de función. Su error es asumir que const habría actuado de la misma manera si fuera un tipo de puntero.
Para ampliar el ejemplo de ARBY:
typedef int table_t[3]; typedef int *pointer_t; void doSomething(const table_t t) { t++; //No error, it's a non-const pointer. t[1]=3; //Error, it's a pointer to const. } void doSomethingElse(const pointer_t t) { t++; //Error, it's a const pointer. t[1]=3; //No error, it's pointer to plain int } Actúa de manera similar a const int * , pero const pointer_t es equivalente a int * const .
(Además, descargo de responsabilidad, los nombres definidos por el usuario que terminan con _t no están permitidos por POSIX, están reservados para futuras expansiones)