Debugger in XCode

T

Thomas_xp

Aktives Mitglied
Thread Starter
Dabei seit
05.04.2006
Beiträge
632
Reaktionspunkte
13
Hallo.

Ich habe mal einen schnelle Frage an die Profis hier. Ich habe mit XCode ein neues Projekt gestart. Ein Command-Line-Utility. Also ein ganz einfach C Programm. Nun möchte ich zu sehen wie Schritt für Schritt, also jeder Zeile nach einander, vom Programm durchlaufen wird.

1) Geht das? Und wie?
2) Was bedeuten die ganzen Dinge in den einzelen Teilen des Debugger-Fensters? Weil außer scanf und main sehe ich da nicht viel.

Ich habe mich zwar in der Helpdatei eingelesen aber weiter geholfen hat es nicht. Ich wäre für jede Hilfe von euch dankbar.
 
1) Geht das? Und wie?
Klar geht das. Allerdings musst Du zuerst einen Breakpoint setzen. Bei den meisten GUI Programmen wäre es ziemlicher Unsinn, von Anfang an alle Befehle durchzusteppen, also muss Du sagen, ab wo gestoppt werden soll.
Und ab da mit Step Into oder Step over.

2) Was bedeuten die ganzen Dinge in den einzelen Teilen des Debugger-Fensters? Weil außer scanf und main sehe ich da nicht viel.

scanf ? Von welchem Fenster reden wir?

Alex
 
na in der GDB. Ich bin jetzt schon mal einen Schritt weiter. Breakpoints gesetzt. Aber das wichtige war die Standard I/O. weil da muss ich ja Werte für das Programm eingeben. Jetzt hab ich es auch so mehr oder weniger. Jetzt muss ich nur noch das Programm verstehen.

Kannst du mir da vielleicht helfen. Es geht um Recursion.

int factorial(int num)
{
int ans=1;
if (num == 1 ) return;
printf("num ist %d; ans ist %d\n", num, ans);
ans = num * factorial(num-1);
printf("num ist %d; ans ist %d\n", num, ans);
return ans;
}

ICh verstehe nicht, warum "num" sagen wir per scanf eingegeben als 5 runter zählt bis 1 und dann wieder hoch. Ich verwürde es verstehen, wenn die IF Anweisung nicht zu komisch gerschieben wäre. Was hat es mit dem return auf sich? UNd wo bitte ist die else Anweisung?
 
wo zählt num denn wieder hoch??
da das ganze die Fakultät berechnen soll, wird bei einem Ausgangswert von 1 sofort die 1 zurückgegeben (1!=1)
 
Habs jetzt. Ja, es gibt 1 auf weil 1!, Aber das ist ja der fünfte recusive aufruf. ANS 1, 2, 6, 24, 120. Ich schnall das noch nicht so auf anhieb. Ich frag mich wie ich auf sowas kommen soll? Wie soll ich sehen, dass ich vor einem Problem stehe, welches ich geschickt durch Rekursion lösen kann?

Weil: Fakultät ausrechnen. Ich habs so gelöst:
int factorial(int num)
{
int count, ans=1;
for (count=1 ; count <= num; count++ ) ans *= count;
return ans;
}
Nennt sich Iteration. Warum keine Ahnung. Das ist einfach mein Lösungsansatz gewesen.

Nun aber die Rekursion:
int factorial(int num)
{
int ans=1;
if (num == 1 ) return;
printf("num ist %d; ans ist %d\n", num, ans);
ans = num * factorial(num-1);
printf("num ist %d; ans ist %d\n", num, ans);
return ans;
}

Wie soll ich auf soetwas kommen?
 
Soll das also heißen, dass ich jede "Aufgabe", die ich iterativ z.B. mit einer for-Schleife gelöst habe auch rekursiv lösen kann?
Wo wäre denn da der Vorteil? Iterativ verbraucht doch weniger Systemresourcen oder nicht? Was ist der Vorteil einer Rekursion und so bietet es sich an eine Rekursion anderen Lösungen vorzuziehen?
 
Soll das also heißen, dass ich jede "Aufgabe", die ich iterativ z.B. mit einer for-Schleife gelöst habe auch rekursiv lösen kann?
Ich will jetzt mein Diplom nicht riskieren, aber ich glaube, Rekursion und Iteration sind Äquivalent.

Wo wäre denn da der Vorteil? Iterativ verbraucht doch weniger Systemresourcen oder nicht?

Rekursionen erlauben den "Divide et Impera" Ansatz, also das Zerlegen eines Problems in kleine, schöne, überschaubare Einheiten. Man kann das "Türme von Hanoi" Problem auch iterativ lösen, sieht aber nicht so schick aus.

Alex
 
Wenn das alles ist, schmeiß ich mich weg. Denn dann ist Rekursion total nutzlos, weil es einfach mehr Resourcen verbraucht. Und bei einem richtigen Programmierer sind Prioritäten klar. Und da steht funktionsfähigkeit mit möglichst wenig Resourcen auf jeden Fall vor "Schönheit"
 
Und bei einem richtigen Programmierer sind Prioritäten klar. Und da steht funktionsfähigkeit mit möglichst wenig Resourcen auf jeden Fall vor "Schönheit"

Ach, Du programmierst in Assembler?

Alex

