C-char-Array-Initialisierung

Lesezeit: 7 Minuten

Benutzeravatar von lkkeepmoving
lkbeweg dich

Ich bin mir nicht sicher, was nach der Initialisierung auf folgende Weise im char-Array enthalten sein wird.

1.char buf[10] = "";

2. char buf[10] = " ";

3. char buf[10] = "a";

Für Fall 2, denke ich buf[0] sollte sein ' ', buf[1] sollte sein '\0'und von buf[2] zu buf[9] wird zufälliger Inhalt sein. Für Fall 3, denke ich buf[0] sollte sein 'a', buf[1] sollte ‘\0’ sein, und von buf[2] zu buf[9] wird zufälliger Inhalt sein.

Ist das korrekt?

Und für den Fall 1, was in der sein wird buf? buf[0] == '\0' und von buf[1] zu buf[9] wird zufälliger Inhalt sein?

  • Nun, mein Compiler akzeptiert Ihren (korrigierten) Code nicht: “array type ‘char [10]’ ist nicht zuweisbar”.

    –Martin R

    8. September 2013 um 22:00 Uhr

  • @MartinR jetzt wird es funktionieren …

    – lkbeweg dich

    8. September 2013 um 22:05 Uhr

  • @lkkeepmoving: char buf[10]; buf = "a"; tut nicht kompilieren. – Bitte versuchen Sie es zuerst und kopieren Sie dann Ihre tatsächlich Code in die Frage. Das erspart Ihnen und allen Lesern Ihrer Frage viel Arbeit.

    –Martin R

    8. September 2013 um 22:08 Uhr

  • @MartinR Entschuldigung dafür. Ich dachte, ich kann den Buf zuweisen[] letzteres aber es scheint nein. Jetzt läuft der Code.

    – lkbeweg dich

    8. September 2013 um 22:14 Uhr

  • Mögliches Duplikat von Zählt ein Zeichenfolgenliteral als partieller Initialisierer und Null-Initialisierung?

    – Antti Haapala – Слава Україні

    5. Juli 2016 um 11:08 Uhr

Benutzeravatar von ouah
ouah

So initialisieren Sie kein Array, sondern für:

  1. Die erste Erklärung:

    char buf[10] = "";
    

    ist äquivalent zu

    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  2. Die zweite Erklärung:

    char buf[10] = " ";
    

    ist äquivalent zu

    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  3. Die dritte Erklärung:

    char buf[10] = "a";
    

    ist äquivalent zu

    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    

Wie Sie sehen können, kein zufälliger Inhalt: Wenn es weniger Initialisierer gibt, wird der Rest des Arrays mit initialisiert 0. Dies ist auch dann der Fall, wenn das Array innerhalb einer Funktion deklariert wird.

  • Für den Fragesteller sei darauf hingewiesen, dass der C-Standard verlangt, dass jede teilweise vollständige Array-Initialisierung für die verbleibenden Elemente (vom Compiler) mit Null aufgefüllt wird. Dies gilt für alle Datentypen, nicht nur char.

    – Reisfeld

    8. September 2013 um 21:54 Uhr


  • @ouah warum gibt es kein ‘\0’ am Ende von buf[]?

    – lkbeweg dich

    8. September 2013 um 22:06 Uhr

  • @lkkeepmoving 0 und '\0 denselben Wert haben.

    – au

    8. September 2013 um 22:15 Uhr

  • @Pacerier char buff[3] = "abcdefghijkl"; ist ungültig. char p3[5] = "String"; ist ebenfalls ungültig. char p[6] = "String"; ist gültig und ist dasselbe wie char p[6] = {'S', 't', 'r', 'i', 'n', 'g'};.

    – au

    19. Dezember 2014 um 11:17 Uhr

  • @delive Was meinst du und welche Relevanz hatte es für diese Antwort?

    – Unterstrich_d

    31. Oktober 2017 um 9:24 Uhr


  1. Diese sind gleichwertig

    char buf[10] = "";
    char buf[10] = {0};
    char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  2. Diese sind gleichwertig

    char buf[10] = " ";
    char buf[10] = {' '};
    char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    
  3. Diese sind gleichwertig

    char buf[10] = "a";
    char buf[10] = {'a'};
    char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0};
    

