PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zufällige Werte in 50x50 matrix?



Darkthief
27.10.2008, 14:52
hi ich hab folgenden cCode aus einem Buch abgeschrieben.
Es hieß er soll "die größte und kleinste Komponente einer (50x50)-matrix herausfinden.
Ich dachte, dass alle Werte einer nich definierten Matrix (array, feld) gleich 0 sind und daher diese Anwendung keinen Sinn ergeben würde.



#include <iostream>
#include <math.h>
using namespace std;

int main() {
int mat[50][50];

int max = mat[0][0], min = max;

for (int i = 0; i < 50 ; i++)
for (int j = 0; j < 50 ; j++)
{
int aij = mat[i][j];

cout <<aij <<endl; //Diese Zeile habe ich eingefügt um die Zwischenwerte zu sehen.

if (aij > max)
max = aij;
else if (aij < min)
min = aij;
}
cout << "\nMin:"<< min <<"\nMax:" <<max <<endl;
return 0;


Ich habe keine ahnung woher diese werte kommen. Und warum sind immer so große negative und kleine positive werte dabei?

Bitte um Aufklärung[/quote]

Easysurfer
27.10.2008, 15:03
Soweit ich das seh machst Du ne 50*50 Matrix, die Du aber mit den Werten leer lässt. Das ist der Fehler. Du hast sie zwar erzeugt, musst sie aber dann auch mit Nullen befüllen, da der Speicherbereich sonst die Zahlen die da noch drinstehen nimmt. (ist nen bisschen schwer zu erklären, ich versuchs aber mal). BSP: Du erzeugst per Int eine Variable: int i; jetzt hat i aber den Wert des Speicherbereiches auf dem sie Steht, d.h. i kann -321437 sein oder auch 6 oder so, je nachdem was zuvor darauf stand. Also musst Du indem Fall int i = 0 schreiben, das auch der Wert richtig Initialisiert ist. Mit der Matrix machst Du das so:


for (int i = 0; i < 50 ; i++)
for (int j = 0; j < 50 ; j++)
{
mat[i][j] = 0;
cout<<"Hier noch die Ausgabe: "<<mat[i][j]<<endl;
}
}


danach kannnst Du die MAtrix erst befüllen, mit Rand() oder weis ich was...

-[RiDER]-
27.10.2008, 20:16
Hi :D

Mit memset() kannste den Kram mit Nullen füllen:
memset(mat, 0, 50 * 50);

Is natürlich Schwachsinn, wenn Du hinterher Zufallswerte reinschreiben willst :D

GreetZ RiDER :D :D :D

Darkthief
27.10.2008, 23:19
aber wenn man z.B. ein andere variable deklariert.
int i;
dann ist sie automatisch 0, warum ist das nicht beier matrix so?
d.h. also, das der speicher nicht gelöscht wird bzw. mit nullen initialisiert wird, wenn eine variable nichtmehr gebracuht wird?

blackberry
27.10.2008, 23:52
dann ist sie automatisch 0, warum ist das nicht beier matrix so?
d.h. also, das der speicher nicht gelöscht wird bzw. mit nullen initialisiert wird, wenn eine variable nichtmehr gebracuht wird?

Bei einem Integer alle Bits auf null zu setzen ist kein großer Aufwand.
Wenn du einen char-Array mit 99999 Elementen anlegst kann das dauern.
Unter 32-Bit Windows ist ein Adressraum von 4 GB pro Programm adressierbar (das heißt nicht, dass Windows so eine Menge Speicher an ein Programm vergeben würde, es wäre aber möglich).
Schonmal 4 GB mit nullen überschrieben??? xD

Bei Standartdatentypen kannst du also von einer Initialisierung mit 0 ausgehen, bei abgeleiteten nicht!


mfG. BlackBerry

noctem
27.10.2008, 23:53
#include <iostream>
using namespace std;
int main()
{
int i;
cout << i << endl;

return 0;
}

Ich erhalte da immer Zufallswerte. Stimmt schon, was oben geschrieben wurde.

Darkthief
28.10.2008, 00:12
@noctem:
bist du dir sicher?
Im c++ buch stand was von standart initialisiernung…


Bei Standartdatentypen kannst du also von einer Initialisierung mit 0 ausgehen, bei abgeleiteten nicht!
Danke!!! das hat mir sehr geholfen!

@all:
hab grat rausgefunden, dass
int mat[10][10] = {};

auch alle feldkomponenen auf 0 setzt :-P

noctem
28.10.2008, 00:20
Hier noch meine Ausgabe:

01:20:20 noctem@lappi $ ./test
-1208603216
01:20:23 noctem@lappi $ ./test
-1208877648
01:20:25 noctem@lappi $ ./test
-1208451664
01:20:25 noctem@lappi $ ./test
-1208906320
01:20:26 noctem@lappi $ ./test
-1208795728
01:20:26 noctem@lappi $ ./test
-1208734288
01:20:27 noctem@lappi $ ./test
-1208046160
01:20:27 noctem@lappi $ ./test
-1208427088
01:20:28 noctem@lappi $ ./test
-1208672848
01:20:29 noctem@lappi $ ./test
-1208926800

Also durchaus immer andere Werte. (Linux, g++)

-[RiDER]-
28.10.2008, 12:37
Hi :D

Bei Standartdatentypen kannst du also von einer Initialisierung mit 0 ausgehen, bei abgeleiteten nicht!
Ich bin mir nicht ganz sicher und habs jetzt auch nicht ausprobiert, aber mich dünkt, dass das nur auf statische und globale Variablen zutrifft.

D.h. bei
int i;
int main(void)
{
printf("%d", i);
} wird i IIRC mit 0 initialisiert.
Bei
int main(void)
{
int i;
printf("%d", i);
} nicht unbedingt.
Wohl aber wiederum bei
int main(void)
{
static int i;
printf("%d", i);
}

noctem, probier doch mal i statisch oder global zu deklarieren. Mal sehen was passiert. :)

GreetZ RiDERder noch immer im Urlaub ist und nur eingeschränkten Zugriff auf Computer hat, was zu starken Entzugserscheinungen, wie dem Singen von Sourcecodes oder einem unkontrollierten mit den Fingern auf die Tischplatte Hacken führt.

Darkthief
28.10.2008, 13:06
hm stimmt, dann ist das was BlackBerry gesagt hat wohl doch nicht richtig…

also, ersma kann man keine const Variable deklarieren ohne sie zu initialisieren, es sei denn, sie ist extern.
Und ja, extern bzw. globale Variablen werden immer mit 0 initialisiert, auch Felder (habs getestet).

jetzt hab ich noch ne Frage, nämlich wie im folgenden Code, die selbe Variable, die constant ist, immer wieder mit anderen Werten initialisiert werden kann.



for (int i = 0; i < 50 ; i++)
for (int j = 0; j < 50 ; j++)
{
const int aij = mat[i][j];

cout <<aij <<endl;
}

is der selbe Code wie in meinem ersten Post, nur mit const Variable, wies auch eigentlich im Buch stand.

-[RiDER]-
28.10.2008, 13:49
Hi :D

also, ersma kann man keine const Variable deklarieren ohne sie zu initialisieren, es sei denn, sie ist extern.
Und ja, extern bzw. globale Variablen werden immer mit 0 initialisiert, auch Felder (habs getestet).
Ich glaube, dass Du hier extern, const, static und globale Variablen in einen Topf wirfst.

extern hat was mit modularer Programmierung zu tun, ist also für diesen Thread weitestgehend uninteressant.

Variablen, die als const deklariert sind, lassen sich nicht ändern, zumindest sollte das Dein Compiler nicht zulassen.

Variablen, die innerhalb einer Funktion als static deklariert sind, bleiben nach Verlassen ihres Gültigkeitsbereichs erhalten und haben bei erneutem Aufruf (im gleichen Gültigkeitsbereich) noch ihren alten Wert, wurden also nicht gelöscht.

Es gibt noch sowas wie volatile oder restrict, was aber hierfür keine Bedeutung hat. ;)

Globale Variablen sind Variablen, deren Gültigkeitsbereich sich über das gesamte Programm erstreckt (bei modularer Programmierung kommen noch ein Paar Umstände hinzu, doch das hat wie gesagt nichts mit dem Topic zu tun...). ;)

Wenn Du Variablen eines Vektor mit Zufallswerten füllen willst, dann tu das mit rand().

int mat[50][50];
int i, j;

srand(time(NULL)); // rand() initialisieren

for(i = 0; i < 50; i++)
{
for(j = 0; j < 50; j++)
{
mat[i][j] = (int)(INT_MAX * rand() / (RAND_MAX + 1));
// Wert zwischen 0 und INT_MAX
}
}

GreetZ RiDER :D :D :D

noctem
28.10.2008, 14:12
Nun bin ich etwas verwirrt:

15:12:21 noctem@lappi $ ./test
Normales i: 134515113
Statisches i: 0
Globales i: 0
15:12:25 noctem@lappi $ ./test
Normales i: 134515113
Statisches i: 0
Globales i: 0
15:12:26 noctem@lappi $ ./test
Normales i: 134515113
Statisches i: 0
Globales i: 0
15:12:27 noctem@lappi $ ./test
Normales i: 134515113
Statisches i: 0
Globales i: 0
15:12:27 noctem@lappi $ ./test
Normales i: 134515113
Statisches i: 0
Globales i: 0
15:12:28 noctem@lappi $ ./test
Normales i: 134515113
Statisches i: 0
Globales i: 0

<< Immer das gleiche. o.O

Code:

#include <iostream>
using namespace std;

int global_i;

int main()
{
static int static_i;
int normal_i;

cout << "Normales i: " << normal_i << endl;
cout << "Statisches i: " << static_i << endl;
cout << "Globales i: " << global_i << endl;
}

blackberry
28.10.2008, 17:09
-]Ich bin mir nicht ganz sicher und habs jetzt auch nicht ausprobiert, aber mich dünkt, dass das nur auf statische und globale Variablen zutrifft.

Wäre möglich - ich habe bisjetzt die Erfahrung gemacht, dass ein Boolean, ohne Initialisierung, immer falsch war...
Ich schau es mir nochmal an :)


mfG. BlackBerry

Darkthief
10.11.2008, 19:37
sind const variablen nicht static variablen?
naja und mit extern meinte ich auserhalb von main deklarierte variablen, die werden mit 0 initialisiert
konstante variablen muss man ja initialisieren, also werden sie halt so initialisiert, wei man sie initialisiert.
und da ich dachte, das man const variablen nicht mehr verändern kann, wollte ich wissen, warum hier iimmer ien anderer wert initialisiert werden kann:
#include <iostream>
#include <math.h>
using namespace std;

int main() {
int mat[50][50];

int max = mat[0][0], min = max;

for (int i = 0; i < 50 ; i++)
for (int j = 0; j < 50 ; j++)
{
int aij = mat[i][j];

cout <<aij <<endl; //Diese Zeile habe ich eingefügt um die Zwischenwerte zu sehen.

if (aij > max)
max = aij;
else if (aij < min)
min = aij;
}
cout << "\nMin:"<< min <<"\nMax:" <<max <<endl;
return 0;

ist der wertigkeits bereich einer in einer schleife definierten variable nur in der schleife?
das würds nämich erklären.

und bei einer matrix mit bool werten krieg ich immer random werte, aber auch größere als 1. ich achte bool kann nur 0 oder 1 enthalten?

-[RiDER]-
10.11.2008, 20:15
Hi :D

ist der wertigkeits bereichDu sprichst vom Gültigkeitsbereich?
Oder Wertebereich?
Ein Zwischending, wie Du es verwendest, gibt es nicht.

einer in einer schleife definierten variable nur in der schleife?
das würds nämich erklären.
Ja, das stimmt, ist für Deinen Kode aber ohne Bedeutung.
Und was würde das erklären?

Ich verstehe nicht, wieso Du diesen Kode in Zusammenhang mit "const Variablen" postest - ich sehe dort keine solche Variable!

Wenn Du mit Deinem Programm eine Matrix mit zufälligen Werten füllen willst, dann fehlt Deinem Kode eine entscheidende Sache: das Füllen der Matrix mit zufälligen Werten!

Um auch gleich die Frage mit der Initialisierung zu klären, 6.7.8p10:
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate. If an object that has static storage duration is not initialized explicitly,
then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules.
Die Variablen Deiner Matrix gehören zum im ersten Satz beschriebenen Variablen: Ihr Wert ist unbestimmt!
Das ist etwas anderes als zufällig!

Wenn irgendwas an Deinem Programm nicht funktioniert, dann würde ich das darauf zurückführen!


und bei einer matrix mit bool werten krieg ich immer random werte, aber auch größere als 1. ich achte bool kann nur 0 oder 1 enthalten?
6.2.5p5 besagt:

An object declared as type _Bool is large enough to store the values 0 and 1.
Das ist alles, was der Standard dazu vorschreibt.
_Bool kann also (implementierungsbedingt) auch andere Werte als 0 und 1 haben - nur diese beiden müssen auf jeden Fall dabei sein.

GreetZ RiDER :D :D :D

Darkthief
16.11.2008, 12:01
ok sry hab die const variable vergessen.
ja ich meinte den gültigkeitsbereich.
und nien ich wil keine matrix mit zufälligen werten fülle, sondern habe mich gewundert, warum zufällige werte in einer matrix erscheinen, wenn sie nicht initialisiert wird, aner jetzt weis ichs ja.

und bei dem code hat einfach das "const" vor dem "int aij = mat[i][j];" gefehlt.
also soweit ich das verstanen habe, sind in einer schleife deklarierte variablen nur in dieser gültig.

-[RiDER]-
16.11.2008, 16:06
Hi :D

und nien ich wil keine matrix mit zufälligen werten fülle, sondern habe mich gewundert, warum zufällige werte in einer matrix erscheinen, wenn sie nicht initialisiert wird
Achso. :)


also soweit ich das verstanen habe, sind in einer schleife deklarierte variablen nur in dieser gültig.
Das hast Du richtig verstanden. :)
Das gilt übrigens nicht nur für for-Schleifen, sondern für jede Art von Block.

In C++ ist AFAIK auch eine Schreibweise wie man sie z.B. von Perl auch kennt möglich:
for(int foo = bar; foo < foobar; foo++)
Streng genommen ist hierbei foo außerhalb der Schleife deklariert (um ganz genau zu sein: definiert), die Variable verliert ihre Wertigkeit aber beim Verlassen der Schleife.

Dann gibts noch sowas wie den Spezifizierer auto und eine kleine Ausnahme für Vektoren variabler Länge, aber das sind sehr seltene Ausnahmen...

GreetZ RiDER :D :D :D