Forum: PC-Programmierung C Code Fehler


von Jen (Gast)


Lesenswert?

Hey,

ich habe folgenden C Code gegeben und soll sagen, was für ein Fehler 
auftritt. Ich glaube ich habe den Fehler, aber weiß nicht ob ich da 
richtig liege. Kann mir jemand bitte helfen?
Der Fehler liegt glaube ich darin, dass die Funktion times_two nichts 
zurückgibt?
Und dadurch entsteht eine Endlosschleife.

1
#include <stdio.h>
2
void times_two(int i)
3
  {
4
   i = i * 2;
5
  }
6
int main(void){
7
   int i = 1;
8
   do {
9
      printf("%d\n", i);
10
      times_two(i);
11
   } while (i <= 256);
12
   return 0;
13
}

von Teo D. (teoderix)


Lesenswert?

Jen schrieb:
> Der Fehler liegt glaube ich darin, dass die Funktion times_two nichts
> zurückgibt?

Wieso?

von Karl H. (kbuchegg)


Lesenswert?

Deine Analyse klingt gut.

Jetzt noch dein Entwicklungssystem hochfahren, den Code eingeben, 
compilieren (was sagt der Compiler dazu) und nachsehen ob die Analyse so 
stimmt, bzw. ob der Compiler dazu was zu sagen hat.

von Max H. (hartl192)


Lesenswert?

Jen schrieb:
> Der Fehler liegt glaube ich darin, dass die Funktion times_two nichts
> zurückgibt?
Wie auch wenn sie eine void-Funktion ist?
i wird by Value übergeben, by Reference würde es klappen:
1
void times_two(int *i)
2
{
3
  *i = *i * 2;
4
}
aufruf dann mit
1
times_two(&i);

von Jen (Gast)


Lesenswert?

Habe ich jetzt mal gemacht, es wird immer wieder eine 1 ausgegeben.
Jetzt sollen wir das Problem benennen und eventuell verbessern. Muss ich 
mit Pointern arbeiten?

von Tom (Gast)


Lesenswert?

Eine gute Gelegenheit, den Unterschied zwischen call by reference und 
call by value nachzulesen, und wie das in C geht.

von Jen (Gast)


Lesenswert?

Okey danke euch beiden, das beantwortet mir meine Frage :))

von Karl H. (kbuchegg)


Lesenswert?

Im übrigen ist diese Aussage
1
Und dadurch entsteht eine Endlosschleife.

ein bischen zu krass. Wenn die Funktion nicht times_two geheissen hätte, 
sondern irgendwie anders, hättest du diese Verbindung nicht hergestellt.

Ich würde das als Antwort durchaus so akzeptieren, aber ich fände die 
Antwort "Das Programm endet in einer Endlosschleife, weil die Variable i 
innerhalb der Schleife keine Möglichkeit hat verändert zu werden" 
besser. Denn das ist die eigentliche Ursache - dass i innerhabld der 
Schleife nicht verändert wird. Das es so gedacht war, dass times_two 
diese Veränderung macht ist hingegen Spekulation deinerseits. Der 
Programmierer könnte ja auch ein ++ in der Schleife in main vergessen 
haben.
Diese Spekulation ist natürlich begründet, keine Frage. Aber es ist erst 
mal eine Spekulation.

: Bearbeitet durch User
von Jen (Gast)


Lesenswert?

Danke finde deine Antwort auch besser :)

von Karl H. (kbuchegg)


Lesenswert?

Jen schrieb:
> Habe ich jetzt mal gemacht, es wird immer wieder eine 1 ausgegeben.
> Jetzt sollen wir das Problem benennen und eventuell verbessern. Muss ich
> mit Pointern arbeiten?

Du musst nicht.

Du kannst. Aber es gibt auch noch eine andere Möglichkeit.
Welche Möglichkeiten kennst du denn, wie eine Funktion einen Wert an 
ihren Aufrufer mitteilen kann?

von Max H. (hartl192)


Lesenswert?

Nachtrag:
Mit einem Makro würde es auch gehen:
1
#define TIMES_TWO(a) do { a = a * 2; } while(0)

Aufruf dann mit:
1
TIMES_TWO(i);

von Jen (Gast)


Lesenswert?

Eine Sach wäre da noch das unkorrigierte von vorhin nennt man CbV und 
das Max H. CbR?

von Karl H. (kbuchegg)


Lesenswert?

Max, machs nicht so kompliziert.

Wie teilt denn ein sin() seinem Aufrufer den errechneten Wert mit? Oder 
die Funktion abs()?

(Ich will Jen die Lösung nicht präsentieren. Er soll selber 
draufkommen.)

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Jen schrieb:
> Eine Sach wäre da noch das unkorrigierte von vorhin nennt man CbV und
> das Max H. CbR?

Ja.

Aber ganz ehrlich. Wenn du mir diese Lösung präsentierst, würdest du von 
mir Punkteabzug kriegen. Denn die naheliegenste Lösung sieht anders aus.

