mikrocontroller.net

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


Autor: Klausi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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, ...

Autor: Daniel (Gast)
Datum:

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

@Klausi
welchen Compiler hast du?

Autor: Klausi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Klausi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
    p_real=&sig[16/2-1].real;
    p_cmpx=&sig[16-1];
    
     for(i=16;i>0;i--)
     {
        (*p_cmpx).real = *p_real--;
        (*p_cmpx--).imag = 0;
        
     }

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.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
typedef struct{
     int real;
     int imag;
         } cmpx; 

cmpx sig[16]={...};
int* p_real=&sig[0].real;

Wenn ich jetzt folgendes mache:
for(i=0;i<16;i++)
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 !

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
woher soll er es denn wissen?

p_real++

macht zum schluss immer p_real + sizeof( p_real )

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter wrote:

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

Nein, p_real + sizeof( *p_real )

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht 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.
>
>
> typedef struct{
>      int real;
>      int imag;
>          } cmpx;
> 
> cmpx sig[16]={...};
> int* p_real=&sig[0].real;
> 
>
> Wenn ich jetzt folgendes mache:
>
>
> for(i=0;i<16;i++)
> 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 !

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:
struct Test
{
  char a;
  char b;
  char c;
} 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 .

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also der gcc macht mit dem Beispiel oben kein alignment, aber mit 
folgendem:
struct Test
{
  char a;
  char b;
  char c;
  short int d;
} test[20];

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.