# struct Variablen an Funktion übergeben



## Razorhawk (7. Oktober 2005)

Ich wollte Fragen ob ich den ganzen Inhalt einer Struct Variable in eine selbstgeschriebene Funktion als Parameter übergeben kann. (also dass der Funktionsparameter auch eine Struct-Variable ist)

Wenn nicht, wie würde ich es am elegantesten lösen können?
Eine Idee habe ich, aber die erscheint mir noch nicht elegant genug.


----------



## deepthroat (7. Oktober 2005)

Hi.

Ja, das geht. Aber warum probierst du sowas nicht einfach aus?


----------



## CodeFatal (7. Oktober 2005)

Moin Moin,
Übung und etwas Risikobereitschaft macht den Meister.
Aber zur Erinnerung: Achtung wenn Zeiger mit im Spiel sind. Da können evt Dinge geändert werden, die nicht geändert werden sollen...

Nur als kleine Anmerkung

Gruss Michael


----------



## Razorhawk (7. Oktober 2005)

Hab ich schon gelesen.. von Rechnerabsturz bis geschrottete Festplatte ist alles drin 


Ich habe aber auch ein Verständnisproblem.

Also ein struct wird so definiert:


```
struct str_adress {char prename[astring];
               char name[astring];
               char telnr[astring];
              } adress;
```

ein struct kann nur in Funktionen und nicht außerhalb definiert werden.
Dann hab ich in dier Funktion eine funktion, welche die Parameter des Structs übergeben soll


```
bla_funktion(adress);
```

aber wie deklariere ich jetzt den Kopf in der funktion


```
void bla_funktion(struct ....)
```

Aber das geht ja so nicht, von daher hab ich das Problem. Ist nicht so dass ich es mir nicht schon überlegt habe


----------



## Endurion (7. Oktober 2005)

Du kannst den Funktionsheader einfach so schreiben:

struct str_adress 
{
  char prename[astring];
  char name[astring];
  char telnr[astring];
} adress;

für C++:

void bla_funktion( str_adress meinStruct );

Für C++ würde ich dann allerdings auf Referenzen gehen (oder Pointer, wenn du einen ungültig-Wert brauchst):

void bla_funktion( const str_adress& meinStruct );
void bla_funktion( str_adress* pMeinStruct );



für C:
void bla_funktion( struct str_adress meinStruct );


----------



## Razorhawk (7. Oktober 2005)

Ja so habe ich das ja versucht, aber er sagt nur "struct defined in parameterlist"
Ich poste einfach mal den ganzen Quellcode.
weiter unten ist der Aufruf und oben die geschriebene Funktion.


```
#include <stdio.h>
#include <stdlib.h>

const adressen = 100, astring = 26;

void suche(int mode,struct str_adresss ad){

 FILE *file;

 // datei öffnen
 if((file = fopen("adressen.dat","w+")) != NULL){
          
     // adressdaten einlesen und nach Korrektheit überprüfen (Länge stimmt?) 
     //und gegebenenfalls Fehlermeldungen ausgeben.     
          
   
     if(mode == 1){
      
       
             
     }else if (mode == 2){
           
             
           
     }else {
           
       //printf("3\n");      
           
     }        

 }     

}





int main(int argc, char *argv[])
{
    char option;
    
    struct str_adress {char prename[astring];
               char name[astring];
               char telnr[astring];
              } adress;
    
    do{
    
        printf(" N : Suchen nach Nachname \n V : Suchen nach Vorname \n T : Suchen nach Telefonnummer \n Q : Programmabbruch \n");
        printf("\n Wählen Sie eine Option: ");
        if (scanf("%s",&option)){
          printf("\n");
                
          switch (option){
               
          case 'n':suche(1,adress);break;
          case 'N':suche(1,adress);break;     
          case 'v':suche(2,adress);break;
          case 'V':suche(2,adress);break;
          case 't':suche(3,adress);break;
          case 'T':suche(3,adress);break;
                               
        }
        
          if (option != 'n' && option != 'v' && option != 't' && option != 'q' && 
          option != 'N' && option != 'V' && option != 'T' && option != 'Q'){ printf("\n unzulaessige Eingabe fuer Optionen!\n\n");}   
          
    }while( option != 'q');
    

  
  
    system("PAUSE");	
    return 0;
}
```


----------



## CodeFatal (7. Oktober 2005)

Deklarier dein Struct mal nicht in der main und verschieb es nach ganz oben. Der Compiler fängt oben an und alles was er noch nicht "gelesen" hat kennt er auch nicht.


