Apa bedanya
char* name
yang menunjuk ke string konstan literal, dan
const char* name
Apa bedanya
char* name
yang menunjuk ke string konstan literal, dan
const char* name
Jawaban:
char*
adalah pointer yang bisa berubah ke karakter / string yang bisa berubah .
const char*
adalah pointer yang bisa berubah ke karakter / string yang tidak dapat diubah . Anda tidak dapat mengubah konten lokasi yang ditunjuk oleh pointer ini. Juga, kompiler diminta untuk memberikan pesan kesalahan saat Anda mencoba melakukannya. Untuk alasan yang sama, konversi dari const char *
ke char*
tidak digunakan lagi.
char* const
adalah pointer yang tidak dapat diubah (tidak dapat menunjuk ke lokasi lain) tetapi konten lokasi yang ditunjukkannya dapat berubah .
const char* const
adalah pointer yang tidak dapat diubah ke karakter / string yang tidak dapat diubah .
char const *
char *
memberikan kesalahan segmentasi saat menjalankan?
const
jika saya ingin kompiler memberikan kesalahan jika saya lupa dan mengubah data secara tidak sengaja, bukan?
char *name
Anda dapat mengubah arang ke name
titik mana , dan juga arang di mana ia menunjuk.
const char* name
Anda dapat mengubah arang ke name
titik mana , tetapi Anda tidak dapat mengubah arang di mana ia menunjuk.
koreksi: Anda dapat mengubah pointer, tetapi bukan karakter yang name
mengarah ke ( https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx , lihat "Contoh" ). Dalam kasus ini, const
specifier berlaku untuk char
, bukan tanda bintang.
Menurut halaman MSDN dan http://en.cppreference.com/w/cpp/language/declarations , const
sebelum itu *
adalah bagian dari urutan decek-specifier, sedangkan const
after *
adalah bagian dari deklarator.
Urutan specifier deklarasi dapat diikuti oleh beberapa deklarator, itulah sebabnya const char * c1, c2
menyatakan c1
sebagaiconst char *
dan c2
sebagai const char
.
EDIT:
Dari komentar, pertanyaan Anda tampaknya bertanya tentang perbedaan antara dua deklarasi ketika pointer menunjuk ke string literal.
Dalam hal ini, Anda tidak boleh memodifikasi char ke name
titik mana , karena dapat menghasilkan Perilaku Tidak Terdefinisi . Literal string dapat dialokasikan di wilayah memori hanya baca (implementasi ditentukan) dan program pengguna tidak boleh memodifikasinya. Setiap upaya untuk melakukannya menghasilkan Perilaku Tidak Terdefinisi.
Jadi satu-satunya perbedaan dalam kasus itu (penggunaan dengan string literal) adalah bahwa deklarasi kedua memberi Anda sedikit keuntungan. Compiler biasanya akan memberi Anda peringatan jika Anda mencoba untuk memodifikasi string literal dalam kasus kedua.
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
Keluaran:
cc1: peringatan diperlakukan sebagai kesalahan
prog.c: Dalam fungsi 'utama':
prog.c: 9: kesalahan: meneruskan argumen 1 dari 'strcpy' membuang kualifikasi dari tipe target penunjuk
Perhatikan kompiler memperingatkan untuk kasus kedua tetapi tidak untuk yang pertama.
name
poin dalam kedua kasus tersebut. Ini bisa menghasilkan UB.
char mystring[101] = "My sample string";
const char * constcharp = mystring; // (1)
char const * charconstp = mystring; // (2) the same as (1)
char * const charpconst = mystring; // (3)
constcharp++; // ok
charconstp++; // ok
charpconst++; // compile error
constcharp[3] = '\0'; // compile error
charconstp[3] = '\0'; // compile error
charpconst[3] = '\0'; // ok
// String literals
char * lcharp = "My string literal";
const char * lconstcharp = "My string literal";
lcharp[0] = 'X'; // Segmentation fault (crash) during run-time
lconstcharp[0] = 'X'; // compile error
// *not* a string literal
const char astr[101] = "My mutable string";
astr[0] = 'X'; // compile error
((char*)astr)[0] = 'X'; // ok
char *
nilai memberikan kesalahan segmentasi karena kami mencoba untuk memodifikasi string literal (yang ada dalam memori hanya baca)
Dalam kedua kasus Anda tidak dapat memodifikasi string literal, terlepas dari apakah pointer ke string literal tersebut dinyatakan sebagai char *
atauconst char *
.
Namun, perbedaannya adalah bahwa jika pointer const char *
maka compiler harus memberikan diagnostik jika Anda mencoba untuk memodifikasi nilai menunjuk-ke, tetapi jika pointer itu char *
maka tidak.
extern ... name
dan memiliki *name = 'X';
. Pada 'sistem operasi yang tepat', itu mungkin gagal, tetapi pada sistem embedded, saya berharap untuk melakukan sesuatu platform / kompiler spesifik.
KASUS 1:
char *str = "Hello";
str[0] = 'M' //Warning may be issued by compiler, and will cause segmentation fault upon running the programme
Set di atas str untuk menunjuk ke nilai literal "Hello" yang dikodekan dalam gambar biner program, yang ditandai sebagai hanya-baca dalam memori, berarti setiap perubahan dalam string literal ini ilegal dan yang akan menyebabkan kesalahan segmentasi.
KASUS 2:
const char *str = "Hello";
str[0] = 'M' //Compile time error
KASUS 3:
char str[] = "Hello";
str[0] = 'M'; // legal and change the str = "Mello".
Yang pertama Anda benar-benar dapat berubah jika Anda mau, yang kedua Anda tidak bisa. Baca tentang const
kebenaran (ada beberapa panduan bagus tentang perbedaannya). Ada juga di char const * name
mana Anda tidak bisa mengulanginya.
Pertanyaannya adalah apa bedanya
char *name
yang menunjuk ke string konstan literal, dan
const char *cname
Yaitu diberikan
char *name = "foo";
dan
const char *cname = "foo";
Tidak ada banyak perbedaan antara 2 dan keduanya dapat dilihat sebagai benar. Karena warisan yang lama dari kode C, string literal memiliki tipe char[]
, tidak const char[]
, dan ada banyak kode lama yang juga menerimachar *
alih-alihconst char *
, bahkan ketika mereka tidak mengubah argumen.
Perbedaan utama dari 2 secara umum adalah bahwa *cname
atau cname[n]
akan mengevaluasi ke nilai tipe const char
, sedangkan *name
atau name[n]
akan mengevaluasi ke tipe nilai char
, yang merupakan nilai yang dapat dimodifikasi . Compiler yang sesuai diperlukan untuk menghasilkan pesan diagnostik jika target penugasan bukan nilai yang dapat dimodifikasi ; itu tidak perlu menghasilkan peringatan tentang penugasan ke nilai jenis char
:
name[0] = 'x'; // no diagnostics *needed*
cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message
Kompiler tidak diharuskan untuk menghentikan kompilasi dalam kedua kasus; cukup itu menghasilkan peringatan untuk tugas cname[0]
. Program yang dihasilkan bukan program yang benar . Perilaku konstruk tidak terdefinisi . Mungkin macet, atau bahkan lebih buruk, mungkin tidak macet, dan mungkin mengubah string literal dalam memori.
Sebenarnya, char* name
bukan pointer ke konstanta, tetapi pointer ke variabel. Anda mungkin berbicara tentang pertanyaan lain ini.