Syntax Frage in C

OP #2483448
Lesenswert?

Hi Zusammen..

Ich habe ne Frage bezüglich Syntax oder ob das überhaupt geht.

Ich habe 10 Funktionen, die alle gleich heissen aber am Schluss nur ne 
andere Zahl haben. (void led1 () - void led10 ())

Jetzt würde es mich interessieren, ob ich im Funktionsaufruf irgendwas 
schreiben kann von wegen void led[x] (); und dann die Variable "x" 
raufzählen kann. Ist sowas möglich?

MFG
Dave
Gast #2483476
Lesenswert?

Hi

weiß ja nicht was du genau vorhast aber du könntest dir evtl mit einer 
weiteren Funktion mit einer switch-case abfrage weiterhelfen die dann je 
nach variablenwert auf die entsprechende LED() funktion verweist...
OP #2483485
Lesenswert?

Lukas v. d. I. schrieb:
> weiß ja nicht was du genau vorhast aber du könntest dir evtl mit einer
> weiteren Funktion mit einer switch-case abfrage weiterhelfen die dann je
> nach variablenwert auf die entsprechende LED() funktion verweist...

Ja das ist sogar mein Plan :)
Wollte nur beim Case '1' led1 Case '2' led1 + led2 etc..

Ich werde wohl die Funktionen noch etaws umschreiben, dachte vllt. geht 
das wie ich mir das vorgestellt habe mit dem led[x] oder led'x' oder was 
auch immer.

Danke für eure Hilfe
#2483488
Lesenswert?

Dave Chappelle schrieb:
> void led[x] (); und dann die Variable "x"
> raufzählen kann. Ist sowas möglich?

Im Prinzip ist das schon möglich. Man kann in C ein Array mit 
Funktionspointern anlegen und die dann so änhlich aufrufen, wie Du es 
beschrieben hast.
Für Deine Anwendung macht das aber keinen Sinn.
Du kannst es so lösen, wie es Michael beschreibt; mit einer Funktion, 
bei welcher Du Parameter mitgibst.
Suche mal im Internet mittels Stichworten wie "C", "Funktion", 
"Parameter", ...
#2483495
Lesenswert?

Ahmed schrieb:
> mach einen Array von Funktionsadressen. Dann rufe den jeweiligen Eintrag
> auf.

:-) War auch mein erster Gedanke. ich glaube aber was Dave machen will 
geht auch viel einfacher.

Der Plan mit einer Funktion und dann mit switch -case verzweigen sollte 
dich gut und übersichtlich zum Ziel führen.
Wie Funktionen allgemein verwendet werden kannst du bei Dr.Google oder 
old school in einem C-Buch nachlesen.

L.g.
#2483516
Lesenswert?

Ahmed schrieb:
> Optimaler sieht es so aus wie bereits
> hingewiesen:
>
> irgendwo oben im Code:
> void (*led[4]) (void) = {led0, led1, led2, led3,...};
>
> irgendwo unten:
> led[x]();

Bitte schlagt doch einem Anfänger nicht so seltsame Sachen vor. Wenn man 
so etwas für nötig hält, hat man wahrscheinlich schon konzeptionell 
irgendwas schwer verbockt. Wahrscheinlich will er doch nur LED x 
umschalten oder so was.
Gast #2483520
Lesenswert?

Da fragt einer nach einfachen Funktionsaufrufen und ihm wird gleich zu 
Zeigern geraten... traurig.

So etwas mahcht jeder mit einfachen Parametern, in der Funktion dann mit 
case unterscheiden. Fertig.

Und das ist mit Sicherheit übersichtlicher als der Zeiger-Kram...
Gast #2483553
Lesenswert?

Mad schrieb:
> Da fragt einer nach einfachen Funktionsaufrufen und ihm wird gleich zu
> Zeigern geraten... traurig.

Es gibt unendlich viele Arten, das ganze zu realisieren. Geraten wurde 
ihm zur optimalen Lösung. Das andere "Mad" sind, weil sie kein C können, 
steht hier nicht zur Diskussion.

