ptr pointer functions examples c function pointers

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; }

Demo.


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.