Ver Mensaje Individual
  #2 (permalink)  
Antiguo 24/06/2014, 03:20
Fw190
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 14 años, 5 meses
Puntos: 73
Respuesta: Teoria de Punteros C

En C, el nombre de un array es, en realidad, un puntero al primer elemento del array. Así, cuando declaras

char cad1[4];

cad1 es un puntero al primero de los cuatro elementos del array; por eso, cuando haces

cad1 = "Hola";

en realidad estás intentando asignar una cadena de caracteres a un puntero, que no es más que un tipo de variable que contiene una dirección de memoria.

En cambio, cuando haces

char *cad1 = "Hola";

lo que has heho es crear un puntero a char al que le has asignado la dirección de comienzo de la constante "Hola", que estará almacenada en alguna parte del mapa de memoria que se asigne al programa.

Dado que un puntero no es más que una variable que guarda una dirección de memoria, esta dirección puede corresponder perfectamente a la de otra variable que sea un puntero. Por tanto, cuando declaras

char **vector;

estás declarando un punero a puntero a char.

Una de las fortalezas/debilidades de C es que te permite utilizar los punteros como arrays; fortaleza porque te permite reservar la memoria que necesites según se necesite durante la ejecución del programa y acceder fácilmente a ella, y debilidad porque puede ser muy confuso si no tienes muy claro cómo funciona el asunto. Así, por ejemplo, puedes declarar

float *x;

más adelante, necesitas reservar memoria, por ejemplo, para 50 elementos:

x = (float *)malloc(50*sizeof(float));

y luego acceder a cada elemento, como si se tratase de un array:

z = x[7] / x[32];

Hay que tener cuidado porque C no establece control alguno sobre los límites de los arrays (o memoria reservada mediante punteros). Así, no te indicará error si intentas trabajar sobre el elemento x[60], pero puedes provocar un desastre al trabajar fuera de la memoria reservada para x (bien de manera fija, declarando float x[50], o bien de manera dinámica, mediante malloc() o alguna otra de las funciones de su familia). Además, puede que el problema no llegue a manifestarse en programas pequeños, o que provoque errores distintos en cada ejecución del programa.

Las inicializaciones en el momento de la declaración son complicadas. Te modifico ligeramente el ejemplo que posteaste (ejercicio de agudeza visual, busca las diferencias):

Código C:
Ver original
  1. void mostrarChar(char **matriz)
  2. {
  3.     int f;
  4.     for (f=0;f<7;f++)
  5.     {
  6.         printf("%s\n",matriz[f]);
  7.     }
  8. }
  9.  
  10. int main(int argc, char** argv)
  11. {
  12.     char *matriz[]={"Lunes","Martes","Miercoles","Jueves","Viernes","Sabado","Domingo"};
  13.     mostrarChar(matriz);
  14.     return (EXIT_SUCCESS);
  15. }

Si vas a trabajar con dobles punteros (o superior, que haberlos haylos) es mejor evitar la inicialización en el momento de la declaración y asignes los valores iniciales ya por programa. Al menos, hasta que le hayas cogido el punto.

Otra cosa que debes tener en cuuenta es que, en C, las cadenas de caracteres siempre terminan con el carácter ASCII 0 (NULL), y que éste también ocupa espacio. Así, por ejemplo, la cadena "Hola" necesita 5 caracteres, y no 4.

Bueno, espero haberte aclarado algo en lugar de liarte aún más. Saludos,