Forum: PC-Programmierung parameter in structure beschreiben


von Franz (Gast)


Lesenswert?

Hallo,
ich habe eine Struktur mit normalen Parametern und constanten parametern
1
typedef struct
2
{
3
    const uint8_t constValue;
4
    uint8_t value;
5
}struct_ts

den Wert value kenne ich erst in einer Funktion, da dieser von einem 
anderen Modul kommt. den constValue kenne ich schon zu beginn.
Jetzt möchte ich eine Structur struct_s erstellen, welche für eine ganze 
Datei gillt
1
static struct_ts struct_s = 
2
{
3
  .constValue = 0x85,
4
  .value = 0x00,
5
};
.
Das Problem ist, dass ich hier für den wert Value einen dummywert 
eingeben muss und diesen in einer späteren Funktion wieder überschreiben 
muss.
In der init funktion kann ich den wert constValue aber nicht mehr 
beschreiben.
1
static struct_ts struct_s;
2
3
void init(void)
4
{
5
  struct_s.constValue = 0x85;  // geht nicht
6
  struct_s.value = getValue();
7
}

gibt es eine möglichkeit die Struktur nur an einer Stelle zu 
beschreiben?
Also am besten in der init-funktion, da ich dort an value komme.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Franz schrieb:

> typedef struct
> {
>     const uint8_t constValue;
>     uint8_t value;
> }struct_ts
...
> In der init funktion kann ich den wert constValue aber nicht mehr
> beschreiben.static struct_ts struct_s;

Wenn du oben das const weglässt?
Wofür setzt du in der typedef was als const wenn du es unten 
veränderlich haben willst?
bin nicht so arg firm in C/C++, in PASCAL heißt const "konstant"

oder auch
Beitrag "c struct const"

: Bearbeitet durch User
von Nur_ein_Typ (Gast)


Lesenswert?

Franz schrieb:
> gibt es eine möglichkeit die Struktur nur an einer Stelle zu
> beschreiben?
> Also am besten in der init-funktion, da ich dort an value komme.

Probier's mal wie in init_mystruct():
1
typ@irgendwo$ cat main.c 
2
#include<stdio.h>
3
4
typedef struct {
5
    const char konst;
6
    int value;
7
} mystruct;
8
9
10
mystruct init_mystruct(int value) { 
11
    return (mystruct){'a', value}; 
12
}
13
14
void print_mystruct(mystruct s) {
15
    printf("konst = %c, value = %d\n", s.konst, s.value);
16
}
17
18
19
int main(void) {
20
    mystruct a = init_mystruct(0);
21
    print_mystruct(a);
22
    
23
    a.value = 15;
24
    print_mystruct(a);
25
    
26
    // a.konst = '3'; // Fehler!
27
    //print_mystruct(a);
28
    
29
    return 0;
30
}
31
typ@irgendwo$ gcc -Wall -Wextra -Wpedantic -o main main.c
32
typ@irgendwo$ ./main 
33
konst = a, value = 0
34
konst = a, value = 15