```
#include <stdio.h>
#include <stdlib.h>

struct str_adress {
     char prename[26];//achtung hier können keine variablen werte angenommen werden
     char name[26];
     char telnr[26];
      } ;

const adressen = 100, astring = 26;

void suche(int mode,struct str_adresss ad){

 FILE *file;

 // datei öffnen
 if((file = fopen("adressen.dat","w+")) != NULL){
          
     // adressdaten einlesen und nach Korrektheit überprüfen (Länge stimmt?) 
     //und gegebenenfalls Fehlermeldungen ausgeben.     
          
   
     if(mode == 1){
      
       
             
     }else if (mode == 2){
           
             
           
     }else {
           
       //printf("3\n");      
           
     }        

 }     

}





int main(int argc, char *argv[])
{
    char option;
    

    
    do{
    
        printf(" N : Suchen nach Nachname \n V : Suchen nach Vorname \n T : Suchen nach Telefonnummer \n Q : Programmabbruch \n");
        printf("\n Wählen Sie eine Option: ");
        if (scanf("%s",&option)){
          printf("\n");
                
          switch (option){
               
          case 'n':suche(1,adress);break;
          case 'N':suche(1,adress);break;     
          case 'v':suche(2,adress);break;
          case 'V':suche(2,adress);break;
          case 't':suche(3,adress);break;
          case 'T':suche(3,adress);break;
                               
        }
        
          if (option != 'n' && option != 'v' && option != 't' && option != 'q' && 
          option != 'N' && option != 'V' && option != 'T' && option != 'Q'){ printf("\n unzulaessige Eingabe fuer Optionen!\n\n");}   
          
    }while( option != 'q');
    

  
  
    system("PAUSE");
    return 0;
}
```

Hoffe ich hab jetzt nichts übersehen. Notfalls nochmal fragen.

Gruss Michael


----------



## deepthroat (7. Oktober 2005)

Generell mußt du bevor du irgendwelche Typen, Funktionen oder Variablen benutzt diese auch deklarieren. Das heißt wenn du eine Funktion schreibst die als Parameter ein struct erhält dann muß dieses struct bereits deklariert sein, oder anders ausgedrückt, du kannst das struct nicht innerhalb der main Funktion deklarieren wenn du es auch außerhalb benutzen willst.

Dann ist dir da ein Tippfehler unterlaufen: str_adresss (mit 3 s!)

Allerdings darfst du auch außerhalb von Funktionen keine variablen Arrays deklarieren. Das heißt, du müßtest es folgendermaßen machen:

```
const int adressen = 100;

#define ASTRING 26

struct str_adress {
  char prename[ASTRING];
  char name[ASTRING];
  char telnr[ASTRING];
};
...
int main(int argc, char *argv[])
{
    char option;
    struct str_adress adress;
```

Allerdings solltest du auch bedenken, das dein struct mind. 3*ASTRING, also 78 Byte groß ist. Beim Funktionsaufruf wird das struct über den Stack übergeben was einen relativ großen Aufwand bedeutet. Es wäre zu überlegen ob du nicht einfach das struct als Pointer übergeben solltest.


----------



## Razorhawk (7. Oktober 2005)

Wenn ich es als Pointer übergebe, muss ich dann die variable adress als Pointer deklarieren?

Also:


```
struct str_adress *adress
```

und dannn einfach in die Funktionsparameter nicht *adress schreiben sondern nur adress?
Bin mit Pointern noch sehr frisch von daher brauch ich eine weile bis der Dreh raus ist.


----------



## deepthroat (7. Oktober 2005)

Nein, das mußt du nicht. Du mußt nur (wie z.B. bei scanf) die Adresse der Variablen adress als Parameter übergeben:
	
	
	



```
void suche (struct str_adress* adr);

struct str_adress adress;

suche (&adress);
```

/edit: Und auf die einzelnen Elemente der Struktur kannst du statt 
	
	
	



```
adress.name;
```
dann innerhalb der Funktion suche so zugreifen:
	
	
	



```
adr->name;
```


----------



## Razorhawk (7. Oktober 2005)

Vielen Dank für die tolle Hilfe.

Das Zugriffsbeispiel dort ist das eine laternative Schreibweise oder muss ich es stattdessen so schreiben?
Wenn es alternativ ist... wozu? Gibt es Unterschiede?


----------



## deepthroat (7. Oktober 2005)

Nein, der -> Operator ist keine alternative Schreibweise für den . Operator. Der -> Operator ist nur für Zeiger auf Strukturen gedacht, der andere Operator für Strukturen.

Normalerweise kann man ja auf den Wert eines Zeigers zugreifen indem man ein Sternchen vor die Variable schreibt, so: 
	
	
	



```
int i = 3; int* pi = &i;

*pi = 5;  /* i ist jetzt 5. */
```

Das Problem mit Zeigern auf Strukturen ist nun, das man nicht einfach 
	
	
	



```
*pstr.member
```
 schreiben kann weil der . Operator stärker bindet als der * Operator. Man muß Klammern benutzen um das auszudrücken was man eigentlich wollte: 
	
	
	



```
(*pstr).member
```
Da das etwas umständlich ist und auch nicht schön aussieht, wurde der -> Operator eingeführt.


```
struct str_adress adr; 
struct str_adress* padr; /* Pointer auf ein struct str_adress. Vorsicht, noch nicht initialisiert! */

padr = &adr; /* jetzt zeigt padr auf die Adresse von adr */

/* 1 */ padr->name
/* 2 */ padr[0].name
/* 3 */ (*padr).name
```
Die letzen 3 Ausdrücke sind alle äquivalent und man kann nehmen was man möchte. Allerdings würde ich Variante 1 bevorzugen.


----------

