'\ 0' ve C de printf ()


21

C'nin giriş dersinde, dizeleri saklarken \0sonunda boş karakterle saklandığını öğrendim . Ama bir dize yazdırmak printf("hello")istersem \0, aşağıdaki ifadeyle bitmediğini fark etsem de

printf("%d", printf("hello"));

Output: 5

ama bu tutarsız gibi görünüyor, kadarıyla dizeleri gibi değişken ana bellekte saklanır biliyorum ve sanırım bir şey yazdırırken de ana bellekte saklanabilir, o zaman neden fark?


1
Kodunuzun en azından kaçırması dışında, bu kodla );ne göstermeyi düşünüyorsunuz? Bunun bir ile bitmediğini nasıl kanıtladınız \0?
glglgl

Ve içinde depolanan hafızanın onunla ne ilgisi var?
Tsakiroglou Fotis

C'de tüm değişmez dizeler , boş sonlandırıcıyı içeren karakter dizileridir .
Bazı programcı ahbap

@glglgl Sanırım printf () ekranda yazdırması gereken karakter sayısını döndürür.
Ajay Mishra

4
@AjayMishra Evet ve gerçekten de 5 karakter basmış olmalıydı. Sonlandırma 0 baytı ekranda yazdırılmaz.
glglgl

Yanıtlar:


13

Boş bayt bir dizenin sonunu işaretler. Dizenin uzunluğu olarak sayılmaz ve bir dize ile yazdırıldığında yazdırılmaz printf. Temel olarak, boş bayt, ne zaman durulacağını dize manipülasyonu yapan işlevlere bildirir.

Farkı göreceğiniz yer, chardizeyle başlatılan bir dizi oluşturmaktır . İşlecin kullanılması, sizeofboş bayt dahil dizinin boyutunu yansıtacaktır. Örneğin:

char str[] = "hello";
printf("len=%zu\n", strlen(str));     // prints 5
printf("size=%zu\n", sizeof(str));    // prints 6

Hikayenin farklı olacağını düşündüm printf(). TBH Nasıl printf()çalıştığı hakkında hiçbir fikrim yok .
Ajay Mishra

8

printfyazdırılan karakter sayısını döndürür. '\0'yazdırılmaz - bu dizede artık karakter olmadığını gösterir. Dize uzunluğuna da sayılmaz

int main()
{
    char string[] = "hello";

    printf("szieof(string) = %zu, strlen(string) = %zu\n", sizeof(string), strlen(string));
}

https://godbolt.org/z/wYn33e

sizeof(string) = 6, strlen(string) = 5

6

Varsayımınız yanlış. Dizeniz gerçekten bir ile bitiyor \0.

Bu 5 karakter arasında içerir h, e, l, l, ove 0 karakteri.

"İç" print()çağrının çıktısı basılan karakter sayısıdır ve bu 5'tir.


6

C'de tüm değişmez dizeler, boş sonlandırıcıyı içeren karakter dizileridir.

Ancak, boş sonlandırıcı olduğu olmayan bir dizi (hazır veya değil) uzunluğu sayılır ve yazdırıldığı değil. Boş sonlandırıcı bulunduğunda yazdırma durur .


Dizeyi bir dizide saklamadan bunu doğrulamak için yine de var mı?
Ajay Mishra

1
@AjayMishra Eh dize zaten olduğu (belirtildiği gibi) bir dizideki ... Ama yok eğer boş sonlandırıcı sonra printfdize aut giderek "rastgele" veya "çöp" karakterlerini yazdırmak ve dönüşü olur dize uzunluğundan farklı bir sayı. Dizenin uzunluğunu zaten biliyorsanız, dizindeki karakterin '\0'çalışıp çalışmadığını ancak dizinin boyutu sonlandırıcıyı içermiyorsa (teknik olarak tanımlanmamış bir davranış olup olmadığını da kontrol edebilirsiniz char arr[5] = "hello";. diziye sonlandırıcı) ekleyin.
Bazı programcı dostum

@AjayMishra Evet E. g., char * p = "Hello"; int i = 0; while (p[i] != '\0') { printf("%d: %c", i, p[i]); i++; }Nasıl çalıştığını ve nasıl çalıştığını görebilirsiniz: dizinli satırları ve bu satırdaki içeriği gösterir. Dizin 4'ten sonra 0 karakterini bulur ve while döngüsünü kırar. Orada 0 karakter olduğunu görüyorsunuz.
glglgl

