Saya membaca buku berjudul "Teach Yourself C in 21 Days" (Saya sudah belajar Java dan C # jadi saya bergerak dengan kecepatan yang jauh lebih cepat). Saya membaca bab tentang petunjuk dan operator->
(panah) muncul tanpa penjelasan. Saya pikir itu digunakan untuk memanggil anggota dan fungsi (seperti yang setara dengan operator (titik), tetapi untuk pointer bukan anggota). Tetapi saya tidak sepenuhnya yakin..
Bisakah saya mendapatkan penjelasan dan contoh kode?
Jawaban:
foo->bar
setara dengan(*foo).bar
, yaitu mendapat anggota dipanggilbar
dari struct yangfoo
menunjuk ke.sumber
->
operator tidak akan diperlukan sama sekali, karena itu akan setara dengan jauh lebih terbacafoo*.bar
. Seluruh kekacauan fungsi mengetik dengan semua tanda kurung tambahan akan dihindari juga.foo*.bar
dan(*foo).bar
keduanya setara denganfoo->bar
? Bagaimana denganFoo myFoo = *foo; myFoo.bar
?Ya itu saja.
Itu hanya versi titik ketika Anda ingin mengakses elemen struct / kelas yang merupakan pointer bukan referensi.
Itu dia!
sumber
pvar = &var
?a->b
hanya kependekan dari(*a).b
segala hal (sama untuk fungsi:a->b()
kependekan(*a).b()
).sumber
Saya hanya menambahkan jawaban "mengapa?".
.
adalah operator akses anggota standar yang memiliki prioritas lebih tinggi daripada*
operator pointer.Ketika Anda mencoba mengakses internal struct dan Anda menulisnya
*foo.bar
maka kompiler akan berpikir untuk menginginkan elemen 'bar' dari 'foo' (yang merupakan alamat dalam memori) dan jelas bahwa alamat belaka tidak memiliki anggota.Jadi Anda perlu meminta kompiler untuk dereferensi pertama dengan
(*foo)
dan kemudian mengakses elemen anggota:,(*foo).bar
yang agak canggung untuk menulis sehingga orang-orang baik telah datang dengan versi singkat:foo->bar
yang merupakan semacam akses anggota oleh operator pointer.sumber
foo->bar
hanya singkatan untuk(*foo).bar
. Hanya itu yang ada untuk itu.sumber
Berikut untuk mengakses nilai-nilai
i
danj
kita dapat menggunakan variabela
dan pointerp
sebagai berikut:a.i
,(*p).i
danp->i
semua sama.Inilah
.
"Pemilih Langsung" dan->
"Pemilih Tidak Langsung".sumber
Yah saya harus menambahkan sesuatu juga. Struktur sedikit berbeda dari array karena array adalah pointer dan struktur tidak. Jadi hati-hati!
Katakanlah saya menulis kode yang tidak berguna ini:
Di sini pointer
ptr
menunjuk ke alamat ( ! ) Dari variabel strukturaudi
tetapi di samping struktur alamat juga memiliki sejumlah data ( ! )! Anggota pertama dari chunk data memiliki alamat yang sama dari struktur itu sendiri dan Anda bisa mendapatkan datanya dengan hanya mereferensikan pointer seperti ini*ptr
(tanpa kawat gigi) .Tapi Jika Anda ingin acess setiap anggota lain dari yang pertama, Anda harus menambahkan penanda seperti
.km
,.kph
,.kg
yang tidak lebih dari offset ke alamat dasar potongan data ...Tetapi karena prioritas Anda tidak dapat menulis
*ptr.kg
karena operator akses.
dievaluasi sebelum operator dereferensi*
dan Anda akan mendapatkan*(ptr.kg)
yang tidak mungkin karena pointer tidak memiliki anggota! Dan kompiler mengetahui hal ini dan karena itu akan mengeluarkan kesalahan misalnya:Alih-alih Anda menggunakan ini
(*ptr).kg
dan Anda memaksa compiler ke 1 dereference pointer dan mengaktifkan acess ke potongan data dan 2 Anda menambahkan offset (penunjuk) untuk memilih anggota.Periksa gambar yang saya buat ini:
Tetapi jika Anda memiliki anggota bersarang, sintaks ini akan menjadi tidak dapat dibaca dan oleh karena
->
itu diperkenalkan. Saya pikir keterbacaan adalah satu-satunya alasan dibenarkan untuk menggunakannya karena iniptr->kg
jauh lebih mudah untuk ditulis daripada(*ptr).kg
.Sekarang mari kita tuliskan ini secara berbeda sehingga Anda melihat hubungannya lebih jelas.
(*ptr).kg
⟹(*&audi).kg
⟹audi.kg
. Di sini saya pertama kali menggunakan fakta yangptr
merupakan "alamataudi
" yaitu&audi
dan fakta bahwa operator "referensi"&
dan "dereferensi"*
membatalkan satu sama lain.sumber
Saya harus membuat perubahan kecil pada program Jack untuk menjalankannya. Setelah mendeklarasikan struct pointer pvar, arahkan ke alamat var. Saya menemukan solusi ini di halaman 242 dari Programming Stephen Kochan di C.
Jalankan ini dalam vim dengan perintah berikut:
Akan menghasilkan:
sumber
%
untuk mewakili nama file saat ini. Seperti itu:!gcc % && ./a.out
sumber
The
->
Operator membuat kode lebih mudah dibaca daripada*
operator dalam beberapa situasi.Seperti: (dikutip dari proyek EDK II )
The
_EFI_BLOCK_IO_PROTOCOL
struct berisi 4 anggota fungsi pointer.Misalkan Anda memiliki variabel
struct _EFI_BLOCK_IO_PROTOCOL * pStruct
, dan Anda ingin menggunakan*
operator lama yang baik untuk memanggil itu pointer fungsi anggota. Anda akan berakhir dengan kode seperti ini:(*pStruct).ReadBlocks(...arguments...)
Tetapi dengan
->
operator, Anda dapat menulis seperti ini:pStruct->ReadBlocks(...arguments...)
.Mana yang terlihat lebih baik?
sumber
output adalah 5 5 5
sumber
Dot adalah operator dereference dan digunakan untuk menghubungkan variabel struktur untuk catatan struktur tertentu. Misalnya:
Sedemikian rupa kita dapat menggunakan operator titik untuk mengakses variabel struktur
sumber
->
. Pertanyaan ini sudah dijawab selama 4,5 tahun.