www.mikrocontroller.net

Forum: Compiler & IDEs Zeiger char - Zeichenketten ersetzen


Autor: C-Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

im Moment beschäftige ich mich gerade mit Zeigern. Leider bin ich auf 
ein Problem gestoßen, dass ich nicht ganz verstehe bzw. wieso es nicht 
so funktioniert. Im Anhang unten ist der C-Code. Egal welche Varianten 
(1-2) ich verwende, meldet der Compiler einen Speicherzugriffsfehler.
Mein Ziel war es, die einzelnen Bustaben von "Hello" durch andere 
Bustaben zu ersetzen. Wenn ich die Variante 3 verwende, dann gibt's 
keine Probleme beim Kompilieren. Woran könnte es liegen?

MfG

void main (void)
{
    char *Text; /* Zeiger vom Typ char */
    Text = "Hello";
    
   /* Variante 1 */
   *(Text+0) = 'B';
   *(Text+1) = 'e';
   *(Text+2) = 'l';
   *(Text+3) = 'l';
   *(Text+4) = 'o';
   *(Text+5) = '\0';

    /* Variante 2 */
    Text[0] = 'B';
    Text[1] = 'e';
    Text[2] = 'l';
    Text[3] = 'l';
    Text[4] = 'o';
    Text[5] = '\0';
   
    /* Variante 3 */
    Text = "Bello";
}

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

Bewertung
0 lesenswert
nicht lesenswert
Dein ganzes Programm hat undefiniertes Verhalten.

Ein String-Literal (also ein konstanter Text, wie zb "Hello") ist 
unveränderlich! Du darfst gar nicht versuchen, ihn zu ändern.
    char *Text; /* Zeiger vom Typ char */
hierdurch hast du einen Zeiger eingerichtet

    Text = "Hello";
jetzt lässt du diesen Zeiger auf einen konstanten Text zeigen

   *(Text+0) = 'B';
und jetzt versuchst du, über den Zeiger den konstanten Text zu 
verändern. Und das darfst du nicht.


Das geht zwar in C nicht, weil ein Integer-Literal (anders als ein 
String) keine Adresse besitzt. Aber im Grunde, analogiemässig gesehen, 
versuchst du jetzt gerade dieses hier zu machen
  int * p;
  p = &78;

  *p = 5;

Deine Variante 3 hingegen, macht etwas ganz anderes. Sie setzt den 
Zeiger um. Der zeigt nicht mehr auf den konstante Text "Hello" sondern 
auf den ebenfalls konstanten Text "Bello"

vorher:
   Text
   +--------+
   |   o-------------------------->"Hello"
   +--------+
                          "Bello"

nachher
   Text
   +--------+
   |   o--------------+            "Hello"
   +--------+         |
                      +-->"Bello"

Autor: C-Beginner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich Danke Dir für deine sehr ausführliche Erläuterung. Zu Beginn dachte 
ich, dass durch die Deklaration
char *Text = "Hello";
ein veränderbares Char-Array statt eine Stringkonstante erhalte. 
Insbesondere deine Schaubilderchen waren sehr hilfreich. Thx, Karl!

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

Bewertung
0 lesenswert
nicht lesenswert
C-Beginner schrieb:
> Ich Danke Dir für deine sehr ausführliche Erläuterung. Zu Beginn dachte
> ich, dass durch die Deklaration
>
>
> char *Text = "Hello";
> 
> ein veränderbares Char-Array

Das kann schon deshalb nicht sein, weil in der ganzen Deklaration kein 
Array vorkommt.
Eine Pointer Variable ist immer nur eine Variable, die auf etwas zeigen 
kann. Worauf sie zeigt ... das ist immer davon getrennt.

Keine Sorge: das ist ein weit verbreitetes Misverständnis.

  char Text[] = "Hello";

das sieht zwar fast gleich aus, hat aber einen entscheidenden und 
wichtigen Unterschied: Hier wird Speicher, und zwar veränderbarer 
Speicher, allokiert und dieser Speicher wird mit den Zeichen 'H', 'e', 
'l', 'l', 'o', '\0' initialisiert. Aber grundsätzlich ist dieses Text 
jetzt veränderbar. Du kannst auch einen Pointer darauf einrichten

  char * p = Text;
oder
  char * p = &Text[0];

und dann über den Pointer die Zeichen in Text manipulieren

  *p = 'B';

die Situation im Speicher ist jetzt aber eine ganz andere

  p
 +-------+
 |  o------------------+
 +-------+             |  Text
                       |  +---+---+---+---+---+---+
                       +->| H | e | l | l | o | \0|
                          +---+---+---+---+---+---+

Autor: g457 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das kann schon deshalb nicht sein, weil in der ganzen Deklaration kein
> Array vorkommt.

Dem kann man abhelfen:
$ cat main.c 
#include <stdio.h>

int main()
{
        char text[] = "Hallo";

        printf("original: '%s'\n", text);

        text[0] = 'B';
        text[1] = 'e';
        printf("neu: '%s'\n", text);

        return 0;
}
$ gcc -Wall -o main main.c
$ ./main 
original: 'Hallo'
neu: 'Bello'

HTH

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
g457 schrieb:
>> Das kann schon deshalb nicht sein, weil in der ganzen Deklaration kein
>> Array vorkommt.
>
> Dem kann man abhelfen:

Wichtige Regel: Bevor man eine Antwort auf ein Posting versendet, sollte 
man es komplett gelesen haben.

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.