Nabend. Muss ja jetzt hier an der Uni C machen. Wir haben jetzt so ne schöne Aufgabe bekommen ein kurzes Codefitzelchen von seinen Fehlern zu befreien. Als alter Streber und C64 Coder frage ich mich gerade, ob Kürzungen bei C auch Einfluss auf das kompilierte Programm haben.
D.h. wird das kompilierte File kleiner, wenn ich in einer Variablendeklaration bereits einen Wert zuweise und nicht erst irgendwo im Programm.
Oder, was ich besonders spannend finde:
Nehmen unterschiedliche Schleifentypen mehr oder weniger Platz weg beim Kompilat?
Hallo Besucher, der Thread wurde 4,7k mal aufgerufen und enthält 24 Antworten
letzter Beitrag von sauhund am
-
-
Probiers doch aus. Assembler-Code ankucken hat noch keinem geschadet.
-
die antwort ist natürlich ja zu allem weiteres erfährst du aber wirklich nur durch disassemblieren und ausprobieren.
-
D.h. wird das kompilierte File kleiner, wenn ich in einer Variablendeklaration bereits einen Wert zuweise und nicht erst irgendwo im Programm.
Nein, normal nicht, außer der Compiler ist schlecht designedOder, was ich besonders spannend finde:
Nehmen unterschiedliche Schleifentypen mehr oder weniger Platz weg beim Kompilat?
Ja, unter Umständen schon, weil andere Assemblerbefehle verwendet werden -
Insbesondere bei eingeschalteter Optimierung fliegt oft mehr Stuss raus, als man denkt. Mach die ersten Tests mal ohne Optimierung, dann siehst Du, dass selbst marginale Änderungen wie "for (i = 0; i < 5; i++)" vs. "for (i = 0; i < 5; ++i)" unterschiedlich "guten" Code erzeugen.
Und ja, das Assembler-Listing ansehen kann sehr interessant sein.
-
Jau, Danke. Das reicht schon als Antwort
-
Hier noch 'ne Schaltjahr-Berechnung in C++:
(Hochoptimiert, natürlich!)// Schaltjahrberechnung
// by Lady Gaga 11/2009
#include <iostream>
using namespace std;
int main (void) {
int jahr, i, k=0;
cout<<“Jahr eingeben: “;
for ( i=1, k=0, scanf(”%i”,& jahr) ;
k = (0==jahr%4 && ( 0 != jahr % 100 0==jahr % 400 )), i <= 1 ;
i++ ) {cout <<“Schaltjahr: “; k==1?cout<<“ja”:cout<<“nein”; };
} -
(Hochoptimiert, natürlich!)
Da gibt's nur noch eine fehlende Optimierung: indent -
Sorry, noch eine:
k==1?cout<<“ja”:cout<<“nein”
besser:
cout<<(k?“ja”:“nein”)
-
Geht sicher noch mehr, aber für auf die Schnelle
Und for allem stellt sich die Frage: Erkennt der Kompiler den "Missbrauch" der For-Schleife und optimiert das weg? Fragen über Fragen...
-
Und for allem stellt sich die Frage: Erkennt der Kompiler den "Missbrauch" der For-Schleife und optimiert das weg? Fragen über Fragen...
"for (a;b;c) { foo; }" ist in C nur eine bequeme Art um "a; while (b) { foo; d; }" hinzuschreiben. Bei dieser Konstruktion würde ich ansonsten darauf tippen, dass ein hinreichend neuer gcc mit aktiver Optimierung erkennt, dass die Schleife nur einmal durchlaufen wird. -
Doch noch ne kurze Frage. Etwas anderes Thema, aber kein Bock einen neuen Thread aufzumachen.
Geht um Variablentypen. Muss hier ne Aufsummierung machen von:
1 / i^2 (von i=1 bis i=n).für n und i "reichen" ja eigentlich Integerzahlen, nur für die Summe braucht man eigentlich float.
Dennoch krieg ich immer 1 raus, wenn ich i als int definiere. Mit i als float gehts. Warum? -
Und for allem stellt sich die Frage: Erkennt der Kompiler den "Missbrauch" der For-Schleife und optimiert das weg?
Das ist doch kein Missbrauch, das ist Kunst! (Oh, der Thread entgleist wieder. Und dabei hat er so gut gestartet )Zitatdass ein hinreichend neuer gcc mit aktiver Optimierung erkennt, dass die Schleife nur einmal durchlaufen wird.
Ich hatte mal einen Fehler in einem Program, der dazu geführt hat, dass ein paar Zeilen weiter unten die Schleife nie durchlaufen wurde (Abbruchbedingung hat immer gezogen). Hab ich mich gewundert, warum das Assemblerlisting der Funktion so kurz war -
Warum?
Na rechne das doch mal per Hand aus:1 / ( i * i ) ;
(Tip: Im Integer-Bereich bleiben, also Nachkommastellen wegschmeißen) -
Doch noch ne kurze Frage. Etwas anderes Thema, aber kein Bock einen neuen Thread aufzumachen.
Geht um Variablentypen. Muss hier ne Aufsummierung machen von:
1 / i^2 (von i=1 bis i=n).
Ah, Zahlenreihen. Das löst man natürlich rekusiv!
für n und i "reichen" ja eigentlich Integerzahlen, nur für die Summe braucht man eigentlich float.
Dennoch krieg ich immer 1 raus, wenn ich i als int definiere. Mit i als float gehts. Warum?Was für ein Kompiler? Evtl musst du das explizit casten, wenn das implizite nicht korrekt greift. Siehe:
-
(Tip: Im Integer-Bereich bleiben, also Nachkommastellen wegschmeißen)
Ja, das ist mir schon klar. Wie gesagt: die Variable "summe" muss definitiv als float definiert werden.
Warum aber i auch? i hat doch immer ganzzahlige Werte. Das Ergebnis nicht, das ist klar.EDIT:
@Lady Gaga: GCC -
@Lady Gaga: GCCWenn du einen Float durch einen Integer teilst, was soll der Compiler dann machen?
1.) float -> integer, integer durch integer
2.) integer -> float, dann float durch float
das weiss er ja nicht, deswegen macht er das nächstbeste. In so einem Fall immer sicherheitshalber casten. -
Ja, das ist mir schon klar. Wie gesagt: die Variable "summe" muss definitiv als float definiert werden.
Warum aber i auch? i hat doch immer ganzzahlige Werte. Das Ergebnis nicht, das ist klar.
Weil in C und C++ eine Division von zwei ganzzahligen Zahlen ganzzahlig durchgeführt wird. Deswegen musst Du explizit casten. -
Weil in C und C++ eine Division von zwei ganzzahligen Zahlen ganzzahlig durchgeführt wird. Deswegen musst Du explizit casten.
Worin besteht dann konkret der Unterschied, ob ich i direkt als float definiere oder eben an der Stelle explizit caste?
-
Zitat
das weiss er ja nicht, deswegen macht er das nächstbeste. In so einem Fall immer sicherheitshalber casten.
natürlich macht er NICHT das "nächstbeste", sondern er macht das nach genau festgelegten regeln.und ohne die jetzt weiter erklären zu wollen sollte man einfach im hinterkopf behalten das in C im zweifelsfall _alles_ implizit nach int gecastet wird. das ergebnis irgendeines ausdrucks in dem ein int vorkommt wird auch wieder zu einem int, auch wenn ein float drin ist.