Forum: PC-Programmierung C -> Struktur initalisieren


von Jan H. (janiiix3)


Lesenswert?

Moin Moin,

ist es möglich die in der Struktur (cmd_t) befindliche Struktur 
(cmdTable_t) schon am Anfang zu initalisieren?
Und nicht so ->

const cmdTable_t cmdTab[] = "..." ( wie weiter unten..)
1
typedef struct
2
{
3
  cmdTable_t    cmdTable;
4
  cmdRaw_t    cmdRawData;
5
}cmd_t;
6
7
const cmdTable_t cmdTab[] =
8
{
9
  {"set_kx"       ,   "-setk"    ,   NULL   },
10
  {"unset_kx"      ,   "-usetk"  ,  NULL  },
11
12
  {"get_v"      ,  "-gvol"    ,  NULL  },
13
  {"get_i"      ,  "-gcur"    ,  NULL  },
14
  {"get_p"      ,  "-gpwr"    ,  NULL  },
15
  {"get_err"      ,  "-gerr"    ,  NULL  },
16
  
17
  {"write_eep"    ,  "-weep"    ,  NULL  },
18
  {"read_eep"      ,  "-reep"    ,  NULL  },
19
  {"clear_eep"    ,  "-ceep"    ,  NULL  },
20
  
21
  {"set_user"      ,  "-suser"  ,  NULL  },
22
  {"set_sernr"    ,  "-ssrn"    ,  NULL  },  
23
  {"set_time"      ,  "-stme"    ,  NULL  },  
24
};

Ich möchte meiner Funktion nicht unnötig zwei Parameter übergeben. Wenn 
ich die Struktur schon am Anfang einmal initalisieren lasse ( const ) 
brauche ich später dort nichts mehr rein zu schreiben.

: Verschoben durch Moderator
von Markus F. (mfro)


Lesenswert?

Frage ist nicht klar. Möchtest Du

- verschachtelte Strukturen initialisieren oder gar
- eine Struktur initialisieren, bevor sie im Programm bekannt ist

??

von Einer K. (Gast)


Lesenswert?

Meines Wissens nach, in C nicht möglich.

in C++ könnte das so aussehen:
1
struct Test
2
{
3
  const byte pin; 
4
  uint16_t count;
5
  Test(const byte pin):pin(pin),count(0){}
6
};
7
8
Test array[] {2,3,4,5};

Das Test.pin stammt aus der Initialisierungsliste
Test.count wird auf 0 gesetzt

Falls dich das nicht befriedigt, gilt:
Markus F. schrieb:
> Frage ist nicht klar.

von egger (Gast)


Lesenswert?

Oder möchtest du das?
1
typedef struct
2
{
3
  cmdTable_t    cmdTable;
4
  cmdRaw_t    cmdRawData;
5
}cmd_t;
6
7
static const cmd_t cmd[] = { 
8
 {
9
   (cmdTable_t){ "set_kx", "-setk", NULL }, (cmdRaw_t)wasAuchImmer1
10
 },
11
 {
12
   (cmdTable_t){ "get_v", "-gvol", NULL }, (cmdRaw_t)wasAuchImmer2
13
 },
14
 {
15
   (cmdTable_t){ "get_i", "-gcur", NULL }, (cmdRaw_t)wasAuchImmer3
16
 }
17
};

und dann geht auch z.B:
1
cmd[0].cmdTable.callback(cmd[0].cmdRawData);

von A. S. (Gast)


Lesenswert?

Da nicht klar ist, was Du meinst, reduzier Dein Beispiel so weit es 
geht, z.B.:
1
typedef struct
2
{
3
  cmdTable_t    cmdTable;
4
  cmdRaw_t    cmdRawData;
5
}cmd_t;
6
7
const cmdTable_t cmdTab[] =
8
{
9
  {"a","b",0},
10
  {"c","d",0},
11
};
cmdTable_t und cmdRaw_t sind nicht bekannt. Egal, wir nehmen an, dass 
erstere unten "richtig" gefüllt wurde.

Unten hast Du ein Array, oben nur ein Feld. Die beiden cmdTable_t haben 
also nichts miteinander zu tun.

Möchtest du eine Instanz von cmd_t initialisieren? ja, das geht, z.B. 
so:
1
cmd_t myCmd = {
2
  {"e","f",0},  /* cmdTable analog Deinem Beispiel */
3
  {3,4,5,6,7}   /* wie auch immer cmdRawData gefüllt werden muss */
4
}

da der erste Eintrag aber cmd*Table* genannt ist, meinst Du vermutlich 
etwas anderes, als Du schreibst.

von Jan H. (janiiix3)


Lesenswert?

