pointer - ptr function c
¿Por qué es ilegal un argumento temporal? (3)
Tengo una función, f(char **p)
, y quería llamarlo de la forma más simple que pude.
Lo intenté
char ** p = {"a", "b"};
f(p);
y consiguió:
objeto escalar requiere un elemento en el inicializador
así que lo cambié en
char * p[2] = {"a", "b"};
f(p);
y eso estuvo bien [ también hubiera estado bien con solo char * p[]
].
¿Por qué no puedo crear una serie de punteros sobre la marcha como los siguientes?
f({"a", "b"});
C99 y posteriores añadieron literales compuestos para el propósito exacto: crear matrices y estructuras sobre la marcha
Ejemplo:
struct foo {int a; char b[2];} structure;
structure = ((struct foo) {1, ''a'', 0});
int *y = (int []) {1, 2, 3};
int *z = (int []) {1};
Además de la norma C99 y posteriores, GCC también ofrece esta función como una extensión.
En tu caso esto funcionará.
f((char *[]){"a","b"});
(char *[]){"a","b"}
es un literal compuesto que crea una matriz de 2 punteros a char
sobre la marcha.
Esta declaración char ** p = {"a", "b"};
activa una advertencia porque C no sabe cómo interpretar el contenido de las llaves {
}
:
- El tipo de declaración
char**
sugiere que es un puntero a puntero a char único - El contenido de
{
}
especifica dos elementos.
Debe decirle a C que está inicializando un puntero a puntero con un puntero al elemento inicial de una matriz anónima especificando un tipo delante de las llaves:
char ** p = (char*[]){"a", "b"}
Este constructo se llama un "literal compuesto". Podría usarse en una declaración, pero también funciona como una expresión.
Nota: si planea pasar una matriz como esa a una función, debe proporcionar una manera de determinar el tamaño de la matriz. Un enfoque es pasar NULL
para "terminar" la matriz, de esta manera:
void f(char **p) {
int i = 0;
while (*p) {
printf("%d:%s/n", i++, *p++);
}
}
int main(void) {
f((char*[]){"a", "b", NULL});
return 0;
}
Esto da una advertencia:
char ** p = {"a", "b"};
porque p
no es una matriz
Esto tampoco es legal:
f({"a", "b"});
ya que las llaves por sí mismas no están permitidas en una expresión (pero se pueden usar como inicializador).
Es posible crear una matriz sobre la marcha utilizando un literal compuesto :
f((char *[]){"a", "b"});
También puedes usar un literal compuesto para inicializar un temporal:
char ** p = (char *[]){"a", "b"};
A diferencia de la primera declaración, esto es válido porque el literal es una matriz de tipo char *[2]
y se reducirá a un char **
que se puede usar para inicializar una variable de este tipo.
Consulte la sección 6.5.2.5 del estándar C para obtener más información sobre los literales compuestos.