Forum: Mikrocontroller und Digitale Elektronik Deklaration einer Unterfunktion


von Tar (Gast)


Lesenswert?

Wie deklariere ich die Unterfunktion richtig, so dass sie nach main 
stehen kann bzw. in einem eigenen Headerfile?
1
/* array10.c */
2
#include <stdio.h>
3
#include <stdlib.h>
4
#define MAX 10
5
6
void function(int feld[], int n_anzahl) {
7
   int i;
8
9
   for(i = 0; i < n_anzahl; i++)
10
      printf("%d; ", feld[i]);
11
   printf("\n");
12
}
13
14
15
int main(void) {
16
   int val[MAX];
17
   int i;
18
19
   for(i = 0; i < MAX; i++)
20
      val[i] = i+1;
21
22
   function(val, MAX);
23
24
   return 0;
25
}

von Mike M. (mikeii)


Lesenswert?

1
/* array10.c */
2
#include <stdio.h>
3
#include <stdlib.h>
4
#define MAX 10
5
6
void function(int feld[], int n_anzahl);
7
8
9
10
11
int main(void) {
12
   int val[MAX];
13
   int i;
14
15
   for(i = 0; i < MAX; i++)
16
      val[i] = i+1;
17
18
   function(val, MAX);
19
20
   return 0;
21
}
22
23
24
void function(int feld[], int n_anzahl) {
25
   int i;
26
27
   for(i = 0; i < n_anzahl; i++)
28
      printf("%d; ", feld[i]);
29
   printf("\n");
30
}

Ansonsten den Prototypen in die *.h Datei und die Implementierung in die 
*.c Datei


Zur Erklärung, man schreibt den Kopf der Funktion erst mit Strichpunkt, 
damit der Compiler weiß, das es sowas geben wird.
Dann meckert er auch nicht, wenn die Funktion irgendwo als Aufruf 
entdeckt wird, bevor sie implementiert wurde

von Mike M. (mikeii)


Lesenswert?

Sonst
1
/* array10.c */
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include "fkt.h"
5
6
int main(void) {
7
   int val[MAX];
8
   int i;
9
10
   for(i = 0; i < MAX; i++)
11
      val[i] = i+1;
12
13
   function(val, MAX);
14
15
   return 0;
16
}

1
/*fkt.c*/
2
3
#include "fkt.h"
4
void function(int feld[], int n_anzahl) {
5
   int i;
6
7
   for(i = 0; i < n_anzahl; i++)
8
      printf("%d; ", feld[i]);
9
   printf("\n");
10
}


1
/*fkt.h*/
2
#ifndef FKT_H_INCLUDED
3
#define FKT_H_INCLUDED
4
5
#define MAX 10
6
7
void function(int feld[], int n_anzahl);
8
9
#endif

von Fabian O. (xfr)


Lesenswert?


von Tar (Gast)


Lesenswert?

OK funktioniert danke.

von Tar (Gast)


Lesenswert?

Ich hatte gedacht, man schreibt nur z.b. (int) in die Deklaration, ohne 
Variablenname.

von Mike M. (mikeii)


Lesenswert?

Nein, der Kopf muss genauso aussehen, wie bei der Implementiertung.
Der Compiler will auch prüfen ob die richtige Anzahl an Parametern, bzw. 
der richtige Typ übergeben wird, bevor er die tatsächliche 
Implementierung gefunden hat.

von Karl H. (kbuchegg)


Lesenswert?

Mike Mike schrieb:
> Nein, der Kopf muss genauso aussehen, wie bei der Implementiertung.

Ich denke, er meinte die Angabe der Parameternamen.

> Ich hatte gedacht, man schreibt nur z.b. (int) in die Deklaration,
> ohne Variablenname.

Das kannst du natürlich tun. Die Frage ist ob das für dich als 
Programmierer sinnvoll ist.

Angenommen ich gebe dir ein Modul von mir. Also ein C-File und ein 
Header File. Anstatt lange den Code zu studieren schaust du einfach mal 
ins Header File rein, weil du eine Funktion benutzen willst, die dir aus 
einem Bruttopreis und dem Steuersatz den Nettopreis berechnen soll.

Du findest die Funktion
1
double calcNetto( double, double );
syntaktisch ist das korrekt. Aber: fehlt dir da nicht eine Information? 
Von den beiden double, die du der Funktion übergeben sollst, welcher ist 
denn der Bruttopreis und welcher ist der Steuersatz?

und jetzt vergleich mal mit
1
double calcNetto( double brutto, double taxPercent );
syntaktisch ist das immer noch die gleiche Information. Der Compiler hat 
alles was er braucht.
Aber was ist mit dir - dem Programmierer? Mit welcher Version kannst du 
auf Anhieb mehr anfangen?

von Mike M. (mikeii)


Lesenswert?

Geht das tatsächlich? Ich hatte die Frage schon genau so verstanden.
Mein MinGW meckert das z.B. an, und meines Wissens nach muss Prototyp 
und Implementierung gleich sein.

von Peter II (Gast)


Lesenswert?

Mike Mike schrieb:
> Geht das tatsächlich?
ja, man kann sogar verschiende namen hinschreiben

> Ich hatte die Frage schon genau so verstanden.
> Mein MinGW meckert das z.B. an, und meines Wissens nach muss Prototyp
> und Implementierung gleich sein.

dann geht ja kein default parameter, denn dort sind beide auch 
verschieden

int f( a int, b int = 0 );

int f( a int, b int ) {
  return a*b;
}

von Stefan E. (sternst)


Lesenswert?

Mike Mike schrieb:
> Mein MinGW meckert das z.B. an,

Beispiel?

> und meines Wissens nach muss Prototyp
> und Implementierung gleich sein.

