Uni Aufgabe in C (Über Pythagoras und Rekursion)?

2 Antworten

Die Aufgaben sind mehr mathe- als programmierlastig. Wie schon geschrieben solltest du zu den jeweiligen Aufgaben erst die notwendigen Formeln / mathematischen Lösungswege heraussuchen, sofern sie nicht schon von der Aufgabe vorgegeben werden.

Beispiel Pythagoras:

c = √(a² + b²)

Diese Formel brauchst du nur noch in die Programmierspache übersetzen. Dabei wirst du auf folgende Probleme stoßen: Wie zieht man die Wurzel? Wie bildet man eine Potenz? Wie bildet man eine Summe?

C bietet für alle drei Probleme Lösungen. Es gibt mathematische Operatoren und in der math.h sind bereits mathematische Funktionen vorimplementiert.

Die Implementationsdetails für die Funktion werden von der Aufgabe schon genau vorgegeben.

Initialisieren Sie die Variablen für die Katheten a = 1.9 und b = 4.2 als double-Werte. (...) eine Funktion pythagoras(), die die Katheten a und b als Parameter entgegen nimmt und die Länge der Hypotenuse zurückgibt. (...)

Der Name für die Funktion ist genau vorgegeben, die Parameterliste und der Rückgabetyp lassen sich leicht erschließen.

So sieht die Funktionsdeklaration aus:

double pythagoras(double a, double b);

und die dazugehörige Funktionsdefinition:

#include <math.h>

double pythagoras(double a, double b)
{
  return sqrt(pow(a, 2), pow(b, 2));
}

Beispiel Potenzrechnung mit Rekursion:

Bei einer Rekursion hast du eine Funktion, die sich selbst aufruft. Bei jedem Aufruf wird ein Teilergebnis berechnet und weitergegeben. Dieser Ablauf ist vergleichbar mit einer Schleife, denn auch in dieser wird der selbe Code mehrmals wiederholt, bis eine Abbruchbedingung eingetreten ist.

Ich zeige es zunächst am einem sehr einfachen Beispiel, beginnend mit der Formulierung einer Schleife:

int i;
int max = 5;

for (i = 0; i < max; ++i) {
  printf("%d", i);
}

Die Abbruchbedingung der Schleife lautet i < max. Pro Iterationsschritt wird i um 1 erhöht und eine Ausgabe auf der Konsole findet statt. Übertragen wir das:

void printNumbers(int i, int max)
{  
  if (i < 5) {
    printf("%d", i);
    printNumbers(i + 1, max);
  }
}

// call:
printNumbers(0, 5);

Nun wäre die Frage, wie es bei einer Potenzierung aussieht. Mathematisch kann man eine Potenzrechnung zunächst einmal so aufschlüsseln:

2³ = 2 * 2 * 2

Man könnte dies iterativ so formulieren:

int product = 1;
int i;

for (i = 0; i < exponent; ++i) {
  product = product * base;
}

Sollte der Exponent 0 sein, wäre das Ergebnis 1. Andernfalls wird aufbauend auf der 1 noch höher gerechnet.

Übertragen wir es zu einer rekursiven Funktion:

void power(int product, int base, int exponent, int i)
{
  if (i < exponent) {
    product = product * base;
    power(product, base, exponent, i + 1);
  }
  else {
    printf("%d", product);
  }
}

// call:
power(1, 2, 3, 0);

Nun fordert die Aufgabenstellung aber, dass Ausgaben nur in der main-Methode ausgeführt werden dürfen (d.h., die Funktion muss stattdessen ihr Ergebnis zurückgeben) und generell ist diese Umsetzung etwas unschön: Es sind so viele Parameter, die dauernd mitgetragen werden müssen.

Besser wäre eine Zählung rückwärts, um sich einen Parameter zu sparen. Man kann den Exponenten schrittweise nach unten zählen. Die Abbruchbedingung liegt bei 0. Dann ergibt nämlich die Potenz 1.

int power(int base, int exponent)
{
  if (exponent != 0) {
    int subProduct = power(base, exponent - 1);
    return base * subProduct;
  }

  return 1;
}