6

Tüm cevaplar gerçekten iyi ama tüm bunları tamamlamak için başka bir örnek daha eklemek istiyorum

#include <stdio.h>

int main()
{
    char a_char_array[12] = "Hello world";

    printf("%s", a_char_array);
    printf("\n");

    a_char_array[4] = 0; //0 is ASCII for null terminator

    printf("%s", a_char_array);
    printf("\n");

    return 0;
}

Online gdb üzerinde denemek istemeyenler için çıktı:

Selam Dünya

cehennem

https://linux.die.net/man/3/printf

Bu, kaçış sonlandırıcının ne yaptığını anlamakta yardımcı olur mu? Bir char dizisi veya dize için bir sınır değildir. Buraya kadar -STOP, (yazdır) ayrıştırma ayrışan adama söyleyecek karakter.

Not: Ayrıştırır ve karakter dizisi olarak yazdırırsanız

for(i=0; i<12; i++)
{
    printf("%c", a_char_array[i]);
}
printf("\n");

olsun:

Cehennem dünyası

burada, l çiftinden sonraki boşluk null sonlandırıcıdır, ancak char dizisini ayrıştırmak her baytın char değerini gösterir. Başka bir ayrıştırma yapar ve her baytın int değerini ("% d%, char_array [i]) yazdırırsanız, boşluk alanının 0 değerine sahip olduğunu görürsünüz (ASCII kod int gösterimini alırsınız).


4

In Cfonksiyonu printf(), baskılı karakter sırasını verir \0bir olduğu nullc dilinde dize sonunu belirtmek için kullanılır ve hiçbir orada inşa edilmiştir terminatör stringitibarıyla türü c++ancak senin dizi boyutunda ihtiyaçları sayısı daha az büyük olması, charsizin istediğiniz depolamak.

İşte ref: cpp ref printf ()


3

Ama bir dize yazdırmak istersem, şu ifadeyi izleyerek \ 0 ile bitmediğini fark etsem de printf ("merhaba") deyin

printf("%d", printf("hello"));

Output: 5

Hatalısınız. Bu ifade, dize değişmezinin "hello"sonlanan sıfır karakteriyle bitmediğini doğrulamaz '\0'. Bu deyim, işlevin printfsonlu sıfır karakteri ile karşılaşılana kadar bir dizenin öğelerini verdiğini doğrular .

Yukarıdaki ifadede olduğu gibi bir dize değişmezi kullandığınızda, derleyici, değişmez dize öğelerini içeren statik depolama süresine sahip bir karakter dizisi oluşturur.

Aslında bu ifade

printf("hello")

derleyici tarafından aşağıdaki gibi işlenir

static char string_literal_hello[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
printf( string_literal_hello );

Printf fonksiyonunun bu eylemini aşağıdaki şekilde hayal edebilirsiniz

int printf( const char *string_literal )
{
    int result = 0;

    for ( ; *string_literal != '\0'; ++string_literal )
    {    
        putchar( *string_literal );
        ++result;
    }

    return result;
}

Değişken "merhaba" dizesinde saklanan karakter sayısını almak için aşağıdaki programı çalıştırabilirsiniz

#include <stdio.h>

int main(void) 
{
    char literal[] = "hello";

    printf( "The size of the literal \"%s\" is %zu\n", literal, sizeof( literal ) );

    return 0;
}

Program çıktısı

The size of the literal "hello" is 6

0

Önce konseptinizi temizlemelisiniz .. Dizi ile uğraşırken silineceği gibi, kullandığınız print komutu sadece parantez içine yerleştirilmiş karakterleri sayar. \ 0 ile biteceği dizi dizesinde gereklidir


0

Dize, karakterlerin bir vektörüdür. Dizeyi oluşturan karakter dizisini ve ardından özel bitiş karakteri dizesini içerir: '\ 0'

Örnek: char str [10] = {'H', 'e', ​​'l', 'l', 'o', '\ 0'};

Örnek: '\ 0' ile bitmediği için aşağıdaki karakter vektörü bir dize değildir

char str [2] = {'h', 'e'};


Sanırım C'de vektör yok.
Ajay Mishra
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.