Domanda

Ciao Sto lavorando con C e ho una domanda circa l'assegnazione di puntatori.

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
}

auto e _car hanno stessa dichiarazione così perché sto ottenendo un errore sui tipi incompatibili? La mia ipotesi è che ha qualcosa a che fare con loro che sono i puntatori (perché sono puntatori ad array di char *, giusto?), Ma non vedo il motivo per cui questo è un problema.

quando ho dichiarato char * car; invece di char * car[MAXINT]; compila bene. ma io non vedo come sarebbe utile per me più tardi, quando ho bisogno di accedere a determinate informazioni utilizzando l'indice, sarebbe molto fastidioso per l'accesso che informazioni più tardi. in realtà, io non sono nemmeno sicuro se sto andando per il verso giusto, forse c'è un modo migliore per archiviare un gruppo di stringhe invece di utilizzare array di char *?

EDIT:. Non intendevo usare INT_MAX (valore massimo di int), è solo un altro int, che è di circa 20

È stato utile?

Soluzione

Si sta creando una nuova gamma di dimensioni MAXINT. Penso che si desidera creare un puntatore a un array di dimensione MAXINT.

Creazione di un puntatore a un array di char * 's:

Il seguente è un array di dimensione MAXINT a char * elementi:

char * car[MAXINT]; 

Il seguente è un puntatore a: un array di dimensione MAXINT a char * elementi:

char* (*car)[MAXINT];

Il seguente è come si imposta un puntatore a: un array di dimensione MAXINT a char * elementi:

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

Altri errori di sintassi nella questione:

  • È necessario disporre di un punto e virgola dopo la sua definizione struct.
  • Si deve usare foo* non foo. Così dovrebbe essere:
    struct foo* thing = (struct foo *) arg;
  • Si deve usare thing non arg:
    bar = thing->_bar;
    car = thing->_car;

Altri suggerimenti

car e _car sono entrambi gli array, ed è possibile matrici non si assegna a C (eccetto quando l'array è incorporato in una struttura (o unione) e si fa un incarico di struttura).

Sono anche array di puntatori a char, piuttosto che puntatori ad array di char. Quello che hai scritto nel codice è probabilmente quello che volete - è possibile memorizzare i puntatori a un massimo di nomi maxint nella matrice. Tuttavia, si dovrebbe descrivere il tipo correttamente -. Come un array di puntatori a char o char puntatori

Un puntatore a un array di caratteri sarà simile:

char (*car)[MAXINT];

e un punto ad un array di puntatori di caratteri (grazie, Brian) sarà simile:

char *(*car)[MAXINT];

Fare attenzione di MAXINT; che potrebbe essere un allineamento molto grande (su Linux, definisce <values.h> MAXINT come INT_MAX, che è almeno 2 31 -1).


Il look codice come:

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
}

Né l'incarico di bar né auto dovrebbe compilare a tutti - arg è un void *. È presumibilmente significava utilizzare thing in una forma o nell'altra. Come ha osservato Brian, ci sono problemi anche lì:

O si vuole:

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 se si vuole:

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...
}

In alternativa, anzi:

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...
}

Infine, trattare con l'assegnazione array, in C si può ragionevolmente usare memmove() per fare questo:

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 funzione simile memcpy() non ha semantica affidabili se le aree da copiare sovrapposizione, che fa memmove(); è più semplice utilizzare sempre memmove() perché funziona sempre correttamente. In C ++, è necessario essere cauti sull'utilizzo memmove() (o memcpy()). In questo codice, sarebbe abbastanza sicuro, ma capire il motivo per cui non è banale.

Si ha bisogno di essere consapevoli del fatto che si sta solo copiando puntatori qui - non sta copiando le stringhe che i puntatori puntano a. Se qualcosa cambia altro quelle corde, colpisce sia i valori visti tramite car e la variabile nel codice chiamante.

Un ultimo punto - per ora: sei sicuro è necessario l'argomento alla funzione come un void *? Si apre il codice per tutti i tipi di abuso che può essere evitata se la funzione è dichiarata a prendere un 'struct foo *' al posto (o anche un 'const struct foo *').

Non è possibile assegnare ad un allineamento il modo in cui si sta facendo. Si può fare una copia elemento-saggio.

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

Si noti che se se le stringhe non sono costanti, potrebbe essere necessario l'uso strcpy.

Array notazione in C è legittimamente confusione; il codice non vuol dire ciò che si pensa che significa.

mezzi arg->_car "L'indirizzo del _car matrice". Analogamente, mezzi car "l'indirizzo della car matrice". Se stai cercando di copiare il contenuto di _car a macchina, allora questo lo farà:

memcpy(car, _car, MAXINT);

Ma la vostra vera domanda, a mio avviso, è "qual è il modo migliore per conservare una lista di stringhe?" Questa risposta è:. Un elenco dinamico (uno che cresce automaticamente quando si aggiungono elementi)

Si sarebbe dichiararla in questo modo:

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

Per aggiungere una macchina:

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

Per elencare le auto:

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

Per rimuovere la macchina alla posizione n:

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

Questo è completamente di routine in C. Nota: Quanto sopra è la parte superiore della mia testa e non copiato da un programma di lavoro, quindi non posso promettere tutto il * sono al posto giusto . Ho il sospetto che questo è un compito a casa, quindi non voglio darvi tutto ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top