Benutzeravatar von verbose
ausführlich

Bearbeiten: OP (oder ein Redakteur) hat einige der einfachen Anführungszeichen in der ursprünglichen Frage irgendwann stillschweigend in doppelte Anführungszeichen geändert, nachdem ich diese Antwort gegeben hatte.

Ihr Code führt zu Compilerfehlern. Ihr erstes Codefragment:

char buf[10] ; buf=""

ist doppelt illegal. Erstens gibt es in C so etwas wie ein Leerzeichen nicht char. Sie können doppelte Anführungszeichen verwenden, um eine leere Zeichenfolge zu kennzeichnen, wie bei:

char* buf = ""; 

Das gibt Ihnen einen Hinweis auf a NUL Zeichenfolge, dh eine Zeichenfolge mit nur einem Zeichen, in der nur die NUL Charakter darin. Aber Sie können keine einfachen Anführungszeichen mit nichts darin verwenden – das ist undefiniert. Wenn Sie die benennen müssen NUL Zeichen, Sie müssen es angeben:

char buf="\0";

Der umgekehrte Schrägstrich ist zur Unterscheidung von Zeichen erforderlich '0'.

char buf = 0;

erreicht dasselbe, aber ersteres ist etwas weniger zweideutig zu lesen, denke ich.

Zweitens können Sie Arrays nicht initialisieren, nachdem sie definiert wurden.

char buf[10];

deklariert und definiert das Array. Die Array-ID buf ist jetzt eine Adresse im Speicher, und Sie können den Ort nicht ändern buf Punkte durch Zuweisung. So

buf =     // anything on RHS

ist illegal. Ihr zweites und drittes Codefragment sind aus diesem Grund illegal.

Um ein Array zu initialisieren, müssen Sie dies zum Zeitpunkt der Definition tun:

char buf [10] = ' ';

gibt Ihnen ein 10-stelliges Array, wobei das erste Zeichen das Leerzeichen ist '\040' und der Rest ist NULdh, '\0'. Wenn ein Array mit einem Initialisierer deklariert und definiert wird, werden die Array-Elemente (sofern vorhanden) nach denen mit angegebenen Anfangswerten automatisch aufgefüllt 0. Es wird keine “zufälligen Inhalte” geben.

Wenn Sie das Array deklarieren und definieren, aber nicht initialisieren, wie im Folgenden:

char buf [10];

Sie werden zufällige Inhalte in allen Elementen haben.

  • “Um ein Array zu initialisieren, müssen Sie es zum Zeitpunkt der Definition tun …” Diese und die folgende Zeile machen dies besser als die akzeptierte Antwort.

    – Laurie Stearn

    28. Dezember 2016 um 3:48 Uhr


Der relevante Teil des C11-Standardentwurfs n1570 6.7.9 Initialisierung sagt:

14 Ein Array vom Zeichentyp kann durch ein Zeichenfolgenliteral oder ein UTF-8-Zeichenfolgenliteral initialisiert werden, das optional in geschweiften Klammern eingeschlossen ist. Aufeinanderfolgende Bytes des Zeichenfolgenliterals (einschließlich des abschließenden Nullzeichens, wenn Platz vorhanden ist oder das Array eine unbekannte Größe hat) initialisieren die Elemente des Arrays.

und

21 Wenn es gibt weniger Initialisierer in einer in geschweiften Klammern eingeschlossenen Liste als Elemente oder Mitglieder eines Aggregats vorhanden sind, oder weniger Zeichen in einem Zeichenfolgenliteral verwendet werden, um ein Array bekannter Größe zu initialisieren, als Elemente im Array vorhanden sind, wird der Rest des Aggregats implizit genauso initialisiert wie Objekte, die es haben statische Speicherdauer.

