PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Array durchlaufen C



peecee
28-07-2003, 19:52
Hi

Ein eindimensionales Array kann man ja bequem so mit Zufallszahlen füllen.




int field [5];

for (i = 1; i <= 5; i ++) {

*(field+i) = (rand() %6);
}



aber wie kann man ein mehrdimensionales Array sagen wir




int field [7][10];



bequem mit Zufallszahlen auffüllen.

Mir fällt irgendwie keine effizente Lösung ein da ich noch nicht so mit Programmieren vertraut bin.

Ich dachte ich frage weil es in C sicher eine elegante Lösung gibt und ich sie gerne sehen möchte.

mfg peecee

wraith
28-07-2003, 20:03
Original geschrieben von peecee
[B]



int field [5];

for (i = 1; i <= 5; i ++) {

*(field+i) = (rand() %6);
}


Array-Indices in C beginnen bei 0,und gehen bis n -1.
Also ist deine Variante falsch.
Außerdem ist der Code leichter lesbar,wenn du auf das Array so zugreifst


for(i = 0;i < 5;i++)
field[i] = ...




aber wie kann man ein mehrdimensionales Array sagen wir
int field [7][10];
bequem mit Zufallszahlen auffüllen.

Entweder mit zwei verschachtelten for-Schleifen,oder du holst dir einen Zeiger auf das 1.Element,und läufst mit einer for-Schleife von 0 bis 7*10-1.

peecee
29-07-2003, 10:53
Mich interesiert die Zeiger Variante mehr.

ein Zeiger auf das Erste Element meines Arrays wäre ja "*field"

warum geht das nicht ?




for(i=0 ; i<=68 ; i++) {

*(field+i) = (rand() %6);

printf("%d\n", *(field+i));
}


dann kommt eie Meldung in der Art "Operands auf = have illegal types

Ich denke mal der Zeiger auf das Erste Element ist nicht richtig .

Kannst du mir die Lösung verraten.

mfg

wraith
29-07-2003, 11:03
1D-Array


int field[10];
int *pInt = &field[0];

for(;pInt != field + 10;++pInt)
*pInt = rand();


2D-Array


int field2D[3][7];
int *pInt = &field2D[0][0];

for(;pInt != &field2D[0][0] + 3 * 7;++pInt)
*pInt = rand();

peecee
29-07-2003, 12:37
Danke für die Lösung !!!

cybercrow
29-07-2003, 15:33
Original geschrieben von wraith
2D-Array


int field2D[3][7];
int *pInt = &field2D[0][0];

for(;pInt != &field2D[0][0] + 3 * 7;++pInt)
*pInt = rand();


imho ein schönes Beispiel warum man in C nicht alles machen sollte, was möglich ist.
Das versteht doch nacher niemand mehr!

Ich würde da eher die "klasische" Methode empfehlen:



int felt[3][7]
int i,j;

for (i=0; i <= 3; i++)
for(j=0; j<= 7;j++)
feld[i][j] = rand();

wraith
29-07-2003, 15:43
Original geschrieben von cybercrow

Ich würde da eher die "klasische" Methode empfehlen:



int felt[3][7]
int i,j;

for (i=0; i <= 3; i++)
for(j=0; j<= 7;j++)
feld[i][j] = rand();

Herrlich,und schon zwei Fehler drin :).

Btw. der OP wollte die Pointer-Variante.

cybercrow
29-07-2003, 15:53
Original geschrieben von wraith
Herrlich,und schon zwei Fehler drin :).


ok, die Grenzen sind falsch, habe halt schon eine weile nichts mehr in C gemacht:



int feld[3][7]
int i,j;

for (i=0; i <= 2; i++)
for(j=0; j<= 6;j++)
feld[i][j] = rand();


das ändert aber nichts an meiner Grundaussage.



Btw. der OP wollte die Pointer-Variante.


ja, trotzdem würde ich sowas nie verwenden...

wraith
29-07-2003, 15:55
Original geschrieben von cybercrow

