Pertanyaan inisialisasi const char *


Ini adalah salah satu penggunaan yang saya temukan dalam perangkat lunak open source. Dan saya tidak mengerti cara kerjanya. ketika saya ouput ke stdout, itu "versi 0.8.0".

const char version[] = " version " "0" "." "8" "." "0";

8
2018-03-27 15:13


asal


Jawaban:


Ini adalah fitur dasar dari C89 dan C ++ 98 yang disebut 'rangkaian string berdekatan' atau sekitar itu.

Pada dasarnya, jika dua literal string berdekatan satu sama lain tanpa tanda baca di antaranya, keduanya digabung menjadi string tunggal, seperti yang ditunjukkan oleh output Anda.


Dalam standar C ++ 98, bagian §2.1 'Fase terjemahan [lex.phases]' mengatakan:

6 Token literal string biasa yang berdekatan dirangkai. Token sastra string lebar yang berdekatan disambung.

Ini setelah preprocessor selesai.

Dalam standar C99, bagian yang sesuai adalah §5.1.2.1 'Fase Terjemahan' dan ia mengatakan:

6 Token literal string yang berdekatan dirangkai.

Kata-katanya akan sangat mirip dengan standar C atau C ++ lainnya yang dapat Anda tangani (dan saya mengenali bahwa C ++ 98 dan C99 digantikan oleh C ++ 11 dan C11; Saya tidak memiliki salinan elektronik dari standar terakhir, belum).


7
2018-03-27 15:16



Ini disebut penggabungan string - ketika Anda menempatkan dua (atau lebih) string kutipan di sebelah satu sama lain dalam kode sumber tanpa apa pun di antara mereka, kompilator menempatkan mereka bersama-sama ke dalam string tunggal. Ini paling sering digunakan untuk string panjang - apa pun yang lebih dari satu baris panjang:

char whatever[] = "this is the first line of the string\n"
    "this is the second line of the string\n"
    "This is the third line of the string";

Sebelum penggabungan string diciptakan, Anda harus melakukannya dengan kelanjutan garis yang agak kaku, menempatkan backslash pada akhir setiap baris (dan memastikan itu adalah akhir, karena kebanyakan kompiler tidak akan memperlakukannya sebagai garis kelanjutan jika ada setiap spasi setelah backslash). Ada juga keburukan dengan itu membuang lekukan, karena setiap spasi di awal baris berikutnya mungkin termasuk dalam string.

Ini dapat menyebabkan masalah kecil jika Anda ingin meletakkan koma di antara string, seperti saat menginisialisasi array pointer ke char. Jika Anda melewatkan koma, kompilator tidak akan memperingatkan Anda tentang hal itu - Anda hanya akan mendapatkan satu string yang mencakup apa yang dimaksudkan untuk menjadi dua string terpisah.


9
2018-03-27 15:15



Bagian dari penerapan standar C ++ menyatakan bahwa string literal yang berada di samping satu sama lain akan digabungkan bersama.

Kutipan dari C dan C ++ Standard:

Untuk C (mengutip C99, tetapi C11 memiliki sesuatu yang serupa dalam 6.4.5p5):

(C99, 6.4.5p5) "Dalam fase terjemahan 6, karakter multibyte   urutan yang ditentukan oleh setiap urutan karakter yang berdekatan dan   token literal string yang identik-asli digabung menjadi a   urutan karakter multibyte tunggal. "

Untuk C ++:

(C ++ 11, 2.14.5p13) "Dalam fase terjemahan 6 (2.2), string yang berdekatan   literal digabung. "


6
2018-03-27 15:16



const char version[] = " version " "0" "." "8" "." "0";

sama seperti:

const char version[] = " version 0.8.0";

Compiler menggabungkan berdekatan potongan string-literal, membuat satu bagian lebih besar dari string-literal.

Sebagai sidenote, const char* (yang ada di judul Anda) tidak sama dengan char char[] (yang ada di kode diposting Anda).


3
2018-03-27 15:15



Compiler secara otomatis menggabungkan string literal yang ditulis setelah satu sama lain (dipisahkan oleh spasi-putih saja) .. Ini seolah-olah Anda telah menulis

const char version[] = "version 0.8.0";

EDIT: pre-processor yang dikoreksi ke compiler


2
2018-03-27 15:16



Liter literal yang berdekatan adalah digabung:

Saat menentukan literal string, string yang berdekatan akan digabungkan.   Oleh karena itu, pernyataan ini:

char szStr [] = "12" "34"; identik dengan deklarasi ini:

char szStr [] = "1234"; Penggabungan string yang berdekatan ini membuatnya   mudah untuk menentukan string panjang di beberapa baris:

cout << "Empat skor dan tujuh tahun"
          "lalu, nenek moyang kita melahirkan"
          "di benua ini sebuah negara baru.";


2
2018-03-27 15:16



Cukup meletakkan string satu setelah yang lain menggabungkannya pada waktu kompilasi, jadi:

"Hello" ", " "World!" => "Hello, World!"

Ini adalah penggunaan fitur yang aneh, biasanya untuk memungkinkan #define string yang akan digunakan:

#define FOO "World!"

puts("Hello, " FOO);

Akan dikompilasi ke yang sama seperti:

puts("Hello, World!");

0
2018-03-27 15:17