2011-08-11 44 views
11

estoy estudiando Linux de programación C++ cuando veo¿Qué es char * const argv []?

int execve(const char *path, 
      char *const argv[], 
      char *const envp[]); 

No entiendo lo que es char *const argv[]. Sé que char *const foo es un puntero constante para char. Y const char *foo es un puntero a un const char. ¿Pero qué es char *const argv[]?

¿Es una matriz de punteros de const para char o una serie de punteros para const char?

Y ahora tengo un vector<string>, ¿cómo convertirlo a char *const argv[]?

Respuesta

28

Es una matriz de punteros const char o una matriz de punteros a const char ?

tipos de lectura de derecha a izquierda:
const siempre se une a la izquierda (a menos que sea en el extremo izquierdo)

char *const argv[] 

       ^^ Array of 
     ^^^^^  const 
    ^   pointer to 
^^^^    char 

Una serie de "const pointer" a Char

Así que los punteros en la matriz no puede ser modificada.
Pero lo que señalan se puede modificar.

Nota: Como lo señala Steve a continuación. Porque esto se está utilizando como un parámetro. De hecho, se descompone en un "puntero A a "const pointer" en char" o "char * const *".

Y tengo una cadena de vectores < > ahora, la forma de convertir a char * const argv []?

int execve(const char *path, 
     char *const argv[], 
     char *const envp[]); 

int main() 
{ 
    std::vector<std::string> data; /// fill 
    std::vector<char*>   argv; 
    std::vector<char*>   envp; 

    for(std::vector<std::string>::iterator loop = data.begin(); loop != data.end(); ++loop) 
    { 
     argv.push_back(&(*loop)[0]); 
    } 

    // I also bet that argv and envp need to be NULL terminated 
    argv.push_back(NULL); 
    envp.push_back(NULL); 
    execve("MyAppName", &argv[0], &envp[0]); 
} 
+2

+1 para la explicación diagramática: D – Nawaz

+3

Es cierto que 'char * const argv []' es un tipo de matriz, pero en este contexto, un parámetro de función, el tipo no es 'char * const argv []', es 'char * const * argv'. –

2

cdecl.org dice:

char *const argv[] 

declaran argv como conjunto de const puntero a char

+0

y cómo convertir '' vector a 'const char * argv []'? – Kaoet

+1

También es útil: http://www.unixwiz.net/techtips/reading-cdecl.html –

+0

@MrPhone: Posiblemente publique eso como una pregunta separada. Es bastante simple, pero se necesita más que un comentario para escribir. –

1
// says: argv is a constant pointer pointing to a char* 
int main(int c, char *const argv[]); 

Usted no será capaz de cambiar "argv" dentro de la función.

Como acaba de aprender C, le recomiendo que realmente intente comprender las diferencias entre matrices y punteros primero en lugar de las cosas comunes.

En el área de parámetros y matrices, hay algunas reglas confusas que deberían estar claras antes de continuar. Primero, lo que declaras en una lista de parámetros se trata de manera especial. Hay situaciones en las que las cosas no tienen sentido como un parámetro de función en C.Estos son

  • Funciones como parámetros
  • matrices como parámetros

matrices como parámetros

El segundo quizás no es inmediatamente claro. Pero queda claro cuando se considera que el tamaño de una dimensión de matriz forma parte del tipo en C (y una matriz cuyo tamaño de dimensión no se proporciona tiene un tipo incompleto). Por lo tanto, si crea una función que toma un valor por orden de matriz (recibe una copia), ¡podría hacerlo solo para un tamaño! Además, las matrices pueden volverse grandes y C intenta ser lo más rápido posible.

En C, por estos motivos, los valores de matriz no existen. Si desea obtener el valor de una matriz, lo que obtiene en su lugar es un puntero al primer elemento de esa matriz. Y aquí en realidad ya se encuentra la solución. En lugar de dibujar un parámetro de matriz no válido por adelantado, un compilador de C transformará el tipo del parámetro respectivo para que sea un puntero. Recuerda esto, es muy importante. El parámetro no será una matriz, sino que será un puntero al tipo de elemento respectivo.

Ahora, si intenta pasar una matriz, lo que se pasa en su lugar es un puntero al primer elemento de las matrices.

excursión: Funciones como parámetros

Para finalizar, y porque creo que esto le ayudará a entender mejor el asunto, vamos a ver cuál es el estado de cosas es cuando se trata de tener una función como un parámetro. De hecho, primero no tendrá ningún sentido. ¿Cómo puede un parámetro ser una función? Huh, queremos una variable en ese lugar, por supuesto! Entonces, lo que hace el compilador cuando eso sucede es, una vez más, transformar la función en un puntero de función. Intentar pasar una función pasará un puntero a esa función respectiva. Por lo tanto, los siguientes son los mismos (análogo a la matriz de ejemplo): se necesita

void f(void g(void)); 
void f(void (*g)(void)); 

Nota que los paréntesis alrededor *g. De lo contrario, especificaría una función que devuelve void*, en lugar de un puntero a una función que devuelve void.

Volver a las matrices de

Ahora, he dicho al principio que las matrices pueden tener un tipo incompleto - lo que sucede si usted no da un tamaño aún. Como ya pensamos que un parámetro de matriz no existe, sino que cualquier parámetro de matriz es un puntero, el tamaño de la matriz no importa. Eso significa, que el compilador se traducirá todo lo siguiente, y todos son la misma cosa:

int main(int c, char **argv); 
int main(int c, char *argv[]); 
int main(int c, char *argv[1]); 
int main(int c, char *argv[42]); 

Por supuesto, no tiene mucho sentido para ser capaz de poner cualquier tamaño en el mismo, y es simplemente arrojados lejos. Por esa razón, el C99 se acercó con un nuevo significado para esos números, y permite que otras cosas que aparecen entre corchetes:

// says: argv is a non-null pointer pointing to at least 5 char*'s 
// allows CPU to pre-load some memory. 
int main(int c, char *argv[static 5]); 

// says: argv is a constant pointer pointing to a char* 
int main(int c, char *argv[const]); 

// says the same as the previous one 
int main(int c, char ** const argv); 

Las dos últimas líneas dicen que usted no será capaz de cambiar "argv" dentro de la función: se ha convertido en un puntero const. Sin embargo, pocos compiladores C admiten esas características C99. Pero estas características dejan en claro que la "matriz" no es en realidad una. Es un puntero.

una palabra de advertencia

Tenga en cuenta que todo lo dicho anteriormente es cierto sólo cuando usted tiene una matriz como un parámetro de una función. Si trabaja con matrices locales, una matriz no será un puntero. Se comportará como un puntero, porque como se explicó anteriormente, una matriz se convertirá en un puntero cuando se lea su valor. Pero no se debe confundir con punteros.

Un ejemplo clásico es el siguiente:

char c[10]; 
char **c = &c; // does not work. 

typedef char array[10]; 
array *pc = &c; // *does* work. 

// same without typedef. Parens needed, because [...] has 
// higher precedence than '*'. Analogous to the function example above. 
char (*array)[10] = &c; 
+0

No estoy seguro de por qué esto fue downvoted hoy –

Cuestiones relacionadas