Anfängerfrage (call by value)

Laik

Grünschnabel
Hi,
ich bin neu und absoluter Anfänger und habe eine Frage zu folgendem Code in C:

C++:
void einlesen(int zahl, int min, int max) {
    do {
        printf("Ihre Eingabe im Bereich %d...%d: ", min, max);
        scanf("%d", zahl);
     } while (zeiger<min || zeiger>max);
}

int main(void) {
    int eingabe;
    einlesen(eingabe, 1, 100);
    return 0;
}

Ich kenne den Unterschied zwischen call by value und reference und weiß, dass dieser Code mehr Sinn macht mit einem Zeiger als Parameter.
Wieso wird aber in Zeile 5. die Eingabe nicht mit den Werten min oder max verglichen?
Zumindest hört das Programm bei mir in Zeile 4 auf.

Danke schonmal.
 

Jennesta

Erfahrenes Mitglied
Hallo Laik,

kompiliert dein Programm überhaupt? In deiner Funktion benutzt du die Variable "zeiger", welche es aber gar nicht gibt. Vermutlich meintest du "zahl".
Der nächste Fehler liegt in der Verwendung der Funktion "scanf". Diese Erwartet einen Zeiger auf eine Variable, in die geschrieben werden soll.

Ich habe deinen Code einmal korrigiert. Dieser läuft bei mir.

C++:
#include <cstdio>

void einlesen(int zahl, int min, int max) {
    do {
        printf("Ihre Eingabe im Bereich %d...%d: ", min, max);

        scanf_s("%d", &zahl);
    } while(zahl<min || zahl>max);
}

int main(void) {
    int eingabe = 0;
    einlesen(eingabe, 1, 100);
    return 0;
}

Viele Grüße
Jennesta
 

Laik

Grünschnabel
Vielen Dank! Sorry, es sollte natürlich Zahl heißen, hab das hier falsch geschrieben, im Code steht’s bei mir korrekt.
Dann lag mein Fehler in der scanf Funktion. Scanf_s kannte ich tatsächlich noch nicht.
LG Laik
 

Jennesta

Erfahrenes Mitglied
Das mit "scanf" ist ggf. mein Fehler. Ich benutze immer Visual Studio mit aktuellem Standard und das beschwert sich, bei unsicheren Funktionen und bietet "scanf_s" an.

Du solltest theoretisch problemlos deine scanf Funktion verwenden können. Der Parameter ist allerdings wichtig.
 

Neonof

Mitglied
Hallo Laik,
nur, um das einmal der Deutlichkeit halber zu ergänzen:
Der &-Operator vor einer Variable sorgt dafür, dass nicht der beinhaltete Wert der Variable, sondern ihre Adresse im Speicher zurückgegeben wird. Wenn du dir in einer Dokumentation die Funktion scanf() ansiehst, werden für alle Parameter nach dem Formatstring Pointer erwartet. Also Adressen von den Variablen, auf die der eingelesene Inhalt geschrieben werden soll. Lässt du das & weg und deine Variable Zahl enthält beispielsweise 3, dann versucht das Programm in den virtuellen Adressraum des Prozesses an der Position 0x000003 zu schreiben. Der vordere Speicherbereich des Prozesses ist jedoch für Verwaltungsinformationen fürs System reserviert, weswegen das Programm selbst keinen Schreibzugriff darauf hat. Das System verweigert den Zugriff, meldet eine Zugriffsverletzung und bricht dein Programm ab, weil es etwas versucht, das es nicht darf.
 

Laik

Grünschnabel
Hallo Laik,
nur, um das einmal der Deutlichkeit halber zu ergänzen:
Der &-Operator vor einer Variable sorgt dafür, dass nicht der beinhaltete Wert der Variable, sondern ihre Adresse im Speicher zurückgegeben wird. Wenn du dir in einer Dokumentation die Funktion scanf() ansiehst, werden für alle Parameter nach dem Formatstring Pointer erwartet. Also Adressen von den Variablen, auf die der eingelesene Inhalt geschrieben werden soll. Lässt du das & weg und deine Variable Zahl enthält beispielsweise 3, dann versucht das Programm in den virtuellen Adressraum des Prozesses an der Position 0x000003 zu schreiben. Der vordere Speicherbereich des Prozesses ist jedoch für Verwaltungsinformationen fürs System reserviert, weswegen das Programm selbst keinen Schreibzugriff darauf hat. Das System verweigert den Zugriff, meldet eine Zugriffsverletzung und bricht dein Programm ab, weil es etwas versucht, das es nicht darf.

Danke dir, hast natürlich vollkommen recht! Ich habe das & Zeichen vergessen und es nicht bemerkt, daher meine Verwirrung.
Danke auch für die ausführliche Begründung, so entwickelt man gleich ein besseres Verständnis