2012-02-19 11 views
10

Soy nuevo en C, y las cosas son diferentes en C que en cualquier otro idioma que haya aprendido. En mi tarea quiero crear una matriz de caracteres que apuntan a una matriz de caracteres, pero en lugar de hacer una matriz de caracteres multidimensional, me imagino que tendría más control y crear matrices de caracteres y poner cada uno en los índices de la matriz de caracteres original:¿Puedo crear una matriz de punteros Char en C?

char keywords[10]; 
keywords[0] = "float"; 

El ejemplo anterior es para aclarar y un caso simple. Pero mi pregunta se debe a la investigación que he estado haciendo, y estoy confundido acerca de algo. Normalmente esto funciona en otros idiomas, pero en C sería:

char *keyword[10]; 
keywords[0] = "float"; 

Pero cuando quiero enviarlo a través de una función, ¿por qué es necesario:

void function(char **keyword); //function prototype 

No sería de paso el puntero de matriz es suficiente?

+3

¿Qué piensas/espero que sea el prototipo de función? –

+0

También puede pasar la palabra clave char * [], significa exactamente lo mismo – Matthieu

+0

Sí, puede .... hacer lo que quiera. Pero la verdadera pregunta es qué buenos libros de programación de C has leído ... –

Respuesta

10

Parece que está confundido por las estrellas dobles en

void function(char ** keyword); 

Las estrellas dobles sólo significa que esta función espera que usted pasa un puntero a un puntero a un char. Esta sintaxis no incluye ninguna información sobre el hecho de que está utilizando una matriz, o que la char es en realidad la primera char de muchas cadenas. Depende de usted, como programador, saber a qué tipo de estructura de datos se refiere este char **.

Por ejemplo, supongamos que el comienzo de su matriz se almacena en la dirección 0x1000. El argumento keyword para la función debe tener un valor de 0x1000. Si desreferencia keyword, obtiene la primera entrada en la matriz, que es un char * que apunta al primer carácter de la cadena "flotante". Si desreferencia el char *, obtiene el carácter "f".

El (artificial) código para ese sería el resultado:

void function(char **keyword) 
{ 
    char * first_string = *keyword; // *keyword is equivalent to keyword[0] 
    char first_char = *first_string; // *first_string is equivalent to first_string[0] 
} 

Había dos punteros en el ejemplo anterior. Al agregar un desplazamiento al primer puntero antes de desreferenciarlo, puede acceder a diferentes cadenas en el conjunto. Al agregar un desplazamiento al segundo puntero antes de desreferenciarlo, puede acceder a diferentes caracteres en la cadena.

+0

Veo lo que dices. Es un poco confuso con las estrellas, pero aprecio la aclaración. – Andy

+0

Agregar una estrella a un tipo T simplemente lo cambia a "puntero a T". Entonces "char *" es "puntero a char" y "char **" es "puntero a puntero a char". –

1
char *keyword[10]; 

keyword es una matriz 10 de char *. En un contexto de valor, se convirtió en un puntero a char *.

Esta conversión es una parte de lo que Chris Torek llama "La Regla":.

"Como se ha señalado en otros lugares, C tiene una regla muy importante acerca de las matrices y los punteros Esta regla - La Regla - - dice que, en un contexto de valor, un objeto de tipo 'matriz de T' se convierte en un valor de tipo 'apuntador a T', apuntando al primer elemento de esa matriz "

Consulte aquí para obtener más información: http://web.torek.net/torek/c/pa.html

El C-FAQ también tiene una entrada en esta matriz a la conversión de puntero:

Pregunta 6.3: ¿Qué se entiende por la "equivalencia de apuntadores y arreglos '' en C?

http://c-faq.com/aryptr/aryptrequiv.html

+2

Esto es correcto, pero no muy claro para alguien nuevo en el idioma. Debería considerar explicar lo que quiere decir con un "contexto de valor". –

+0

Aprecio el enlace – Andy

0

En C, realmente no se puede pasar a una variedad de funciones. En cambio, pasa un puntero al principio de la matriz. Como tiene una matriz de char*, la función obtendrá un puntero a char*, que es char**.

Si lo desea, puede escribir (en el prototipo) char *keyword[] en lugar de char **keyword. El compilador lo convertirá automáticamente.

Además, en C puede desviar punteros como matrices, por lo que no pierde casi nada con esa "conversión a puntero".

1

Si desea

void function(char **keyword); 

Andy, piensa en que una matriz es simplemente un puntero (al comienzo de la matriz), por eso se escribe:

void function(char **keyword); 

Debido a que tiene crea una matriz para los punteros de char.

Si es más fácil de entender probar:

void function(char *keyword[]); 

Pero es más estándar de C para utilizar la primera, aunque si se utiliza un compilador de C++ no importa realmente.

+4

Obligatorio -1 para "array es solo un puntero". –

1

Aquí está la respuesta.

#include<stdio.h> 

int main(void) 
{ 
     char *CharPtr[3]; 
     char a[4]="abc"; 
     char b[4]="def"; 
     char c[4]="ghi"; 
     CharPtr[0]=a; 
     CharPtr[1]=b; 
     CharPtr[2]=c; 

     printf("\n content of CharPtr[0] =%s",CharPtr[0]); 
     printf("\n content of CharPtr[1] =%s",CharPtr[1]); 
     printf("\n content of CharPtr[2] =%s\n",CharPtr[2]); 

     printf(" \n content of char a[4]=%s",a); 
     printf(" \n content of char b[4]=%s",b); 
     printf(" \n content of char c[4]=%s\n",c); 
} 
+0

Esto no es exactamente lo que se preguntó en la pregunta ... Creo que deberías leer la pregunta primero cuidadosamente ... – Mayank

0

char *keywords[10] es una matriz de punteros de caracteres. Por lo tanto, keywords[0], keywords[1] .. y así sucesivamente tendrán las direcciones para diferentes matrices de caracteres.

En printf puede utilizar %s y keywords[0] imprimir todo el array de caracteres cuya dirección (es decir. La dirección del primer byte de la matriz) se almacena en keywords[0].

Al pasar a una función, si se le da *keywords, se está refiriendo al valor en (dirección almacenada en keywords[0]) que es otra vez una dirección. Entonces, para obtener el valor en lugar de la dirección, puede agregar otro * ... Espero que aclare un poco ...

0

Estoy asumiendo que va a asignar su primera cadena:

"float" 

a la primera posición de índice de palabras clave [0]

char keyword[0] = "float"; 

que es la primera posición de índice de la matriz:

char keyword[10]; 

Si es el caso anterior, en cierto sentido, básicamente está creando una estructura de datos que tiene una estructura de datos. La matriz de cualquier tipo es la estructura de datos 'más pequeña' de ese tipo en C. Teniendo en cuenta que en su ejemplo está creando una matriz de caracteres, está utilizando el tipo de datos más pequeño (char = 1bit) en cada posición de índice del la estructura de datos construida más pequeña (la matriz).

Con eso dicho, si en su ejemplo, está intentando crear una matriz de matrices; su matriz de caracteres

/* Hold ten characters total */ 
char keyword[10]; 

se diseñó para contener 10 caracteres. Uno en cada posición de índice (que probablemente ya conozcas). Así que después de declarar la matriz titulado palabras clave, a continuación, intenta inicializar la primera posición de índice de la matriz con otra (la segunda) matriz de caracteres:

/* I believe this is what you had stated */ 
char keywords[0] = "float"; 

Con la segunda matriz de caracteres que tiene un índice de 5 posiciones en tamaño.

Para lograr su objetivo deseado, esencialmente creará una matriz que básicamente emula el efecto de una estructura de datos que "contiene" otras estructuras de datos.

NOTA: Si tenía/tiene planes para tratar de crear una estructura de datos que contenga una estructura de datos que contenga una estructura de datos. A.K.A. una estructura de datos triple anidada y en este caso creo que sería una Matriz, ¡QUE NO RECOMENDARÍA!

Sin embargo, la estructura matricial tendría la forma de la primera posición de índice de la palabra clave, asignando toda la matriz de palabras clave, que incluiría todos los datos almacenados en cada posición de índice de la matriz de palabras clave. Entonces no habría algo que probablemente le gustaría: keywords1, keywords2, ... keywords9,

que emular esencialmente la forma de:

char *keyword[10] = { 
         char *keywords0[10] = {"float", etc, etc, etc.}; 
         char *keywords1[10] = {"keyword1", "secondIndexOfThisArray", etc, etc, etc.}; 
         and so 

        }; 

Así que, básicamente, de derecha a izquierda, el conjunto de palabras clave, es un conjunto de punteros que apuntan a un conjunto de punteros que apuntan a matrices de caracteres.

Si eso es lo que está representando, sería mejor definir un tipo de datos personalizado de estructura/registro, y con esa estructura personalizada, querría definir un nivel subordinado o secundario de estructuras. También puede declararlos previamente y luego inicializarlos.

p. Ej.

typedef *nestedDataStructures { 

    struct keyWords[]; 
    struct keyWords1[]; 
    struct keyWords2[]; 

    ... and so on. 
}; nestedDataStructures 

En lugar de añadir diez estructuras con una estructura personalizada me descomponerse en 3 o 4 (cómo cada vez las estructuras y el uso de muchos) y crear un módulo con el fin de producir capas simétricas de la abstracción como manipular el conjunto de datos .

Sin embargo, no puede crear la matriz de caracteres y asignar potencialmente la otra matriz de caracteres de la manera que lo hizo (o quién sabe que tal vez pueda), pero de la forma en que desearía emular la matriz que contiene las matrices , es crear una matriz de punteros de caracteres en el frente, de posiciones de índice de números X y luego inicializar y luego usar las matrices de caracteres en forma de cadenas declaradas con en la inicialización de la declaración original.

Así que, básicamente, puede declarar toda su matriz por adelantado, luego con el diseño de su programa, ya sea eliminar la referencia de cada posición de índice, usar la asignación o imprimir/escribir la posición del índice.

Como por ejemplo siempre se puede hacer algo como esto:

/* Example of the program and declaration with out a function */ 
#include <stdio.h> 

int main(){ 

    /* 
    * A character pointer array that contains multiple 
    * character arrays. 
    */ 

    char *grewMe[2] = {"I want to ", "grow to be bigger"}; 

    int w = 0; 

    for(; w < 2;) { 
     printf("%s", grewMe[w]); 
     ++w; 
    } 

    printf(" :-)\n"); 
    w = 0; 
    return 0; 
} 
// Output: 
// I want to grow to be bigger :-) 

O algo así:

/* Example of program: function passed arguments 
* of a pointer to the array of pointers 
*/ 
#include <stdio.h> 

void mygrowth(char *growMe[]); 

int main(){ 

    char *growMe[2] = {"I want to ", "grow to be bigger"}; 

    mygrowth(growMe); 
    printf(" :-)\n"); 

    return 0; 

} 
void mygrowth(char *growMe[]) 
{ 

    int w = 0; 
    for (; w < 2;) { 
     printf("%s", growMe[w]); 
     ++w; 
    } 
} 

La cesión de cada posición del índice como se le pasa como argumento:

/* 
* This program compiles, runs and outputs properly 
* Example of a program with a function of 
* arguments pnt2pnter 
*/ 

#include <stdio.h> 
#include <stdlib.h> 

void thoughtAsAFunction(char **iThink); 

int main() 
{ 

    char *iThink[10] = {"I am trying to grow, but it's a hard task to ", 
         "accomplish. My father is short ", 
         "my mother is even shorter than him, ", 
         "what is the probability of me getting taller? ", 
         "Well both my grandfather's were Six ", 
         "Foot Five, and both my grandmother's ", 
         "were over 5 foot 8 inches tall! If my ", 
         "grandparent's genes point to my parents, and my ", 
         "parent's genes point to mine I might have a chance ", 
         "of being 6 foot. Do you know what I mean? "}; 

    thoughtAsAFunction(iThink); 

    printf(":-)\n"); 

    return 0; 
} 
void thoughtAsAFunction(char **iThink) { 

    int andy = 0; 
    for (; andy < 10;) { 
     char * pntThroughPnt = iThink[andy]; 
     printf("%s", pntThroughPnt); 
     ++andy; 
    } 
    andy = 0; 
} 

O pase por referencia, con un incremento de la variable de recuento de bucles:

/* 
* This program compiles, runs, and outputs all of the character 
* arrays. 
* 
*/ 
#include <stdio.h> 
#include <stdlib.h> 

void thoughtAsAFunction(char **iThink); 

int main() 
{ 

    char *iThink[10] = {"I am trying to grow, but it's a hard task to ", 
         "accomplish. My father is short ", 
         "my mother is even shorter than him, ", 
         "what is the probability of me getting taller? ", 
         "Well both my grandfather's were Six ", 
         "Foot Five, and both my grandmother's ", 
         "were over 5 foot 8 inches tall! If my ", 
         "grandparent's genes point to my parents, and my ", 
         "parent's genes point to mine, then I might have a chance ", 
         "of being 6 foot. Do you know what I mean? "}; 

    int andy = 0; 
    for (; andy < 10;) { 
     // pass by reference and increment. 
     thoughtAsAFunction(&iThink[andy]); 
     ++andy; 

    } 

    printf(":-)\n"); 
    andy = 0; 

    return 0; 
} 
void thoughtAsAFunction(char **iThink) { 

    char * pntThroughPnt = *iThink; 
    printf("%s", pntThroughPnt); 

} 

Tenga en cuenta que este es el caso si se declara la matriz de punteros (char * array [10];), y cada puntero apunta a un array de caracteres.

Cuestiones relacionadas