das ändert aber nichts an meiner Grundaussage.
Die ich aber schon in meinem ersten Post aufgegriffen hatte
>>Außerdem ist der Code leichter lesbar,wenn du auf das Array so zugreifst

Aber der OP wollte ebend lernen :).

BLUESCREEN3D
30-07-2003, 13:45
Original geschrieben von wraith

Original geschrieben von cybercrow


int felt[3][7]
int i,j;

for (i=0; i <= 3; i++)
for(j=0; j<= 7;j++)
feld[i][j] = rand();

Herrlich,und schon zwei Fehler drin :)

mir fällt gerade auf, dass es sogar drei Fehler sind :P



int felt[3][7]; //hier
int i,j;

for (i=0; i <= 2; i++) //hier
{
for(j=0; j<= 7;j++) //und hier
{
feld[i][j] = rand();
}
}


BTW: Die gescheiften Klammern sollte man auch setzen, wenn man nur einen Befehl hat und ein Block somit unnötig ist - ist einfach besserer Programmierstil weil übersichtlicher, konsequenter und fehlerunanfälliger (wenn man z.B. mal einen 2. Befehl einfügen will).

cybercrow
30-07-2003, 14:55
Original geschrieben von BLUESCREEN3D

BTW: Die gescheiften Klammern sollte man auch setzen, wenn man nur einen Befehl hat und ein Block somit unnötig ist - ist einfach besserer Programmierstil weil übersichtlicher, konsequenter und fehlerunanfälliger (wenn man z.B. mal einen 2. Befehl einfügen will).

Wenn wir jetzt schon mit dem Erbsenzählen anfangen, dann richtig ;)



int feld[3][7];
int i,j;

for (i=0; i <= 2; i++) {
for(j=0; j <= 7; j++) {
feld[i][j] = rand();
}
}


Für öffnende Klammer fängt man normal keine neue Zeile an (ausnahme Funktionen)! :p

wraith
30-07-2003, 15:06
Original geschrieben von cybercrow

Für öffnende Klammer fängt man normal keine neue Zeile an (ausnahme Funktionen)! :p
Dir ist klar,daß es darum schon blutige Flamewars gegeben hat :).
Was ich damit sagen,es ist eine Stilfrage,und in C/C++ setze ich die öffnende Klammer immer auf eine neue Zeile (bei Java komischerweise nicht).

Aber wenn ich nach den Gurus gehe,dann preferrieren die doch auch meine Variante.

quinte17
30-07-2003, 15:06
Original geschrieben von cybercrow
Wenn wir jetzt schon mit dem Erbsenzählen anfangen, dann richtig ;)
Für öffnende Klammer fängt man normal keine neue Zeile an (ausnahme Funktionen)! :p

dass is nur eine sache der betrachtung!

ich mache auch lieber
for...
{
...
}

weil ich somit die blöcke in meiner betrachtung primär im blickfeld habe

im gegensatz zu
for... {
...
}

da hat man dann den befehl im blickfeld nicht aber den block...

ist 1. geschmacksache, und 2. gewohnheit...

also bitte keinen flame jetzt wegen sowas

mfg

cybercrow
30-07-2003, 15:17
Original geschrieben von wraith
Was ich damit sagen,es ist eine Stilfrage,und in C/C++ setze ich die öffnende Klammer immer auf eine neue Zeile (bei Java komischerweise nicht).

Aber wenn ich nach den Gurus gehe,dann preferrieren die doch auch meine Variante.

Wer sind die "Gurus"?
Also der Linux coding-style hält sich stark an K&R und da wird keine neue Zeile angefangen und um mal den linux-coding-style zu zitieren:
" but all right-thinking people know that (a) K&R are right and (b) K&R are right." ;)

Bei gnu-coding-style wird eine neue Zeile angefangen, dafür wird aber bei einer einzigen Zeile nicht geklammert. Beispiel:


if (x < foo (y, z))
haha = bar[4] + 5;
else
{
while (z)
{
haha += foo (z, z);
z--;
}
return ++x + bar ();
}


Ich würde sagen dadurch gleicht sich der "Platzverbrauch" einigermaßen aus. Immer klammern und dann auch noch jedesmal eine neue Zeile halte ich aber für etwas übertrieben...

Die beiden styles würde ich mal als die zwei "Haupt-styles" bezeichnen.
BLUESCREEN3Ds code passt aber auf keiner der beiden styles :p


PS: Ich bevorzuge eigentlich zu einem großen Teil den gnu-style, deswegen habe ich in meinem ersten Beispiel auch die Klammern weg gelassen.

wraith
30-07-2003, 16:18
Original geschrieben von cybercrow
Wer sind die "Gurus"?

Chris Torek,Richard Heathfield,Sutters,Alexandrescu...


Also der Linux coding-style hält sich stark an K&R und da wird keine neue Zeile angefangen und um mal den linux-coding-style zu zitieren:

Ich liebe den L.T Kernel Style Guide,den ziehe ich mir immer an regnerischen Tagen rein.Was hab' ich gelacht :)


Tabs are 8 characters, and thus indentations are also 8 characters.
There are heretic movements that try to make indentations 4 (or even 2!)
characters deep, and that is akin to trying to define the value of PI to
be 3.

Der Mann hätte Komiker werden können.



" but all right-thinking people know that (a) K&R are right and (b) K&R are right."

Woher hat er das?
Zitat: The Practice of Programming (B.W Kernighan)


Use a consistent indentation style and brace style.[...]Programmers have always argued about the layout of programs,but the specific style is much less important than its consistent application.Pick one style,use it consistently and don't waste time arguing.

Wenn er es aus den Quelltexten der Bücher abgeschaut hat,dort verwendent Sie Tabs mit 4 Leerzeichen :),und ich dachte K&R hätten immer Recht ;).




Bei gnu-coding-style wird eine neue Zeile angefangen, dafür wird aber bei einer einzigen Zeile nicht geklammert.

Ja,das deckt sich mit meinem Stil.

cybercrow
30-07-2003, 16:41
Original geschrieben von wraith
Woher hat er das?
Zitat: The Practice of Programming (B.W Kernighan):

Use a consistent indentation style and brace style.[...]Programmers have always argued about the layout of programs,but the specific style is much less important than its consistent application.Pick one style,use it consistently and don't waste time arguing.


Naja, er hat vielleicht nie versucht aus seinem coding-style einen Standard zu machen, für sich selber sieht man es oft immer sehr locker ("ich mach es halt so, andere sollen es so machen wie sie wollen"), wenn man sich aber einen Namen auf einem Gebiet gemacht hat, man oft zitiert wird und wenn wie bei K&R das Buch auch noch zu einem absoluten Standardwerk wird, dann gibt es automatisch auch viele die sich diesen style aneignen und es entsteht ein "Standard". Unabhängig davon ob es der Verfasser ursprünglich wollte oder nicht.



Wenn er es aus den Quelltexten der Bücher abgeschaut hat,dort verwendent Sie Tabs mit 4 Leerzeichen :),und ich dachte K&R hätten immer Recht ;).


Da hast du recht, das ist ein Wiederspruch. Wobei man hier vielleicht noch mit dem Buchformat argumentieren kann. ;)
Tabs = 8 Zeichen ist ja schon irgendwo eine Faustregel...
Wobei man natürlich bei 8er Tabs ziemlich schnell über den Bildschrimrand hinaus kommt, 4 ist da imho ein guter Kompromiss.



Ja,das deckt sich mit meinem Stil.

Da sind wir uns ja dann einig :)
Überhaupt finde ich den gnu-style sehr konsistent und gut durchdacht.
Wobei wie gesagt, wenn man schon alles klammert, dann sollte man sich an K&R orrientieren, denn sonst wird es schon etwas sehr groß..

f0rtex
30-07-2003, 16:45
Ich sage da nur: Gelobt sei das Tool indent :-)

Ich schreibe die Programme nach meinem Stil und wenn sie jemandem nicht gefallen, dann lass ich sie durch indent durch und das Problem ist gelöst. :-)

