2012-03-09 14 views
43

Estoy haciendo una tarea en la que tenemos que leer una serie de cadenas de un archivo en una matriz. Tengo que llamar a un algoritmo de cifrado en la matriz (el cifrado transpone matrices 2D). Entonces, al principio puse toda la información del archivo en una matriz 2D, pero tuve muchos problemas con tipos conflictivos en el resto de mi código (específicamente tratando de establecer char [] a char *). Entonces, decidí cambiar a una serie de punteros, lo que hizo que todo fuera mucho más fácil en la mayoría de mi código.¿Es posible convertir char [] a char * en C?

Pero ahora necesito convertir char * a char [] y viceversa, pero no puedo resolverlo. No he podido encontrar nada en google. Estoy comenzando a preguntarme si es posible.

+1

Lea la sección 6 de las [preguntas frecuentes comp.lang.c] (http://c-faq.com/). –

Respuesta

87

Parece que está confundido entre punteros y matrices. Punteros y arrays (en este caso char * y char []) son not the same thing.

  • Una matriz char a[SIZE] dice que el valor en la posición de a es una matriz de longitud SIZE
  • Un puntero char *a; dice que el valor en la ubicación de a es un puntero a char. Esto se puede combinar con la aritmética de punteros a comportarse como una matriz (por ejemplo, a[10] es 10 entradas anteriores donde a puntos)

En la memoria, parece que este (ejemplo tomado de the FAQ):

char a[] = "hello"; // array 

    +---+---+---+---+---+---+ 
a: | h | e | l | l | o |\0 | 
    +---+---+---+---+---+---+ 

char *p = "world"; // pointer 

    +-----+  +---+---+---+---+---+---+ 
p: | *======> | w | o | r | l | d |\0 | 
    +-----+  +---+---+---+---+---+---+ 

Es fácil confundirse acerca de la diferencia entre punteros y matrices, porque en muchos casos, una referencia de matriz "se descompone" en un puntero a su primer elemento. Esto significa que en muchos casos (como cuando se pasa a una llamada a función) las matrices se convierten en punteros. Si desea saber más, this section of the C FAQ describes the differences in detail.

Una diferencia práctica importante es que el compilador sabe cuánto tiempo es una matriz. Siguiendo los ejemplos anteriores:

char a[] = "hello"; 
char *p = "world"; 

sizeof(a); // 6 - one byte for each character in the string, 
      // one for the '\0' terminator 
sizeof(p); // whatever the size of the pointer is 
      // probably 4 or 8 on most machines (depending on whether it's a 
      // 32 or 64 bit machine) 

Sin ver su código, es difícil recomendar el mejor curso de acción, pero sospecho cambiando utilizar punteros de todo el mundo va a resolver los problemas que estás teniendo.Tome nota de que ahora:

  • Deberá inicializar la memoria donde quiera que estén las matrices. Por ejemplo, char a[10]; se convertirá en char *a = malloc(10 * sizeof(char));, seguido por un cheque que a != NULL. Tenga en cuenta que en realidad no necesita decir sizeof(char) en este caso, porque sizeof(char) se define como 1. Lo dejé para completarlo.

  • En cualquier lugar que previamente había sizeof(a) para la longitud de la matriz tendrá que ser reemplazado por la longitud de la memoria que asigna (si está usando cuerdas, se puede usar strlen(), que cuenta hasta el '\0').

  • Necesitará hacer una llamada correspondiente al free() para cada llamada al malloc(). Esto le dice a la computadora que ha terminado de usar la memoria que solicitó con malloc(). Si su puntero es a, solo escriba free(a); en un punto del código donde sepa que ya no necesita los puntos a.

Como otra respuesta ha señalado, si desea obtener la dirección del inicio de una matriz, puede utilizar:

char* p = &a[0] 

usted puede leer esto como "puntero char p convierte en la dirección del elemento [0] de a ".

+7

+1 Gran respuesta –

+0

En el último ejemplo, no se puede 'char * p = & a [0]' simplificarse a 'char * p = y a'? –

+1

@thom_nic: No, porque '& a' tiene el tipo' char (*) [6] ', es decir, un puntero a una matriz de seis caracteres. Esto no es lo mismo que 'char *', entonces recibirás una advertencia. Sin embargo, puede decir 'char * p = a;', porque una referencia de matriz puede [decaer en un puntero a su primer elemento] (http://c-faq.com/aryptr/aryptrequiv.html). Usé la forma más larga aquí, porque ilustra mejor lo que está sucediendo. –

9

Si tiene char[] c entonces usted puede hacer char* d = &c[0] y acceso elemento de c [1] haciendo *(d+1), etc.

+0

¡oh, gracias! Voy a intentar eso. – tparf

+0

O simplemente puede 'char * d = c;'. – mah

-4

Bueno, no estoy seguro de entender su pregunta ...

En C, Char [] y Char * son la misma cosa.

Editar: gracias por este interesante enlace.

+2

Me temo que eso no es cierto - [los punteros y las matrices no son lo mismo en C] (http://www.lysator.liu.se/c/c-faq/c-2.html) –

+0

Pensé que sí también, pero el compilador me está dando un error :( – tparf

+0

@TimothyJones: un mejor enlace para las preguntas frecuentes es http://c-faq.com/. Y, por supuesto, es 100% correcto: las matrices y los punteros son * no * lo mismo. (Y se deletrea 'char', no' Char'; es importante) –

2

No necesita declararlos como matrices si desea utilizarlos como punteros. Puede simplemente referenciar punteros como si fueran matrices multidimensionales. Basta con crear como un puntero a un puntero y usar malloc:

int i; 
int M=30, N=25; 
int ** buf; 
buf = (int**) malloc(M * sizeof(int*)); 
for(i=0;i<M;i++) 
    buf[i] = (int*) malloc(N * sizeof(int)); 

y luego se puede hacer referencia a buf[3][5] o lo que sea.

+3

No arroje el resultado de 'malloc()'. –

+0

Es necesario porque 'malloc()' devuelve un 'void *', que debe ser convertido a 'int *' para ser almacenado en 'buf'. – Arcinde

+4

No, el yeso no es necesario. En C, una expresión de tipo 'void *' se puede convertir implícitamente a cualquier tipo de puntero a objeto (o puntero a incompleto). Consulte la pregunta 7.7b de las [preguntas frecuentes comp.lang.c] (http://c-faq.com/) y la sección 6.5.16.1 del [estándar C] (http://www.open-std.org/ jtc1/sc22/wg14/www/docs/n1570.pdf). (C++ tiene reglas diferentes, que serían relevantes si estuviéramos discutiendo sobre C++). –