2016-08-13 5 views
-2

Ich habe eine Frage zum besseren Unterschätzen, wie Arrays und Nullbytes in C arbeiten.C-Arrays und Null-Byte

Nehmen wir an, ich habe eine int-Array von 13 Zellen. Lassen Sie uns sagen, ich möchte Zellen Nummer: 1, 2, 3 und 10 einen Wert haben. Die anderen, die als Standard übrig sind, erhalten automatisch den Nullchar \ 0 als Wert?

Mein Verständnis von \ 0 war, dass das Nullbyte immer am Ende des Arrays ist und seine Funktion ist, dem Programm mitzuteilen, wo Array endet. Aber scheint falsch zu sein

ich eine einfache prog schrieb, um zu überprüfen, und wie es scheint, das heißt:

int nums[13] = {1,2,3}; 
nums[10] = 69; 
int i; 
for(i=0;i<13;i++) { 
    if(nums[i]=='\0') { 
     printf("null char found! in position: %d\n",i); 
    } 
    else { 
     printf("element: %d found in position: %d of int array\n",nums[i],i); 
    } 
} 

return 0; 

hier ist die Ausgabe:

Element: 1 in Position gefunden: 0 von int Array

Element 2 in Position gefunden: 1 von int array

Element: 3 in Position gefunden: 2 von int array

null char gefunden! in Position: 3

null char gefunden! in Position: 4

null char gefunden! in Position: 5

null char gefunden! in Position: 6

null char gefunden! in Position: 7

Nullstelle gefunden! in Position: 8

null char gefunden! in Position: 9

Element 69 in Position gefunden: 10 von int array

null char gefunden! in Position: 11

null char gefunden! in Position: 12

| 1 | | 2 | | 3 | | \ 0 | | \ 0 | | \ 0 | | \ 0 | | \ 0 | | \ 0 | | 69 | | \ 0 | | \ 0 | | \ 0 |

Warum also Standardzellen mit dem Wert \ 0 gesetzt? anstatt zum Beispiel leer zu bleiben?

Sollte das Nullzeichen nicht nur einmal am Ende des gesamten Arrays sein? Danke

+0

Statisch zugeordneter Speicher wird mit 0 für Skalare oder NULL (\ 0) für Zeiger gefüllt. Wenn Sie \ 0 als Skalar darstellen, wird es in 0 umgewandelt. Es gibt keine "leeren" Objekte. Sie sollten NULL (\ 0) trotzdem nicht mit einem int vergleichen, verwenden Sie ein Literal 0. – Tibrogargan

+4

"Mein Verständnis von \ 0 war, dass das Nullbyte immer am Ende des Arrays ist .." ist völlig falsch. Sie verwechseln reguläre Arrays und C-Strings. – usr2564301

+0

@Tribrotargan '\ 0' (das NUL-Zeichen) ist nicht dasselbe wie der' NULL'-Zeiger. '\ 0' ist ein Byte, bei dem alle Bits auf 0 gesetzt sind, was immer gleich dem 'int'0 ist. – Kninnug

Antwort

3

Es gibt keine Anforderung in C, dass Arrays am Ende eine \0 benötigen. Ein NUL-Terminator wird nur für C Strings benötigt (die normalerweise die char oder wchar_t oder andere Zeichen Typ haben). In einer C-Zeichenfolge muss das \0 Byte auch nicht am Ende des Arrays sein, das es enthält, aber es muss sich am Ende des String-Teils befinden. Es ist durchaus zulässig, irgendwo innerhalb eines Arrays Nullen zu haben. Wenn dieses Array jedoch als String verwendet wird, interpretieren die Standard-C-String-Funktionen die 0 mit dem niedrigsten Index, um das Ende des Strings zu bezeichnen.

Wenn Sie eine Variable (nums) in C mit einem Initialisierer ({1,2,3}) erklären in

int nums[13] = {1,2,3}; 

alle Indizes, die in dem initializer erwähnt (3 bis 12) nicht haben ihren Wert zu 0 initialisiert. Es ist nicht möglich, leere Zellen in einem Array zu haben. Alle Zellen haben einen Wert, es liegt am Programm (mer) welche Werte als leer zu betrachten sind.

1

C-Typen entsprechen Speicher, und Speicher hat kein echtes Konzept von "leer". Es gibt Sprachen, in denen alles (oder fast) "leer" gemacht werden kann, indem einige "leer" konstant gehalten werden (Python hat None, zum Beispiel), aber C erlaubt das nicht. Ein Grund, es nicht zuzulassen, ist, dass es zwingt, ein spezielles universelles Muster für den leeren Zustand zu haben, und dies hat geringe Auswirkungen. Zum Beispiel kann ein Zeichen einen beliebigen Wert von 0 bis einschließlich 255 annehmen. Das liegt daran, dass Zeichen 8 Bits belegen. Wenn Sie auch einen leeren Zustand wünschen, ohne mögliche Werte für Zeichen zu opfern, benötigen Sie mindestens ein weiteres Bit, da die 8 anderen Bits aus legitimen Gründen verwendet werden können, was aus vielen Gründen unerwünscht ist.

Für Ihr Array setzt die von Ihnen verwendete Initialisierungssyntax jedes nicht spezifizierte Element auf Null. Wenn Sie schreiben:

char foo[4] = {1, 2, 3, 4}; 

