C Struct - großes Problem

Gast #888362
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.
#888378
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.
Gast #888505
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 ?
Gast #888541
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.
Gast #888613
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 !
#888787
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 .
#888808
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.

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