Forum: Compiler & IDEs C Funktion mit Parametern unterschiedlichen Datentyps


von Michael L. (eagle87)


Lesenswert?

Hallo zusammen,
gibt es in C die Möglichkeit eine Funktion mit unterschiedlichen 
Datentypen auszuführen?

Beispiel:
1
uint8_t inc(uint16_t *var, uint16_t bottom, uint16_t top)
2
{
3
  if(*var<top)
4
  {
5
    ++(*var);
6
    return 0;
7
  }
8
  else
9
  {
10
    *var=bottom;
11
    return 1;
12
  }
13
}

Diese Funktion will ich mit uint8_t und uint16_t Variablen als 
Übergabeparameter ausführen können.

Gruß
Michael

von Peter II (Gast)


Lesenswert?

Michael L. schrieb:
> gibt es in C die Möglichkeit eine Funktion mit unterschiedlichen
> Datentypen auszuführen?

für diesen zweck nicht wirklich. Hier könnte man sogar über ein Makro 
nachdenken, dann ist der type egal.

von Michael L. (eagle87)


Lesenswert?

Hallo Peter,
wie würde das mit dem Makro gehen? Ich brauch nämlich einen 
Rückgabewert.
1
#define  inc(var, bottom, top)  ({if( (var) < (top) ){++(var); return 0;}  else{(var) = (bottom); return 1;} })
liefert
1
warning: ‘return’ with a value, in function returning void
und
1
error: lvalue required as left operand of assignment

Gruß
Michael

von Peter II (Gast)


Lesenswert?

#define inc(var, bottom, top) ( (var) < (top) ? ++var, 0 : var = bottom, 
1 )

ungetestet

von Michael L. (eagle87)


Lesenswert?

Geht leider auch nicht.
1
games/X01.c:135:5: error: lvalue required as left operand of assignment
2
games/X01.c:135:8: warning: left-hand operand of comma expression has no effect
3
games/X01.c:135:5: error: lvalue required as left operand of assignment
4
games/X01.c:135:41: warning: left-hand operand of comma expression has no effect
5
games/X01.c:135:41: warning: statement with no effect

Der Aufruf sieht übrigens so aus:
1
if(inc(player, 1, numberofplayers)) inc(lap, 1, 99);

von Peter II (Gast)


Lesenswert?

so geht es bei mir durch den Compiler, ob es geht habe ich nicht 
getestet

#define inc(var, bottom, top) ( (var) < (top) ? var++, 0 : (var=bottom, 
1) )

von Dr. Sommer (Gast)


Lesenswert?

Und deswegen gibt es C++ und Meta-Programmierung:
1
template <typename T>
2
bool inc (T& var, T bottom, T top) {
3
  if (var < top) {
4
    var++;
5
    return false;
6
  } else {
7
    var = bottom;
8
    return true;
9
  }
10
}
Aufzurufen z.B. so:
1
uint8_t bla;
2
if (inc (bla, 2, 27)) {
3
}
oder:
1
uint16_t bla;
2
if (inc (bla, 2, 2217)) {
3
}
Oder beliebigen anderen Integer-Typen. Im Endeffekt wird für jeden 
angebenen Typ eine eigene Funktion speziell für diesen Typ erzeugt, die 
dann auch entsprechend effizient ist.

Dies ist dann auch typsicher, d.h. so etwas wird vom Compiler 
angemeckert:
1
uint8_t bla;
2
if (inc (bla, 2, 2217)) {
3
}
und hat einen eigenen Scope und Typ, im Gegensatz zum Makro, und ist 
deswegen vorzuziehen.

von Peter II (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Und deswegen gibt es C++ und Meta-Programmierung:

er wollte aber

> gibt es in C die Möglichkeit

von Dr. Sommer (Gast)


Lesenswert?

Peter II schrieb:
> er wollte aber
>
>> gibt es in C die Möglichkeit
Diese Anforderung hat er vermutlich nur angegeben weil er kein C++ 
kannte; er kann mit großer Wahrscheinlichkeit einfach seinen Code mit 
einem C++ Compiler compilen und die C-Kompatibilität von C++ nutzen.

von Michael L. (eagle87)


Lesenswert?

@Peter:
Jetzt kompilierts bei mir auch ohne Fehler und Warnung. Die Klammer um 
"var=bottom, 1" hat geholfen. Testen werd ichs aber heute nicht mehr. 
Vielen Dank für die Hilfe.

@Dr. Sommer:
Dass es in C++ mehr Möglichkeiten gibt war schon bekannt. Es ging 
wirklich explizit um C. Dennoch danke für den Post.

von Rosa-Kleidchen (Gast)


Lesenswert?

Ich wuerde einen void-pointer verwenden (void *var).
Rosa

von Peter II (Gast)


Lesenswert?

Rosa-Kleidchen schrieb:
> Ich wuerde einen void-pointer verwenden (void *var).
> Rosa

und dann weiter? wie willst du mit einen void inrement machen?

von Rosa-Kleidchen (Gast)


Lesenswert?

Übergebe einen Void-Pointer und carste das dann in der Funktion abhängig 
von dem, was Du erwartest:

int8 var8;
int16 var16;

void myFunction (void *var, int kind) {
  if (0 == kind) {
    int8 var8 = (int8) *var;
    ...
  } else {
    int16 var16 = (int16) *var;
    ...
  }
  ...
}


myFunction ((void *) &var8, 0);
myFunction ((void *) &var16, 1);

Rosa

von type cast (Gast)


Lesenswert?

Rosa-Kleidchen schrieb:
> carste

Grüße an Cartsen ...

von Sven P. (Gast)


Lesenswert?

Rosa-Kleidchen schrieb:
> int8 var8;
> int16 var16;
>
> void myFunction (void *var, int kind) {
>   if (0 == kind) {
>     int8 var8 = (int8) *var;
>     ...
>   } else {
>     int16 var16 = (int16) *var;
>     ...
>   }
>   ...
> }

Das geht in die Hose.

von Peter II (Gast)


Lesenswert?

Rosa-Kleidchen schrieb:
> Übergebe einen Void-Pointer und carste das dann in der Funktion abhängig
> von dem, was Du erwartest:

naja, aber dann kann man auch gleich 2 Funktionen schreiben.

von Rosa-Kleidchen (Gast)


Lesenswert?

>Das geht in die Hose.
Jau, ist nur exemplarisch. Ich vergass den rechtlichen Hinweis.

von Dr. Sommer (Gast)


Lesenswert?

Rosa-Kleidchen schrieb:
> Übergebe einen Void-Pointer und carste das dann in der Funktion abhängig
> von dem, was Du erwartest:
Diese C-Ineffizienz... Langsamer und am Ende auch noch größer als die 
C++ Template Version... Typunsicher sowieso.

Michael L. schrieb:
> Es ging
> wirklich explizit um C. Dennoch danke für den Post.
Wenn das nicht gerade eine Hausaufgabe ist in der steht "schreiben Sie 
in C..." gibt es eigentlich kaum einen Grund nicht einfach mit C++ zu 
compilen, die template-Funktion reinzuschreiben und den ganzen 
restlichen Code zu lassen wie er ist...

von Andreas B. (andreas_b77)


Lesenswert?

Rosa-Kleidchen schrieb:
>     int8 var8 = (int8) *var;

Einen void* kann man nicht dereferenzieren. Wenn schon, dann
1
int8_t var8 = *(int8_t *)var;

> myFunction ((void *) &var8, 0);

Casts sind hier unnötig. Umwandlungen zwischen void* und anderen 
Pointern funktioneren auch ohne.

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.