Pregunta

Hola estoy trabajando con C y tengo una pregunta sobre la asignación de punteros.

struct foo
{
   int _bar;
   char * _car[SOME_NUMBER]; // this is meant to be an array of char * so that it can hold pointers to names of cars
}

int foofunc (void * arg)
{
   int bar;
   char * car[SOME_NUMBER];

   struct foo * thing = (struct foo *) arg;

   bar = thing->_bar; // this works fine
   car = thing->_car; // this gives compiler errors of incompatible types in assignment
}

coche y tienen _car misma declaración así que ¿por qué recibo un error sobre tipos incompatibles? Mi conjetura es que tiene algo que ver con ellos siendo punteros (porque son punteros a arrays de char *, ¿verdad?) Pero yo no veo por qué esto es un problema.

cuando me declaré char * car; en lugar de char * car[MAXINT]; que compila bien. pero yo no veo cómo eso sería útil para mí más tarde cuando necesito para acceder a cierta información mediante el índice, sería muy molesto para el acceso esa información más tarde. de hecho, ni siquiera estoy seguro de si voy por el camino correcto, tal vez hay una mejor manera de almacenar un montón de cadenas en lugar de utilizar arreglo de char *?

EDIT:. No fue mi intención de utilizar INT_MAX (valor máximo de int), es sólo otro int, que es aproximadamente 20

¿Fue útil?

Solución

Usted está creando una nueva matriz de tamaño MAXINT. Creo que desea crear un puntero a una matriz de tamaño MAXINT.

Creación de un puntero a una matriz de char * 's:

La siguiente es una matriz de tamaño MAXINT a char * elementos:

char * car[MAXINT]; 

El siguiente es un puntero a: una matriz de tamaño MAXINT a char * elementos:

char* (*car)[MAXINT];

La siguiente es la forma de configurar un puntero a: una matriz de tamaño MAXINT a char * elementos:

char* (*car)[MAXINT];
car = &arg->_car;

Otros errores de sintaxis en la pregunta:

  • Es necesario tener un punto y coma después de su definición struct.
  • Debe utilizar foo* no foo. Por lo que debe ser:
    struct foo* thing = (struct foo *) arg;
  • Debe utilizar thing no arg:
    bar = thing->_bar;
    car = thing->_car;

Otros consejos

car y _car son ambas matrices, y que pueda matrices no asigna en C (excepto cuando la matriz está incrustado en una estructura (o unión) y hacer una asignación de la estructura).

También son matrices de punteros a char, en lugar de punteros a las matrices de carbón. Lo que ha escrito en el código es probablemente lo que quiere - se puede almacenar punteros a hasta nombres MAXINT en la matriz. Sin embargo, se debe describir el tipo correcto -. Como una matriz de punteros a char o CHAR punteros

Un puntero a una matriz de caracteres se vería así:

char (*car)[MAXINT];

y un punto a un conjunto de punteros a carácter (gracias, Brian) se vería así:

char *(*car)[MAXINT];

Tenga cuidado de MAXINT; que podría ser un arsenal muy grande (en Linux, define <values.h> MAXINT como INT_MAX, que es al menos 2 31 -1).


El código es como:

struct foo
{
   int _bar;
   char * _car[MAXINT];
}

int foofunc (void * arg)
{
   int bar;
   char * car[MAXINT];
   struct foo thing = (struct foo *) arg;
   bar = arg->_bar; // this works fine
   car = arg->_car; // this gives compiler errors of incompatible types in assignment
}

Ni la asignación a un bar, ni coche debe compilar en absoluto - arg es un void *. Presumiblemente referimos a utilizar thing en una forma u otra. Como se ha señalado Brian, hay problemas allí, también:

, o bien quieren:

int foofunc(void *arg)
{
    int bar;
    char *car[MAXINT];
    struct foo thing = *(struct foo *)arg;
    bar = thing._bar; // this works fine
    car = thing._car; // this is still an array assignment
    ...other code using bar and car...
}

O desea:

int foofunc(void *arg)
{
    int bar;
    char *car[MAXINT];
    struct foo *thing = (struct foo *) arg;
    bar = thing->_bar; // this works fine
    car = thing->_car; // this is still an array assignment
    ...other code using bar and car...
}

O, en efecto:

int foofunc(void *arg)
{
    struct foo *thing = (struct foo *) arg;
    int bar           = thing->_bar; // this works fine
    char *car[MAXINT] = thing->_car; // this is still an array assignment
    ...other code using bar and car...
}

Por último, se trata de la asignación de matrices, en C se puede utilizar razonablemente memmove() para hacer esto:

int foofunc(void *arg)
{
    struct foo *thing = (struct foo *) arg;
    int bar           = thing->_bar; // this works fine
    char *car[MAXINT];
    memmove(car, thing->_car, sizeof(car));
    ...other code using bar and car...
}

La función similar memcpy() no tiene la semántica fiables si las áreas a ser copiados solapamiento, mientras que memmove() hace; es más sencillo de utilizar siempre memmove() porque siempre funciona correctamente. En C ++, es necesario tener cuidado al usar memmove() (o memcpy()). En este código, que sería lo suficientemente seguro, pero la comprensión de por qué no es trivial.

Usted tiene que ser consciente de que está copiando simplemente punteros aquí - no está copiando las cadenas que los punteros apuntan a. Si hay algo más cambia las cuerdas, que afecta tanto a los valores observados a través de car y la variable en el código de llamada.

Un último punto - por ahora: ¿está seguro de lo que necesita el argumento de la función como void *? Se abre el código para todo tipo de abuso que pueden prevenirse si la función se declara a tomar un 'struct foo *' en lugar (o incluso un 'const struct foo *').

No se puede asignar a una matriz de la forma en que está haciendo. Usted puede hacer una copia elemento a elemento.

for(int i = 0; i < MAXINT; i++)
{
  car[i] = (arg->_car)[i]
}

Tenga en cuenta que si si las cadenas no son constantes, es posible que necesite usar strcpy.

notación de matriz en C es legítimamente confundir; su código no significa lo que usted piensa que significa.

medios arg->_car "La dirección de la _car array". Del mismo modo, los medios car "la dirección de la car array". Si usted está tratando de copiar el contenido de _car al coche, entonces esto va a hacerlo:

memcpy(car, _car, MAXINT);

Sin embargo, su verdadera pregunta, creo, es "¿cuál es la mejor manera de almacenar una lista de cadenas?" Esta respuesta es:. Una lista dinámica (que crece automáticamente a medida que se agregan elementos)

Se había declarar así:

#define CARSIZE 65
int numCars = 0;
char **car; /* a list of addresses, each one will point to a string */

Para añadir un coche:

char *newCar = malloc(CARSIZE); /* make room */
strncpy(newCar, "Mercedes", CARSIZE); /* newCar has the address of the string */
car[numCars++] = newCar; /* store it */

Para una lista de los coches:

int n;
for (n = 0; n < numCars; ++n)
    printf("%s\n", car[n]);

Para eliminar el coche en la posición n:

free(car[n]); /* release the memory */
/* condense the list of pointers */
for ( ; n < numCars - 1; ++n)
    car[n] = car[n+1];

Esto es completamente rutina en C. Nota: Lo anterior es la parte superior de la cabeza y no copiado de un programa de trabajo, así que no puedo prometer todo el * están en el lugar correcto . Sospecho que esto es una tarea, por lo que no quiero dar todo ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top