Damit "cmd_t cmd[]"
würde ich ja mehrere Strukturen von der Struktur ansich anlegen.
Was ich wollte sind mehrere Strukturen vom Member "cmdTable_t 
cmdTable;".
Diese sollten dann halt mit einem Wert einmal initalisiert werden.
Sonst würde ich mit "cmd_t cmd[]" unnötig Speicherplatz verschenken.

Pseudocode
1
typedef struct  
2
{
3
  cmdTable_t  table[10];
4
  cmdRaw_t  raw;
5
}cmd_t;
6
7
cmd_t cmd =
8
{
9
  (cmdTable_t){ NULL , NULL , NULL }, // [0]
10
  (cmdTable_t){ NULL , NULL , NULL }, // [1]
11
  (cmdTable_t){ NULL , NULL , NULL }, // [2]
12
  (cmdTable_t){ NULL , NULL , NULL }, // [3]
13
};
So meine ich das..

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

Jan H. schrieb:
> So meine ich das..

Zumindest mir (aber da scheine ich nicht alleine zu sein, die Anderen 
raten ja auch nur rum) ist deine Frage immer noch nicht klar. Im 
Gegenteil.

Dein letztes Beispiel ist etwas ganz anderes, als das zuerst gepostete.

von Falk B. (falk)


Lesenswert?

@Jan H. (janiiix3)

>Diese sollten dann halt mit einem Wert einmal initalisiert werden.
>Sonst würde ich mit "cmd_t cmd[]" unnötig Speicherplatz verschenken.

Nicht wirklich. Denn cmt_t cmd braucht so oder so den vollen 
Speicherplatz. Lediglich die Initialisierungsdaten landen dann halt 
mehrfach im Flash und werdem bei der C-Init Sequenz in die RAM-Variable 
kopiert. So what! Mußt du WIRKLICH so sehr Speicher sparen? Oder ist das 
eher Einbildung.

Wenn du denn WIRKLICH meinst, das tun zu müssen, mußt du das zur 
Laufzeit über eine Schleife und memcpy machen, dann reicht es, einmal 
die Init-Daten in dein Array zu kopieren.

von A. S. (Gast)


Lesenswert?

Kennst Du Pointer? Wenn ja, dann verweise immer dort, wo Du das gleiche 
mehrfach haben möchtest, mit einem Pointer auf eine Instanz.

Wenn nein, dann formuliere einmal ein Beispiel aus und schreibe dazu, 
was Du anders haben möchtest oder was nicht klappt.

Dein Pseudocode wäre in C übrigns:
Jan H. schrieb:
1
cmd_t cmd =
2
{
3
  /* eigene Klammern für das Array zuerst */
4
  {
5
      { NULL , NULL , NULL }, // [0]
6
      { NULL , NULL , NULL }, // [1]
7
      { NULL },               /* [2] Wenn nur noch Felder mit 0 kommen,       
8
      { NULL },               /* [3] */
9
      /* und auch die letzten 6 kannst Du weglassen, wenn 0 */
10
  }, /* die Tabelle ist initialisiert */
11
  /* und jetzt Deine zweite Struktur */ 
12
  { 
13
    1, /* erstes Element (was immer Du da hast) */
14
    2,
15
    3,
16
    4  /* 4tes Element, geraten... */
17
  }
18
};
Dein (cmdTable_t) ist übrigens unnütz.

von Falk B. (falk)


Lesenswert?

@Achim S. (achs)

>Kennst Du Pointer? Wenn ja, dann verweise immer dort, wo Du das gleiche
>mehrfach haben möchtest, mit einem Pointer auf eine Instanz.

Nö, denn dann hast du nur viele Verweise (Pointer) auf eine Instanz. Das 
ist NICHT das Gleiche, wie wenn man mehrere Instanzen mit den gleichen 
Daten initialisieren will, denn danach will man den Inhalt der Instanzen 
vielleicht auch ändern?

von M. K. (kichi)


Lesenswert?

Falk B. schrieb:
> Das
> ist NICHT das Gleiche, wie wenn man mehrere Instanzen mit den gleichen
> Daten initialisieren will, denn danach will man den Inhalt der Instanzen
> vielleicht auch ändern?

Glaube ich nicht, denn:

Jan H. schrieb:
> Wenn
> ich die Struktur schon am Anfang einmal initalisieren lasse ( const )
> brauche ich später dort nichts mehr rein zu schreiben.

von Jan H. (janiiix3)


Lesenswert?