dann hat jedes Element einen Wert (Hinweis, dass es keinen Null-Byte am Ende hat, weil Arrays nicht einen Null-Byte in der End-aber haben müssen, wenn Sie sie als Zeichenfolgen zu verwenden, dann sollten sie sehr). Wenn Sie schreiben:

char foo[4] = {1, 2}; 

Elemente 0 und 1 haben einen bestimmten Wert, aber 2 und 3 nicht, und mit dieser Syntax C wird davon ausgegangen, dass Sie sie Null machen wollen. Auf der anderen Seite, wenn Sie schreiben:

char foo[4]; 

Sie einen beliebigen Wert auf jedes Element nicht zuweisen, und in diesem Fall C wird das Array überhaupt nicht initialisiert werden. Es wäre undefiniertes Verhalten, daraus zu lesen; In der Praxis nehmen die Elemente normalerweise die Werte dessen, was zufällig an ihrem Speicherort vorlag, an.

-1

Zunächst verwechseln Sie C-Strings mit regulären Arrays. Bei Strings gibt es immer ein \0 am Ende des char Arrays. Es kennzeichnet das Ende der Zeichenfolge. Zum Beispiel, sagen Sie dies haben:

char myText[] = "hello"; 

In diesem Fall sehen die Array Sitze:

 

    myText[0] = 'h'; 
    myText[1] = 'e'; 
    myText[2] = 'l'; 
    myText[3] = 'l'; 
    myText[4] = 'o'; 
    myText[5] = '\0'; 

jedoch Arrays führen nicht zum Abbruch mit '\0'. Nehmen wir ein anderes Beispiel:

int myArray[3] = {1, 2, 3}; 

Nach Ihrer Regel, da Arrays mit einem '\0' zu beenden haben, ist dies nicht eine rechtliche Aussage, da wir nur die Anordnung 3 Elemente anstelle von 4 geben, und wir müssten vier Elemente schließe eine '\0' ein. Dies ist jedoch eine völlig legale Aussage in C. Offensichtlich wird Platz für die '\0' in Arrays nicht benötigt, nur am Ende von C-Strings.

Beachten Sie auch, dass '\0' die ganze Zahl entspricht, wie in den Kommentaren Kninnug hingewiesen:

\0 (die Null-Zeichen) nicht die gleichen wie der NULL-Zeiger. \0 ein Byte mit allen Bits auf 0 gesetzt, die immer gleich vergleichen würden die int 0.

in Ihrem Programm also, könnte man nur gleich überprüfen, ob:

if(nums[i] == 0) 

Nun lassen sie beweisen Sie, warum Sie Ihre Ausgabe erhalten.

Sollte das Nullzeichen nicht nur einmal am Ende des gesamten Arrays sein?

Nein. Alle anderen leer gelassenen Elemente werden mit dem Wert Null initialisiert. Deshalb sehen Sie die Ausgabe, die Sie haben; Elemente, die nicht num[0], num[1], num[2] oder num[10] sind, werden mit Null initialisiert. Da Sie für \0 werden überprüft (auch 0) dann alles andere mit nicht diesen Elementen 0 sein wird


Wie alk in den Kommentaren darauf hingewiesen, das Null-Zeichen und der Null-Zeiger wörtliche sind unterschiedlich. Am Ende von C-Strings sehen Sie das Nullzeichen (NUL), das '/0' oder 0 ist. Das Nullzeigerliteral (NULL) ist jedoch unterschiedlich.

+0

Kann jemand die Abstimmung unten erklären, also kann ich die Post verbessern? – iRove

+0

NUL (der Name für das Nullzeichen) und 'NULL' (das Nullzeigerliteral) sind verschiedene Arten von Tieren. – alk

+0

Ein C- "String" ist ein Zeichen-Array, bei dem mindestens eines der Elemente dem NUL entspricht, das Null-Zeichen (gleich '\ 0'', was gleich' 0 'ist). Ein Zeichen-Array ist nicht unbedingt eine C- "Zeichenfolge". – alk

0

NULL definiert als (void *) 0 - Es ist Null mit generischem ptr Gießen, weicht gleich die ASCII-Code der NUL-Zeichen (\ 0) - 0

Arrays müssen nicht mit jedem beenden Sonderzeichen/Nummer.

Strings brauchen mit einem Sonderzeichen zu beenden, und der Grund ist einfach, es läßt Funktionen auf Strings weichen arbeitet „wissen“, wo die Zeichenfolge endet, zum Beispiel:

char str[100] = {'h','e','l','l','o',0}; // same as {'h','e','l','l','o','\0'} 
printf("%s",str); 

druckt: hallo

Wenn das letzte Zeichen in der Zeichenfolge nicht NUL war, wird es nach der Zeichenfolge ("hallo") 95 ungültige Zeichen ausgeben, da die Arraygröße 100 ist und der Compiler keine Möglichkeit hat zu wissen, wo die Zeichenfolge endet.

Obwohl die Null in der 6. Zelle die Zeichenfolge in den meisten Compilern beendet, können Sie nur die "Hallo" -String und sie füllen den Rest der Zellen mit Nullen, so dass es in beiden Fällen in Ordnung sein wird.

+0

NUL (der Name für das Null-Zeichen) und 'NULL' (das Null-Zeiger-Literal) sind unterschiedliche Arten von Tieren. – alk

+0

Ich habe nicht geschrieben, sie sind das gleiche .. –

Verwandte Themen