Forum: Mikrocontroller und Digitale Elektronik C Struct - großes Problem


von Klausi (Gast)


Lesenswert?

Ich probiere hier schon seit ca. 1 Stunde die Verwirrung zu beseitigen, 
aber komme nicht weiter.

[c]typedef struct{
        int real;
        int imag;
        } cmpx;
cmpx 
sig[16]={2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 
};[\c]

Erste Frage an euch:

Wie ist nun die Zuordnung ?

sig[0].real=2 und sig[1].real=2 oder sig[1].imag=2.

Was würdet Ihr sagen ?

Welchem Objekt sig[i] wird was zugeordnet.

Gebe ich zum Beispiel alle sig[i].real aus, dann kommt folgendes raus:

2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1

Gebe ich jetzt alle sig[i].imag aus, dann kommt folgendes raus:

2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1

Wer bekommt dann die Nullen ?

Ich bin echt verwirrt ??

Danke.

von Karl H. (kbuchegg)


Lesenswert?

Klausi wrote:
> Ich probiere hier schon seit ca. 1 Stunde die Verwirrung zu beseitigen,
> aber komme nicht weiter.
>
> [c]typedef struct{
>         int real;
>         int imag;
>         } cmpx;
> cmpx
> sig[16]={2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };[\c]
>

Wusste gar nicht, das das geht.

Schreibs so

cmpx sig[16] =
  {
    { 2, 2 },
    { 1, 1 },
    { 2, 2 },
    { 1, 1 },
    ....
  };

dann gibts keine Misverständnisse.

von Stefan E. (sternst)


Lesenswert?

Karl heinz Buchegger wrote:

> Wusste gar nicht, das das geht.

Ich auch nicht. Laut kurzem Test ist die Zuordnung so, wie man es auch 
vermuten würde, nämlich:
[0].real, [0].imag, [1].real, [1].imag, ...

von Daniel (Gast)


Lesenswert?

Diese Zuordnung wäre dann aber nicht wie bei Klausi.

@Klausi
welchen Compiler hast du?

von Klausi (Gast)


Lesenswert?

Hallo,

ich benutze den Blooodshed DEVC++ Compiler.

Diese Zuordnung habe ich aus dem Quellcode von Microchip.
Da dort diese Werte dann umsortiert werden und ich den 
Sortieralgorithmus nicht ganz verstanden habe, wollte ich der Sache auf 
den Grund gehen und es in DEVCPP nachprogrammieren.

Das Problem ist, dass die Zuordnung beliebig ist, je nach dem, wie ich 
die Werte auslese. Aber er will genau 32 Werte haben, sonst meckert der 
Compiler wegen der Länge.

Szenarien:

Gebe ich alle .real-Werte aus, dann bekomme ich:

  2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1

Für alle .imag-Werte:

 2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1

Und wenn ich beide abwechselnd ausgebe, also [i].real,[i].imag:

0.real 2   0.imag 2
1.real 1   1.imag 1
2.real 2   2.imag 2
3.real 1   3.imag 1
4.real 2   4.imag 2
5.real 1   5.imag 1
6.real 2   6.imag 2
7.real 1   7.imag 1
8.real 0   8.imag 0
9.real 0   9.imag 0
10.real 0   10.imag 0
11.real 0   11.imag 0
12.real 0   12.imag 0
13.real 0   13.imag 0
14.real 0   14.imag 0
15.real 0   15.imag 0

Blickt da noch jemand durch ?

von Stefan E. (sternst)


Lesenswert?

Klausi wrote:

> Das Problem ist, dass die Zuordnung beliebig ist, je nach dem, wie ich
> die Werte auslese.

Also das kann ich wirklich nicht glauben.
Poste doch mal den Code, der diese Ausgabe produziert:
>   2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1

von Klausi (Gast)


Lesenswert?

Hallo,

das ist komisch, aber auf einmal wird alles wieder korrekt.

Also so:

0.real 2   0.imag 2
1.real 1   1.imag 1
2.real 2   2.imag 2
3.real 1   3.imag 1
4.real 2   4.imag 2
5.real 1   5.imag 1
6.real 2   6.imag 2
7.real 1   7.imag 1
8.real 0   8.imag 0
9.real 0   9.imag 0
10.real 0   10.imag 0
11.real 0   11.imag 0
12.real 0   12.imag 0
13.real 0   13.imag 0
14.real 0   14.imag 0
15.real 0   15.imag 0

Es scheint zu passen, aber trotzdem verstehe ich diesen 
Sortieralgorithmus nicht.
1
    p_real=&sig[16/2-1].real;
2
    p_cmpx=&sig[16-1];
3
    
4
     for(i=16;i>0;i--)
5
     {
6
        (*p_cmpx).real = *p_real--;
7
        (*p_cmpx--).imag = 0;
8
        
9
     }

Wieso wird p_real auf die Mitte gesetzt ?

Der Sinn:

Aus

0.real 2   0.imag 2
1.real 1   1.imag 1
2.real 2   2.imag 2
3.real 1   3.imag 1
4.real 2   4.imag 2
5.real 1   5.imag 1
6.real 2   6.imag 2
7.real 1   7.imag 1
8.real 0   8.imag 0
9.real 0   9.imag 0
10.real 0   10.imag 0
11.real 0   11.imag 0
12.real 0   12.imag 0
13.real 0   13.imag 0
14.real 0   14.imag 0
15.real 0   15.imag 0

