Frage

Hallo, ich arbeite mit C # und ich habe eine Frage über die Zuweisung von Zeigern.

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-und _car haben dieselbe Erklärung also, warum bekomme ich eine Fehlermeldung inkompatible Typen?Meine Vermutung ist, dass es hat etwas zu tun mit Ihnen-Zeiger (weil Sie Zeiger auf arrays von char *, oder?) aber ich sehe nicht, warum das ein problem.

als ich erklärte char * car; statt char * car[MAXINT]; es kompiliert fein.aber ich sehe nicht, wie, nützlich sein würde, um mich später, wenn ich brauche, um Zugang zu bestimmten info mit index, wäre es sehr ärgerlich für den Zugriff auf diese Informationen später.in der Tat, ich bin mir auch nicht sicher, ob ich dabei bin, über den richtigen Weg, vielleicht gibt es einen besseren Weg, um Geschäft eine Reihe von Zeichenfolgen anstelle von array von char *?

EDIT:Ich habe nicht bedeuten, Sie zu verwenden, INT_MAX (maximaler Wert von int), es ist nur eine andere int, der etwa 20.

War es hilfreich?

Lösung

Sie sind ein neues Array der Größe MAXINT zu schaffen. Ich glaube, Sie wollen einen Zeiger auf ein Array der Größe MAXINT erstellen.

Erstellen einen Zeiger auf ein Array von char * 's:

Im Folgenden ist ein Array der Größe MAXINT zu char * Elemente:

char * car[MAXINT]; 

Im Folgenden ist ein Zeiger auf: eine Anordnung von Größe MAXINT zu char * Elemente:

char* (*car)[MAXINT];

Folgendes ist, wie Sie setzen einen Zeiger auf: eine Reihe von Größe MAXINT zu char * Elemente:

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

Andere Syntaxfehler in der Frage:

  • Sie benötigen ein Semikolon nach dem struct Definition haben.
  • Sie sollten mit foo* werden nicht foo. So soll es sein:
    struct foo* thing = (struct foo *) arg;
  • Sie sollten thing nicht arg werden:
    bar = thing->_bar;
    car = thing->_car;

Andere Tipps

car und _car sind beide arrays, und Sie können zuweisen von arrays in C (außer, wenn das array ist eingebettet in eine Struktur (oder der union), und Sie tun eine Struktur, Zuordnung).

Sie sind auch arrays von Zeigern auf char, sondern als Zeiger auf arrays von char.Was Sie geschrieben haben, in der code ist wahrscheinlich das, was Sie wollen - Sie können speichern Zeiger auf bis zu MAXINT Namen in das array.Allerdings sollten Sie beschreiben die Art richtig - wie ein array von Zeigern auf char oder char-Zeigern.

Ein Zeiger auf ein array von Zeichen Aussehen würde:

char (*car)[MAXINT];

Und einen Punkt, um ein array von Zeichen Zeiger (danke, Brian) würde wie folgt Aussehen:

char *(*car)[MAXINT];

Vorsichtig sein, MAXINT;das könnte eine sehr große array (on Linux, <values.h> definiert MAXINT als INT_MAX, die mindestens 231-1).


Der code sieht folgendermaßen aus:

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
}

Weder die Zuordnung zu bar, noch ein Auto, sollten kompilieren überhaupt - arg ist ein void *.Sie vermutlich gemeint zu verwenden thing in irgendeiner form.Brian erwähnt, gibt es Probleme gibt, zu:

Entweder du willst:

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

Oder Sie wollen:

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

Oder, in der Tat:

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

Schließlich ist der Umgang mit der array-Zuweisung in C können Sie vernünftig nutzen memmove() um dies zu tun:

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

Die ähnliche Funktion memcpy() nicht über zuverlässige Semantik, wenn die Flächen kopiert werden sich überlappen, in der Erwägung, dass memmove() hat;es ist einfacher, sich immer verwenden, memmove() weil es immer funktioniert richtig.In C++, Sie müssen vorsichtig sein, über die Verwendung memmove() (oder memcpy()).In diesem code, es wäre sicher genug, aber das Verständnis, warum ist nicht trivial.

Sie müssen sich bewusst sein, dass Sie einfach zu kopieren Zeiger hier - Sie sind nicht das kopieren von Zeichenfolgen, die die Zeiger zeigen können.Wenn etwas ändert die Saiten, es wirkt sich sowohl auf die Werte gesehen, die über car und die variable in der aufrufenden code.

Ein letzter Punkt für heute:sind Sie sicher, Sie müssen das argument der Funktion als void *?Es öffnet sich der code, um alle Arten von Missbrauch, die verhindert werden können, wenn die Funktion deklariert wird, um eine"struct foo *'statt (oder sogar ein 'const struct foo *').

Sie können nicht auf ein Array zuweisen, wie Sie tun. Sie können ein Element weise Kopie tun.

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

Beachten Sie, dass, wenn, wenn die Strings nicht konstant sind, die Sie verwenden strcpy benötigen.

Array-Notation in C ist berechtigterweise verwirrend; Ihr Code bedeutet nicht, was Sie denken, es bedeutet.

arg->_car bedeutet „die Adresse des Arrays _car“. In ähnlicher Weise car bedeutet „die Adresse des Arrays car“. Wenn Sie versuchen, den Inhalt von _car zu dem Auto zu kopieren, dann dies wird es tun:

memcpy(car, _car, MAXINT);

Aber Ihre eigentliche Frage, glaube ich, ist: „Was ist der beste Weg, um eine Liste von Zeichenketten speichern?“ Diese Antwort ist: a. Dynamische Liste (eine, die automatisch wächst, wie Sie Elemente hinzufügen)

Sie würden es so erklären:

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

ein Auto hinzuzufügen:

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

Um die Autos Liste:

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

Um das Auto an Position entfernen n:

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

Das ist völlig Routine in C Hinweis: Das oben aus der Spitze von meinem Kopf und nicht von einem Arbeitsprogramm kopiert, so dass ich nicht versprechen kann, alle * an der richtigen Stelle ist . Ich vermute, das eine Hausaufgabe ist, so dass ich Ihnen nicht geben will alles ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top