Forum: Mikrocontroller und Digitale Elektronik Zeiger funktioniert nicht


von Stefan H. (stefan_h143)


Lesenswert?

Hallo zusammen,

Könntet ihr mir vielleicht bei einem vermutlich totalen Anfängerfehler 
helfen?

Ich möchte eigentlich nur mit einer Funktion eine Variable bis zu einem 
gewissen Grad inkrementieren und dann wieder zurück setzten.

Allerdings funktioniert der Zugriff über den Zeiger irgendwie nicht und 
die Variable verändert sich nicht.
1
void increment (int *value, int lower_bound, int upper_bound )
2
{
3
  if (*value < upper_bound)
4
  {
5
    *value++;
6
  } else
7
  {
8
    *value = lower_bound;
9
  }
10
  
11
}
12
13
14
int main()
15
{
16
static int step=0;
17
18
19
increment(&step,0,13);
20
21
22
}

Ich mache natürlich normalerweise noch was damit. Ich habe jetzt nur mal 
den Ausschnitt gepostet, da das Programm doch recht groß ist.

Kann mir kurz einer auf die Sprünge helfen, warum er die Variable nicht 
verändert?

Gruß
stefan

von nicht"Gast" (Gast)


Lesenswert?


von Rezy (Gast)


Lesenswert?

Moin,

das Inkrement hat eine höhere Priorität als die Dereferenzierung. 
Entsprechend führst du implizit gerade
1
*(value++)
aus und nicht das, was du eigentlich willst:
1
(*value)++
Du inkrementierst aktuell also nur die Adresse des pointers lokal in der 
Funktion.

von Stefan H. (stefan_h143)


Lesenswert?

Top! Danke für die schnelle Antwort :)

Ja... hätte man drauf kommen können

von Stefan F. (Gast)


Lesenswert?

Es muss
> (*value)++;

heißen, dann klappt es. Der ++ Operator hat Vorrang, wenn du die 
Klammern weg lässt.

Nachtrag: Oh, zu spät. Das Testen hat eine Weile gedauert.

von Stefan H. (stefan_h143)


Lesenswert?

Stefan F. schrieb:
> Nachtrag: Oh, zu spät. Das Testen hat eine Weile gedauert.

Trotzdem Danke für die Mühe :)

von Wilhelm M. (wimalopaan)


Lesenswert?

Der Fehler wäre nicht passiert, wenn Du const (read-only) verwendet 
hättest.

von Stefan H. (stefan_h143)


Lesenswert?

Wilhelm M. schrieb:
> Der Fehler wäre nicht passiert, wenn Du const (read-only) verwendet
> hättest.

Wie meinst du das? ich möchte die ja verändern und nicht nur lesen. also 
an welcher Stelle das const?

von Wilhelm M. (wimalopaan)


Lesenswert?

Stefan H. schrieb:
> Wilhelm M. schrieb:
>> Der Fehler wäre nicht passiert, wenn Du const (read-only) verwendet
>> hättest.
>
> Wie meinst du das? ich möchte die ja verändern und nicht nur lesen. also
> an welcher Stelle das const?
1
void increment (int* const value, const int lower_bound, const int upper_bound ) {...}

Mache alles const, wenn Du kannst, und nur non-const, wenn Du musst.

Bei einem Zeiger gibt es immer zwei Objekte, einmal die Zeigervariable 
und einmal das Zielobjekt. Du hast einen sog. Output-Parameter, d.h. das 
Zielobjekt ist non-const.

von Wilhelm M. (wimalopaan)


Lesenswert?

Stefan H. schrieb:
> Wie meinst du das?

Bei einem Zeiger gibt es vier Möglichkeiten:
1
int* ptr1;
2
int* const ptr2 = ...;
3
const int* ptr3;
4
const int* const ptr4 = ...;

Bei ptr1 und ptr3 ist die Zeigervariable selbst non-const, was nur 
sinnvoll ist, wenn man sie als Iterator verwenden will.

Bei ptr3 und ptr4 ist das Zielobjekt const, also read-only,

Bei ptr1 und ptr2 ist das Zielobjekt non-const.

von Wilhelm M. (wimalopaan)


Lesenswert?

In einer Parameterliste bei der Funktionsdefinition macht man 
sinnvollerweise alle Parametervariablen const. Denn mit dem Namen der 
Parametervariablen ist eine Bedeutung verbunden. Eine Wertänderung ist 
oftmals auch eine Bedeutungsänderung, und deswegen unerwünscht.

Bei lokalen Variablen sollte man auch alles const machen wenn es geht, 
dann kann man die Initialisierung nicht vergessen. Bei C++ kann man las 
DT auch auto nehmen, dann kan man selbst bei non-const die 
Initialisierung nicht vergessen.

von Stefan H. (stefan_h143)


Lesenswert?

Wilhelm M. schrieb:
> Bei einem Zeiger gibt es vier Möglichkeiten:

Eieiei :D

Also wenn ich eine Variable mit einem Zeiger verwenden will, verhindere 
ich durch Variante 2 quasi, dass sich die Zugriffsadresse ändert. Ich 
kann aber weiterhin den Wert verändern.

Wenn ich die zugriffsadresse ändern möchte, also zb. um ein Array 
durchzugehen ohne den Inhalt zu verändern, nehme ich Variante 4.

Ist das so richtig?

Hast du da auf die Schnelle vielleicht eine Quelle wo man sich das mal 
genau anschauen kann?

von Bernd (Gast)


Lesenswert?

void incrementiere_den_wert(int* const value)
{
  (*value)++;
}

void incrementiere_die_adresse(const int* value)
{
  *(value++);
}

void veraendere_nichts(const int* const value)
{
}

Diese 3 Varianten gibt es.

Bernd

von Wilhelm M. (wimalopaan)


Lesenswert?

Stefan H. schrieb:
> Also wenn ich eine Variable mit einem Zeiger verwenden will, verhindere
> ich durch Variante 2 quasi, dass sich die Zugriffsadresse ändert. Ich
> kann aber weiterhin den Wert verändern.

Ja.

Stefan H. schrieb:
> Wenn ich die zugriffsadresse ändern möchte, also zb. um ein Array
> durchzugehen ohne den Inhalt zu verändern, nehme ich Variante 4.

Nein, ptr3.

Stefan H. schrieb:
> Hast du da auf die Schnelle vielleicht eine Quelle wo man sich das mal
> genau anschauen kann?

Leider nein. Ich kann Dir nur umgekehrt sagen, dass ein Lehrbuch, dass 
es nicht so macht bzw. nicht darauf hinweist, sein Geld nicht Wert ist.

Wilhelm M. schrieb:
> Mache alles const, wenn Du kannst, und nur non-const, wenn Du musst.

Dieser Satz ist ganz wichtig! Denke darüber nach und setze diese Regel 
kompromisslos ein.

von Wilhelm M. (wimalopaan)


Lesenswert?

Bernd schrieb:
> Diese 3 Varianten gibt es.

Eine hast Du vergessen ...

von Stefan H. (stefan_h143)


Lesenswert?

Wilhelm M. schrieb:
> Nein, ptr3.

Hoppla, da hab ich mich vertippt... Meinte die 3. Bei 4 ist ja alles 
unveränderbar.

Super, Danke für eure Erklärungen :)

von Dirk B. (dirkb2)


Lesenswert?

Der Compiler weiß, das es nicht verändert werden soll.
Wenn du es über die Variable/Zeiger probierst, meckert er.

Zur Compiletime. Nicht während der Laufzeit.

Das heißt aber nicht, dass du es nicht mit unsauberer/böser 
Programmierung trotzdem ändern kannst.

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.