EDIT: Ein bischen Background, primitive Rekursionen lassen sich tatsächlich effizienter mit Iterationen umsetzen. Dass die iterative Lösunge einer nicht-primitiven Rekursion weniger Platz oder Zeit braucht bitte ich zu beweisen.
 
Zuletzt bearbeitet:
@below: Nein. Kein Assembler. Schau dir das "Programm" ober doch mal an. Die Fakultät ausrechnen. Mit Rekursion müssen die jeweiligen Aufrufe ja gespeichert werden, bis der letzte Aufruf mit Ergebniss aufartet und dieses an die vorherigen Aufrufe übergibt. Somit wir wesentlich mehr Speicher verbraucht, da sich der Rechner ja die Vorschritte/Zwischenschritte merken muss. Beim Itertiven Ansatz wird ja ein Ergebnis zurückgegeben, mit welchen dann im nächsten Schrit der Schleife wieder gerechnete wird. Hier wir also weniger Speicher verbraucht. Zudem Rechnet eine Iteration auch schneller. Die Rekursion muss ja erst rückwärst rechen, bis ein Ergebnis vorliegt und dann wieder "hoch" rechen um zum eigentlich Endergebnis zu kommen.

Bitte korrigiert mich, wenn das nicht richtig ist. Was zur meiner Frage führt, was ist für dich "nicht-primitiv"? Weil am Beispiel der Fakultät kann man ganz klar sehen, weniger Speicher und Zeit mit Iteration. Kannst du mir ein konkretes Beispiel (am besten Quellcode posten) nennen, wo das nicht so ist und wo die Rekursion zumindests schneller vielleicht auch speichersparender ist?
 
Wenn das alles ist, schmeiß ich mich weg. Denn dann ist Rekursion total nutzlos, weil es einfach mehr Resourcen verbraucht. Und bei einem richtigen Programmierer sind Prioritäten klar. Und da steht funktionsfähigkeit mit möglichst wenig Resourcen auf jeden Fall vor "Schönheit"

@below: Nein. Kein Assembler.
Komisch. Ich dachte:
bei einem richtigen Programmierer sind Prioritäten klar. Und da steht funktionsfähigkeit mit möglichst wenig Resourcen auf jeden Fall vor "Schönheit"
Ein C Compiler ist auf jeden Fall Schönheit vor Funktionalität und Resourcen. Weg damit!

Schau dir das "Programm" ober doch mal an. Die Fakultät ausrechnen.
Klar. Das ist eine primitive Rekursion.

Wir befinden uns hier in einem historischen, aber schon entschiedenen Streit:
"1926 vermutete David Hilbert, dass jede berechenbare Funktion primitiv-rekursiv sei. Vereinfacht bedeutet dies, dass sich jede durch einen Computer berechenbare Funktion aus einigen wenigen, sehr einfachen Regeln zusammensetzen lässt und dass sich die Dauer der Berechnung im Voraus abschätzen lässt. Dies trifft auf nahezu alle in der Praxis vorkommenden Funktionen zu.
Ebenfalls 1926 konstruierte Ackermann eine Funktion, die diese Vermutung widerlegt, und veröffentlichte sie 1928. Ihm zu Ehren wird diese Funktion heute Ackermannfunktion genannt. Sie kann von einem Computer in endlicher Zeit ausgewertet werden, ist aber nicht primitiv-rekursiv."
http://de.wikipedia.org/wiki/Ackermannfunktion

Natürlich kann man die Ackermannfunktion auch Iterativ lösen, dazu muss ich dann aber den Stack selber nachbauen. Das ist dann mindestens so aufwendig wie die Rekursive Lösung.

Im übrigen wirst Du in Deinem Berufsleben auch noch feststellen, das lesbarer und verständlicher Code sehr viel wichtiger ist, als Du heute glaubst. Mit etwas Pech verstehe ich meinen eigenen Code von vor drei Monaten nicht mehr. Und wenn meherer Leute an dem Code arbeiten ist es entsprechend schlimmer.

Alex
 
Also...

Lesbarer und verständlich finde ich gerade Iteration. Bei Rekursion muss ich rückwarts denken, wo bin ich jetzt, wo würde ich vorher gewesen sein etc. Iteration ist für mich einfach nur Ergebnis eins und dann hochzählen. Vielleicht ist das für mich im Moment nur so, weil ich noch am Anfang stehe.

In dem Text auf Wiki wird aber auch gesagt "...dieser teileise iterative... ist etwas effizienter...". Also stellt sich mir die Frage, wann ist eine Rekursion wirklich besser (schneller, einfacher, speichersparend)?
 
Das ist eine spannende Frage, die ich aber als Übung dem Leser überlasse ;)
Für eine nicht-primitive Rekursion brauche ich einen Overhead, der wahrscheinlich gleich gross ist wie bei einer natürlichen Rekursion. Aber das ist alles schon so lange her ...

Diesen Fragen solltest Du nachgehen, dann kommst Du sehr schnell zur Komplexitätstheorie, einem wichtigen Gebiet der Informatik. Im Schöning sollten ein paar Hinweise dazu sein, aber ich finde meinen im Moment nicht.

Aber bitte, wirklich mit allem Respekt, bitte erzähl Du mir nichts von "richtigen Programmieren" ;)

Alex
 
Ich schätze es ist Benutzer-spezifisch, ich glaube das menschliche Hirn würde immer eher die einfache, iterative Variante wählen, statt die entsprechende Funktion rekursiv zu implementieren.
 
Zurück
Oben Unten