Christian Kruse: C - Zeigerfrage Array

Beitrag lesen

Moin Mechthild,

Nein, da hast du etwas missverstanden. Auch wenn du dein Dokument in utf-8 kodierst, ist der interne Datentyp char in C immer noch 1 byte lang (auf gängiger Hardware). Und deshalb wird ein char \*ptr = "aä"; ++ptr; danach immer noch auf das erste Byte der UTF-8-Sequenz zeigen.

so ganz kapiert hab ich's noch nicht. Oder anders, das, was du schreibst, verstehe ich schon so einigermaßen. Was unitedpower schrieb, kann ich aber nicht so recht einordnen. Oder sollte das vermutlich nur ein Beispiel sein, um zu veranschaulichen, dass die Datengröße beim Dereferenzieren immer automatisch berechnet wird?

Was 1UnitedPower veranschaulichen wollte, war die Tatsache, dass bei Pointer-Arithmetik die Anzahl der Bytes, die ein *(ptr+1) „nach vorne gehen“ muss, vom Compiler ausgerechnet wird anhand der Typen-Informationen. Einfaches Beispiel:

  
#include <stdio.h>  
  
int main(void) {  
  int ifield[] = {1,2};  
  char cfield[] = {'a','b'};  
  printf("address of ifield and ifield+1: %p %p\n", ifield, ifield+1);  
  printf("address of cfield and cfield+1: %p %p\n", cfield, cfield+1);  
  return 0;  
}  

Beispielhafter output:

  
address of ifield and ifield+1: 0x7fff2ea67890 0x7fff2ea67894  
address of cfield and cfield+1: 0x7fff2ea67880 0x7fff2ea67881  

Wie du sehen kannst, ist die Differenz der beiden Integer-Pointer 4 (0x7fff2ea67890 - 0x7fff2ea67894 = 4) und die Differenz der beiden Char-Pointer 1 (0x7fff2ea67880 - 0x7fff2ea67881 = 1), und das obwohl wir bei beiden Arrays nur 1 addiert haben.

Wie ist denn das dann eigentlich mit uft8 bzw. Mehrbytekodierungen? Ist die interne Größe von
char *ptr = 'ä'; 1 Byte, egal wie das Dokument kodiert ist?

Das fliegt dir um die Ohren:

  
int main(void) {  
  char c = 'ä';  
  return 0;  
}  

  
→ ckruse@achilles ~  % gcc -W -Wall -o test test.c  
test.c: In function ‘main’:  
test.c:4:12: warning: multi-character character constant [-Wmultichar]  
   char c = 'ä';  
            ^  
test.c:4:3: warning: overflow in implicit constant conversion [-Woverflow]  
   char c = 'ä';  
   ^  
test.c:4:8: warning: unused variable ‘c’ [-Wunused-variable]  
   char c = 'ä';  
        ^  
→ ckruse@achilles ~  %  

Ein Byte kann halt nicht mehrere Bytes aufnehmen :-) Du musst das als char-Array handhaben:

  
int main(void) {  
  char *c = "ä";  
  return 0;  
}  

  
→ ckruse@achilles ~  % gcc -W -Wall -o test test.c  
test.c: In function ‘main’:  
test.c:4:9: warning: unused variable ‘c’ [-Wunused-variable]  
   char *c = "ä";  
         ^  
→ ckruse@achilles ~  %  

C kennt halt keine Zeichen, sondern nur Bytes. Insofern ist der Datentyp char natürlich auch irreführend allerdings halt auch der Zeit geschuldet, in der C entstanden ist.

LG,
 CK