// call:
int product = power(2, 3);

Laufe diese rekursiven Beispiele mit Zettel und Stift manuell ab, um zu verstehen, was da passiert.

Tipps zu den Aufgaben:

Es dürfen keine globalen Variablen verwendet werden.

Das lässt sich an sich leicht lösen, indem du stets mit Parametern arbeitest, wenn du außenstehende Variablen innerhalb von Funktionen verwenden möchtest.

Das Programm muss fehlerfrei und ohne Warnungen mit folgendem Aufruf übersetzbar sein: gcc ­-Wall ­-o -­lm

Lies dazu hier und siehe hier.

Zu den mathematischen Lösungsverfahren der einzelnen Aufgaben schreibe ich nichts weiter, denn das lässt sich alles via Google gut recherchieren.

Um dir helfen zu können wäre es gut zu wissen womit du Probleme hast.

Allgemeines Programmierverständnis? Was ist die Aufgabenstellung? Spezifische Probleme?

Woher ich das weiß:Berufserfahrung – Arbeit als Programmierer
Archiimedes 
Fragesteller
 04.11.2019, 16:01

Naja, es sind mehrere Aufgaben, meistens soll ich eine Funktion erstellen die Werte einliest, etwas berechnet, und dann wieder ausgibt. Am besten ich schick dir irgendwo die Aufgaben und du kannst sie dir selbst mal kurz angucken, ich weiß sonst nicht wie ich sie genau erklären sollte. Ich wäre dir wirklich sehr dankbar! Ich bin schon am verzweifeln

0
Archiimedes 
Fragesteller
 04.11.2019, 16:43
@regex9

Ok, ist aber eine ganze Menge:

Schreiben Sie ein Programm, das die Länge der Hypotenuse berechnet, wenn die Katheten gegeben sind. • Alle Ausgaben finden im Hauptprogramm statt. • Initialisieren Sie die Variablen für die Katheten a = 1.9 und b = 4.2 als double-Werte.

a) Schreiben Sie eine Funktion pythagoras(), die die Katheten a und b als Parameter entgegen nimmt und die Länge der Hypotenuse zurückgibt. • Geben Sie das Ergebnis aus.

Schreiben Sie eine Funktion konvertRadius(). Aufrufparameter ist die Kantenlänge c des Hypotenusen-Quadrates aus Aufgabe a). Rückgabe ist der Radius r einer Kreisfläche mit identischem Flächeninhalt . Der Radius muss berechnet und als double-Wert zurückgegeben werden.

Schreiben Sie zwei weitere Funktionen: • kubusVolumen() zur Berechnung des Volumen des Würfels mit der Kantenlänge c • kugelVolumen() zur Berechnung des Volumens der Kugel mit dem Radius r. Die Ergebnisse sollen als double-Werte zurückgegeben werden. 

Es dürfen keine globalen Variablen verwendet werden. Das Programm muss fehlerfrei und ohne Warnungen mit folgendem Aufruf übersetzbar sein: gcc ­- Wall ­-o   -­lm

Sie werden von einem Ingenieurbüro für Landvermessung beauftragt eine Programm zur Höhenbestimmung von Gebäuden zu programmieren. Die Höhenbestimmung erfolgt über trigonometrische Funktionen

φ = β - α

u =s * sin α / sin φ

h =u * sin β

Schreiben Sie ein Programm, das die drei oben genannten Funktionen phi(), u() und hoehe() implementiert um die Höhe des Leuchtturmes zu berechnen.

Dazu noch diese Skizze: http://prntscr.com/psbgqt