: Bearbeitet durch User
von Jen (Gast)


Lesenswert?

Keine Ahnung mit return i zurückgeben lassen, habe ich auch vergeblich 
versucht.
lg jenny(jen)

von Max H. (hartl192)


Lesenswert?

Jen schrieb:
> habe ich auch vergeblich versucht.
Wie (C-Code)?

von Jen (Gast)


Lesenswert?

Habe noch eine Aufgabe dazu und hier habe ich es nicht hinbekommen. Habe 
die Funktion dann rausgelassen, denke aber dass ich dafür keine Punkte 
kriegen werde.
1
#include <stdio.h>
2
/*void next(int i)
3
{
4
    i++;
5
}*/
6
int main(void)
7
{
8
int i, fib[10];
9
fib[0] = 1;
10
fib[1] = 1;
11
i = 2;
12
printf("fib[0] = %d\n",fib[0]);
13
printf("fib[1] = %d\n",fib[1]);
14
do {
15
fib[i] = fib[i-1]+fib[i-2];
16
printf("fib(%d) =%d\n", i ,fib[i]);
17
i ++;
18
} while (i <= 10);
19
return 0;
20
}

von Jen (Gast)


Lesenswert?

1
#include <stdio.h>
2
void times_two(int i)
3
  {
4
   i = i * 2;
5
   return i;
6
  }
7
int main(void){
8
   int i = 1;
9
   do {
10
      printf("%d\n", i);
11
      times_two(i);
12
   } while (i <= 256);
13
   return 0;
14
}

von Max H. (hartl192)


Lesenswert?

Jen schrieb:
> denke aber dass ich dafür keine Punkte
> kriegen werde.
Wieso? Musst du eine Funktion für i++ schreiben?


Jen schrieb:
> void times_two(int i)
>  {
>    i = i * 2;
>    return i;
>  }
Diese müsstest du dann mit
1
i = times_two(i);
aufrufen

: Bearbeitet durch User
von Jen (Gast)


Lesenswert?

Ich weiß nicht, ich muss einfach nur wieder den Fehler im Programm 
finden und wenn möglich korrigieren.

von Jen (Gast)


Lesenswert?

Und ich glaube das void in int umändern?

von npn (Gast)


Lesenswert?

Jen schrieb:
> Und ich glaube das void in int umändern?

Rischtisch :-)

von Max H. (hartl192)


Lesenswert?

Jen schrieb:
> ich muss einfach nur wieder den Fehler im Programm
> finden und wenn möglich korrigieren.

Das Problem ist wieder der gleiche und du kannst es auch wieder lösen 
mit:
- Call by reference: netx(&i);
- Return Wert i = netx(i);
- Makro
- i++ in den Code schreiben.

next() muss dann halt entsprechen angepasst werden.

Jen schrieb:
> Und ich glaube das void in int umändern?
Stimmt, das habe ich ganz übersehen.

: Bearbeitet durch User
von Jen (Gast)


Lesenswert?

Vielen lieben Dank!

von Profi (Gast)


Lesenswert?

Du kannst auch i ganz am Anfang deklarieren, dann hat das über das 
gesamte Programm Gültigkeit.

von Max H. (hartl192)


Lesenswert?

Dann dürfte er i aber nicht in der main und in der anderen Funktion 
nachmals deklarieren. Eine globale Variable für so etwas ist mMn nicht 
wirklich sauber programmiert.

von Karl H. (kbuchegg)


Lesenswert?

Max H. schrieb:
> Dann dürfte er i aber nicht in der main und in der anderen Funktion
> nachmals deklarieren. Eine globale Variable für so etwas ist mMn nicht
> wirklich sauber programmiert.

Exakt.
Ausserdem denke ich nicht, dass das der Sinn der Übung ist.
So wie die beiden Aufgaben aussehen, sind sie speziell dafür gedacht, 
den Lernenden an Returnwerte von Funktionen zu gewöhnen und ihm da eine 
gewisse Übung zuzuschanzen. Das die beiden 'Fehlerfälle' exakt dem 
gleichen Strickmuster folgen, ist denke ich kein Zufall.

von Stefan R. (srand)


Lesenswert?

Tom schrieb:
> Eine gute Gelegenheit, den Unterschied zwischen call by reference und
> call by value nachzulesen, und wie das in C geht.

In C gibts aber nur call by value. :-)

von Tom (Gast)


Lesenswert?

Die Fußnote "In C gibt es kein call by reference, man kann aber mit 
Zeigern ein de-facto-call-by-reference nachbauen." wollte ich dem OP bei 
seinem momentanen Kenntnisstand ganz bewusst ersparen. Über solche 
Details kann man nachdenken, wenn man Zeiger etc. sicher verwenden kann, 
Programmieren lernen funktioniert (bei normalen Menschen) nicht wie ein 
mathematischer Beweis.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.