Pointer incrementieren schlägt fehl?!

OP #5112745
Lesenswert?

Hallo.

Auf nem MEGA32 klappt es, nur auf dem Rechner nicht. Es wird nichts 
angezeigt. Wieso?
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4

5
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
6

7

8

9
void ausgabe(char *str){
10
  
11
  int x = 0;
12
  
13
  *str++ = 'A';
14
  *str++ = 'B';
15
  *str++ = 'C';
16
  
17
  //str[x++] = 'A';
18
  //str[x++] = 'B';
19
  //str[x++] = 'C';
20
  
21
  printf(str);
22
}
23

24

25
int main(int argc, char *argv[]) 
26
{
27
  char *buff = (char*)calloc(11,sizeof(char));
28
  ausgabe(buff);
29

30
  return 0;
31
}
#5112765
Lesenswert?

Für printf und andere String-Fkt. würde ich einen String auch imemr mit 
'\0' abschliessen.

Würde mich wundern wenn genau der Source aufm µC läuft.
FEHLER beim Copy&Paste ? ;-)

Versuch das:
1
void ausgabe(char *str){
2
  
3
  char *tmp = str;
4

5
  *tmp++ = 'A';
6
  *tmp++ = 'B';
7
  *tmp++ = 'C';
8
  *tmp   = '\0';
9
 
10
  printf(str);
11
}
Gast #5112778
Lesenswert?

Tipp am Rande: Bei der Inkrementierungs-Dereferenzierungs-Geschichte 
Klammern setzen. Dann ist auf Anhieb klar was deine Intention war und 
was der Code macht wenn man die C Operator Precedence gerade nicht parat 
hat ;)
Gast #5112782
Lesenswert?

Mit dem Verändern von Parametern innerhalb einer Funktion kann man sich 
wie man hier sieht sehr elegant und effizient selbst hereinlegen.
1
void ausgabe(char *str)
2
{
3
    char* write_cursor = str;
4
    *write_cursor++ = 'A';
5
    *write_cursor++ = 'B';
6
    *write_cursor++ = 'C';
7
     
8
    printf(write_cursor);
9
}
In dieser Version wäre der Fehler offensichtlich gewesen. 'str' ist im 
Hinterkopf als "der String, in den ich schreibe" abgelegt. Wenn man den 
String am Ende der Funktion ausgeben will, liegt 'printf(str)' nahe; 
dass man 'str' vorher verändert hat, hat man an der Stelle leicht schon 
wieder vergessen.
Gast #5112808
Lesenswert?

Jan H. schrieb:
> char *buff = (char*)calloc(11,sizeof(char));

sizeof(char) ist per Definition immer 1. Du kannst also einfach 
calloc(11,1) oder noch einfacher malloc(11) schreiben. Der Grund ist, 
dass sizeof die Größe des Typs als Vielfache von der Größe von "char" 
zurückgibt, und "char" ist nunmal genau 1 char groß, also ist es immer 
1. (Siehe z.B. http://en.cppreference.com/w/c/language/sizeof )

Der Cast nach char* ist übrigens in C nicht nötig, nur in C++ - aber da 
würde man onehin lieber "new" nutzen.
OP #5112821
Lesenswert?

Habe das gerade mal ausprobiert.
Da stürzt die .exe ab.
1
void ausgabe(char *str)
2
{
3
    char* write_cursor = str;
4
    *write_cursor++ = 'A';
5
    *write_cursor++ = 'B';
6
    *write_cursor++ = 'C';
7
     
8
    printf(write_cursor);
9
}
10

11
int main(int argc, char *argv[]) {
12
  
13
  ausgabe("WIRD EH NICHT BENUTZT^^");
14
  
15
  return 0;
16
}
#5112835
Lesenswert?

Es ist doch immer wieder Interessant, wie viele Fehler man in so wenig 
Zeilen machen kann.

Interessant ist auch, dass das ganze auf 'nem Mega32 geklappt haben 
soll.


Da war doch irgendwo eine uralte Schwarte mit den Grundlagen zu "C".

Oder kann es sein, dass man so etwas heute nicht mehr braucht?

Also ich würde sagen man kann den Ansatz: "Learning by doing" auch 
übertreiben.
#5112842
Lesenswert?

Adam P. schrieb:
> Versuch das:
>
>
1
> void ausgabe(char *str){
2
> 
3
>   char *tmp = str;
4
> 
5
>   *tmp++ = 'A';
6
>   *tmp++ = 'B';
7
>   *tmp++ = 'C';
8
>   *tmp   = '\0';
9
> 
10
>   printf(str);
11
> }
12
>

In der Praxis würde ich jeweils noch die Länge des reservierten 
Speichers für die Zeichenkette mitgeben und beachten. Ansonsten kann es 
bei späteren Anpassungen und Unachtsamkeit durch einen selbst oder 
andere Entwickler schnell mal passieren, dass man über den reservierten 
Speicher hinaus schreibt und es dann zu nicht gewolltem Verhalten führen 
kann, welches nur sehr mühsam aufzuspüren ist.
#5112924
Lesenswert?

Reinhold schrieb:
> Tipp am Rande: Bei der Inkrementierungs-Dereferenzierungs-Geschichte
> Klammern setzen.

Der Ausdruck *str++ ist derart grundlegend für C, dass ich geradezu 
davon abraten würde, dort Klammern zu setzen. Sondern raten würde, zu 
verstehen, warum das so funktioniert.

An dieser Stelle Klammern zu setzen sorgt eher für Erheiterung 
erfahreneren Publikums als für Verständnis beim Lesen.

Es gibt gute Gründe dafür, solche Seiteneffekt-Operationen abzulehnen, 
unbeschadet des intuitiven oder unintuitiven Vorrangs der Operatoren. 
Aber dann richtig. Also
  *str = 'A'; str += 1;
  *str = 'B'; str += 1;
um Diskussionen zu vermeiden, was bei
  *str++ = *str++ = *str++ = 0;
alles rauskommen kann. ;-)
Gast #5112946
Lesenswert?

Reinhold schrieb:
> Tipp am Rande: Bei der Inkrementierungs-Dereferenzierungs-Geschichte
> Klammern setzen. Dann ist auf Anhieb klar was deine Intention war und
> was der Code macht wenn man die C Operator Precedence gerade nicht parat
> hat ;)

wir würdest du denn die Klammern setzen wollen?

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