Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Vektor von Zeigern inkrementieren



musketaquid
03-04-2006, 22:15
#include <stdio.h>

int main()
{
char message[] = "Das\0 ist\0 ein\0 Test\0";
char *p[4];
int i;

p[0] = &message[0];

p[1] = &message[5];

p[2] = &message[10];

p[3] = &message[15];

printf("%s\n", *p);
printf("%s\n", p[1]);
printf("%s\n", p[2]);
printf("%s\n", p[3]);

/* jetzt in einer Schleife */
printf("\n");

for (i=0; i<4; i++)
printf("%s\n", p[0]++);

return 0;
}


Das Testprogramm aufgerufen, ergibt folgendes:

Das
ist
ein
Test

Das
as
s

Wie muss ich p in der fett gedruckten Zeile inkrementieren, damit die Schleife das gleiche produziert wie der erste Teil des Programms?

Caveman
03-04-2006, 22:59
gar nicht
in die Klammer kommt i:

printf("%s\n", p[i]);

musketaquid
04-04-2006, 14:30
Danke, aber dass das so geht, weis ich auch. Es geht mir einfach darum, wie man einen Vektor von Zeigern inkrementiert.
Anders ausgedrückt,
bei K&R Seite 106 steht

Da linptr ein Vektorname ist, kann er selbst auch als Zeiger behandelt werden...

#define MAXLINES 5000 /* maximale Anzahl Zeilen */
char *lineptr[MAXLINES]; /* Zeiger auf die Textzeilen */

/* writelines: Zeilen ausgeben */
void writelines(char *lineptr[], int nlines)
{
while (nlines-- > 0)
printf("%s\n", *lineptr++);
}

Wenn ich bei meinem Progrämmchen *p++ in printf schreibe, gibt der Compiler folgende Fehlermeldung:

test.c: In Funktion »main«:
test.c:26: error: wrong type argument to increment

Warum funktioniert das bei K&R und bei mir nicht?

Boron
04-04-2006, 15:15
/* Das hier in deiner main-Funktion vom ersten Beitrag */
for (i=0; i<4; i++)
{
printf("%s\n", p[0]);
p = p + (5 * sizeof(p));
}Ungetestet!
Außerdem ist das allerübelster Programmierstil. Aber zum rumprobieren mit Zeigern und Felder ganz witzig.

Die neue Zeile p = p + (5 * sizeof(p)); lässt den Zeiger p auf eine andere Adresse zeigen. Nämlich um 5 chars weiter "hinten".

musketaquid
04-04-2006, 17:23
Die neue Zeile p = p + (5 * sizeof(p)); lässt den Zeiger p auf eine andere Adresse zeigen. Nämlich um 5 chars weiter "hinten".

Das nützt nichts. Denn im richtigen programm, steht ein bisschen mehr als nur "Das\0 ist\0 ein\0 Test\0" in dem Vektor und die Zeiger sind Querbeet verstreut. Etwa so:

char message[] = "Das\0 ist\0 ein\0 Test\0 schon\0 wieder\0";
char *p[4];

p[0] = &message[0];
p[1] = &message[5];
p[2] = &message[22];
p[3] = &message[30];
p[4] = &message[10];
p[5] = &message[15];


War vielleicht blöd, dass die ersten Wörter alle gleich lang sind.

Boron
04-04-2006, 19:04
Ja, dann war das ein blödes Beispiel :rolleyes:.

Wenn die Worte wild verstreut sind (und dann auch noch mit '\0' abgeschlossen sind :eek:) dann kannst du das mit den "Zeiger-verschieben" vergessen. Das lässt sich nicht mit sinnvollem Aufwand automatisieren. zumindest fällt mir da auf die Schnelle nix ein.

Obwohl....
Wenn du sequentiell alle '\0' suchen lässt, dann weißt du wieviele Worte du hast.
Abgesehen vom letzen \0 beginnt genau zwei Zeichen nach einem \0 ein neues Wort.

Du kannst ein Array mit Zeigern auf char* erstellen mit der Anzahl der Worte:
char* worte[anzWorte];

Jedem Eintrag in worte (also worte[0], worte[1] usw.) musst du nur noch die Adresse des ersten Buchstabens des gewünschten Wortes zuweisen:
worte[0] = &message[0];
worte[1] = &message[5];
usw.
(Das jetzt hier natürlich nicht so hart codiert, sondern in einer Schleife die das dynamisch macht.)

Mit einem zweiten Array char** sortierung[anzWorte] kannst du in der gewünschten Sortierung auf die Einträge im ersten Array verweisen.

Kannst du damit was anfangen?

musketaquid
04-04-2006, 22:34
Danke für die Mühe, aber ich versuche einfach zu verstehen, wie das mit dem Inkrementieren von Zeigervektoren geht. Alles andere ist Nebensache.
Beidesmal dieselbe printf, aber einmal in main (hier beschwert sich der Compiler) und das anderemal in einer eigenen Funktion (plötzlich kann er doch inkrementieren), das versteh ich nicht!
In main:
#include <stdio.h>

int main()
{
char message[] = "Das\0 ist\0 ein\0 Test\0";
char *p[4];
int i, z;

z = 0;

for (i=0; i<16; i++)
if (i%5 == 0)
p[z++] = &message[i];

z = 4;
while (z-- > 0)
printf("%s\n", *p++);

return 0;
}Compilerausgabe:
test1.c: In Funktion »main«:
test1.c:17: error: wrong type argument to increment

In eigener Funktion:
#include <stdio.h>

void write(char *ptr[]);

int main()
{
char message[] = "Das\0 ist\0 ein\0 Test\0";
char *p[4];
int i, z;

z = 0;

for (i=0; i<16; i++)
if (i%5 == 0)
p[z++] = &message[i];

write(p);

return 0;
}

void write(char *p[])
{
int k;

k = 4;
while (k-- > 0)
printf("%s\n", *p++);
}Ausgabe:
Das
ist
ein
Test

peschmae
05-04-2006, 07:57
#include <stdio.h>

int main()
{
char message[] = "Das\0 ist\0 ein\0 Test\0";
char *p[4];
char **cp = p;
int i, z;

z = 0;

for (i=0; i<16; i++)
if (i%5 == 0)
p[z++] = &message[i];

z = 4;
while (z-- > 0)
printf("%s\n", *cp++);

return 0;
}


Der Punkt ist folgender: p ist kein Pointer im eigentlichen Sinne. Wenn du den irgendwo verwendest entspricht der zwar der Adresse des Arrayanfangs, aber verändern kannst du p nicht.
Manche bezeichnen das dann als "const pointer".

Das was du in der Funktion übergeben kriegst und innerhalb der Funktion siehst ist hingegen nicht p selber, sondern ein Pointer, der auf dem Stack liegt. Den kannst du natürlich beliebig verändern.

MfG Peschmä

musketaquid
05-04-2006, 15:18
Jetzt hats klick gemacht :) Danke!