www.vorhilfe.de
Vorhilfe

Kostenlose Kommunikationsplattform für gegenseitige Hilfestellungen.
Hallo Gast!einloggen | registrieren ]
Startseite · Forum · Wissen · Kurse · Mitglieder · Team · Impressum
Forenbaum
^ Forenbaum
Status Vorhilfe
  Status Geisteswiss.
    Status Erdkunde
    Status Geschichte
    Status Jura
    Status Musik/Kunst
    Status Pädagogik
    Status Philosophie
    Status Politik/Wirtschaft
    Status Psychologie
    Status Religion
    Status Sozialwissenschaften
  Status Informatik
    Status Schule
    Status Hochschule
    Status Info-Training
    Status Wettbewerbe
    Status Praxis
    Status Internes IR
  Status Ingenieurwiss.
    Status Bauingenieurwesen
    Status Elektrotechnik
    Status Maschinenbau
    Status Materialwissenschaft
    Status Regelungstechnik
    Status Signaltheorie
    Status Sonstiges
    Status Technik
  Status Mathe
    Status Schulmathe
    Status Hochschulmathe
    Status Mathe-Vorkurse
    Status Mathe-Software
  Status Naturwiss.
    Status Astronomie
    Status Biologie
    Status Chemie
    Status Geowissenschaften
    Status Medizin
    Status Physik
    Status Sport
  Status Sonstiges / Diverses
  Status Sprachen
    Status Deutsch
    Status Englisch
    Status Französisch
    Status Griechisch
    Status Latein
    Status Russisch
    Status Spanisch
    Status Vorkurse
    Status Sonstiges (Sprachen)
  Status Neuerdings
  Status Internes VH
    Status Café VH
    Status Verbesserungen
    Status Benutzerbetreuung
    Status Plenum
    Status Datenbank-Forum
    Status Test-Forum
    Status Fragwürdige Inhalte
    Status VH e.V.

Gezeigt werden alle Foren bis zur Tiefe 2

Navigation
 Startseite...
 Neuerdings beta neu
 Forum...
 vorwissen...
 vorkurse...
 Werkzeuge...
 Nachhilfevermittlung beta...
 Online-Spiele beta
 Suchen
 Verein...
 Impressum
Das Projekt
Server und Internetanbindung werden durch Spenden finanziert.
Organisiert wird das Projekt von unserem Koordinatorenteam.
Hunderte Mitglieder helfen ehrenamtlich in unseren moderierten Foren.
Anbieter der Seite ist der gemeinnützige Verein "Vorhilfe.de e.V.".
Partnerseiten
Dt. Schulen im Ausland: Mathe-Seiten:

Open Source FunktionenplotterFunkyPlot: Kostenloser und quelloffener Funktionenplotter für Linux und andere Betriebssysteme
Forum "C/C++" - call by reference
call by reference < C/C++ < Programmiersprachen < Praxis < Informatik < Vorhilfe
Ansicht: [ geschachtelt ] | ^ Forum "C/C++"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien

call by reference: Frage (beantwortet)
Status: (Frage) beantwortet Status 
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.


        
Bezug
call by reference: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 19:57 Di 24.08.2004
Autor: Marc

Hallo choky,

[willkommenvh]

>  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

Bezug
                
Bezug
call by reference: Frage (beantwortet)
Status: (Frage) beantwortet Status 
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

Bezug
                        
Bezug
call by reference: Antwort
Status: (Antwort) fertig Status 
Datum: 19:56 Fr 27.08.2004
Autor: Karl_Pech

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



Bezug
                                
Bezug
call by reference: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
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

Bezug
                                        
Bezug
call by reference: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
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



Bezug
                                                
Bezug
call by reference: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
Datum: 14:10 Sa 28.08.2004
Autor: Hanno

Hi Karl.
Ja, da fehlen noch die Typen.

Gruß,
Hanno

Bezug
        
Bezug
call by reference: Antwort
Status: (Antwort) fertig Status 
Datum: 20:43 Di 24.08.2004
Autor: JohnnyFu

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ß

Bezug
                
Bezug
call by reference: Mitteilung
Status: (Mitteilung) Reaktion unnötig Status 
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

Bezug
        
Bezug
call by reference: Antwort
Status: (Antwort) fertig Status 
Datum: 18:34 Fr 27.08.2004
Autor: michael7

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

> }


Bezug
Ansicht: [ geschachtelt ] | ^ Forum "C/C++"  | ^^ Alle Foren  | ^ Forenbaum  | Materialien


^ Seitenanfang ^
www.vorhilfe.de