Hilfe zu Ansi C Code

Gast #1278381
Lesenswert?

Ich hab in meinem Projekt ein Array mit dem Namen Daten definiert.
Dieses Array hat eine Größe von 100.
--> double Daten[100];
Ich möchte innerhalb auf das Array zugreifen und durch einen Zeiger 
dieses Array mit Zahlen befüllen. Leider funktioniert dies nicht so, wie 
ich es implementiert habe. Siehe folgender Code:
1
int *ptr;
2
ptr = pthis->Daten;
3
for (i = 0; i < 100; i++)
4
{
5
   *ptr = i;
6
   ptr++;
7
}

In dem Array Daten stehen die fortlaufenden Zaheln nicht drin. Waron 
könnte dies liegen?
#1278390
Lesenswert?

Gast schrieb:
> Ich hab in meinem Projekt ein Array mit dem Namen Daten definiert.
> Dieses Array hat eine Größe von 100.
> --> double Daten[100];
> Ich möchte innerhalb auf das Array zugreifen und durch einen Zeiger
> dieses Array mit Zahlen befüllen. Leider funktioniert dies nicht so, wie
> ich es implementiert habe. Siehe folgender Code:
>

Hat den der Compiler dazu gar keine Meinung?

> int *ptr;

Aha. ptr ist also ein Zeiger auf int

> ptr = pthis->Daten;

und Daten hast du uns oben als ein double Array untergejubelt

    int != double

> In dem Array Daten stehen die fortlaufenden Zaheln nicht drin. Waron
> könnte dies liegen?

Wenn das nur ein Tippfehler war, dann poste den Code direkt aus deinem 
Editor. Und zeig auch ein wenig mehr. Aus dem Schnipsel ist nicht 
erkennbar, welche Fehler du noch gemacht haben könntest. Zb. könnte ich 
mir ein Gewirx mit lokalen Variablen vorstellen, etc.
#1278391
Lesenswert?

1. ist das kein vollständiges Beispiel; z.B. sehe ich nicht, wo
pthis herkommen soll.

2. ist ptr ein Zeiger auf int, während in Daten[]
angeblich (?) double stehen sollen. Das kann nicht gut gehen.

3. hat der Compiler bestimmt Warnungen ausgegeben, um die
sich offenbar niemand kümmert.
Stattdessen wird erstmal im Forum gefragt.

4. kommt mir Gast (Gast) irgendwie bekannt vor, habe ich bestimmt
schon mal gelesen?
#1279174
Lesenswert?

nee, wenn schon dann kann man auf i auch gleich verzichten!
1
#define DATEN_ARRAY_SIZE 100
2

3
double daten[DATEN_ARRAY_SIZE];
4
double *p_daten;
5

6
for( p_daten = daten; p_daten < daten + DATEN_ARRAY_SIZE; p_daten++ )
7
{
8
    *p_daten = p_daten - daten;
9
}

Das verwirrt doch viel schöner, und nach dem Optimierer kommt 
wahrscheinlich dasselbe raus.
Gast #1279716
Lesenswert?

Daniel (root) schrieb:
> wobei hier die Quelle nicht zwei mal beschrieben wird ...
> wie im typischen
>
1
> i=i++;
2
>
>
> hier kommt es wohl auf die Zugriffsreihenfolge read/write oder
> write/read.
Es ist ebenfalls undefiniertes Verhalten, da bin ich auch drüber 
gestolpert, die Diskussion gabs neulich noch hier mit sehr anschaulichen 
Beispielen. Such halt mal.
#1280092
Lesenswert?

Daniel (root) schrieb:
>
1
> (assign (dereference pdata) (add (dereference (incr pdata)) 1))
2
> 
3
> (assign (dereference (incr pdata)) (add (dereference pdata) 1))
4
>
>
> interessant ist, dass man in lispsyntax keine Zweideutigkeiten
> erzeugen kann.

Keine Ahnung wie das in Lisp ist. Ist es da exakt definiert in welcher 
Reihenfolge Listen ausgewertet werden.

(assign a b)

ok es ist klar, dass sowohl a als auch b evaluiert werden müssen, ehe 
der assign seine Arbeit tun kann.
Aber ist auch geregelt, ob zuerst eval(a) und dann eval(b) gemacht wird 
oder umgekehrt, oder ist das freigestellt.

In C ist das freigestellt. D.h. ein "Lisp compiler - C-like" (ich hoffe 
man versteht was ich damit meine), könnte

 (assign (dereference pdata) (add (dereference (incr pdata)) 1))

mit diesen Schritten implementieren

  eval(dereference pdata)
  eval(add (dereference (incr pdata)) 1)
  assign

Er könnte aber auch

  eval(add (dereference (incr pdata)) 1)
  eval(dereference pdata)
  assign

implementieren. Damit hast du schon mal einen Teil des undefinierten 
Verhaltens. In C-Speak: Es ist nicht festgelegt, ob zuerst der rechte 
oder der linke Teil bei einer Zuweisung ausgewertet wird oder gar eine 
Mischung aus beidem.

Der andere Teil des undef. Verhaltens kommt daher, dass nicht festgelegt 
ist, wann genau der Increment bei ++ zu erfolgen hat. C fordert 
lediglich, dass dieser Nebeneffekt spätestens beim nächsten Sequenzpunkt 
(sequence point) abgeschlossen sein muss.

Sequence Points sind im wesentlichen
 * alle ;
 * Ein Funktionsaufruf
 * fällt mir grade nicht ein

D.h. der Compiler darf in

  *++pdata = *pdata+1;

den Inkrement von pData rumschieben wie er lustig ist. Die Anweisung 
kann komplett abgearbeitet sein und pdata hat überall denselben Wert und 
erst kurz bevor in der logischen Sequenz der ; kommt wird pdata auf den 
nächsten Wert gesetzt. Ist eine Möglichkeit. Der Compiler kann den 
increment von pdata aber auch vorziehen soweit er möchte (und es die 
Datenflussanalyse erlaubt). Ob also deine rechte Seite in obiger 
Zuweisung noch den vorhergehenden oder bereits den incrementierten Wert 
von pdata sieht, ist nicht definiert.

Denn eines steht fest: Ein = ist kein Sequencepoint, auch wenn viele 
das gerne implizit annehmen.
Persönliche Seite #1280566
Lesenswert?

Daniel (root) schrieb:
>
1
> double * data = new double[100], * pdata = data;
2
> *pdata = 0.0;
3
> while(*pdata < 100.0)
4
>     *(pdata+1) = *pdata+1;
5
> // ...
6
> delete [] data;
7
>
>
> mit so einem code macht man sich unverzichbar ;-)

Mit solchem Code machst du sich für die Firma verzichtbar :-)

1) Addition von double ist nicht assoziativ.
2) Erst wenn die 100 schon geschrieben ist, hörst du auf autsch

Johann

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