Archiv verlassen und diese Seite im Standarddesign anzeigen : Array durchlaufen C
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
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.
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
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();
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();
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...
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
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.
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ß..
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>
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...
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
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.
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é
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.
ich hab daher geglaubt wenn man als letzes arg. NULL hat, schreibt man const vorm char*, ansonsten nicht! danke für die antwort!
mfG
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.