wird durch Umsortierung:

 0.real 2    0.imag 0
 1.real 2    1.imag 0
 2.real 1    2.imag 0
 3.real 1    3.imag 0
 4.real 2    4.imag 0
 5.real 2    5.imag 0
 6.real 1    6.imag 0
 7.real 1    7.imag 0
 8.real 2    8.imag 0
 9.real 2    9.imag 0
10.real 1   10.imag 0
11.real 1   11.imag 0
12.real 2   12.imag 0
13.real 2   13.imag 0
14.real 1   14.imag 0
15.real 1   15.imag 0

Im Microchip Quellcode scheint es zu klappen.

von Thomas (Gast)


Lesenswert?

Hallo,

stimmt es, dass ein Zeiger auf einen beliebigen Datentyp beide 
Strukturelemente beim inkrementieren/dekrementieren durchläuft ?
Das wäre nähmlich die Lösung für meine Probleme.

Also z.B.
1
typedef struct{
2
     int real;
3
     int imag;
4
         } cmpx; 
5
6
cmpx sig[16]={...};
7
int* p_real=&sig[0].real;

Wenn ich jetzt folgendes mache:
1
for(i=0;i<16;i++)
2
p_real++;

Ist die Reihenfolge diese ?

*p_real=sig[0].real;  p_real++;
*p_real=sig[0].imag;  p_real++;
*p_real=sig[1].real;  p_real++;
*p_real=sig[1].imag;  p_real++;
.
.
.

Also durchläuft der Zeiger auf int alle ints dieses Strukturelementes 
und nicht nur den real-Teil ?

Das hätte ich nähmlich nicht gedacht !

von Peter (Gast)


Lesenswert?

woher soll er es denn wissen?

p_real++

macht zum schluss immer p_real + sizeof( p_real )

von Stefan E. (sternst)


Lesenswert?

Peter wrote:

> p_real++
>
> macht zum schluss immer p_real + sizeof( p_real )

Nein, p_real + sizeof( *p_real )

von I_ H. (i_h)


Lesenswert?

Thomas wrote:
> Hallo,
>
> stimmt es, dass ein Zeiger auf einen beliebigen Datentyp beide
> Strukturelemente beim inkrementieren/dekrementieren durchläuft ?
> Das wäre nähmlich die Lösung für meine Probleme.
>
> Also z.B.
>
>
1
> typedef struct{
2
>      int real;
3
>      int imag;
4
>          } cmpx;
5
> 
6
> cmpx sig[16]={...};
7
> int* p_real=&sig[0].real;
8
>
>
> Wenn ich jetzt folgendes mache:
>
>
1
> for(i=0;i<16;i++)
2
> p_real++;
3
>
>
> Ist die Reihenfolge diese ?
>
> *p_real=sig[0].real;  p_real++;
> *p_real=sig[0].imag;  p_real++;
> *p_real=sig[1].real;  p_real++;
> *p_real=sig[1].imag;  p_real++;
> .
> .
> .
>
> Also durchläuft der Zeiger auf int alle ints dieses Strukturelementes
> und nicht nur den real-Teil ?
>
> Das hätte ich nähmlich nicht gedacht !

In deinem Fall ist das so, weil das Zeugs hintereinander im Speicher 
liegt.  Aber vergiss das mal ganz schnell wieder, das ist nämlich eher 
Zufall, dass es funktioniert. Normalerweise bläht der Compiler structs 
noch so auf, dass sie am besten mit dem Alignment der CPU harmonieren. 
Das heist ein struct mit 2 Int kann je nach CPU auch mal 128bit lang 
sein. Dann zeigt dein Zeiger bei jedem struct 2mal in's Leere.

Du kannst mit Zeigern viele Sachen machen die nicht immer gehen. Setze 
die Dinger weise und überlegt ein, und probier nicht einfach rum bis es 
geht, ohne zu wissen was da abläuft.

Mach mal folgendes:
1
struct Test
2
{
3
  char a;
4
  char b;
5
  char c;
6
} test[10];

und wiederhole das Spielchen mit einem char*. Einmal mit -O0 compiliert, 
und einmal mit -O3 compiliert.

Mit structs wird leider ziemlich viel Unsinn gemacht, auch in C/C++ 
Büchern. Es ist zB. völliger Bullshit Daten aus einer Datei zu laden, 
und ein Struct drüberzulegen um an die einzelnen Werte ranzukommen.
Das geht zwar meistens wenn man dem Compiler noch sagt, dass er structs 
nicht umsortieren/verändern soll, dann bleibt aber immernoch das 
Endian-Problem .

von I_ H. (i_h)


Lesenswert?

Also der gcc macht mit dem Beispiel oben kein alignment, aber mit 
folgendem:
1
struct Test
2
{
3
  char a;
4
  char b;
5
  char c;
6
  short int d;
7
} test[20];

Die structure ist 6 Byte lang, nicht 5. Beim compilieren Angabe von 
-march nicht vergessen.

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.