Wenn der TE damit nichts anfangen kann (nichts gegen dich, Dave), dann 
muss er solange C Tutorials wälzen, bis er etwas damit anfangen kann. 
Oder nicht solche Fragen stellen. Nicht in einem Mikrocontroller-Forum. 
Vielleicht eher in einem C-For-Kids Forum.
OP #2483574
Lesenswert?

Oke ich muss mal kurz was richtigstellen.
Die Übergabe eines Parameters erachte ich als nicht so sinnvoll (ausser 
ich habe da etwas falsch verstanden).
In meinen einzelnen Funktionen werden Pins gesetzt, in allen Funktionen 
verschiedene.

also z.B.
1
void led8 ()
2
{
3
kathode1 = 1;
4
kathode2 = 0;
5
PORTC = 0x00;
6
anode4 =1;
7
}

Das mit dem Array habe ich mir auch überlegt, da wusste ich nur noch 
weniger wie die Syntax aussieht :)

Habe noch nie ein Funktionen-Array benutzt.
Ich weiss aber was ein Array ist und auch was Pointer sind, nur bin ich 
eben erst am Anfang.

Ahmed schrieb:
> Oder nicht solche Fragen stellen. Nicht in einem Mikrocontroller-Forum.
> Vielleicht eher in einem C-For-Kids Forum.

Ich denke mir Experten können auch triviale Fragen beantworten?
Natürlich ist die Frage nicht schwer, wenn man C voll umfänglich 
versteht!
Gast #2483604
Lesenswert?

Dave Chappelle schrieb:
> Ich denke mir Experten können auch triviale Fragen beantworten?
> Natürlich ist die Frage nicht schwer, wenn man C voll umfänglich
> versteht!


Ja. Hab mich nur etwas aufgeregt über: traurig, einen Neuling mit 
Pointern zu verunsichern. Offensichtlich hat der "Neuling" ja schon mal 
Kontakt mit Pointern gehabt. Außerdem kommt man als Programmierer um 
Zeiger nicht herum, dass ist nicht nur ein Thema für "Experten".

Es gibt zwei Lösungswege. Der intuitive über Switch...case...case oder 
das gleiche per If...else...else. Dies erzeugt einen langen Quelltext 
und braucht auch bei der Ausführung viel Zeit, besonders wenn die 
häufigsten Case/Else-Zweige unten stehen.

Die bessere/übersichtlichere Lösung sind die Funktionspointer. 
Eigentlich nicht schwer zu nutzen. Braucht sehr wenige Zeilen Quelltext, 
und die Ausführung ist sehr viel schneller.

Wenn die Größe der Firmware egal ist (weil sowieso sehr klein), dann 
kann man auch Makros nutzen. Aber die Vor- und Nachteile von Funktionen 
vs. Makros sind ja allgemein bekannt. Dafür definiert man oben etwas 
wie:

#define macro_led0() PORTC = 0x00; anode4 =1

und unten im Code sagt man dann

macro_led0();

Hoffe die Diskussion ist hilfreich.
Gast #2483633
Lesenswert?

#include <stdio.h>

//Funktionen, die die LEDs schalten:
void led0(void) {printf("led0\n");}
void led1(void) {printf("led1\n");}
void led2(void) {printf("led2\n");}

//Funktionsarray:
void (*led[3]) (void) = {led0, led1, led2};

//Aufruf im Hauptprogramm:
int main(void) {
led[0]();
led[1]();
led[2]();
}
Gast #2483650
Lesenswert?

>> Allerdings werde ich nicht um einen Switch kommen, da je nach grösse
>> meiner Variable eine bestimmte Funktion aufgerufen werden muss.

Genau dieser Zusammenhang sollte von dir erklärt werden. So ist es ein 
Ratespiel.

