Kompiler C yang disematkan mengizinkan void main () karena mungkin tidak ada sistem operasi yang dapat memberikan kode pengembalian.
Jeanne Pindar
26
Bagaimana pertanyaan seperti ini bisa mendapat suara positif begitu sering? Ini benar-benar tidak menarik ... Maksud saya, string adalah array dan array adalah pointer benar-benar topi lama di C, bukan?
Felix Dombek
64
@Felix, ini adalah pertanyaan yang ditulis secara singkat yang membahas titik kebingungan umum bagi pendatang baru di bahasa ini. SO tidak hanya untuk ahli - ini juga untuk pemula, dan pertanyaan bertarget seperti ini bagus untuk merujuk pemula di masa depan.
bdonlan
37
@Felix: Anda salah. array bukanlah penunjuk
John Dibling
Jawaban:
209
Yang Anda bandingkan adalah dua alamat memori untuk string berbeda, yang disimpan di lokasi berbeda. Melakukannya pada dasarnya terlihat seperti ini:
if(0x00403064==0x002D316A)// Two memory locations{
printf("Yes, equal");}
Gunakan kode berikut untuk membandingkan dua nilai string:
Selain itu, "a" == "a"mungkin memang mengembalikan true, tergantung pada kompiler Anda, yang dapat menggabungkan string yang sama pada waktu kompilasi menjadi satu untuk menghemat ruang.
Saat Anda membandingkan dua nilai karakter (yang bukan penunjuk), ini adalah perbandingan numerik. Sebagai contoh:
GCC juga memiliki opsi -fmerge-constantsdan -fno-merge-constantsuntuk mengaktifkan / menonaktifkan string dan penggabungan konstan floating-point di seluruh unit terjemahan, meskipun pada beberapa GCC tampaknya penggabungan konstan selalu diaktifkan terlepas dari opsi itu.
Adam Rosenfield
2
Ini akan berhasil jika Anda menggunakan 'a', bukan "a". Yang pertama adalah karakter, yang sebenarnya merupakan nilai numerik.
GolezTrol
@ GolezTrol: di C, literal 'a' sebenarnya memiliki inttipe. :-) Selain itu, pointer tidak harus berupa nilai numerik.
Bastien Léonard
intapakah numerik juga, bukan? Tapi saya pikir karakter itu Byte. Int adalah 4 byte. Pointer itu sendiri adalah bilangan bulat juga. Mereka berisi alamat sekumpulan data (data yang memang tidak harus numerik).
GolezTrol
'a' == 'A' // not true... MySQL sangat berbeda.
Steven
52
Saya agak terlambat ke pesta, tetapi saya akan tetap menjawab; secara teknis bit yang sama, tetapi dari perspektif yang sedikit berbeda (C bahasa di bawah):
Dalam C, ekspresi "a"menunjukkan literal string , yang merupakan array statis tanpa nama const char, dengan panjang dua - array terdiri dari karakter 'a'dan '\0'- karakter null yang mengakhiri menandakan akhir string.
Namun, di C, dengan cara yang sama Anda tidak bisa meneruskan array ke fungsi berdasarkan nilai - atau menetapkan nilai padanya ( setelah inisialisasi ) - tidak ada operator yang kelebihan beban ==untuk array, jadi tidak mungkin membandingkannya secara langsung. Mempertimbangkan
int a1[]={1,2,3};int a2[]={3,4,5};
a1 == a2 // is this meaningful? Yes and no; it *does* compare the arrays for// "identity", but not for their values. In this case the result// is always false, because the arrays (a1 and a2) are distinct objects
Jika ==tidak membandingkan array, lalu apa yang sebenarnya dilakukannya? Di C, di hampir semua konteks - termasuk yang satu ini - array meluruh menjadi pointer (yang mengarah ke elemen pertama dari array) - dan membandingkan pointer untuk persamaan melakukan apa yang Anda harapkan. Sangat efektif, saat melakukan ini
"a"=="a"
Anda sebenarnya membandingkan alamat karakter pertama dalam dua larik tanpa nama . Menurut standar C, perbandingan tersebut dapat menghasilkan benar atau salah (yaitu 1 atau 0) - "a"s sebenarnya dapat menunjukkan larik yang sama atau dua larik yang sama sekali tidak terkait. Dalam istilah teknis, nilai yang dihasilkan tidak ditentukan , artinya perbandingan diperbolehkan (yaitu bukan perilaku tidak terdefinisi atau kesalahan sintaksis), tetapi salah satu nilai tersebut valid dan implementasi (kompilator Anda) tidak diperlukan untuk mendokumentasikan apa yang sebenarnya akan terjadi.
Seperti yang telah ditunjukkan orang lain, untuk membandingkan "string c" (yaitu string yang diakhiri dengan karakter null) Anda menggunakan fungsi kemudahan yang strcmpditemukan di file header standar string.h. Fungsi tersebut memiliki nilai kembalian 0untuk string yang sama; dianggap praktik yang baik untuk secara eksplisit membandingkan nilai yang dikembalikan 0daripada menggunakan operator `! ´, yaitu
strcmp(str1, str2)==0// instead of !strcmp(str1, str2)
Tidak ditentukan apakah array ini berbeda asalkan elemennya memiliki nilai yang sesuai .
Jadi dalam kasus ini tidak ditentukan apakah keduanya "a"berbeda. Kompiler yang dioptimalkan bisa menyimpan satu "a"di lokasi hanya-baca dan kedua referensi bisa merujuk ke sana.
Karena keduanya terpisah const char*, pointer, tidak ada nilai aktual. Anda mengatakan sesuatu seperti 0x019181217 == 0x0089178216yang tentu saja mengembalikan TIDAK
String literal bukanlah pointer, melainkan array. Namun, mereka membusuk menjadi petunjuk perbandingan.
GManNickG
@Gman benar, maaf karena tidak terlalu jelas tentang itu, cenderung melupakannya :)
Antwan van Houdt
9
Sederhananya, C tidak memiliki operator perbandingan string bawaan. Ini tidak dapat membandingkan string dengan cara ini.
Sebaliknya, string dibandingkan menggunakan rutinitas pustaka standar seperti strcmp () atau dengan menulis kode untuk mengulang setiap karakter dalam string.
Di C, string teks dalam tanda kutip ganda mengembalikan pointer ke string. Contoh Anda adalah membandingkan pointer, dan tampaknya kedua versi string Anda ada di alamat yang berbeda.
Tapi itu tidak membandingkan string itu sendiri, seperti yang Anda harapkan.
Yang pertama "a"adalah penunjuk ke string ASCII yang diakhiri dengan null.
Yang kedua "a"adalah penunjuk ke string ASCII lain yang diakhiri dengan null.
Jika Anda menggunakan kompiler 32-bit, saya harapkan "a"=="a"-4. Saya baru saja mencobanya dengan tcc / Win32, dan saya mengerti "a"=="a"-2. Baiklah...
Mengapa Anda mengharapkan string disejajarkan dengan batas 4 byte? Mereka bukan int. 2 adalah yang saya harapkan (jika kompilator tidak menggabungkannya), karena setiap string memiliki panjang dua byte, termasuk terminator null.
Sergei Tachenov
Beberapa derajat kesejajaran mungkin, misalnya, memungkinkan strcmpuntuk menjalankan beberapa byte sekaligus. Beberapa kompiler melakukannya, beberapa tidak, beberapa melakukannya hanya untuk string yang lebih panjang dari beberapa minimum ...
zwol
@ Zack: bagaimana mereka mengetahui panjang string sebelum benar-benar membandingkannya?
Joachim Sauer
Maksud saya, beberapa kompiler menyelaraskan string lebih lama dari beberapa minimum.
zwol
1
Anda membandingkan dua alamat memori, jadi hasilnya tidak selalu benar. Apakah kamu sudah mencobanya if('a' == 'a'){...}?
Karakter hanya menempati 1 byte, tetapi literal karakter, seperti 'a', sebenarnya adalah bilangan bulat.
Spidey
0
Beberapa kompiler memiliki opsi 'merge string' yang dapat Anda gunakan untuk memaksa semua string konstan memiliki alamat yang sama. Jika Anda akan menggunakan itu, "a" == "a"akan true.
void main
??? Ew ...Jawaban:
Yang Anda bandingkan adalah dua alamat memori untuk string berbeda, yang disimpan di lokasi berbeda. Melakukannya pada dasarnya terlihat seperti ini:
Gunakan kode berikut untuk membandingkan dua nilai string:
Selain itu,
"a" == "a"
mungkin memang mengembalikan true, tergantung pada kompiler Anda, yang dapat menggabungkan string yang sama pada waktu kompilasi menjadi satu untuk menghemat ruang.Saat Anda membandingkan dua nilai karakter (yang bukan penunjuk), ini adalah perbandingan numerik. Sebagai contoh:
sumber
-fmerge-constants
dan-fno-merge-constants
untuk mengaktifkan / menonaktifkan string dan penggabungan konstan floating-point di seluruh unit terjemahan, meskipun pada beberapa GCC tampaknya penggabungan konstan selalu diaktifkan terlepas dari opsi itu.int
tipe. :-) Selain itu, pointer tidak harus berupa nilai numerik.int
apakah numerik juga, bukan? Tapi saya pikir karakter itu Byte. Int adalah 4 byte. Pointer itu sendiri adalah bilangan bulat juga. Mereka berisi alamat sekumpulan data (data yang memang tidak harus numerik).'a' == 'A' // not true
... MySQL sangat berbeda.Saya agak terlambat ke pesta, tetapi saya akan tetap menjawab; secara teknis bit yang sama, tetapi dari perspektif yang sedikit berbeda (C bahasa di bawah):
Dalam C, ekspresi
"a"
menunjukkan literal string , yang merupakan array statis tanpa namaconst char
, dengan panjang dua - array terdiri dari karakter'a'
dan'\0'
- karakter null yang mengakhiri menandakan akhir string.Namun, di C, dengan cara yang sama Anda tidak bisa meneruskan array ke fungsi berdasarkan nilai - atau menetapkan nilai padanya ( setelah inisialisasi ) - tidak ada operator yang kelebihan beban
==
untuk array, jadi tidak mungkin membandingkannya secara langsung. MempertimbangkanJika
==
tidak membandingkan array, lalu apa yang sebenarnya dilakukannya? Di C, di hampir semua konteks - termasuk yang satu ini - array meluruh menjadi pointer (yang mengarah ke elemen pertama dari array) - dan membandingkan pointer untuk persamaan melakukan apa yang Anda harapkan. Sangat efektif, saat melakukan iniAnda sebenarnya membandingkan alamat karakter pertama dalam dua larik tanpa nama . Menurut standar C, perbandingan tersebut dapat menghasilkan benar atau salah (yaitu 1 atau 0) -
"a"
s sebenarnya dapat menunjukkan larik yang sama atau dua larik yang sama sekali tidak terkait. Dalam istilah teknis, nilai yang dihasilkan tidak ditentukan , artinya perbandingan diperbolehkan (yaitu bukan perilaku tidak terdefinisi atau kesalahan sintaksis), tetapi salah satu nilai tersebut valid dan implementasi (kompilator Anda) tidak diperlukan untuk mendokumentasikan apa yang sebenarnya akan terjadi.Seperti yang telah ditunjukkan orang lain, untuk membandingkan "string c" (yaitu string yang diakhiri dengan karakter null) Anda menggunakan fungsi kemudahan yang
strcmp
ditemukan di file header standarstring.h
. Fungsi tersebut memiliki nilai kembalian0
untuk string yang sama; dianggap praktik yang baik untuk secara eksplisit membandingkan nilai yang dikembalikan0
daripada menggunakan operator `! ´, yaitusumber
Menurut C99 (Bagian 6.4.5 / 6)
Jadi dalam kasus ini tidak ditentukan apakah keduanya
"a"
berbeda. Kompiler yang dioptimalkan bisa menyimpan satu"a"
di lokasi hanya-baca dan kedua referensi bisa merujuk ke sana.Lihat hasilnya di gcc di sini
sumber
Karena keduanya terpisah
const char*
, pointer, tidak ada nilai aktual. Anda mengatakan sesuatu seperti0x019181217 == 0x0089178216
yang tentu saja mengembalikan TIDAKGunakan
strcmp()
sebagai ganti==
sumber
Sederhananya, C tidak memiliki operator perbandingan string bawaan. Ini tidak dapat membandingkan string dengan cara ini.
Sebaliknya, string dibandingkan menggunakan rutinitas pustaka standar seperti strcmp () atau dengan menulis kode untuk mengulang setiap karakter dalam string.
Di C, string teks dalam tanda kutip ganda mengembalikan pointer ke string. Contoh Anda adalah membandingkan pointer, dan tampaknya kedua versi string Anda ada di alamat yang berbeda.
Tapi itu tidak membandingkan string itu sendiri, seperti yang Anda harapkan.
sumber
Pointer.
Yang pertama
"a"
adalah penunjuk ke string ASCII yang diakhiri dengan null.Yang kedua
"a"
adalah penunjuk ke string ASCII lain yang diakhiri dengan null.Jika Anda menggunakan kompiler 32-bit, saya harapkan
"a"=="a"-4
. Saya baru saja mencobanya dengan tcc / Win32, dan saya mengerti"a"=="a"-2
. Baiklah...sumber
strcmp
untuk menjalankan beberapa byte sekaligus. Beberapa kompiler melakukannya, beberapa tidak, beberapa melakukannya hanya untuk string yang lebih panjang dari beberapa minimum ...Anda membandingkan dua alamat memori, jadi hasilnya tidak selalu benar. Apakah kamu sudah mencobanya
if('a' == 'a'){...}
?sumber
pertanyaan ini menetapkan jejak penjelasan yang sangat baik untuk semua pemula ....
izinkan saya juga berkontribusi untuk itu .....
seperti yang dijelaskan semua orang di atas, mengapa Anda mendapatkan keluaran seperti itu.
sekarang jika Anda menginginkan prog Anda. Untuk mencetak "ya sama" lalu
baik digunakan
atau
jangan gunakan "a" sebagai string, gunakan sebagai karakter ....
dalam karakter C adalah 1 byte bilangan bulat pendek .......
sumber
'a'
, sebenarnya adalah bilangan bulat.Beberapa kompiler memiliki opsi 'merge string' yang dapat Anda gunakan untuk memaksa semua string konstan memiliki alamat yang sama. Jika Anda akan menggunakan itu,
"a" == "a"
akantrue
.sumber
jika perbandingan antar karakter selalu dalam satu kutipan, mis
dan C tidak dapat mendukung perbandingan string seperti
"abc" == "abc"
Selesai dengan
strcmp("abc","abc")
sumber
Orang ini tidak menggunakan variabel. Sebagai gantinya, dia menggunakan larik teks sementara:
a
dana
. Alasan mengapatidak bekerja tentu saja, adalah bahwa Anda tidak membandingkan variabel.
Jika Anda ingin membuat variabel seperti:
maka Anda bisa membandingkan
text
dengantext2
, dan itu harus benarMungkin Anda tidak boleh lupa menggunakan
{
dan}
=)sumber