Daher wird das ‘\0’ angehängt, wenn genug Platz istund die restlichen Zeichen werden mit dem Wert initialisiert, den a static char c; würde innerhalb einer Funktion initialisiert werden.

Endlich,

10 Wenn ein Objekt mit automatischer Speicherdauer nicht explizit initialisiert wird, ist sein Wert unbestimmt. Wenn ein Objekt, das hat statisch oder Thread-Speicherdauer wird nicht explizit initialisiert, dann:

[–]

  • wenn es einen arithmetischen Typ hat, wird es auf (positiv oder vorzeichenlos) Null initialisiert;

[–]

Daher, char Da es sich um einen arithmetischen Typ handelt, wird auch der Rest des Arrays garantiert mit Nullen initialisiert.

Interessanterweise ist es möglich, Arrays jederzeit im Programm auf beliebige Weise zu initialisieren, vorausgesetzt, sie sind Mitglieder von a struct oder union.

Beispielprogramm:

#include <stdio.h>

struct ccont
{
  char array[32];
};

struct icont
{
  int array[32];
};

int main()
{
  int  cnt;
  char carray[32] = { 'A', 66, 6*11+1 };    // 'A', 'B', 'C', '\0', '\0', ...
  int  iarray[32] = { 67, 42, 25 };

  struct ccont cc = { 0 };
  struct icont ic = { 0 };

  /*  these don't work
  carray = { [0]=1 };           // expected expression before '{' token
  carray = { [0 ... 31]=1 };    // (likewise)
  carray = (char[32]){ [0]=3 }; // incompatible types when assigning to type 'char[32]' from type 'char *'
  iarray = (int[32]){ 1 };      // (likewise, but s/char/int/g)
  */

  // but these perfectly work...
  cc = (struct ccont){ .array='a' };        // 'a', '\0', '\0', '\0', ...
  // the following is a gcc extension, 
  cc = (struct ccont){ .array={ [0 ... 2]='a' } };  // 'a', 'a', 'a', '\0', '\0', ...
  ic = (struct icont){ .array={ 42,67 } };      // 42, 67, 0, 0, 0, ...
  // index ranges can overlap, the latter override the former
  // (no compiler warning with -Wall -Wextra)
  ic = (struct icont){ .array={ [0 ... 1]=42, [1 ... 2]=67 } }; // 42, 67, 67, 0, 0, ...

  for (cnt=0; cnt<5; cnt++)
    printf("%2d %c %2d %c\n",iarray[cnt], carray[cnt],ic.array[cnt],cc.array[cnt]);

  return 0;
}

Benutzeravatar von Eric Rapsing
Eric Rapsing

Ich bin mir nicht sicher, aber normalerweise initialisiere ich ein Array mit “”. In diesem Fall brauche ich mir keine Gedanken über das Null-Ende der Zeichenfolge zu machen.

main() {
    void something(char[]);
    char s[100] = "";

    something(s);
    printf("%s", s);
}

void something(char s[]) {
    // ... do something, pass the output to s
    // no need to add s[i] = '\0'; because all unused slot is already set to '\0'
}

Benutzeravatar von mrigendra
mrigendra

Ich verwende das folgende Format, wenn ich Zeichenfolgen usw. verwende

#include <stdio.h>
#include <string.h>



void func(char *str)
{
       char str1[50]={'\0'};
       int length=0;           
        
       if ((strlen(str) + 1) > 50)
                fprintf(stderr, "string too long\n");
       else if (str == NULL)
                fprintf(stderr, "Invalid pointer\n");
       else {
                memcpy(str1, str, strlen(str) + 1);
                if(*str1 == '\0' )
                        fprintf(stderr, "Invalid string\n");
                else         
                        printf("--> %s\n", str1);
               
                memset(str1 ,'\0' , strlen(str1) + 1);
                str=NULL;
       }
}

int main()
{
        func("this is my string");
        return 0;
}

1424020cookie-checkC-char-Array-Initialisierung

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy