C semikolon fehlt?!

freddmann

Ensign
Registriert
Sep. 2005
Beiträge
241
hallo, ich bin hier gerade am verzweifeln. mir wird gesagt, das ein semikolon fehlt, und zwar in der zeile, wo die int main(void) anfängt. folglich muss der fehler ja vorher liegen, aber ich finde ihn nicht:(;)

die genaue fehlermeldung lautet:
Fehler 5 error C2143: Syntaxfehler: Es fehlt ';' vor 'Typ'


Code:
#include <stdio.h>

void matrixauslesen_neu(float *max, float *positionx, float *positiony) {
	FILE *datei;
	float matrix[6][6], maxDerMatrix = 0;
	int zeile,spalte;
	

	datei = fopen("matrix.txt", "r");
	if(datei != NULL) {
		for(zeile=0;zeile<5;zeile++) {
			for(spalte=0;spalte<5;spalte++) {
				fscanf(datei, "%f", &matrix[zeile][spalte]);
				if(matrix[zeile][spalte]>maxDerMatrix) {
					*max = matrix[zeile][spalte];
					*positionx = zeile;
					*positiony = spalte;
				}
			}
	} 


int main(void) {
int a;
	float max,positionx, positiony;
	matrixauslesen_neu(max, positionx, positiony);
	printf("das maximum lautet: %f und ist an position x=%f und y=%f\n", max, positionx, positiony); 
	printf("zum beenden was eingeben und enter druecken\n");
	scanf("%d", &a);
}
 
Du hast zwei "}" vor dem "int main" vergessen. Du öffnest 5 Klammern, schließt aber nur 3.
 
Das kommt davon wenn man öffnende und schließende Klammern nicht untereinander schreibt :rolleyes:.

Ist "Zeilensparen" das wert?
PHP:
// irgendwie übersichtlich
void function( void )
{
   for( ... )
   {
      if( ... )
      {
         ...
      }
   }
}

// irgendwie unschön
void function( void ) {
   for( ... ) {
      if( ... ) {
         ...
      }
   }
}
Ist aber ein absoluter Glaubenskrieg (Stichwort: Programmierstil). Es sollen deswegen schon Freundschaften zerbrochen sein :freak:.
 
Ich bevorzuge zweiteres und finde ersteres unschön :)

Eine ordentliche IDE setzt die Klammern ohnehin automatisch, bzw. weist daraufhin, dass eine Klammer fehlt.

Und btw, der Autoformater in Eclipse setzt standardmäßig auch die Klammern in die selbe Zeile.
 
Boron schrieb:
Ist aber ein absoluter Glaubenskrieg (Stichwort: Programmierstil).
Die ganz harten machen es dann so:
Code:
void function() {
   for( ... ) {
      if( ... ) {
         ...
      } // end if
   } // end for
} //end function

Ich bevorzuge auch die öffnende Klammer in einer separaten Zeile, aber manchmal muss man sich leider bestehenden Richtlinien anpassen.
 
@snow1: Das lässt sich aber mit wenigen klicks ändern. Je aufwändiger der Code, deto unübersichtlicher wird er. Ich schreib dann auch öfters hin wo was aufhört. Da löscht man nichts ausversehen :)
 
Nebuk schrieb:
@snow1: Das lässt sich aber mit wenigen klicks ändern. Je aufwändiger der Code, deto unübersichtlicher wird er. Ich schreib dann auch öfters hin wo was aufhört. Da löscht man nichts ausversehen :)

Wenn man keine gigantischen Methoden baut, wird auch nichts so schnell unübersichtlich. Wenn doch ist ohnehin Refactoring angesagt.

Ein guter Richtwert ist, wie ich finde, dass Methoden nicht länger als 1, maximal 2 Bildschirmseiten lang sind. Dann klappts auch mit der Übersicht :)
 