Beispiel: In Abhängigkeit eines AD Wandlerwertes sollen 1-20 LEDs 
geschaltet werden z.B. als Leuchtband (LED Kette). Wenn das Ganze linear 
verläuft dann packt man das in eine Formel und berechnet die Anzahl der 
LEDs und übergibt das an eine einzige Ausgabe welche den Parameter 
(AnzahlLeds) aufnehmen kann.
OP #2483653
Lesenswert?

Ticker schrieb:
> #include <stdio.h>
>
> //Funktionen, die die LEDs schalten:
> void led0(void) {printf("led0\n");}
> void led1(void) {printf("led1\n");}
> void led2(void) {printf("led2\n");}
>
> //Funktionsarray:
> void (*led[3]) (void) = {led0, led1, led2};
>
> //Aufruf im Hauptprogramm:
> int main(void) {
> led[0]();
> led[1]();
> led[2]();
> }

Das klingt gut, das war es, was ich gesucht habe.
Falls schon jemand von dieser Lösung sprach, sorry, habe es wohl nicht 
auf Anhieb verstanden!
Danke für die ausführliche Beschreibung.
#2483802
Lesenswert?

Oh Mann.

Da hat einer Schwierigkeiten mit Funktionsargumenten und wahrscheinlich 
ist seine Lösung darin zu suchen, dass er sich ganz einfach ein Array 
mit Masken zurechtlegt, welches er über einen Index anspricht und ihr 
ratet ihm zu Funktionspointern.

Seid ihr noch zu retten?
#2483805
Lesenswert?

Dave Chappelle schrieb:


> Ich denke mir Experten können auch triviale Fragen beantworten?
> Natürlich ist die Frage nicht schwer, wenn man C voll umfänglich
> versteht!


Von vollumfänglich kann überhaupt nicht die Rede sein!
Das sind banalste Grundlagen.
Sozusagen 3. Stunde C Unterricht von 20.

Beschreib endlich dein wirkliches Problem und hör auf eine Lösung zu 
verfolgen, die dich in deiner C Entwicklung nicht weiterbringt.
#2483809
Lesenswert?

Ahmed schrieb:
> Mad schrieb:
>> Da fragt einer nach einfachen Funktionsaufrufen und ihm wird gleich zu
>> Zeigern geraten... traurig.
>
> Es gibt unendlich viele Arten, das ganze zu realisieren.

Entschuldige aber das ist einfach nur kompletter Blödsinn! Einem 
Anfänger zeigt man nicht die komlpexeste und komplizierteste Art, wie er 
dieses Problem angehen kann. Wenn er in einem Jahr das erste mal auf 
Funktionspointer stösst, dann ist das früh genug. Früher braucht kein 
Mensch Funktionspointer.
Das macht mich richtig wütend, dass du du diesen Unsinn auch noch 
verteidigst.

Er soll seine 8 oder 10 Funktionen herzeigen, dann sieht man mal weiter 
mit welcher Technik man die 10 Funktionen zu einer einzigen 
zusammenfassen kann.
Gast #2483813
Lesenswert?

Dave Chappelle schrieb:
> In meinen einzelnen Funktionen werden Pins gesetzt, in allen Funktionen
> verschiedene.
>
> also z.B.
>
> void led8 ()
> {
> kathode1 = 1;
> kathode2 = 0;
> PORTC = 0x00;
> anode4 =1;
> }

die prozedur sollte also setPins(_param1, ... _paramx) heißen?

solang dir der speicher reicht schreibs so wie es für dich am les- 
debug- und wartbarsten ist :)
#2483968
Lesenswert?

Karl Heinz Buchegger schrieb:
> Oh Mann.
>
> Da hat einer Schwierigkeiten mit Funktionsargumenten und wahrscheinlich
> ist seine Lösung darin zu suchen, dass er sich ganz einfach ein Array
> mit Masken zurechtlegt, welches er über einen Index anspricht und ihr
> ratet ihm zu Funktionspointern.
>
> Seid ihr noch zu retten?

+1k