Alle Ein- und Ausgaben finden im Hauptprogramm statt. ● Definieren Sie die Variablen für die Länge s und die Winkel α und β als double-Werte. Lesen Sie die Werte vom Benutzer ein. ● Bestimmen Sie die Parameterlisten und Rückgabewerte der Funktionen hoehe(), phi() und u(). Achten Sie auf die richtige Reihenfolge bei der Definition/Implementierung der Funktionen. ● Rufen Sie im Hauptprogramm die Funktion für die Berechnung der Höhe h auf. ● Die Funktionen phi() und u() werden von der Funktion hoehe() aufgerufen! ● Die Sinus-Funktion ist Teil der math-Bibliothek (#include sowie CompilerSchalter -lm am Ende der Befehlszeile). Sie berechnet das Ergebnis im Bogenmaß. ● Schreiben Sie Hilfsfunktionen, zur Umrechnung von Winkelangabe ins Bogenmaß und umgekehrt, wenn Sie diese benötigen. α in rad = (π/180) * α in ° 

a) Schreiben Sie eine rekursive Funktion power() zur Berechnung der Potenz von int-Werten (Ganzzahlen) gemäß der Funktionsdefinition: f(x, y) = xy  = x * X y­1

● Lesen Sie die int-Werte für x und y ein und reichen sie diese zur Berechnung an die Funktionen power() weiter.

● Beachten Sie auch die Verarbeitung von negativen Zahlen für x und y. Bleiben Sie im Raum der ganzen Zahlen.

● Geben Sie das Ergebnis im Hauptprogramm aus.

b) Schreiben Sie eine rekursive C-Funktion int fibo(int n) zur Berechnung des n-ten Folgengliedes der Fibonacci-Folge: f n ={ 1 wenn n≤2; n∈ℕ f n−1 + f n−2 sonst ;n∈ℕ Die Fibonacci-Folge lautet: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...

● Geben Sie die ersten 10 Fibonacci-Zahlen im Hauptprogramm aus. 

a) Schreiben Sie ein Programm das mit Hilfe einer rekursiven Funktion Primzahlen-Paare findet:

● Schreiben Sie eine rekursive Funktion isPrim(), die mit Hilfe der ModuloFunktion bestimmt, ob die übergebene Zahl eine Primzahl ist. Verwenden Sie den Datentyp bool als Ergebnistyp der Funktion. Sie müssen dazu die Header-Datei per #include in Ihr Programm einbeziehen.

● Lesen Sie im Hauptprogramm einen Wert für die Obergrenze max der Suche nach Primzahlen-Paaren ein. Primzahlen-Paare sind zwei Primzahlen, die den Abstand 2 zueinander haben, z.B. 17 und 19. Die Ausgabe soll so aussehen: „(3 5) (5 7) (11 13) (17 19) ... “

● Geben Sie im Hauptprogramm alle Primzahlen-Paare aus, die kleiner als max sind. Testen Sie Ihr Programm mit dem Wert 10000 für max. 

b) Ergänzen Sie Ihr Programm um die Bestimmung der Primfaktorenzerlegung (PFZ) einer natürlichen Zahl. Beispiel 1: Die Zahl 42 hat die Primfaktoren 2, 3 und 7, denn das Produkt 2 * 3 * 7 ist 42. Beispiel 2:  Die Zahl 756 hat die Primfaktoren 2, 2, 3, 3, 3 und 7. ● Schreiben Sie eine rekursive Funktion doPFZ(), die die Primfaktoren einer übergebenen natürlichen Zahl bestimmt und ausgibt. ● Lesen Sie im Hauptprogramm einen Wert für eine natürliche Zahl ein und reichen Sie ihn zur Bestimmung an die Funktion doPFZ() weiter. 

Ich habe erst vor wenigen Wochen mit dem programmieren angefangen und bin ehrlichgesagt total überfordert und weiß überhaupt nicht wie ich denn überhaupt genau anfangen soll.

0
regex9  04.11.2019, 16:54
@Archiimedes

Ich schaue heute Abend drüber. Vielleicht beteiligt sich bis dahin auch noch jemand anderes.

Wie du starten solltest: Löse die Aufgaben selbst schon auf mathematischen Weg bzw. ermittle den mathematischen Lösungsweg zu ihnen.

1
Archiimedes 
Fragesteller
 04.11.2019, 18:49
@regex9

Dafür wäre ich dir wirklich unglaublich dankbar^^

0