Sehe ich auch so, wobei eine komplette Bildschimseite schon grenzwertig ist. Leider habe ich häufig mit Code zu tun, in dem Funktionen mit 5000, 10000 und mehr Zeilen keine Seltenheit sind. :freak:
 
Naja, ein Bildschirminhalt ist ja immer von der Auflösung des jeweiligen Bildschirmes abhängig.
Für jemanden, der mit einem 24" Monitor arbeitet, wären das dann ca. 50 Zeilen und jemand, der einen kleineren Monitor hat, vielleicht 30 Zeilen.
Daher würde ich eher als Richtlinie 40 max. 50 Zeilen nehmen. Das sollte eigentlich genug Zeilen sein.
Wenn das nicht reichen sollte, würde ich mir schon Gedanken machen, ob man bestimmte Dinge nicht eher in eine Prozedur/Funktion/Methode ausgrenzen kann. Aber selbst dann kann es doch manchmal recht unübersichtlich werden. Darum sollte man sich auch schnellstmöglich angewöhnen detaillierte Kommentare und Funktions-/Methodenköpfe zu schreiben. Dass, was ich von Programmierern mit mehrjähriger Erfahrung manchmal sehe, ist ein Graus.

allein sowas
Code:
if (datei != NULL) { ...}
würde mich persönlich schon ein wenig aufregen, weil was interessiert mich, ob der Zeiger ungleich NULL ist? Ich möchte wissen, ob die Datei gelesen werden kann. Ich würde da einfach
Code:
if (datei) { ... }
schreiben. Es liest sich semantisch einfach besser, sind weniger Zeichen und dies ist sogar ein wenig performanter. Das obere würde man "Wenn Datei ungleich NULL" und das untere "Wenn Datei" lesen. Es sind immer solche Kleinigkeiten, die das Leben eines Programmierers erheblich erleichtern.
 
Zuletzt bearbeitet:
@Whiz-zarD: Da muss ich dir sogar widersprechen. Ich finde den Ausdruck "if (datei != NULL)" aussagekräftiger. Ein erhebliches Erleichtern sehe ich durch das weglassen von "!= NULL" ehrlich gesagt nicht.

Und hast du Quellen für einen Unterschied in der Performance?

Im Grunde wäre es sogar denkbar, eine Funktion zu schreiben (oder nen Makro oder sonst was...)
Code:
bool isFileOpen(FILE* file)
{
  return file != NULL;
}
Mag sinnlos aussehen... aber da erkennt nunmal jeder was man will

Code:
if (isFileOpen(datei)) {

}

Und nochmal zum Thema Performance: Optimieren ja, aber nur dort wo es sinnvoll ist. Kann sogar sein, dass ein Compiler sogar den selben Code macht, wenn man diese Funktion hat...
 
1668mib schrieb:
Und hast du Quellen für einen Unterschied in der Performance?

Ne Quelle hab ich nicht direkt.
Die Aussage kommt von meinem Dozenten, der auch mit Assembler programmiert. Er hat es mal nebenbei erklärt aber so ganz bekomm ich das grad nicht auf die Reihe. Ich weiß nur noch, dass beim Ungleich mehrere Prozessorinstruktionen von Nöten sind.
Sicherlich, es ist nur eine minimale Optimierung die gar nicht ins Gewicht fällt.

Warum sollte (datei != NULL) aussagekräftiger sein?
Ich will ja nicht wissen, ob der Zeiger ungleich NULL ist, sondern ob der Zeiger auf eine Adresse zeigt. Wenn er es nicht tut, ist er automatisch NULL und somit auch die If-Anweisung false. Im Endeffekt ist zwar alles das selbe aber es liest sich semantisch einfach besser und dies hab ich mittlerweile schon von diversen Professoren bestätigt bekommen.
 
Also daß es performance-mäßig zwischen if ( file ) und if ( file != 0 ) auch nur den geringsten Unterschied gibt, wage ich jetzt mal zu bezweifeln, wenn wir davon ausgehen, daß file vom Typ FILE* ist. Der Compiler sollte da meiner Meinung den exakt gleichen Code erstellen.
Ich persönlich zähle mich auch ins Lage derer, die if ( file ) für schöner halten als if ( file != 0 ). Aber letzten Endes ist das wohl bloße Geschmackssache.


