mikrocontroller.net

Forum: Compiler & IDEs Pointer & AVRGCC


Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

ich hab hier vier int-Datenfelder auf die 4 unsigned int Pointer zeigen
die stellenweise gemittelt werden sollen:

adc_dat0[0]=(unsigned int *)RAMEND+1;
adc_dat0[1]=(unsigned int *)RAMEND+1+2000;
adc_dat0[2]=(unsigned int *)RAMEND+1+4000;
adc_dat0[3]=(unsigned int *)RAMEND+1+6000;

Versuche ich das so:
Aufruf: gfx_mw(adc_dat0[0]);

void gfx_mw(unsigned int *dat)
{
    unsigned int i,t;

    for(i=0;i<1000;i++)
    {
        t=*(dat);
        t+=*(dat+1000);
        t+=*(dat+2000);
        t+=*(dat+3000);
        *dat=t/4;
        dat++;
    }
}

kommt nur Müll raus. Erhöhe ich die Pointer jedoch um das doppelte des
festen Wertes (sprich +2000, +4000 usw.) passt das Ergebnis. Sollte der
Compiler nicht anhand des Datentypes (unsigned int *) automatisch um
die richtige Anzahl Bytes erhöhen oder übersehe ich das was?

Matthias

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probier's mal mit
  t += *(dat + 2000 * sizeof(unsigned int))

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

das ist mir schon klar das das dann funktioniert. Aber ich hatte
eigentlich die Vermutung das der Inkrement automatisch ermittelt wird.

Matthias

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bißchen konfus sieht das alles aus.  So ganz ist mir nicht klar,
wofür das Array eigentlich gut ist (vielleicht brauchst Du das
ja noch woanders).  Aber ich glaube, Dein Denkfehler liegt schon
hier:

adc_dat0[0]=(unsigned int *)RAMEND+1;
adc_dat0[1]=(unsigned int *)RAMEND+1+2000;

Denk mal über die Prioritäten der Operatoren nach.  Das da ist
äquivalent zu

adc_dat0[0]=((unsigned int *)RAMEND)+1;
adc_dat0[1]=((unsigned int *)RAMEND)+1+2000;

Ich glaube aber, Du willst eher

adc_dat0[0]=(unsigned int *)(RAMEND+1);
adc_dat0[1]=(unsigned int *)(RAMEND+1+2000);

haben.


t+=*(dat+1000);

...sieht ja hübsch aus, aber findest Du nicht, daß

t += dat[1000];

etwas weniger gewöhnungsbedürftig wäre?  Ich habe kein Problem
mit Pointern, ich schreibe allemal lieber

... = foo + 15;

statt

... = &foo[15];

aber in diesem Falle halte ich die Array-Schreibweise für etwas
einleuchtender.

Autor: Oryx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Mathias,
wie Du schon geahnt hast, übersiehst Du etwas!

Wenn ich das richtig sehe, hast Du eine Adresse, zu der Du 1000
addierst. Mit dem Inhalt der daraus resultierenden Adresse wilst Du
etwas machen. Wie soll der Compiler da mitdenken können.
Wenn der Compiler den Datentyp beachten soll, ist Jörg seine Variante
mit dat[1000] richtig. Also den 1000. Eintrag von dat. Die Adresse
liegt in Deinem Fall bei dat+2000 (dat+1000*sizeof(unsigned int)).
Ich gehe mal davon aus, das sizeof(int) == 2 ist.

Fazit:
Das Mischen von Pointerarithmetik und Arrayzugriffen macht immer wieder
viel Freude. Dazu dann noch Adressbereiche am Linker vorbei ist dann
noch eine Stufe besser. Aber wenn kein new und delete bzw. malloc und
free zur Verfügung stehen, kann man solche Ansätze durchaus machen.

Endlich wal wieder richtig Sommer
Oryx

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, Oryx, Du solltest Dir das Kapitel über Pointer und Arrays im
K&R nochmal antun. ;-)

dat[1000]

und

*(dat+1000)

sind identisch.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

@Jörg
Operator-prioritäten! patsch *indietischkantebeiß* Das wars. Man
sieht den Wald vor lauter Operatoren nicht. So ein Mist aber auch.

BTW:
Hinter der deklaration der Variablen steckt schon eine Idee dahinter.
Hätte ich den ganzen Code gepostet wäre das wohl etwas klarer geworden.
Aber ich wollte keinem zumuten in 12 Dateien die entsprechenden
Codestellen rauszusuchen. Du konntest das Problem ja auch so lösen.

Matthias

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.