(Ja, Zeiger wären schöner, aber das sei dem geschätzten Leser zur Übung 
überlassen.)

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Nur_ein_Typ schrieb:
> typedef struct {
>     const char konst;
>     int value;
> } mystruct;
> mystruct init_mystruct(int value) {
>     return (mystruct){'a', value};

m.M.n. umgehst du seine fragestellung komplett
Er will konst einen char zuweisen, (was nicht geht).
Du lässt einfach einen char an der Stelle von konst ausgeben ohne ihn 
zuzuweisen.

von Sheeva P. (sheevaplug)


Lesenswert?

Mike B. schrieb:
> Nur_ein_Typ schrieb:
>> typedef struct {
>>     const char konst;
>>     int value;
>> } mystruct;
>> mystruct init_mystruct(int value) {
>>     return (mystruct){'a', value};
>
> m.M.n. umgehst du seine fragestellung komplett
> Er will konst einen char zuweisen, (was nicht geht).
> Du lässt einfach einen char an der Stelle von konst ausgeben ohne ihn
> zuzuweisen.

Das hier funktioniert genauso:
1
mystruct init_mystruct(char konst, int value) {
2
    return (mystruct){konst, value};
3
}
4
/* [...] */
5
6
int main(void) {
7
    mystruct a = init_mystruct('a', 0);
8
/* [...] */

von Rolf M. (rmagnus)


Lesenswert?

Sheeva P. schrieb:
> Das hier funktioniert genauso:

Dann steht das Ergebnis aber nicht in der globalen Struktur, sondern in 
einer lokalen Variable innerhalb der aufrufenden Funktion.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Franz schrieb:
> Jetzt möchte ich eine Structur struct_s erstellen, welche für eine ganze
> Datei gillt1static struct_ts struct_s =
> 2{
> 3  .constValue = 0x85,
> 4  .value = 0x00,
> 5};
> .
> Das Problem ist, dass ich hier für den wert Value einen dummywert
> eingeben muss und diesen in einer späteren Funktion wieder überschreiben
> muss.
> In der init funktion kann ich den wert constValue aber nicht mehr
> beschreiben.

Dann mach das doch einfach nicht. constValue hat den Wert 0x85, und das 
bleibt bis zum Ende der Welt (bzw. des Programms) so. Schreib in value 
rein,was immer du willst, und lass constValue einfach in Ruhe. Ich 
verstehe dein Problem gar nicht.

Oliver

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Wenn Du sagst, warum der Wert const sein muss, kann man einen workaround 
genau dafür empfehlen.

Sonst indem Du das

Mike B. schrieb:
> const weglässt?

von Ein Kommentar (Gast)


Lesenswert?

Eine der beiden Ideen hinter dem "const": Der Compiler kann Lesezugriffe 
weg optimieren. Er kann Berechnungen mit den konstanten Werten während 
der Kompilierung durchführen und das Ergebnis direkt in den 
Maschinencode einbauen.

Der Compiler darf sogar den Speicherplatz für "static 
struct_ts.constValue" komplett weg optimieren.

Da ist die Frage, wenn Franzs Konstruktion erlaubt ist, wie findet der 
Compiler heraus: für "struct_ts.constValue" kann er immer und überall 
den Wert 0x85 direkt in den Maschinencode einbauen?

von Simon (Gast)


Lesenswert?

geht das Folgenbde nicht einfach?
1
struct xxxxx_t
2
{
3
  const uint32_t c_var;
4
  uint32_t var_var;
5
};
6
7
void funktion()
8
{
9
  struct xxxxx_t x = {.c_var = 0x55};
10
}

von Ein Kommentar (Gast)


Lesenswert?

> geht das Folgenbde nicht einfach?

Ist halt eine ganz andere Sache.

Das struct_s von Franz ist in der gesamten Datei sichtbar. Das x nur 
innerhalb von main.

Und das stecken unterschiedliche Konzepte dahinter. Modernes C benutzt 
das Wort const für 2 unterschiedliche Sachen.
- Das alte "#define constValue 0x85" ersetzen
- Dem Benutzer eines Moduls mitteilen: das Modul wird den Speicherplatz 
nicht verändern.

Verwirrung entsteht wahrscheinlich, weil im C Standard die Konstruktion 
von Franz für den ersten Zweck gedacht war, er aber den ańderen Zweck 
erreichen will.

von Klaus W. (mfgkw)


Lesenswert?

Wenn man nicht C, sondern C++ nimmt, kann man mit mutable einen Teil 
einer struct oder class veränderbar halten - auch wenn der Rest drumrum 
als const deklariert ist.

(Wenn man C++ nicht mag, kann man sich ja genau das rauspicken und den 
Rest wie sonst in C schreiben.)

von Oliver S. (oliverso)


Lesenswert?

Klaus W. schrieb:
> Wenn man nicht C, sondern C++ nimmt, kann man mit mutable einen Teil
> einer struct oder class veränderbar halten

Falls der TO das wirklich wollte (was er anscheined ja gar nicht will), 
wäre das die bessere Lösung:

Mike B. schrieb:
> Wenn du oben das const weglässt?

Oliver

von A. S. (Gast)


Lesenswert?

Ein Kommentar schrieb:
> Der Compiler kann Lesezugriffe
> weg optimieren. Er kann Berechnungen mit den konstanten Werten während
> der Kompilierung durchführen und das Ergebnis direkt in den
> Maschinencode einbauen.
>
> Der Compiler darf sogar den Speicherplatz für "static
> struct_ts.constValue" komplett weg optimieren.

Ein C-Compiler? Seit wann? (Gut, der C-Compiler sowieso nicht, aber ab 
Linker, geschenkt).

von Mikro 7. (mikro77)


Lesenswert?

Franz schrieb:
> gibt es eine möglichkeit die Struktur nur an einer Stelle zu
> beschreiben?

Die const Member der Struktur kannst du nur an einer Stelle setzen, 
nämlich beim Erzeugen der Instanz. Ein nachfolgendes Schreiben auf das 
const Member würde ja dem "const" widersprechen.

Franz schrieb:
> Das Problem ist, dass ich hier für den wert Value einen dummywert
> eingeben muss und diesen in einer späteren Funktion wieder überschreiben
> muss.
> In der init funktion kann ich den wert constValue aber nicht mehr
> beschreiben.
1
static struct_ts struct_s;
2
void init(void)
3
{
4
  struct_s.constValue = 0x85;  // geht nicht
5
  struct_s.value = getValue();
6
}

Aber auch hier hast du bereits einen "dummywert" verwendet, nämlich 
struct_s.value=0 (mit dem implizit initialisiert wurde).

Wenn du unbedingt den globalen Zugriff brauchst und nur an einer Stelle 
die Initialisierung durchführen möchtest, dann musst du das wohl über 
einen Pointer realisieren. (Oder du überschreibst per Casting/memcpy das 
const, was ja aber nicht der Sinn der Übung sein sollte.)

: Bearbeitet durch User
von Einer (Gast)


Lesenswert?

Franz schrieb:

> eine Struktur mit normalen Parametern und constanten parametern

[...]

> den Wert value kenne ich erst in einer Funktion, da dieser von einem
> anderen Modul kommt. den constValue kenne ich schon zu beginn.

[...]

> Das Problem ist, dass ich hier für den wert Value einen dummywert
> eingeben muss und diesen in einer späteren Funktion wieder überschreiben
> muss.

[...]

> In der init funktion kann ich den wert constValue aber nicht mehr
> beschreiben.

[...]

> gibt es eine möglichkeit die Struktur nur an einer Stelle zu
> beschreiben?

Merkst Du es nicht?

Bis jetzt hast Du nur eine Lösung präsentiert, ohne das ursprüngliche 
Problem zu benennen.

Der ganze Ansatz ist offensichtlich falsch. Er passt nicht zum 
ursprünglichem Problem. Du dokterst an Pseudo-Problemen rum, die es gar 
nicht gibt, sondern die Du künstlich geschaffen hast.

Darum die entscheidende Frage:

Was ist Dein eigentliches Problem, welche Aufgabe willst Du lösen?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mikro 7. schrieb:
> Oder du überschreibst per Casting/memcpy das const,

Das ist Undefined Behaviour in C/C++.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Sheeva P. schrieb:

> Das hier funktioniert genauso:
> mystruct init_mystruct(char konst, int value) {
>     return (mystruct){konst, value};
> }
> /* [...] */
> int main(void) {
>     mystruct a = init_mystruct('a', 0);
> /* [...] */

nee, das is was anderes, da du genau an der richtigen Stelle
mystruct init_mystruct(*...* char konst, int value) {

Mike B. schrieb:
> ... das const weglässt

p.s. wie lauten bitte die Schlüsselwörter zur codeformatierung hier im 
Forum?

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Mike B. schrieb:
> p.s. wie lauten bitte die Schlüsselwörter zur codeformatierung hier im
> Forum?

Das findest du oberhalb des Eingabefeldes, in das du deinen Text 
schreibst, gleich unter den wichtigen Regeln, die unter "Wichtige Regeln 
- erst lesen, dann posten!" stehen.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Rolf M. schrieb:

> Das findest du oberhalb des Eingabefeldes, in das du deinen Text
> schreibst,

wer lesen kann ist klar im Vorteil, dann noch die richtige Brille auf 
der Nase und das geht nochmal doppelt so gut :D
Danke!

von Sheeva P. (sheevaplug)


Lesenswert?

Rolf M. schrieb:
> Sheeva P. schrieb:
>> Das hier funktioniert genauso:
>
> Dann steht das Ergebnis aber nicht in der globalen Struktur, sondern in
> einer lokalen Variable innerhalb der aufrufenden Funktion.

Oh... true! ;-)

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.