Das klappt mit dem init. nicht..
1
typedef struct
2
{
3
  /*
4
  *  Name des Kommandos
5
  */
6
  char  name[20];
7
  
8
  /*
9
  *  Befehl der empfangen werden muss
10
  */
11
  char  instruction[15];
12
      
13
  /*
14
  *  Funktion die beim entsprechenden Kommando 
15
  *  ausgeführt werden soll
16
  */  
17
  void*  (*fnc) (void* , void*);
18
  
19
}cmdTable_t;
20
21
typedef struct  
22
{
23
  uint8_t dataInRawBuff :1;
24
  char cmdRawBuff[CMD_SIZE_OF_MAX_RAW_DATA];  
25
}cmdRaw_t;
26
cmdRaw_t cmdRaw;
27
28
typedef struct  
29
{
30
  cmdTable_t  table[4];
31
  cmdRaw_t  raw;
32
}cmd_t;
33
34
cmd_t cmd =
35
{
36
  {
37
    { NULL , NULL , NULL }, // [0]
38
    { NULL , NULL , NULL }, // [1]
39
    { NULL , NULL , NULL }, // [2]
40
    { NULL , NULL , NULL }, // [3]    
41
  },
42
  {
43
    0,
44
    .cmdRawBuff = "",
45
  },
46
};

von A. S. (Gast)


Lesenswert?

lass bitte das bitfeld weg (wozu auch), also:

uint8_t dataInRawBuff;

Und statt  .cmdRawBuff = ...
besser gernichts oder wenn überhaupt:

{{0}}

Zudem hast Du jeweils noch ein Komma am Ende zuviel (egal, obs vom 
Compiler ignoriert wird oder nicht).

Fang einfach mit leeren Mengen an und initialisiere jeweils ein element 
mehr. Und wenn das eine element mehr nicht klappt, dann lies dir die 
Fehlermeldung durch. Und wenn Du damit nichts anfangen kannst, dann 
poste sie hier. So ist das alles nur ein großer, nicht funktionierender 
Matsch, der Dich und uns nicht weiter bringt.

von DPA (Gast)


Lesenswert?

Wie wärs mit sowas:
1
#include <stdbool.h>
2
#include <stddef.h>
3
4
#define CMD_SIZE_OF_MAX_RAW_DATA 256
5
6
typedef struct cmdTable {
7
  const char*  name;
8
  const char*  instruction;
9
  void*  (*fnc) (void* , void*);
10
} cmdTable_t;
11
12
typedef struct cmdRaw {
13
  bool dataInRawBuff;
14
  char cmdRawBuff[CMD_SIZE_OF_MAX_RAW_DATA];
15
} cmdRaw_t;
16
17
typedef struct cmd {
18
  const struct cmdTable* table;
19
  size_t table_length;
20
  struct cmdRaw* buffer;
21
} cmd_t;
22
23
// (Nicht definierte felder werden mit 0 initialisiert)
24
static const struct cmdTable table[] = {
25
  { "set_kx", "-setk" },
26
  {
27
    .name = "unset_kx",
28
    .instruction = "-usetk"
29
  },
30
};
31
32
struct cmd cmd = {
33
  .table = table,
34
  .table_length = sizeof(table)/sizeof(*table),
35
  .buffer = &(struct cmdRaw){0},
36
};
37
38
int main(){}

von Markus F. (mfro)


Lesenswert?

Weil's falsch ist. So (z.B.) ginge das:
1
cmd_t cmd =
2
{
3
  {
4
    { {0} , {0} , NULL }, // [0]
5
    { {0} , {0} , NULL }, // [1]
6
    { {0} , {0} , NULL }, // [2]
7
    { {0} , {0} , NULL }, // [3]
8
  },
9
  {
10
    0,
11
    .cmdRawBuff = "",
12
  },
13
};

name und instruction sind char-Arrays, keine Zeiger. Entsprechend kann 
man sie nicht mit einem NULL-Zeiger initialisieren.

Ob das natürlich das ist, was Du wirklich haben willst, kannst nur Du 
selbst wissen (uns verrätst Du's ja nicht).

von Jan H. (janiiix3)


Lesenswert?

DPA schrieb:
> Wie wärs mit sowas:
>
1
> struct cmd cmd = {
2
>   .table = table,
3
>   .table_length = sizeof(table)/sizeof(*table),
4
>   .buffer = &(struct cmdRaw){0},
5
> };
6
> 
7
> int main(){}
8
>

Die Variante sieht gut aus. Werde ich nehmen.
Kurze Frage noch..
1
>   .table_length = sizeof(table)/sizeof(*table),
Müsste das nicht so lauten?
1
.table_length = sizeof(table)/sizeof(table[0]),

von Karl M. (Gast)


Lesenswert?

Hallo Jan,

C Grundlagen, ist das selben.

Jan H. schrieb:
>>   .table_length = sizeof(table)/sizeof(*table),
> Müsste das nicht so lauten?.table_length =
> sizeof(table)/sizeof(table[0]),

von Jan H. (janiiix3)


Lesenswert?

Karl M. schrieb:
> Hallo Jan,
>
> C Grundlagen, ist das selben.
>
> Jan H. schrieb:
>>>   .table_length = sizeof(table)/sizeof(*table),
>> Müsste das nicht so lauten?.table_length =
>> sizeof(table)/sizeof(table[0]),

Ja natürlich.. Peinlich! Danke.

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.