Nur den Typen nach. Die Namen im Prototyp sind für den Compiler komplett 
irrelevant.

von Mike M. (mikeii)


Lesenswert?

1
/* array10.c */
2
#include <stdio.h>
3
#include <stdlib.h>
4
#define MAX 10
5
void function(int, int);
6
7
void function(int feld[], int n_anzahl) {
8
   int i;
9
10
   for(i = 0; i < n_anzahl; i++)
11
      printf("%d; ", feld[i]);
12
   printf("\n");
13
}
14
15
16
int main(void) {
17
   int val[MAX];
18
   int i;
19
20
   for(i = 0; i < MAX; i++)
21
      val[i] = i+1;
22
23
   function(val, MAX);
24
25
   return 0;
26
}

Gibt conflicting types for function.....



*ach ich depp....


int[] ....


Dann gehts ja wirklich :P Man lernt immer wieder was

von Tar (Gast)


Lesenswert?

Also ich hatte das so in der Art und da kamen etliche Fehler:
1
void fkt (int);
2
3
int main (void {
4
   int b;
5
   fkt(b);
6
}
7
8
void fkt (a){
9
  
10
}

von Mike M. (mikeii)


Lesenswert?

Naja mach mal die Klammer nach void zu

von Garden (Gast)


Lesenswert?


von Mike M. (mikeii)


Lesenswert?

Naja mach mal die Klammer nach void zu und schreib bei der Funktion 
unten den Typen dazu

void fkt (int);

int main (void) {
   int b;
   fkt(b);
}

void fkt (int a){

}


Und jetz die Frage an die Profis, muss da der Typ unten dabei Stehen?
Geht ja jetzt auch ohne :P

Hab ich noch nie so gemacht

von Karl H. (kbuchegg)


Lesenswert?

Tar schrieb:
> Also ich hatte das so in der Art

'in der Art' ist schlecht.

> und da kamen etliche Fehler:
>
> [c]
>
> void fkt (int);
>
> int main (void {
>    int b;
>    fkt(b);
> }
>
> void fkt (a){

void fkt( int a ) {
          ***

Nur weil du beim Protoyp den Parameternamen weglassen kannst, bedeutet 
das nicht im Umkehrschluss, dass du bei der Funktion den Datentyp 
weglassen kannst :-)

von Karl H. (kbuchegg)


Lesenswert?

Mike Mike schrieb:

>
> Und jetz die Frage an die Profis, muss da der Typ unten dabei Stehen?
> Geht ja jetzt auch ohne :P

Welchen 'Typ' meinst du?

> Hab ich noch nie so gemacht

SChau.
Was ist denn der eigentliche Sinn des Funktionsprotoypen.

Der Sinn besteht darin, dass der Compiler überprüfen kann, ob beim 
Aufruf der Funktion

     fkt(b);

die Datentypen passen, ob sie passend gemacht werden können, oder ob das 
gar nicht geht.

Was braucht der Compiler dazu?

> void fkt (int);

Für den Compiler reicht das.
Daraus entnimmt er:
Die Funktion fkt existiert ganz sicher.
Sie übernimmt genau 1 Argument. Und dieses eine Argument ist ein int.
DIe Funktion liefert auch keinen Wert.

D.h. der Compiler ist damit im Bilde, was er bei

   fkt( 2.0 );

zu tun hat, nämlich den double auf einen int runterzucasten. Er weiß 
auch, dass
   fkt( 1, 2 );
illegal ist, weil die Funktion nur 1 Argument nimmt. Ebenso ist

   i = fkt( 2 );

illegal, weil die Funktion nichts liefert.

Damit hat sich die Sache für den Compiler. Für seine Zwecke ist damit 
alles erledigt.
Aber nicht so für den Programmierer. Denn der entnimmt aus dem Namen des 
Arguments noch weitere Information. Funktionsnamen und Variablennamen 
sind Hilfen für den Programmierer - nicht für den Compiler.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> bedeutet
> das nicht im Umkehrschluss, dass du bei der Funktion den Datentyp
> weglassen kannst

Das hat man früher, in Vor-ANSI-C-Zeiten. Das "gute alte" (sprich: 
schreckliche) K&R-C kannte keine Typen in Funktionsdeklarationen:


Statt
1
int bla(int fusel);
2
3
...
4
5
int bla(int fusel)
6
{
7
...
8
}

schrieb man da
1
int bla(fusel);
2
3
...
4
5
int bla(fusel)
6
int fusel;
7
{
8
...
9
}

Bei der Deklaration (Prototyp) einer Funktion kennt man also nur die 
Anzahl der Argumente, nicht aber deren Typen. Damit sind Prototypen in 
K&R-C recht ... nutzarm.

von Karl H. (kbuchegg)


Lesenswert?

Rufus Τ. Firefly schrieb:


> schrieb man da
> int bla(fusel);
>

Nitpicking

int bla( int );

> Bei der Deklaration (Prototyp) einer Funktion kennt man also nur die
> Anzahl der Argumente, nicht aber deren Typen. Damit sind Prototypen in
> K&R-C recht ... nutzarm.

Und demenstprechend fehleranfällig war das ganze dann auch :-)

von Mike M. (mikeii)


Lesenswert?

Um Gottes Willen!

also ich bleib nach wie vor dabei, den Kopf genauso wie bei der 
Implementierung zu schreiben ;)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
>> schrieb man da
>> int bla(fusel);
>>
>
> Nitpicking
>
> int bla( int );

Hier haben wir uns beide geirrt:

Tatsächlich schrieb man
1
int bla();

Ohne Angabe der Argumentanzahl oder -Typen. Ja, K&R-C ist wirklich 
grässlich und gehört deswegen auch gründlich vergessen.

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.