greets
f0rtex

BLUESCREEN3D
31-07-2003, 00:08
<flame>

wie ich meine klammern setzte hat alles einen sinn:

z.B. bei

for(;;)
{
cout << "bla" << endl; //los, fang noch nen flamewar an, weil ich kein \n benutze!!!
}

-stehen die beiden klammern eine blockes untereinander, wodurch man gleich sieht, ob die anzahl stimmt und was zusammengehört
-sie sind eingerückt, weil ein block gebraucht wird, um statt nur eimem befehl mehrere befehle abzuarbeiten - ein einzelner befehl wäre eingerückt - also rücke ich meine beiden klammern auch ein und mache nicht sowas:

for(;;)
{
cout << "bla" << endl; //los, fang noch nen flamewar an, weil ich kein \n benutze!!!
}

außerdem sieht es so am besten aus :p

</flame>

Silver
05-08-2003, 10:38
Original geschrieben von BLUESCREEN3D


int felt[3][7]; //hier
int i,j;

for (i=0; i <= 2; i++) //hier
{
for(j=0; j<= 7;j++) //und hier
{
feld[i][j] = rand();
}
}


BTW: Die gescheiften Klammern sollte man auch setzen, wenn man nur einen Befehl hat und ein Block somit unnötig ist - ist einfach besserer Programmierstil weil übersichtlicher, konsequenter und fehlerunanfälliger (wenn man z.B. mal einen 2. Befehl einfügen will).

warum gehst du bei der for Schleife mit der Variable j bis zu 7? würde hier nicht <= 6 gehören?

mfG

PS: wenn ich falsch, bitte erklären ;)

tuxipuxi
05-08-2003, 11:54
ja du hast recht.

axeljaeger
05-08-2003, 12:41
Ich hab auch schon sowas gesehen:


if(bedingung) {
cout << "" ;
cout <<< ""; }
else
i = M_PI;


ich persönlich schreibe die öffnende Klammer immer in eine neue Zeile, die Klammern werden nicht mit eingerückt und wenn eingerückt wird, dann mit einem oder zwei Leerzeichen.

BLUESCREEN3D
05-08-2003, 13:17
Original geschrieben von Silver
warum gehst du bei der for Schleife mit der Variable j bis zu 7? würde hier nicht <= 6 gehören?
ups - jetzt hab ich auch noch das falsche übernommen...

Berufspenner
05-08-2003, 13:33
los, fang noch nen flamewar an, weil ich kein \n benutze!!! Hä? Wo würdest du denn das \n hinsetzten? "<< endl;" reicht doch auch :confused:

Cu
André

BLUESCREEN3D
05-08-2003, 16:51
Original geschrieben von Berufspenner
Hä? Wo würdest du denn das \n hinsetzten? "<< endl;" reicht doch auch :confused:

deshalb flamewar: ob man nun endl oder \n benutzt:

cout << "bla" << endl;
oder

cout << "bla\n";

ich habe schon immer das erste benutzt, weil man da alle zeilenwechsel im quellcode schneller sieht



edit: wo ich gerade deinen wohnort sehe - noch ein flamewar-thema:

char* home="Hamburg";
schreibe ich auch anders:

char *home="Hamburg";
weil es mir so irgendwie konsequenter erscheint - schließlich ist "home" der zeiger und nicht "char" :D

Berufspenner
05-08-2003, 16:54
Original geschrieben von BLUESCREEN3D
deshalb flamewar: ob man nun endl oder \n benutzt:

cout << "bla" << endl;
oder

cout << "bla\n";

ich habe schon immer das erste benutzt, weil man da alle zeilenwechsel im quellcode schneller sieht Ach so meintest du das. Ich benutzte zum terminieren einer und wechseln einer Zeile auch immer "endl".

Cu
André

BLUESCREEN3D
05-08-2003, 16:58
jetzt haste mein edit übersehen *gg*

