Zechpreller
Anmeldungsdatum: 27. Dezember 2012
Beiträge: 39
|
Hallo Community, ich hoffe dass ich hier richtig bin da mir langsam wegen diesem Fehler graue Haare wachsen. Im Zuge einer Seminararbeit habe ich begonnen zwei Algorithmen (Newton-Verfahren, Gauß-Algorithmus) in C zu programmieren.
Das habe ich dann in der IDE Eclipse unter Ubuntu gemacht und alles lief perfekt. Jedoch will mein Betreuer das Programm unter Windows haben da er kein Linux verwendet. (Leider ließ er sich da auch auf keine Diskussion ein) Da ich den GNU GCC C/C++ als Compiler verwendet habe, nahm den MinGW Compiler unter windows installierte ihn und Eclipse um das alles zum laufen zu bringen. Das Newton-Verfahren funktioniert wie zuvor noch optimal, jedoch nicht der Gauß-Algorithmus. Das Programm spuckt immer wieder -1.#IND00, 1.#QNAN0 als Fehlercode aus was ja bedeutet dass ich etwas unlösbares berechnen wollte, wie z.B. durch 0 teilen. Das lineare Gleichungssystem wird in ein 2-dimensionales double array geschrieben und dort dann auch berechnet, mir fiel jedoch auf dass die Variablenwerte
welche ich mit scanf einlese nach der Eingabe nicht mit der Ausgabe übereinstimmen. Im debugger taucht für das entsprechende Array auch ein Fehler auf. (lin_var ist der name des Arrays)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | Code
lin_var.2
Error:
Multiple errors reported.
\ Failed to execute MI command:
-var-create - * lin_var.
2 Error message from debugger back end: -var-create:
unable to create variable object\
Unable to create variable object\
Failed to execute MI command: -data-evaluate-expression
lin_var.2 Error message from debugger back end:
A syntax error in expression, near .2'.\
Failed to execute MI command: -var-create - *
lin_var.2 Error message from debugger back end: -var-create:
unable to create variable object
|
Ich hoffe die Informationen reichen für ein paar Tipps. Hier noch die Ausgabe des Programms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 | Sie haben das Programm zur Durchführung des Gaußschen Algorithmus gewählt.
Die Koeffizienten werden von links nach rechts eingelesen.
Wobei die jeweilige Spalte die Variablennummer wiedergibt
Bitte geben sie die Anzahl der zu berechnenden Variablen an
3
Sie befinden sich in der 1. Zeile
Bitte geben Sie den 1. Koeffizienten ein -4
Bitte geben Sie den 2. Koeffizienten ein -2
Bitte geben Sie den 3. Koeffizienten ein 0
Bitte geben Sie den 4. Koeffizienten ein -2
Sie befinden sich in der 2. Zeile
Bitte geben Sie den 1. Koeffizienten ein 0
Bitte geben Sie den 2. Koeffizienten ein 2
Bitte geben Sie den 3. Koeffizienten ein 2
Bitte geben Sie den 4. Koeffizienten ein 4
Sie befinden sich in der 3. Zeile
Bitte geben Sie den 1. Koeffizienten ein 6
Bitte geben Sie den 2. Koeffizienten ein 6
Bitte geben Sie den 3. Koeffizienten ein -3
Bitte geben Sie den 4. Koeffizienten ein 0
Ihr eingegebenes Gleichungssystem
-4.000000 0.000000 6.000000 6.000000
0.000000 6.000000 6.000000 -3.000000
6.000000 6.000000 -3.000000 0.000000
Das umgeformte Array zur Berechnung der Variablen
1.#QNAN0 -1.#IND00 -1.#IND00 -1.#IND00
-1.#IND00 -1.#IND00 -1.#IND00 1.#QNAN0
-1.#IND00 -1.#IND00 1.#QNAN0 -1.#IND00
Das result_array
Die 1. Variable ist -1.#IND00
Die 2. Variable ist 1.#QNAN0
Die 3. Variable ist -1.#IND00
|
Und hier noch der Programmcode er ist bestimmt nicht perfekt ich lerne ja noch, also habt Gnade ☺. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348 | /*
* Gauß_Algorithmus.c
*
* Created on: Aug 12, 2014
* Author: zechpreller
*/
#include <stdio.h>
//***********************************************************************************//
int main()
{
int i_hor = 0; //innerer Schleifenzähler (Einlesen)
int i_ver = 0; //äußerer Schleifenzähler (Einlesen
int length; //Länge des Arrays
int Spalte = 0; //Spalte in welcher das Element eliminiert werden soll
int Zeile = 0; //Zeile welche bearbeitet wird
double lin_var[length][length+1]; //Array für das lin-Gleichungssystem
double zw_sp[length+1]; //Array für die Eliminierung
double mult_var;
double result_array[length]; //Array in welchem die Lösung der Variablen steht
//***********************************************************************************//
//Deklarieren der Variablen beendet
//***********************************************************************************//
double calc_mult_var(int Spalte, int Zeile,int length) //mult Variable Deklaration
{
double calc_mult_var = lin_var[Zeile][Spalte]/lin_var[Spalte][Spalte]*(-1);
return(calc_mult_var);
}
void calc_add_array(Spalte, Zeile, length) //eliminiert eine Variable in einer Zeile
//bearbeitet das Array lin_var
//eliminert nur die Variable in einer Zeile
{
int i_add_array = 0; //äußerer Schleifenzähler (calc add array)
int i_add_array_sub = 0; //inner Schleifenzähler (-"-)
mult_var = calc_mult_var(Spalte,Zeile, length);
for (; i_add_array < length+1; i_add_array++)
{
zw_sp[i_add_array] = mult_var*lin_var[Spalte][i_add_array];
}
for (i_add_array_sub = 0; i_add_array_sub < length+1; i_add_array_sub++)
{
lin_var[Zeile][i_add_array_sub] = lin_var[Zeile][i_add_array_sub]+zw_sp[i_add_array_sub];
}
}
void swap_lines(int Zeile1, int Zeile2,int length)
{
double swap_array[length+1];
int i_swap_array = 0;
for(; i_swap_array < length+1; i_swap_array++)
{
swap_array[i_swap_array] = lin_var[Zeile1][i_swap_array];
lin_var[Zeile1][i_swap_array] = lin_var[Zeile2][i_swap_array];
lin_var[Zeile2][i_swap_array] = swap_array[i_swap_array];
}
printf("\nDie %i. Zeile wurde mit der %i. Zeile getauscht.\n",Zeile1+1, Zeile2+1);
}
void swap_spalte(int Spalte1, int Spalte2, int length)
{
double swap_spalte_array[length];
int i_swap_spalten = 0;
for (; i_swap_spalten < length; i_swap_spalten++)
{
swap_spalte_array[i_swap_spalten] = lin_var[i_swap_spalten][Spalte1];
lin_var[i_swap_spalten][Spalte1] = lin_var[i_swap_spalten][Spalte2];
lin_var[i_swap_spalten][Spalte2] = swap_spalte_array[i_swap_spalten];
}
printf("\nDie %i. Spalte wurde mit der %i. Spalte getauscht.\n",Spalte1+1,Spalte2+1);
}
int check_array_spalten (int length)
{
int i_check_spalten = 0;
int i_check_spalten_sub = 0;
int switched_spalte = 0;
for (;i_check_spalten < length; i_check_spalten++)
{
if (lin_var[i_check_spalten][i_check_spalten] == 0)
{
i_check_spalten_sub = i_check_spalten+1;
for (;i_check_spalten_sub < length; i_check_spalten_sub++)
{
if (lin_var[i_check_spalten_sub][i_check_spalten] != 0 && lin_var[i_check_spalten][i_check_spalten_sub] != 0 && lin_var[i_check_spalten][i_check_spalten] == 0 )
swap_spalte(i_check_spalten, i_check_spalten_sub, length);
{
switched_spalte = 1;
}
}
}
}
return (switched_spalte);
}
int check_array_before (int Spalte,int Zeile,int length)
{
int i_check_before = Zeile;
int i_add = 0;
int return_value = 0;
for (; i_check_before < length; i_check_before++)
{
if (lin_var[i_check_before][i_check_before] == 0)
{
i_add = i_check_before+1;
for (;i_add < length ; i_add++ )
{
if (lin_var[i_add][i_check_before] != 0 && lin_var[i_check_before][i_add])
{
swap_lines(i_check_before, i_add, length);
return_value = 1;
}
}
}
else
{
}
}
return(return_value);
}
void check_array_before_inverted (int length)
{
int i_check_before = length;
int i_add = 0;
for (; i_check_before > 0; i_check_before--)
{
if (lin_var[i_check_before][i_check_before] == 0)
{
i_add = i_check_before-1;
for (;i_add > 0 ; i_add-- )
{
if (lin_var[i_add][i_check_before] != 0 && lin_var[i_check_before][i_add])
{
swap_lines(i_check_before, i_add, length);
}
}
}
else
{
}
}
}
void errase_downstairs (Spalte,Zeile,length)
{
int i_errase_spalte = 0;
int i_switch_spalte = 0;
int switched_line = 0;
for (;i_switch_spalte < length-1 ; i_switch_spalte++)
{
switched_line = check_array_before (0, 0, length);
switched_line = check_array_spalten (length);
Spalte = i_switch_spalte;
Zeile = Spalte;
i_errase_spalte = Spalte;
if (switched_line == 1)
{
i_switch_spalte = 0;
i_errase_spalte = 0;
Zeile = 0;
Spalte = 0;
}
else
{
for (;i_errase_spalte < length ; i_errase_spalte++)
{
Zeile = Zeile+1;
calc_add_array(Spalte, Zeile, length);
}
}
}
}
void errase_upstairs (Spalte,Zeile,length)
{
int i_errase_spalte = 0;
int i_switch_spalte = 1;
for (;i_switch_spalte < length ; i_switch_spalte++)
{
Spalte = i_switch_spalte;
i_errase_spalte = 0;
Zeile = Spalte;
for (;i_errase_spalte < Spalte ; i_errase_spalte++)
{
Zeile = Zeile-1;
calc_add_array(Spalte, Zeile, length);
}
}
}
void array_out(int length)
{
int i_out_hor = 0;
int i_out_ver = 0;
for(i_out_ver = 0; i_out_ver < length ; i_out_ver++)
{
printf("\n");
i_out_hor = 0;
for(; i_out_hor < length+1 ; i_out_hor++)
{
printf("%f", lin_var[i_out_ver][i_out_hor]);
printf("\t");
}
}
}
//***********************************************************************************//
//Deklarieren der Funktionen beendet
//Einleitung
//***********************************************************************************//
printf("\nSie haben das Programm zur Durchführung des Gaußschen Algorithmus gewählt.");
printf("\nDie Koeffizienten werden von links nach rechts eingelesen.");
printf("\nWobei die jeweilige Spalte die Variablennummer wiedergibt\n\n");
//***********************************************************************************//
//Bestimmen der Anzahl zu berechnender Variablen
printf("\nBitte geben sie die Anzahl der zu berechnenden Variablen an\n");
fflush(stdout);
scanf("%d",&length);
//***********************************************************************************//
//Einlesen des Linearen Gleichungssystems
//***********************************************************************************//
for (i_ver = 0; i_ver < length ; i_ver++) //äußere Schleife zum Einlesen
{
Zeile = i_ver;
printf("\n\nSie befinden sich in der %i. Zeile\n\n\n",i_ver+1);
for (i_hor = 0; i_hor < length+1 ; i_hor++) //innere Schleife um die Zeile einzulesen
{
printf("Bitte geben Sie den %i. Koeffizienten ein\t",i_hor+1);
fflush(stdout);
scanf("%lf",&lin_var[Zeile][i_hor]);
}
}
//printf("Die Anzahl der Variablen %i",length);
//printf("\n\n");
//***********************************************************************************//
//Prüfen nach dem Eingeben des Systems
printf("\nIhr eingegebenes Gleichungssystem\n");
array_out(length);
printf("\n\n");
//***********************************************************************************//
//Erste Prüfung auf Lösbarkeit des Systems
//***********************************************************************************//
Zeile = 0;
Spalte = 0;
check_array_before_inverted (length);
check_array_spalten (length);
//***********************************************************************************//
//Testfeld für das Zeilentauschen
//check_array_before (Spalte, Zeile, length);
//***********************************************************************************//
//Einlesen der Koeffizienten beendet
//Beginn der Berechnung
//***********************************************************************************//
int i_cancel = 0;
int cancel = 0;
for (; i_cancel < length ; i_cancel++)
{
if (lin_var[i_cancel][i_cancel] == 0)
{
cancel = 1;
}
}
if (cancel == 0)
{
errase_downstairs(Spalte, Zeile, length);
Zeile = 0;
Spalte = 0;
errase_upstairs(Spalte, Zeile, length);
printf("\nDas umgeformte Array zur Berechnung der Variablen\n");
array_out(length);
//***********************************************************************************//
//***********************************************************************************//
//Berechnen und ausgeben der Variablen-Werte
//***********************************************************************************//
printf("\n\n\nDas result_array \n\n");
int i_out_hor_result = 0;
int i_result_array = 0;
for (; i_result_array < length ; i_result_array++)
{
result_array[i_result_array] = lin_var[i_result_array][length]/lin_var[i_result_array][i_result_array];
}
for(; i_out_hor_result < length ; i_out_hor_result++)
{
printf("Die %i. Variable ist",i_out_hor_result+1);
printf(" %f", result_array[i_out_hor_result]);
printf("\n");
}
}
if (cancel == 1)
{
printf("\n\nGleichungssystem nicht lösbar!\n");
}
return(0);
}
|
Ich bin in C-Programmieren alles andere als ein Profi und hab mir dieses Thema ausgesucht weil ich gerne programmiere und auch mehr darüber lernen wollte.
Ich weiß dass man es am besten lernt indem man sich mit dem Problem intensiv auseinandersetzt und es selbst löst jedoch komme ich gerade kein Stück vorran. mfg Stephan
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
Wenn es hier geht und da nicht, dann würde ich erst mal nach den Compilereinstellungen und Linkereinstellungen schauen (welcher C-Standard wird benutzt). Die einzige Abhängigkeit scheint ja stdio.h zu sein. Vermurkst hier Inyoka die Einrückungen oder bist Du das? Leere else-Blöcke?
|
Zechpreller
(Themenstarter)
Anmeldungsdatum: 27. Dezember 2012
Beiträge: 39
|
Also die Einrückungen hab ich so gemacht, hab das so gelernt dass man wenn eine neue instanz aufgeht ich eins weiter einrücke. Und das mit dem leeren else block ja das hab ich wohl vergessen noch zu entfernen, ich hatte da vorher einen printf Befehl drin um zu prüfen ob die if-clause
richtig funktioniert. Die entferne ich mal fix danke. Und die Einstellungen schau ich eben nach, melde mich dann nochmal muss erstmal nachschauen wie ich das genau in erfahrung bringe.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
Wundert mich, dass das überhaupt kompiliert. Die Struktur ist ja
|
int main ()
{
int x, y = ...;
void foo (int x);
void foo (int x);
code code code;
}
|
Ich kenne das nur so:
|
void foo (int x);
void foo (int x);
int main ()
{
int x, y = ...;
code code code;
}
|
Ich sollte aber dazusagen, dass ich nur noch sporadisch C-Code ansehe und nicht aufmerksam verfolge, was sich da tut.
|
Zechpreller
(Themenstarter)
Anmeldungsdatum: 27. Dezember 2012
Beiträge: 39
|
Du meinst dass ich die Deklarationen der Funktionen vor der Main-Funktion machen sollte? Ich wollte es vermeiden eine globale Variable zu deklarieren und einige Funktionen verwenden die Deklarationen aus der main-Funktion. Natürlich hätte ich die Variable jeder Funktion wieder mitgeben können. Einfach nicht durchdacht von meiner Seite werde das aber
in Zukunft anders machen danke für den Hinweis! Aber mit meinem Problem schätze ich hat das nichts zu tun? Und mit den Einstellungen vom Compiler und Linker, aber ich verwende doch den MinGW welcher ja die windows-version von GCC C/C++ ist.
Deshalb weiß ich gerade nicht so richtig was du meinst.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
Zechpreller schrieb: Du meinst dass ich die Deklarationen der Funktionen vor der Main-Funktion machen sollte?
Ich habe das noch nie in der Mainfunktion gesehen. Wenn das keine Neuerung ist, ist es kurios.
Ich wollte es vermeiden eine globale Variable zu deklarieren und einige Funktionen verwenden die Deklarationen aus der main-Funktion.
Tja - dem Buchstaben nach vermeidest Du so globale Variablen, aber in Wahrheit ist es nur ein Trick um hinterrücks globale Variablen einzuführen, die aus guten Gründen, und nicht aufgrund eines fiesen Dogmas, tabu sind.
Natürlich hätte ich die Variable jeder Funktion wieder mitgeben können. Einfach nicht durchdacht von meiner Seite werde das aber
in Zukunft anders machen danke für den Hinweis! Aber mit meinem Problem schätze ich hat das nichts zu tun?
Richtig.
Und mit den Einstellungen vom Compiler und Linker, aber ich verwende doch den MinGW welcher ja die windows-version von GCC C/C++ ist.
Deshalb weiß ich gerade nicht so richtig was du meinst.
Wenn Du unter Linux sagst:
Wird der Compiler mit verschiedenen Defaulteinstellungen aufgerufen die heute unter einem 32-bit Ubuntu-Linux andere sein können als unter einem 64-bit oder Suse-Linux oder Solaris oder Windowssystem oder einem 2004er Ubuntu. Vor allem IDEs sind großzügig im Setzen von bestimmten Compilerflags, daher würde ich das erst mal ohne Eclipse zu kompilieren versuchen.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
Der Einrückungsstil ist nahe am Allman-Style, aber nicht stringent durchgehalten. Es gehen etwa niemals zwei geschweifte Klammern nacheinander auf der gleichen Einrückungstiefe zu. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 | /*
* Gauß_Algorithmus.c
*
* Created on: Aug 12, 2014
* Author: zechpreller
*/
#include <stdio.h>
//***********************************************************************************//
int main()
{
int i_hor = 0; //innerer Schleifenzähler (Einlesen)
int i_ver = 0; //äußerer Schleifenzähler (Einlesen
int length; //Länge des Arrays
int Spalte = 0; //Spalte in welcher das Element eliminiert werden soll
int Zeile = 0; //Zeile welche bearbeitet wird
double lin_var[length][length+1]; //Array für das lin-Gleichungssystem
double zw_sp[length+1]; //Array für die Eliminierung
double mult_var;
double result_array[length]; //Array in welchem die Lösung der Variablen steht
double calc_mult_var(int Spalte, int Zeile,int length) //mult Variable Deklaration
{
double calc_mult_var = lin_var[Zeile][Spalte]/lin_var[Spalte][Spalte]*(-1);
return(calc_mult_var);
}
void calc_add_array(Spalte, Zeile, length) //eliminiert eine Variable in einer Zeile
//bearbeitet das Array lin_var
//eliminert nur die Variable in einer Zeile
{
int i_add_array = 0; //äußerer Schleifenzähler (calc add array)
int i_add_array_sub = 0; //inner Schleifenzähler (-"-)
mult_var = calc_mult_var(Spalte,Zeile, length);
for (; i_add_array < length+1; i_add_array++)
{
zw_sp[i_add_array] = mult_var*lin_var[Spalte][i_add_array];
}
for (i_add_array_sub = 0; i_add_array_sub < length+1; i_add_array_sub++)
{
lin_var [Zeile] [i_add_array_sub] = lin_var [Zeile] [i_add_array_sub] + zw_sp [i_add_array_sub];
}
}
void swap_lines (int Zeile1, int Zeile2, int length)
{
double swap_array[length+1];
int i_swap_array = 0;
for(; i_swap_array < length+1; i_swap_array++)
{
swap_array[i_swap_array] = lin_var[Zeile1][i_swap_array];
lin_var[Zeile1][i_swap_array] = lin_var[Zeile2][i_swap_array];
lin_var[Zeile2][i_swap_array] = swap_array[i_swap_array];
}
printf("\nDie %i. Zeile wurde mit der %i. Zeile getauscht.\n",Zeile1+1, Zeile2+1);
}
void swap_spalte(int Spalte1, int Spalte2, int length)
{
double swap_spalte_array[length];
int i_swap_spalten = 0;
for (; i_swap_spalten < length; i_swap_spalten++)
{
swap_spalte_array[i_swap_spalten] = lin_var[i_swap_spalten][Spalte1];
lin_var[i_swap_spalten][Spalte1] = lin_var[i_swap_spalten][Spalte2];
lin_var[i_swap_spalten][Spalte2] = swap_spalte_array[i_swap_spalten];
}
printf("\nDie %i. Spalte wurde mit der %i. Spalte getauscht.\n",Spalte1+1,Spalte2+1);
}
int check_array_spalten (int length)
{
int i_check_spalten = 0;
int i_check_spalten_sub = 0;
int switched_spalte = 0;
for (;i_check_spalten < length; i_check_spalten++)
{
if (lin_var[i_check_spalten][i_check_spalten] == 0)
{
i_check_spalten_sub = i_check_spalten+1;
for (;i_check_spalten_sub < length; i_check_spalten_sub++)
{
if (lin_var[i_check_spalten_sub][i_check_spalten] != 0 && lin_var[i_check_spalten][i_check_spalten_sub] != 0 && lin_var[i_check_spalten][i_check_spalten] == 0 )
swap_spalte(i_check_spalten, i_check_spalten_sub, length);
{
switched_spalte = 1;
}
}
}
}
return (switched_spalte);
}
int check_array_before (int Spalte,int Zeile,int length)
{
int i_check_before = Zeile;
int i_add = 0;
int return_value = 0;
for (; i_check_before < length; i_check_before++)
{
if (lin_var[i_check_before][i_check_before] == 0)
{
i_add = i_check_before+1;
for (;i_add < length ; i_add++ )
{
if (lin_var[i_add][i_check_before] != 0 && lin_var[i_check_before][i_add])
{
swap_lines(i_check_before, i_add, length);
return_value = 1;
}
}
}
}
return(return_value);
}
void check_array_before_inverted (int length)
{
int i_check_before = length;
int i_add = 0;
for (; i_check_before > 0; i_check_before--)
{
if (lin_var[i_check_before][i_check_before] == 0)
{
i_add = i_check_before-1;
for (;i_add > 0 ; i_add-- )
{
if (lin_var[i_add][i_check_before] != 0 && lin_var[i_check_before][i_add])
{
swap_lines(i_check_before, i_add, length);
}
}
}
}
}
void errase_downstairs (Spalte,Zeile,length)
{
int i_errase_spalte = 0;
int i_switch_spalte = 0;
int switched_line = 0;
for (;i_switch_spalte < length-1 ; i_switch_spalte++)
{
switched_line = check_array_before (0, 0, length);
switched_line = check_array_spalten (length);
Spalte = i_switch_spalte;
Zeile = Spalte;
i_errase_spalte = Spalte;
if (switched_line == 1)
{
i_switch_spalte = 0;
i_errase_spalte = 0;
Zeile = 0;
Spalte = 0;
}
else
{
for (;i_errase_spalte < length ; i_errase_spalte++)
{
Zeile = Zeile+1;
calc_add_array(Spalte, Zeile, length);
}
}
}
}
void errase_upstairs (Spalte,Zeile,length)
{
int i_errase_spalte = 0;
int i_switch_spalte = 1;
for (;i_switch_spalte < length ; i_switch_spalte++)
{
Spalte = i_switch_spalte;
i_errase_spalte = 0;
Zeile = Spalte;
for (;i_errase_spalte < Spalte ; i_errase_spalte++)
{
Zeile = Zeile-1;
calc_add_array(Spalte, Zeile, length);
}
}
}
void array_out(int length)
{
int i_out_hor = 0;
int i_out_ver = 0;
for(i_out_ver = 0; i_out_ver < length ; i_out_ver++)
{
printf("\n");
i_out_hor = 0;
for(; i_out_hor < length+1 ; i_out_hor++)
{
printf("%f", lin_var[i_out_ver][i_out_hor]);
printf("\t");
}
}
}
printf("\nSie haben das Programm zur Durchführung des Gaußschen Algorithmus gewählt.");
printf("\nDie Koeffizienten werden von links nach rechts eingelesen.");
printf("\nWobei die jeweilige Spalte die Variablennummer wiedergibt\n\n");
//***********************************************************************************//
//Bestimmen der Anzahl zu berechnender Variablen
printf("\nBitte geben sie die Anzahl der zu berechnenden Variablen an\n");
fflush(stdout);
scanf("%d",&length);
//***********************************************************************************//
//Einlesen des Linearen Gleichungssystems
//***********************************************************************************//
for (i_ver = 0; i_ver < length ; i_ver++) //äußere Schleife zum Einlesen
{
Zeile = i_ver;
printf("\n\nSie befinden sich in der %i. Zeile\n\n\n",i_ver+1);
for (i_hor = 0; i_hor < length+1 ; i_hor++) //innere Schleife um die Zeile einzulesen
{
printf("Bitte geben Sie den %i. Koeffizienten ein\t",i_hor+1);
fflush(stdout);
scanf("%lf",&lin_var[Zeile][i_hor]);
}
}
//printf("Die Anzahl der Variablen %i",length);
//printf("\n\n");
//***********************************************************************************//
//Prüfen nach dem Eingeben des Systems
printf("\nIhr eingegebenes Gleichungssystem\n");
array_out(length);
printf("\n\n");
//***********************************************************************************//
//Erste Prüfung auf Lösbarkeit des Systems
//***********************************************************************************//
Zeile = 0;
Spalte = 0;
check_array_before_inverted (length);
check_array_spalten (length);
//***********************************************************************************//
//Testfeld für das Zeilentauschen
//check_array_before (Spalte, Zeile, length);
//***********************************************************************************//
//Einlesen der Koeffizienten beendet
//Beginn der Berechnung
//***********************************************************************************//
int i_cancel = 0;
int cancel = 0;
for (; i_cancel < length ; i_cancel++)
{
if (lin_var[i_cancel][i_cancel] == 0)
{
cancel = 1;
}
}
if (cancel == 0)
{
errase_downstairs(Spalte, Zeile, length);
Zeile = 0;
Spalte = 0;
errase_upstairs(Spalte, Zeile, length);
printf("\nDas umgeformte Array zur Berechnung der Variablen\n");
array_out(length);
//***********************************************************************************//
//Berechnen und ausgeben der Variablen-Werte
//***********************************************************************************//
printf("\n\n\nDas result_array \n\n");
int i_out_hor_result = 0;
int i_result_array = 0;
for (; i_result_array < length; i_result_array++)
{
result_array[i_result_array] = lin_var[i_result_array][length]/lin_var[i_result_array][i_result_array];
}
for(; i_out_hor_result < length ; i_out_hor_result++)
{
printf("Die %i. Variable ist",i_out_hor_result+1);
printf(" %f", result_array[i_out_hor_result]);
printf("\n");
}
}
if (cancel == 1)
{
printf("\n\nGleichungssystem nicht lösbar!\n");
}
return(0);
}
|
Wenn die Einrückung stimmt, dann sind solche Kommentare
| //Einlesen der Koeffizienten beendet
//Beginn der Berechnung
|
überflüssig. In Übungsbüchern teilen solche Kommentare dem Lernenden etwas mit, aber nicht wie man kommentiert, denn man kommentiert nicht für Anfänger ein Tutorial sondern für Leute, von denen man annimmt dass sie die Sprache kennen Dinge, die ungewöhnlich sind und vielleicht fachlich erklärungsbedürftiges. Die 3 Hauptprobleme des Programmierers sind ja bekanntlich off-by-one Fehler und naming-things. Eine gute Funktion heisst vielleicht "Berechnung", und dann sieht der Code so aus | int berechnung (...)
{
// code
}
eingabe (...)
berechnung (...)
ausgabe (...)
|
nicht
/***************************************/
// eingabe
// code
/***************************************/
// berechnung
// code
/***************************************/
// ausgabe
}}}
Um schnell zu erfassen wovon berechnung abhängig ist, ist eine eigene Funktion bestens geeignet, denn die Schnittselle sagt es, und im Ggs. zu einem Kommentar kann sie nicht lügen, irren, veralten (außer man führt globale Variablen ein - aber das sieht man auch schnell). Außerdem soll eine Funktion nur eine Aufgabe erfüllen, aber diese soll klar abzugrenzen sein und keine Seiteneffekte haben. Ob ein Code Nebenläufigkeit benutzt ist nur zu erkennen, wenn man den gesamten Code analysiert. Mit globalen Variablen kann man daher nie wissen, ob es andere Stellen des Codes gibt, die die Variable, die man gerade analysiert, ändert. Das macht die Analyse von so einem kurzen Code wie Deinem schon nahezu unmöglich. Der, der ihn analysiert, macht das am schnellsten, in dem er ihn umschreibt und dann schaut wo es kracht. So würde ich das machen: Alle Funktionen auslagern. Sehen welche Variablen dann unbekannt sind. Diese reinreichen.
Erraten, was das Ergebnis ist und dieses zurückgeben. Schauen, wie man es in den Code integriert. Wiederverwendung ist auch eine tolle Sache, wenn es nicht Variablen sind. Zählvariablen wiederverwenden ist furchtbar. Man hat eine zusätzliche Variable mit enormer Sichtbarkeit (global) von der man nicht weiß, ob man was kaputt macht, wenn man sie ändert. So soll es nicht sein! Die Sichtbarkeit sollte radikal eingeschränkt sein, so dass die Analyse von Code möglichst leicht ist, dass die Deklaration und Verwendung möglichst eng zusammenliegen. Dass Seiteneffekte vermieden werden. 1
2
3
4
5
6
7
8
9
10
11
12 | for (i_ver = 0; i_ver < length ; i_ver++) //äußere Schleife zum Einlesen
{
Zeile = i_ver;
printf("\n\nSie befinden sich in der %i. Zeile\n\n\n",i_ver+1);
for (i_hor = 0; i_hor < length+1 ; i_hor++) //innere Schleife um die Zeile einzulesen
{
printf("Bitte geben Sie den %i. Koeffizienten ein\t",i_hor+1);
fflush(stdout);
scanf("%lf",&lin_var[Zeile][i_hor]);
}
}
|
i_ver wird hier 0 gesetzt, ohne deklariert zu werden - wahrscheinlich ist es ein Int, würde man raten. Und ein Index, was man üblicherweise, wenn es trivial ist, mit i, j, k ausdrückt. Temporäre Variablen zum iterieren. Macht den Code übersichtlicher.
Gegen Nebenläufigkeit spricht, dass da ziemlich unbeherrschbar wird, was i_ver aktuell ist, also schließen wir das mal aus. Am Ende des Codes ist i_ver=length. Wieso braucht man die Variable i_ver später noch mit diesem Wert? Wahrscheinlich gar nicht, sondern wenn, dann wird sie wieder mit 0 initialisiert um eine andere Schleife zu durchlaufen, aber man weiß es erst, wenn man den Code bis zur nächsten Zuweisung durchsucht hat - eine irre Zeitverschwendung die man bei jeder Codeanalyse neu machen muss, wenn man sich nicht an die letzte erinnert. In größeren Codebeständen völlig unmöglich. | for (int i = 0; i < length ; i++)
{
Zeile = i;
printf("\n\nSie befinden sich in der %i. Zeile\n\n\n", i+1);
for (j = 0; j < length + 1 ; j++)
{
printf ("Bitte geben Sie den %i. Koeffizienten ein\t",j+1);
fflush (stdout);
scanf ("%lf", &lin_var [Zeile] [j]);
}
}
|
Zeile kommt auch wie ein Deus Ex Machina über uns. Am Ende der äußeren Schleife wird Zeile=length sein - ist das von Bedeutung für die darauf folgende Verwendung von Zeile? Zumindest hier wird Zeile nirgends mehr überschrieben, aber i auch nicht - wieso wird also i verdoppelt?
| for (int i = 0; i < length ; i++)
{
printf("\n\nSie befinden sich in der %i. Zeile\n\n\n", i+1);
for (int j = 0; j < length + 1 ; j++)
{
printf ("Bitte geben Sie den %i. Koeffizienten ein\t",j+1);
fflush (stdout);
scanf ("%lf", &lin_var [i] [j]);
}
}
|
Als Arrayindex reicht i/j völlig aus, z/s oder r/c für Zeile/Spalte oder row/column wären etwas besser, weil man eine bessere Vorstellung davon hat, was was ist, und x/y sind natürlich auch prima. Wer diesen Code sieht mit lokalem i, j der weiss sofort, dass i und j später out of scope sind, und deren Endzustand keiner Überlegung wert sind. lin_var dagegen ist etwas knapp benannt. Variablen-des-linearen-Gleichungssystems sind wohl gemeint, aber wenn es nur ein solches gibt wäre matrix vielleicht keine schlechte Wahl. Variablen werden qua Konvention durchgängig klein geschrieben, auch wenn man sie deutsch benennt und es Substantive sind. Also wenn, dann zeile. Hat aber alles nichts mit Deinem Problem zu tun. ☺ Ich kann es nur nicht mitansehen, ohne was zu sagen. ☺
|
Zechpreller
(Themenstarter)
Anmeldungsdatum: 27. Dezember 2012
Beiträge: 39
|
Ich sehe du hast einige Fehler in meinem Code gefunden. Zwecks den Kommentaren die habe ich lediglich eingefügt (ich weiß es klingt verrückt) aber mein Betreuer beherrscht kein C, er hat
lediglich die Aufgabe gestellt Algorithmen in eine Programmiersprache zu implementieren und ich hab C ausgewählt, da ich damit schon etwas
Erfahrung hatte. Einige gute Sachen die du angeschnitten hast, ich werde wohl meine ganzen Deklarationen noch einmal überarbeiten müssen. Ich bin dir sehr dankbar dafür es soll ja auch nach etwas aussehen, hab mir das programmieren eben nur selbst beigebracht und das wohl
eher schlecht als recht. Ich werde wohl lieber mal meinen gesamten Code überarbeiten und dann würde ich ihn nochmal reinstellen damit alles seine Richtigkeit hat.
Möchte ja dass das alles seine Ordnung hat. Ich hab es jetzt auch mal ohne IDE ausgeführt, selbes Spiel wie vorher. Ich meld mich nochmal wenn ich meinen Quellcode überarbeitet habe.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17604
Wohnort: Berlin
|
Tja, ich habe eine Formatierung verschlampt, ich korrigiere kurz:
Eine gute Funktion heisst vielleicht "Berechnung", und dann sieht der Code so aus
| int berechnung (...)
{
// code
}
eingabe (...)
berechnung (...)
ausgabe (...)
|
nicht
| /***************************************/
// eingabe
// code
/***************************************/
// berechnung
// code
/***************************************/
// ausgabe
|
Solche Kommentarsternblöcke sind außerdem 70er-Jahre-Stil, als der Editor noch keine Farbhighlights hatte. Heutige Editoren heben Kommentare farblich hervor. Was ja auch arg ist: |
double calc_mult_var (int Spalte, int Zeile,int length) //mult Variable Deklaration
{
double calc_mult_var = lin_var[Zeile][Spalte]/lin_var[Spalte][Spalte]*(-1);
return(calc_mult_var);
}
|
Hier verdeckt die Deklaration von Spalte, Zeile die äußeren Variablen Zeile, Spalte. Da ist die Fehlinterpretation vorprogrammiert. Solche Einrückungen
| for (;i_check_spalten_sub < length; i_check_spalten_sub++)
{
if (lin_var[i_check_spalten_sub][i_check_spalten] != 0 && lin_var[i_check_spalten][i_check_spalten_sub] != 0 && lin_var[i_check_spalten][i_check_spalten] == 0 )
swap_spalte(i_check_spalten, i_check_spalten_sub, length);
{
switched_spalte = 1;
}
}
|
wie in int check_array_spalten (int length) sind dubios. Es sieht aus, als sei switched_spalte = 1; vom vorgehenden if abhängig, aber in Wahrheit ist es nur ein überflüssiger Scope.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Ich frage mich irgend wie, wie das überhaupt funktionieren kann... in Zeile 14 steht ja nur folgendes:
Muss da nicht eine Initialisierung stattfinden? Ansonsten kann legnth doch *irgend einen* vom Compiler (oder der Sprachdefinition) bestimmten Wert haben - und vor allem: immer denselben. Was wenn der Benutzer ein größeres System eingibt, als das Array groß ist? Ich bekomme unter Arch Linux übrigens sofort einen segmentation fault (mit dem Code von user unknown):
| gcc gauss.c -o gauss :(
./gauss
[1] 1758 segmentation fault (core dumped) ./gauss
|
|
Zechpreller
(Themenstarter)
Anmeldungsdatum: 27. Dezember 2012
Beiträge: 39
|
Lysander schrieb: Ich frage mich irgend wie, wie das überhaupt funktionieren kann... in Zeile 14 steht ja nur folgendes:
Muss da nicht eine Initialisierung stattfinden? Ansonsten kann legnth doch *irgend einen* vom Compiler (oder der Sprachdefinition) bestimmten Wert haben - und vor allem: immer denselben. Was wenn der Benutzer ein größeres System eingibt, als das Array groß ist?
Naja ich deklariere die Variable lediglich und weise ihr dann mithilfe von scanf einen Wert zu, und dass ich ihr sofort einen Wert zuweisen muss hab ich noch nicht gehört. Ja ich muss den Code wirklich mal gründlich überarbeiten, bin momentan noch dabei.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Zechpreller schrieb: Naja ich deklariere die Variable lediglich und weise ihr dann mithilfe von scanf einen Wert zu, und dass ich ihr sofort einen Wert zuweisen muss hab ich noch nicht gehört.
Muss man ja auch nicht, aber hier nutzt Du ja die *nicht* initialisierte Variable, um damit die Array-Grenzen zu definieren. Und das dürfte so sicherlich nicht gewollt sein, oder 😉
Ja ich muss den Code wirklich mal gründlich überarbeiten, bin momentan noch dabei.
Ich würde ja bei solchen Datenstrukturen auf die Glib setzen; das ist eine Art STL für C. Damit hast Du neben *dynamischen* Sammlungen auch einheitliche APIs für das Iterieren usw. Naja, und ich hätte wohl letztlich auch kein C gewählt 😎
|
Zechpreller
(Themenstarter)
Anmeldungsdatum: 27. Dezember 2012
Beiträge: 39
|
Ich weiß es sind viele Fehler, eher unglaublich viele Fehler darin, aber ihr müsst das mal von der Seite betrachten dass ich mich vor einiger Zeit sehr für das Programmieren und Computer zu interessieren begann sofort einen Arduino gekauft habe und losgelegt habe. Es ist wirklich schwer bei sowas einen Fuß in die Tür zu kriegen besonders wenn man keinen Ansprechpartner für so Sachen wie Strukturierung des Programms hat. Ich hab mir vorgenommen jetzt erst einmal alle Funktionen auszulagern und einzubinden. Das Problem in meinem Programm habe ich gerade gefunden und zwar habe ich Trottel mein Array vor dem einlesen der length Variable deklariert. Danke für eure Tipps ich werde den Thread dann auch schließen bevor ich mich weiter blamiere :'D
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: 2669
Wohnort: Hamburg
|
Wieso blamieren? Fehler macht jeder und zu Fragen sind wir hier doch da ☺ Es kommt halt immer drauf an, woran man so interessiert ist, aber es gibt sicherlich eine Menge Sprachen, die den Einstieg ins Programmieren einfacher machen als C. Bei anderen Sprachen würde ich Dir jetzt Unittests an Herz legen, aber da ich für C keine solche Lib jemals selber genutzt habe, lasse ich das mal besser 😬 Aber die Glib würde ich Dir dennoch empfehlen! Das macht es auf Dauer definitiv einfacher, in C mit Sammlungen zu arbeiten ☺
|
Zechpreller
(Themenstarter)
Anmeldungsdatum: 27. Dezember 2012
Beiträge: 39
|
Joa vielleicht hab ich mir hier wirklich was schwieriges ausgesucht, jedoch hab ich mich vorher viel mit Python beschäftigt das hat mir sehr gut gefallen, da ich nebenbei noch viel an meinem Raspberry Pi mache. Und vielleicht ist es schwierig aber ich bin jetzt schon einigermaßen im Syntax von C fit und damit hab ich ne große Hürde genommen wie ich finde, und bevor ich mich in eine weitere Programmiersprache stürze möchte ich mich in C jetzt noch etwas beweisen. Danach wollte ich sowieso in Richtung Webserver mehr machen, also so Sachen wie ne eigene Cloud aufsetzen ein Forum das dann auch einrichten verwalten das finde ich noch sehr interessant. Und meine eigenen Seiten da auch zu erstellen also mich in html & php einzuarbeiten. Aber das gehört ja weniger in diesen Thread ☺ und nochmal danke für eure Hilfe und Verständnis.
|