Pointer Übergabeparameter eine Funktion übergeben

Gast #7332880
Lesenswert?

Hallo,

ich habe folgendes Problem in C. Ich möchte quasi einer Init Funktion den Pointer von der List übergeben. Wie müsste der Übergabeparameter lauten?

[test.h] extern sElement List[10];

void Test_Init(....); <= ?????

[main.c] sElement List[10];

//Aufruf Init Funktion Test_Init(...);

Gast #7332895
Lesenswert?

Max schrieb:

ich habe folgendes Problem in C. Ich möchte quasi einer Init Funktion den Pointer von der List übergeben. Wie müsste der Übergabeparameter lauten?

sElement *

[test.h] extern sElement List[10];

Das kann weg, wenn Du das sowieso sauber als Parameter übergibst.

void Test_Init(....); <= ?????

void Test_Init(Element *list_ptr, size_t len);

[main.c] sElement List[10];

Das kann dann auch static sein.

//Aufruf Init Funktion Test_Init(List, sizeof(List) / sizeof(List[0]));

List muß dabei als Array-Deklaration sichtbar sein, was hier aber der Fall ist.

Gast #7332937
Lesenswert?

Nop schrieb:

Geht, sollte man aber nicht so machen, weil die Funktion dann nicht weiß, wie groß das Array ist.

Geht schon, wenn vereinbart wird, daß das Array nullterminiert ist, d.h. mit einem Element endet, in dem alle Elemente Null sind.

Diese Vorgehensweise ist bei Strings in C sehr verbreitet, da ist ein Element halt keine Struktur, sondern nur ein /char/, aber funktional läuft das aufs gleiche raus.

Gast #7333009
Lesenswert?

Émile schrieb:

Geht schon, wenn vereinbart wird, daß das Array nullterminiert ist, d.h. mit einem Element endet, in dem alle Elemente Null sind.

Zum Lesen geht das - aber beim Schreiben, was eine Init-Funktion ja tun soll, müßte man dann vor dem Aufruf alle Elemente bis auf das letzte mit einem ungültigen Wert ungleich null vorinitialisieren. Das ist recht umständlich.

Gast #7333123
Lesenswert?

Vielen Dank für eure Hilfe.

Ich bin etwas unschlüssig wie das alles umsetzen soll. Ich habe quasi eine Instanz in der 5 Elemente enthalten sind. Es stellt sich die Frage soll ich eine Init Funktion erstellen die die Elemente initiallieren soll, ja oder nein?

Gast #7333149
Lesenswert?

Max schrieb:

Ich habe quasi eine Instanz in der 5 Elemente enthalten sind. Es stellt sich die Frage soll ich eine Init Funktion erstellen die die Elemente initiallieren soll, ja oder nein?

Womit werden die Elemente initialisiert? Mit konstanten Werten? Dann brauchst Du keine Init-Funktion, sondern kannst Dein Array gleich beim Definiteren auch initialisieren:

1
typedef struct Element
2
{
3
  uint8_t* Name;
4
  eTimerType Type;
5
  eTimerState State;
6
  uint32_t ValueMillSec;
7
}sElement;
8

9

10
sElement Array[] =
11
{
12
  { "Horst", type1, state1, 34 },
13
  { "Detlef", type0, state7, 123 },
14
 ... etc.
15
};

(angenommen, daß "type1" etc. zu den vermutlich-enums passen).

Gast #7333258
Lesenswert?

Max schrieb:

Es stellt sich die Frage soll ich eine Init Funktion erstellen die die Elemente initiallieren soll, ja oder nein?

Das hängt von mehreren fragen ab:

Was weiß die initfunktion, was du zur compilezeit nicht weißt? Woher kommt der Speicher? Wer macht welche Annahmen über die Liste? Wer garantiert, dass init vor Verwendung aufgerufen wird bzw. alle mit "0" klarkommen.

Die Fragen sind vermutlich schwierig, dann beschreib lieber, was Du machen willst.

Gast #7333320
Lesenswert?