Berufspenner
05-08-2003, 17:04
Original geschrieben von BLUESCREEN3D
jetzt haste mein edit übersehen *gg* Wie auch, wenn ich selber grade was abschicke :D ;) Die einfachste Lösung, um dem zweiten Problem aus dem Weg zu gehen ist wohl
char home[]="Hamburg";Cu
André

cybercrow
05-08-2003, 17:38
wollte nur mal kurz anmerken das ich endl auch für die "Standardlösung" unter C++ halte \n gehört schon eher zu C und kommt auch von da...

Silver
06-08-2003, 08:07
Original geschrieben von BLUESCREEN3D
edit: wo ich gerade deinen wohnort sehe - noch ein flamewar-thema:

char* home="Hamburg";
schreibe ich auch anders:

char *home="Hamburg";
weil es mir so irgendwie konsequenter erscheint - schließlich ist "home" der zeiger und nicht "char" :D

Um ein wenig penibel zu sein :) : Eigentlich würde char* home="Hamburg" richtig sein, weil es ein Char-Pointer ist, welcher 4 Byte belegt nicht wie der normale 1 Byte!

mfg

wraith
06-08-2003, 08:58
Original geschrieben von Silver
Um ein wenig penibel zu sein :) : Eigentlich würde char* home="Hamburg" richtig sein, weil es ein Char-Pointer ist, welcher 4 Byte belegt nicht wie der normale 1 Byte!

Da gibt es wirklich kein falsch und richtig.
In irgendeiner C oder C++ FAQ stand mal drin,daß C Programmierer den * an den Typ schreiben,und C++ Programmierer an die Variable (oder war es umgekehrt ^^,so egal ist das ich weiß es nicht mehr).
Wer sich nicht entscheiden kann soll doch char*name,oder char * name schreiben.

Außerdem wenn man ganz penibel ist,daß sind hier alle Varianten falsch ^^.
Die Zeichenkette ist konstant,korrekt muß es also ein const char* sein.

Silver
06-08-2003, 13:03
da hier wir gerade OT sind, eine kleine frage:

hab mal in einem Source folgendes gesehen:


Variante 1:
char *feld[]={"Acker", "Weizen", "Roggen"};

Variante 2:
const char *grass[]={"Klee", "Löwenzahn", NULL};


beide Varianten sind konstante String-Arrays. Warum schreib ich dann bei Variante 2 als letztes Argument NULL? Gehört dies so, oder wird das hier nur als Sicherheitsmaßnahme verwendet damit man weiss, wo das Ende ist? Könnte man das NULL Argument, auch bei Variante 1 schreiben?

Ich erahne wahrscheinlich die richtige Antwort, aber ich möchte sicher sein, und frage daher euch!

mfG

Berufspenner
06-08-2003, 13:50
@Silver

Ich hab nur so eine Ahnung: "NULL" terminiert das Array. Wenn man "NULL" entfernen würde könnte ich mit "*(grass + 3)" auf die Adresse von "feld[1]" zugreifen.

#include <iostream>
using namespace std;

int main()
{
char *feld[]={"Acker", "Weizen", "Roggen"};
cout << *(feld +1) << endl;

const char *grass[]={"Klee", "Löwenzahn"};
cout << *(grass + 3) << endl;

return 0;
}Cu
André

wraith
06-08-2003, 14:10
Original geschrieben von Silver
[B]


Variante 1:
char *feld[]={"Acker", "Weizen", "Roggen"};

Variante 2:
const char *grass[]={"Klee", "Löwenzahn", NULL};


beide Varianten sind konstante String-Arrays.

Ja,und darum ist Variante 1 auch falsch (siehe mein Posting weiter oben).



Warum schreib ich dann bei Variante 2 als letztes Argument NULL?
So kannst du eine Schleife schreiben,die alle String ausgibt,ohne das zu weißt wieviele String drinsind.

Silver
06-08-2003, 18:57
ich hab daher geglaubt wenn man als letzes arg. NULL hat, schreibt man const vorm char*, ansonsten nicht! danke für die antwort!

mfG