Dave, in deinem eigenen Interesse, ignorier den Müll mit Pointern hier. 
Du musst daran arbeiten das was du programmieren willst in eine 
möglichst einfache Logik zu verpacken (das ist quasi die Vorarbeit die 
du leisten musst) und dann schreibt sich das in C auch ganz einfach.

Wahrscheinlich kannst du ein Array machen wo all deine "Schalter" drin 
sind für jede LED, also der Zustand von kathode1, kathode2, anode4, 
portc und allen anderen. Dann rufst du deine Funktion auf mit 
led_schalten(i), und in der Funktion selber setzt du all die variablen 
(kathode, port etc.) auf den wert im array mit index i.
Gast #2483992
Lesenswert?

Mad schrieb:
> Definitiv NEIN.
>

Doch, das ganze nennt man Funktionszeiger.

http://www.mbernstein.de/atari/prog/kurse/c-kurs/0a08.htm


Ticker schrieb:
> Es gibt zwei Lösungswege. Der intuitive über Switch...case...case oder
> das gleiche per If...else...else. Dies erzeugt einen langen Quelltext
> und braucht auch bei der Ausführung viel Zeit, besonders wenn die
> häufigsten Case/Else-Zweige unten stehen.

Wenn die Frage, welche Funktion aufgerufen werden soll, in der 
Aufrufenden Funktion abgefragt wird, ist hier mit Funktionszeigern nicht 
viel gewonnen.
In diesem Fall ist die Switch/Case Anweisung sinnvoller, da sie zu 
besserem wartbarerem Code führt.

Es hängt halt ganz vom Code ab.
Wenn in der aufrufenden Funktion sowieso eine Abfrage enthalten ist und 
dort z.B. mehrere Dinge ausgeführt werden, dann können die 
Funktionszeiger durchaus Sinn machen.



Ansonsten sind Switch/Case Anweisungen verglichen mit mehreren If/Else 
Abfragen sehr effizient. Wenn möglich sollte man eine Switch Anweisung 
einem If/Else Block immer vorziehen.
Gast #2484001
Lesenswert?

Dave Chappelle schrieb:
> Lukas v. d. I. schrieb:
>> weiß ja nicht was du genau vorhast aber du könntest dir evtl mit einer
>> weiteren Funktion mit einer switch-case abfrage weiterhelfen die dann je
>> nach variablenwert auf die entsprechende LED() funktion verweist...
>
> Ja das ist sogar mein Plan :)
> Wollte nur beim Case '1' led1 Case '2' led1 + led2 etc..
>

Kann man zwar machen, aber eine extra Funktion, die nur schaut, welche 
Funktion aufgerufen werden soll, führt zu mindestens einem überflüssigen 
Funktionsaufruf.

Das ist also langsamer als eine Funktion, die für alle LEDs da ist.
Gast #2484021
Lesenswert?

Johannes G. schrieb:

> Wahrscheinlich kannst du ein Array machen wo all deine "Schalter" drin
> sind für jede LED, also der Zustand von kathode1, kathode2, anode4,
> portc und allen anderen. Dann rufst du deine Funktion auf mit
> led_schalten(i), und in der Funktion selber setzt du all die variablen
> (kathode, port etc.) auf den wert im array mit index i.

Ich würde das ganze einfach in ein Struct packen und vom Struct dann ein 
Array anlegen.

struct leds{
  bool kathode1;
  bool kathode2;
  bool anode4;
  int portc;
}

struct leds x[5];


Und dann die jeweiligen x Einträge einmalig initialisieren. (das kann 
auch in einer extra Init Funktion geschehen.
x[0].kathode1 = 0;
...
x[0].portc = 0x00;

...
x[5].kathode1 = 1;
...
x[5].portc = 0x00;


Anschließend einfach eine Funktion setLed(leds x) aufrufen, die das 
jeweilige Struct als Parameter aufnimmt.

Aufgruf geht dann mit
setLed(*x[4]);


Siehe auch:
http://en.wikipedia.org/wiki/Struct_%28C_programming_language%29

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren