www.mikrocontroller.net

Forum: PC-Programmierung Hilfe zu Ansi C Code


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
int *ptr;
ptr = pthis->Daten;
for (i = 0; i < 100; i++)
{
   *ptr = i;
   ptr++;
}

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

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

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst auf jeden Fall mehr Code zeigen.

Wenn du einfach ein double Array haben möchtest und dann einen zeiger 
drauf und über diesen Zeiger das Array initialisieren dann könnte es 
einfach wie folgt aussehen
double daten[100];
double *ptr = daten; // oder &daten[0]

int i;

for(i = 0; i < 100; i++)
    *ptr++ = i;

Autor: Peter S. (psavr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso nich ganz einfach...
#define DATEN_ARRAY_SIZE 100

double daten[DATEN_ARRAY_SIZE];
int i;

for(i = 0; i < DATEN_ARRAY_SIZE; i++)
{
    daten[i] = i;
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
iss zu einfach, das kann ja jeder.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
..und auch viel zu übersichtlich. Mit solchem Code kann man sich in 
einer Firma nicht unabkömmlich machen.

Autor: zwieblum (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also ich fin'd ja das da viel eleganter:

*ptr++ = i++;

:-)

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nee, wenn schon dann kann man auf i auch gleich verzichten!
#define DATEN_ARRAY_SIZE 100

double daten[DATEN_ARRAY_SIZE];
double *p_daten;

for( p_daten = daten; p_daten < daten + DATEN_ARRAY_SIZE; p_daten++ )
{
    *p_daten = p_daten - daten;
}

Das verwirrt doch viel schöner, und nach dem Optimierer kommt 
wahrscheinlich dasselbe raus.

Autor: Daniel (root) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
double * data = new double[100], * pdata = data;
*pdata = 0.0;
while(*pdata < 100.0)
    *(pdata+1) = *pdata+1;
// ...
delete [] data;

mit so einem code macht man sich unverzichbar ;-)

kann man auch
*++pdata = *pdata+1;
verwenden?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kann man schon, aber das Ergebnis ist nicht definiert.

und mit ...<100.0 kann man auch versehentlich einen Durchlauf
zuviel haben; dann kommt man wenigstens ans schwarze Brett mit
dem Bug der Woche.
Sicherer und viel klarer wäre ...<99.572448

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

Bewertung
0 lesenswert
nicht lesenswert
Daniel (root) schrieb:

> kann man auch
>
> *++pdata = *pdata+1;
> 
> verwenden?

Ähm .... nein. Das ist 'undefined behaviour'

(Als Daumenregel: sobald eine Variable in einem Ausdruck 2 mal vorkommt 
und an einer Stelle steht ++ oder -- vor/hinter der Variablen, hast du 
undefined beh.)

Autor: Daniel (root) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wobei hier die Quelle nicht zwei mal beschrieben wird ...
wie im typischen
i=i++;

hier kommt es wohl auf die Zugriffsreihenfolge read/write oder
write/read.

Ich werde es mir merken ;-)

Autor: Daniel (root) (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lispisch ...
(assign (dereference pdata) (add (dereference (incr pdata)) 1))

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

interessant ist, dass man in lispsyntax keine Zweideutigkeiten
erzeugen kann.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel (root) schrieb:
> wobei hier die Quelle nicht zwei mal beschrieben wird ...
> wie im typischen
>
> i=i++;
> 
>
> 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.

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

Bewertung
0 lesenswert
nicht lesenswert
Daniel (root) schrieb:
>
> (assign (dereference pdata) (add (dereference (incr pdata)) 1))
> 
> (assign (dereference (incr pdata)) (add (dereference pdata) 1))
> 
>
> 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.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel (root) schrieb:
>
> double * data = new double[100], * pdata = data;
> *pdata = 0.0;
> while(*pdata < 100.0)
>     *(pdata+1) = *pdata+1;
> // ...
> delete [] data;
> 
>
> 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

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.