Saya sedikit bingung tentang sesuatu. Saya mendapat kesan bahwa cara yang benar membaca string C dengan scanf()
berjalan sepanjang garis
(apalagi buffer overflow yang mungkin, itu hanya contoh sederhana)
char string[256];
scanf( "%s" , string );
Namun, berikut ini tampaknya berfungsi juga,
scanf( "%s" , &string );
Apakah ini hanya kompiler (gcc) saya, keberuntungan murni, atau yang lainnya?
scanf
, dan pertanyaan dan jawaban yang diterima berfokus pada itu, dan hilangkan pembatasan yang sangat penting untuk panjang input maksimum yang harus digunakan dalam kode nyata (tetapi selain itu poin untuk pertanyaan ini).Jawaban:
Array "meluruh" menjadi sebuah pointer ke elemen pertama, jadi
scanf("%s", string)
sama denganscanf("%s", &string[0])
. Di sisi lain,scanf("%s", &string)
melewati pointer-to-char[256]
, tetapi menunjuk ke tempat yang sama.Kemudian
scanf
, ketika memproses ekor dari daftar argumennya, akan mencoba menarik keluar achar *
. Itulah Hal yang Tepat ketika Anda telah melewatistring
atau&string[0]
, tetapi ketika Anda telah melewati&string
Anda tergantung pada sesuatu yang tidak dijamin standar bahasa, yaitu bahwa pointer&string
dan&string[0]
- pointer ke objek dari berbagai jenis dan ukuran yang mulai dari tempat yang sama - direpresentasikan dengan cara yang sama.Saya tidak percaya saya pernah menemukan sistem yang tidak bekerja, dan dalam praktiknya Anda mungkin aman. Namun, itu salah, dan itu bisa gagal pada beberapa platform. (Contoh hipotetis: implementasi "debugging" yang mencakup mengetikkan informasi dengan setiap pointer. Saya pikir implementasi C pada Simbol "Lisp Machines" melakukan sesuatu seperti ini.)
sumber
&string
bekerja sama denganstring
(alih-alih mengakibatkan kerusakan memori acak, karena jawaban lain salah menyatakan):printf("%x\n%x\n", string, &string);
string
adalah sebuah pointer, dan&string
merupakan alamat dari pointer itu, sehingga keduanya TIDAK dapat dipertukarkan. Seperti yang dijelaskan Gareth, bahkan untuk kasus peluruhan array,string
dan&string
secara teknis bukan tipe yang sama (meskipun mereka dapat dipertukarkan untuk sebagian besar arsitektur), dan gcc akan memberikan peringatan untuk contoh kedua Anda jika Anda menghidupkan-Wall
.Saya pikir ini di bawah ini akurat dan mungkin membantu. Jangan ragu untuk memperbaikinya jika Anda menemukan kesalahan. Saya baru di C.
termasuk terminasi karakter nol
'\0'
&str
,&str[0]
danstr
, ketiganya mewakili lokasi yang sama dalam memori yang merupakan alamat elemen pertama arraystr
char * strPtr = & str [0]; // deklarasi dan inisialisasi
sebagai alternatif, Anda dapat membaginya menjadi dua:
strPtr
adalah pointer ke achar
strPtr
menunjuk pada arraystr
strPtr
adalah variabel dengan alamatnya sendiri di memoristrPtr
adalah variabel yang menyimpan nilai alamat&str[0]
strPtr
alamat sendiri di memori berbeda dari alamat memori yang disimpannya (alamat array di memori alias & str [0])&strPtr
mewakili alamat strPtr itu sendiriSaya pikir Anda bisa mendeklarasikan pointer ke pointer sebagai:
mendeklarasikan dan menginisialisasi dengan alamat penunjuk strPtr
Atau Anda dapat membelah menjadi dua:
*vPtr
menunjuk pada strPtr pointer*vPtr
adalah variabel dengan alamatnya sendiri di memori*vPtr
adalah variabel yang menyimpan nilai alamat & strPtrstr++
,str
alamat adalahconst
, tetapi Anda dapat melakukannyastrPtr++
sumber