P.S. Versuch mit Visual C++ 2010:

if ( file )

Code:
--- c:\temp\test\test\main.cpp -------------------------------------------------
#include <cstdio>
#include <iostream>

int main()
{
00171000  push        ebp  
00171001  mov         ebp,esp  
00171003  and         esp,0FFFFFFF8h  
00171006  push        ecx  
00171007  push        esi  
	FILE* const file = std::fopen( "bla.txt", "r" );
00171008  push        offset string "r" (172124h)  
0017100D  push        offset string "bla.txt" (172128h)  
00171012  call        dword ptr [__imp__fopen (1720C8h)]  
00171018  mov         esi,eax  
0017101A  add         esp,8  

	if ( file )
0017101D  test        esi,esi  
0017101F  je          main+55h (171055h)  
	{
		std::cout << "bla" << std::endl;
00171021  mov         eax,dword ptr [__imp_std::endl (172044h)]  
00171026  push        eax  
00171027  push        ecx  
00171028  mov         ecx,dword ptr [__imp_std::cout (17205Ch)]  
0017102E  push        offset string "bla" (172130h)  
00171033  push        ecx  
00171034  call        std::operator<<<std::char_traits<char> > (171110h)  
00171039  add         esp,0Ch  
0017103C  mov         ecx,eax  
0017103E  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (17204Ch)]  
		std::fclose( file );
00171044  push        esi  
00171045  call        dword ptr [__imp__fclose (1720C4h)]  
0017104B  add         esp,4  
	}

	return 0;
0017104E  xor         eax,eax  
}

if ( file != 0 )

Code:
--- c:\temp\test\test\main.cpp -------------------------------------------------
#include <cstdio>
#include <iostream>

int main()
{
00AF1000  push        ebp  
00AF1001  mov         ebp,esp  
00AF1003  and         esp,0FFFFFFF8h  
00AF1006  push        ecx  
00AF1007  push        esi  
	FILE* const file = std::fopen( "bla.txt", "r" );
00AF1008  push        offset string "r" (0AF2124h)  
00AF100D  push        offset string "bla.txt" (0AF2128h)  
00AF1012  call        dword ptr [__imp__fopen (0AF20C8h)]  
00AF1018  mov         esi,eax  
00AF101A  add         esp,8  

	if ( file != 0 )
00AF101D  test        esi,esi  
00AF101F  je          main+55h (0AF1055h)  
	{
		std::cout << "bla" << std::endl;
00AF1021  mov         eax,dword ptr [__imp_std::endl (0AF2044h)]  
00AF1026  push        eax  
00AF1027  push        ecx  
00AF1028  mov         ecx,dword ptr [__imp_std::cout (0AF205Ch)]  
00AF102E  push        offset string "bla" (0AF2130h)  
00AF1033  push        ecx  
00AF1034  call        std::operator<<<std::char_traits<char> > (0AF1110h)  
00AF1039  add         esp,0Ch  
00AF103C  mov         ecx,eax  
00AF103E  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0AF204Ch)]  
		std::fclose( file );
00AF1044  push        esi  
00AF1045  call        dword ptr [__imp__fclose (0AF20C4h)]  
00AF104B  add         esp,4  
	}

	return 0;
00AF104E  xor         eax,eax  
}

Legt man beide Versionen in einem Diff nebeneinander, sind keine relevanten Unterschiede zu erkennen.
 
Zuletzt bearbeitet:
Kann auch sein, dass ich es grad mit einer anderen Programmiersprache verwechsel.
Ich war der Meinung, dass es in der C-Vorlesung vor kam. Kann auch sein, dass er es bezüglich zu Delphi, in der jeweiligen Delphi-Vorlesung, erwähnte.
 