Da es sich um einen Mikrocontroller handelt werde ich nichts dynam7sch machen. Ich möchte die hardwarenahen Timerfunktionen in eine eigene TimerLib verwenden. Diese TimerLib stellt dan die Funktionen nach außen dar. Es sollen zunächst 6 Instanzen (6 Timer) erzeugt werden. Mir stellt sich die Frage wie man sowas richtig umsetzen kann und wie die Initialisierung aussehen könnte. Die Instanzen sollen auch wo anders verwendet werden wie zum Beispiel in der uart, watchdog usw.

Gast #7333327
Lesenswert?

Max schrieb:

nichts dynam7sch machen

Max schrieb:

Es sollen zunächst 6 Instanzen (6 Timer) erzeugt werden.

Wenn es eben geht, ist es einfacher/flexibler, wenn der Nutzer (aufrufer) den Speicherplatz bereitstellt.

Aber ohne Beispiel-Pseudocode oder ein wenig mehr Erklärung ist kaum erkennbar, was Du genau möchtest.

Gast #7333418
Lesenswert?

A. S. schrieb:

wenn der Nutzer (aufrufer) den Speicherplatz bereitstellt

... dann reicht meist ein Pointer in der Struktur für eine einfach verkettete, 0-terminierte Liste, falls eine Liste notwendig ist.

Schleifen zerfallen dann zu

1
for(p=startPtr;p;p=p->next) {...}

Es ist dann gleich, ob 3 oder 300 Timer genutzt werden.

Und Spar Dir gerne den Aufwand der doppelt-verketteten Liste, bis Du die einfache beherrschst. Der Performancegewinn ist in diesem Stadium vernachlässigbar.

Gast #7333569
Lesenswert?

Guten Morgen,

das mit einer verketten Liste habe ich mir auch überlegt. Ich brauche einen Timer für die UART, Watchdog usw. und auch für eventuell sonstige Aufgaben in der Applikation. Wenn ich das mit einer verketten Liste mache, dann muss ich zum Beispiel für die UART immer die Liste nach dem Timer für die UART suchen. Ich werde manuell die Liste erzeugen und dann jeweils zum Beispiel für die UARTT als Übergabeparameter einen Pointer auf das jeweilige Elment von der List übergeben.

Gast #7333573
Lesenswert?

1
typedef struct List
2
{
3
  TimerElement  timerElement[MAX];
4
  TimerElement* z;                             
5
  int   entries;                
6
}List;
1
void Uart_Init(List* pList, eBaudrate baudrate);

Wenn ich dies so tue, woher weis die Uart welchen Timer in der Liste für ihn bestimmt ist? Da muss ich ja wieder in der Liste suchen.

#7333588
Lesenswert?

Max schrieb:

Ich muss ja der UART den zuständige Timer als Übergabeparameter mitteilen.

Nö. Du übergibst dem Scheduler nur die Ablaufzeit und den Callback. Der Scheduler legt dann beides auf einem freien Platz in der Liste ab. Die Ablaufzeit wird dabei schon richtig in die belegten Einträge der Liste einsortiert. Der Timer muß also immer nur einen Eintrag runterzählen.

Gast #7334149
Lesenswert?

Max schrieb:

Ok. Und vorher muss ich aber trotzdem wissen welche EIntrag von der List für die Uart bestimmt ist.

Wofür brauchst Du denn eine Liste?

Im Uart legst Du den Timer

1
static struct sTimer TimerUart;

lokal an. Und arbeitest mit ihm. Init, Start, Stop, Test, ... was immer. Also z.B.

1
TimStart(&TimerUart);

WENN Du für irgendwas eine Liste brauchst (wofür auch immer), DANN mach die mit einer Pointer-verkettung

1
struct sTimer;
2
struct sTimer {
3
    struct sTimer *next;
4
    char *Name;
5
    ...
6
};
7
static FirstTimer = 0;
8
void TimerInit(struct sTimer *T, char *Name, ...)
9
{
10
    /* einketten des neuen Timers */
11
    T->next = FirstTimer;
12
    FirstTimer = T;
13
    ...
14
    T->Name = Name;
15
    ...
16
}

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