call by reference < C/C++ < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 19:26 Di 24.08.2004 | Autor: | choky |
hallo,
ich möchte die Werte von eine Funktion mit call by reference verfahren in einem C Programm aufrufen. Leider funktioniert das nicht ganz richtig. Was mache ich hier falsch? kann jemand mir dies beantworten?
hier ist das Beispiel:
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
void auswahl_abfrage(int *zahl, char *kette);
main()
{
int eingabe_zahl;
char eingabe_kette[50];
auswahl_abfrage(&eingabe_zahl, &eingabe_kette[0]);
[mm] printf("%i\n", [/mm] eingabe_zahl);
printf("%s", eingabe_kette);
getch();
}
void auswahl_abfrage(int *zahl, char *kette)
{
printf("Eingabe Zahl: ");
fflush(stdin);
scanf("%i", &zahl);
printf("Eingabe Zeichen Kette: ");
fflush(stdin);
gets(kette);
}
Ich habe diese Frage in keinem weiteren Forum gestellt.
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 19:57 Di 24.08.2004 | Autor: | Marc |
Hallo choky,
> ich möchte die Werte von eine Funktion mit call by
> reference verfahren in einem C Programm aufrufen. Leider
> funktioniert das nicht ganz richtig. Was mache ich hier
> falsch? kann jemand mir dies beantworten?
Was ist denn genau das Fehlverhalten?
> hier ist das Beispiel:
>
>
> #include<stdio.h>
> #include<string.h>
> #include<conio.h>
> #include<stdlib.h>
>
>
> void auswahl_abfrage(int *zahl, char *kette);
>
> main()
>
> int eingabe_zahl;
> char eingabe_kette[50];
>
> auswahl_abfrage(&eingabe_zahl, &eingabe_kette[0]);
Ich denke, dass hier das Problem liegt. Hier wird ja eine Referenz auf das erste Element des array eingabe_kette übergeben.
Ich würde es mal mit "&eingabe_kette" oder "&eingabe_kette[]" versuchen.
Viele Grüße,
Marc
|
|
|
|
|
Status: |
(Frage) beantwortet | Datum: | 18:38 Fr 27.08.2004 | Autor: | michael7 |
Hallo Marc,
> > auswahl_abfrage(&eingabe_zahl, &eingabe_kette[0]);
>
> Ich denke, dass hier das Problem liegt. Hier wird ja eine
> Referenz auf das erste Element des array eingabe_kette
> übergeben.
das sollte jedoch kein Problem darstellen; siehe anderen Beitrag.
> Ich würde es mal mit "&eingabe_kette" oder
> "&eingabe_kette[]" versuchen.
Funktioniert &eingabe_kette[] bei Dir? Ich erhalte einen Parse-Error (gcc 3.3.4).
Michael
|
|
|
|
|
Hallo Michael,
> > Ich würde es mal mit "&eingabe_kette" oder
> > "&eingabe_kette[]" versuchen.
>
> Funktioniert &eingabe_kette[] bei Dir? Ich erhalte einen
> Parse-Error (gcc 3.3.4).
Ich frage mich, was das syntaktisch überhaupt bedeuten soll? Die leeren Klammern '[]' werden doch, soweit ich weiß, bei Deklarationen oder bei Parameterdefinitionen für Funktionen benutzt. Also z.B. char some_text[] = "Hallo Michael." oder
1: | void hello(char great_param[])
| 2: | {
| 3: | // some code
| 4: | } |
Wenn du nun aber "hello(&some_text[]);" schreibst, ist der Sinn unklar. Du machst keine Parameterdeklaration, sondern einen Funktionsaufruf. Du definierst auch keine Variablen. Dann bleibt als 3te Möglichkeit noch für den Compiler zu prüfen, ob du auf irgendein Element durch die spitzen Klammern zugreifen willst. Aber in diesen Klammern fehlt die Zahl. Was also tun? Nun z.B. einen Parse Error ausgeben.
Viele Grüße
Karl
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 20:58 Fr 27.08.2004 | Autor: | Marc |
Hallo zusammen!
> > > Ich würde es mal mit "&eingabe_kette" oder
> > > "&eingabe_kette[]" versuchen.
> >
> > Funktioniert &eingabe_kette[] bei Dir? Ich erhalte einen
>
> > Parse-Error (gcc 3.3.4).
Ich auch
> Hmm, ich frage mich, was das syntaktisch überhaupt bedeuten
> soll?
> die leeren Klammern '[]' werden doch, soweit ich weiß, bei
> Deklarationen
> oder bei Parameterdefinitionen für Funktionen benutzt.
>
> Also z.B. char some_text[] = "Hallo Michael."
> oder z.B.
> void hello(char great_param[])
> {
> // some code
> }
> Wenn du nun aber "hello(&some_text[]);" so ist der Sinn
> unklar. Du machst keine Parameterdeklaration,
> sondern
Ich habe da natürlich etwas verwechselt, da ich zur Zeit aus der aktiven C-Programmierung raus bin (bzw. nie drin war, da ich sofort C++ gelernt hatte).
Was ich geschrieben habe, war natürlich Quatsch, ich habe ja ausserdem mehrere Möglichkeiten angegeben, weil ich mir nicht sicher war.
Die Verwechslung kam aber so zustande:
Bei der Definition einer Funktion, z.B.
void test(*meinarray) {}
ist --soweit ich es in Erinnerung habe-- äquivalent zu
void test(meinarray[]) {}
und wenn man dann nicht richtig nachdenkt, bevor man antwortet, kommt eine Antwort wie meine zustande
Sorry für die Verwirrung, die ja zum Glück jetzt restlos geklärt wurde.
Viele Grüße,
Marc
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 11:02 Sa 28.08.2004 | Autor: | Karl_Pech |
Hallo Marc,
> (1) void test(*meinarray) {}
> ist --soweit ich es in Erinnerung habe-- äquivalent zu
> (2) void test(meinarray[]) {}
Bei (1) und (2) fehlen doch jeweils die Typen der Funktionsparameter, oder?
Grüße
Karl
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 14:10 Sa 28.08.2004 | Autor: | Hanno |
Hi Karl.
Ja, da fehlen noch die Typen.
Gruß,
Hanno
|
|
|
|
|
Hi,
bei mir läuft das Programm, aber bei der Laufzeit wird eine seltsame Zahl ausgegeben...
Teste mal, ob es hier liegt:
> void auswahl_abfrage(int *zahl, char *kette)
> {
>
> printf("Eingabe Zahl: ");
> fflush(stdin);
> scanf("%i", &zahl);
> printf("Eingabe Zeichen Kette: ");
> fflush(stdin);
> gets(kette);
> }
und statt
> scanf("%i", &zahl);
nimm
scanf("%i", zahl);
da Du laut Definition in cstdio.h
int scanf ( const char * format [ , argument , ...] );
einen Zeiger übergeben musst... zahl ist ja bereits als Zeiger (also Adresse) deklariert.
Andernfalls präzisiere Dein Problem... wäre hilfreich
Gruß
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 22:10 Di 24.08.2004 | Autor: | choky |
hallo zusammen,
wie du geschrieben hast johnnyfu mit scanf("%i", zahl) ohne Adressenoperator funktioniert es, weil variable zahl schon mit adresse deklariet ist.
ich danke dir
|
|
|
|
|
Hallo,
meine Antwort kommt zwar etwas verspaetet, aber mir sind noch einige Dinge aufgefallen, die vielleicht ganz nuetzlich sind.
> ich möchte die Werte von eine Funktion mit call by
> reference verfahren in einem C Programm aufrufen. Leider
> funktioniert das nicht ganz richtig. Was mache ich hier
> falsch? kann jemand mir dies beantworten?
>
> hier ist das Beispiel:
>
>
> #include<stdio.h>
> #include<string.h>
> #include<conio.h>
Wenn ich mich recht entsinne, dann wird conio.h von Borland-Compilern verwendet. Dies ist aber kein ANSI-C Header und folglich nicht portabel. Also besser nicht verwenden (s.u.).
> #include<stdlib.h>
>
>
> void auswahl_abfrage(int *zahl, char *kette);
Ist korrekt, jedoch koennen die Bezeichner weggelassen werden. Falls sich spaeter mal die Bezeichner unten bei der Funktionsdefinition aendern sollten, muss das hier nicht angepasst werden. (Das muesste es rein syntaktisch sowieso nicht, aber die Code-Wartbarkeit ist damit sicherlich beeintraechtigt). Also:
void auswahl_abfrage(int *, char *);
> main()
Der Standard besagt:
"The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int [...]".
Also korrekt: int main(void)
Auch das void muss in Klammern, da ein leeres Klammernpaar (im Gegensatz zu C++) nicht void impliziert.
> {
> int eingabe_zahl;
> char eingabe_kette[50];
>
> auswahl_abfrage(&eingabe_zahl, &eingabe_kette[0]);
Man kann auch einfach
auswahl_abfrage(&eingabe_zahl, eingabe_kette);
schreiben, da eingabe_kette implizit fuer &eingabe_kette[0] steht, also einen Zeiger auf das erste Element von eingabe_kette.
> [mm] printf("%i\n", [/mm] eingabe_zahl);
> printf("%s", eingabe_kette);
>
> getch();
Dies wird wohl von conio.h bereitgestellt, ist aber wie bereits oben angedeutet kein ANSI-C (funktioniert bei mir hier z.B. nicht). Besser z.B.
getchar();
aus stdio.h verwenden.
Da main int zurueckgibt, muss hier zum Abschluss
return 0;
oder ein
exit(0);
stehen (exit() ist in stdlib.h deklariert).
> }
>
> void auswahl_abfrage(int *zahl, char *kette)
> {
>
> printf("Eingabe Zahl: ");
> fflush(stdin);
Dies ist nicht erlaubt und resultiert in undefiniertem Verhalten, da fflush laut Standard nur fuer Ausgabe-Streams verwendet werden darf. Also Du koenntest
fflush(stdout);
schreiben, damit obiges printf in jedem Fall ausgegeben wird (also z.B. auch dann, wenn die Ausgabe auf einer zeilengepufferten Konsole erfolgt).
> scanf("%i", &zahl);
Wie schon im anderen Beitrag erwaehnt, muss der Adressoperator vor 'zahl' weg, da es sich ja bereits um einen Zeiger auf int handelt.
> printf("Eingabe Zeichen Kette: ");
> fflush(stdin);
> gets(kette);
gets() sollte man niemals verwenden. Falls mehr Zeichen eingelesen werden wie der Puffer gross ist, kommt es zu einem Pufferueberlauf. Abhilfe: fgets() verwenden. Also besser:
if ((fgets(kette, 50, stdin)) == NULL) {
perror("fgets error");
exit(1); /* oder aehnliches */
}
Als zweites Argument kann man hier leider nicht sizeof(kette) verwenden, da kette in der Funktion auswahl_abfrage lediglich ein Zeiger auf das erste Element des Arrays eingabe_kette ist und somit die Groesse des Arrays nicht bekannt ist. sizeof(kette) wuerde von daher die Groesse eines Zeigers nach char auf Deinem System liefern (vermutlich 4).
Jetzt gibt es aber leider immer noch ein subtiles Problem. Obiges scanf liest lediglich die eingegebene Zahl ein, aber das folgende Linefeed [mm] '\n' [/mm] (das beim Druecken von 'Return' erzeugt wurde) verbleibt im Eingabepuffer. Von daher liest gets bzw. fgets genau dieses [mm] '\n' [/mm] und sonst nichts mehr. Man muss also zunaechst dieses [mm] '\n' [/mm] (und evtl. alle sonstigen Zeichen davor) einlesen und "wegwerfen" und erst dann fgets aufrufen, um die eigentliche Zeichenkette des Benutzer einzulesen. Das koennte z.B. so aussehen:
if ((c = getchar()) != [mm] '\n' [/mm] && c != EOF)
while (getchar() != [mm] '\n')
[/mm]
;
Das sollte genau nach dem obigen scanf() stehen.
Falls noch Fragen bestehen, immer her damit.
Michael
> }
|
|
|
|