Im Grunde find ich das schönste eh, wenn man dabei mit Exceptions arbeitet... (schon klar, dass es diese in C nicht gibt)
 
Also Gleichheit oder Ungleichheit macht nur wirklich keinen Unterschied :) In Assembler wird das dann wohl ein JE bzw. JNE.

Und seien wir mal ehrlich, nützt es irgendwem 5 Clock-Cycles zu sparen in einer Zeile die eh nur ein mal aufgerufen wird? Gerade bei den heutigen Prozessoren. Die Wenigsten hier werden im HPC-Bereich arbeiten. Stattdessen ist es wichtiger, dass man lesbaren Code produziert.
Ergänzung ()

antred schrieb:
Leider habe ich häufig mit Code zu tun, in dem Funktionen mit 5000, 10000 und mehr Zeilen keine Seltenheit sind. :freak:

Wer bitte schreibt Funktionen mit 10000 Zeilen Code?? :freak:
 
antred schrieb:
Hier stand ein riesiges "Fullquote"

Nicht ganz..
The controlling expression of an if statement shall have scalar type.
In both forms, the first substatement is executed if the expression compares unequal to 0.
In the else form, the second substatement is executed if the expression compares equal to 0. If the first substatement is reached via a label, the second substatement is not
executed.
So steht es im Standard.. der Grund warum der verwendete Compiler den gleichen Code produziert ist die Optimierung des Compilers.. Ein naiver Compiler könnte aus if ( file != 0 ) auch ein if ( (file != 0) != 0 ) konstruieren.

In einer realen Umgebung ist der Unterschied allerdings irrelevant, da vermutlich alle modernen Compiler daraus den gleichen Code generieren.
 
Zuletzt bearbeitet von einem Moderator:
1668mib schrieb:
@Whiz-zarD: Da muss ich dir sogar widersprechen. Ich finde den Ausdruck "if (datei != NULL)" aussagekräftiger. Ein erhebliches Erleichtern sehe ich durch das weglassen von "!= NULL" ehrlich gesagt nicht.
Hängt von Kontext und Semantik ab. Es muss ja nicht immer ein Zeiger sein. Es gibt auch Leute, die schreiben bei bool
Code:
if (datei_lesbar == true)
Da finde ich
Code:
if (datei_lesbar)
völlig ausreichend und übersichtlicher.

Und ja, ein Makro oder eine Inline Funktion, die das "!= NULL" kapselt, kann auch für mehr Übersichtlichkeit sorgen. Ob man das "!= NULL" weglässt oder nicht, macht für den Compiler übrigens keinen Unterschied. Der erstellt den gleichen Code.


Ansonsten, zur Stilfrage kann ich Boron nur zustimmen. Die Allman Schreibweise ist auch mein Favorit und hat sich in vielen Jahren bewährt.
 
ok gut daran lags also... kann man bei visual studio 2010 iwo einstellen, dass die klammern autoamtisch gesetzt werden?

und wie handhabe ich eine funktion, bei der ich mehrere funktionswerte zurückgegeben bekomme? ich habe iwie keine ordentlich beschreibung gefunden. sondern nur was gefunden, wo es mit den sternen gemacht wurde. aber funktionieren will das beim obigen quelltext nicht:(
 
IceMatrix schrieb:
Ein naiver Compiler könnte aus if ( file != 0 ) auch ein if ( (file != 0) != 0 ) konstruieren.

Das scheint mir jetzt ein bißchen an den Haaren herbeigezogen. Ich schätze, der Standard schließt auch nicht aus, daß irgend ein Spielzeugcompiler 20 nop's generiert, bevor der eigentliche if-Ausdruck ausgewertet wird.
 
snow1 schrieb:
Ergänzung ()

Wer bitte schreibt Funktionen mit 10000 Zeilen Code?? :freak:

Ich bin einmal so frech und antworte für antred.

Vor allem im SAP Umfeld kommt das leider noch zu oft vor.
 
Zurück
Oben