Forum: Compiler & IDEs Pointer & AVRGCC


von Matthias (Gast)


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

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

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

von Matthias (Gast)


Lesenswert?

Hi

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

Matthias

von Joerg Wunsch (Gast)


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.

von Oryx (Gast)


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

von Joerg Wunsch (Gast)


Lesenswert?

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

dat[1000]

und

*(dat+1000)

sind identisch.

von Matthias (Gast)


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

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.