Cara yang benar untuk mendeklarasikan variabel pointer di C / C ++ [closed]

91

Saya perhatikan beberapa orang menggunakan notasi berikut untuk mendeklarasikan variabel pointer.

(a) char* p;

dari pada

(b) char *p;

Saya menggunakan (b). Apa alasan di balik notasi (a)? Notasi (b) lebih masuk akal bagi saya karena penunjuk karakter bukanlah tipe itu sendiri. Sebaliknya jenisnya adalah karakter dan variabel mungkin merupakan penunjuk ke karakter tersebut.

char* c;

Sepertinya ada tipe char * dan variabel c adalah tipe itu. Tapi sebenarnya tipenya adalah char dan * c (lokasi memori yang ditunjukkan oleh c) adalah tipe itu (char). Jika Anda mendeklarasikan beberapa variabel sekaligus, perbedaan ini menjadi jelas.

char* c, *d;

Ini terlihat aneh. Baik c dan d adalah jenis penunjuk yang sama yang mengarah ke karakter. Dalam hal ini sejak yang berikutnya terlihat lebih alami.

char *c, *d;

Terima kasih.

keeda
sumber
7
Apa maksudmu char pointer bukan tipe? Apakah Anda mengatakan bahwa penunjuk bukan tipe?
Benjamin Lindley
1
Saya yakin ini adalah masalah preferensi kecuali jika Anda melihat panduan gaya tertentu (misalnya, perusahaan Anda mungkin memiliki standar pengkodean tertentu yang harus Anda ikuti). Saya cenderung mencampurnya antara pilihan b dan beberapa tempat di tengah. Kadang-kadang saya merasa tidak char *tterlihat pantas, jadi saya mungkin melakukannya char * t;. Namun, saya sudah sering melihatnya char* t;juga.
RageD
1
Juga, alasan Anda "tipe adalah char dan * c (lokasi memori yang ditunjukkan oleh c) adalah tipe itu (char)" akan menunjukkan bahwa ada karakter yang dideklarasikan, padahal sebenarnya tidak ada. Jika diperlakukan seperti itu, seperti yang kadang-kadang dilakukan oleh pemula, itu pasti akan menyebabkan pelanggaran akses memori.
Benjamin Lindley
1
Keduanya masih cukup deskriptif, (b) menunjukkan * p bertipe chardan (a) menunjukkan p adalah apointer to a char
A Person
1
Dengan pengalaman industri lebih dari satu dekade, hari ini adalah pertama kalinya hal ini muncul, dan hanya dalam membaca artikel dari profesional industri lainnya. Jelas, kemudian, saya tidak pernah memiliki percakapan religius tentang ini seperti yang saya lakukan dengan tab v spasi, komentar oleh def atau des, atau topik "ada baiknya tidak ada yang lebih penting untuk diperdebatkan" . Itulah perspektif saya, saya lebih suka, di akhir karir saya, lebih sering menggunakan "char * p" daripada tidak. Ya, spasi sebelumnya, spasi setelah. Sebagian besar karena saya merasa itu mengurangi bug, karena itu membuat penunjuk lebih jelas.
Kit10

Jawaban:

102

Bjarne Stroustrup berkata:

Pilihan antara "int * p;" dan "int * p;" bukan tentang benar dan salah, tapi tentang gaya dan penekanan. C menekankan ekspresi; deklarasi sering dianggap sebagai kejahatan yang diperlukan. C ++, sebaliknya, sangat menekankan pada tipe.

Seorang "programmer C tipikal" menulis "int * p;" dan menjelaskannya "* p adalah int" yang menekankan sintaks, dan mungkin menunjuk ke tata bahasa deklarasi C (dan C ++) untuk memperdebatkan kebenaran gaya. Memang, * mengikat nama p dalam tata bahasa.

Seorang "programmer C ++ biasa" menulis "int * p;" dan menjelaskannya "p adalah penunjuk ke jenis penekanan int". Memang tipe p adalah int *. Saya jelas lebih suka penekanan itu dan menganggapnya penting untuk menggunakan bagian C ++ yang lebih maju dengan baik.

Sumber: http://www.stroustrup.com/bs_faq2.html#whitespace

Saya akan merekomendasikan gaya yang terakhir karena dalam situasi di mana Anda mendeklarasikan beberapa pointer dalam satu baris (contoh ke-4 Anda), memiliki tanda bintang dengan variabel akan menjadi apa yang biasa Anda gunakan.

Selikuran
sumber
34
Orang lain merekomendasikan untuk tidak mendeklarasikan beberapa objek dalam deklarasi yang sama. :-)
Bo Persson
5
Saya menekankan logika di balik sintaks, jadi saya lebih suka int *p:, yang berarti: ketika pdereferensi saya mendapatkan int. Kemudian beberapa deklarasi dipisahkan oleh ,masuk akal: int *p, *q, r(ketika patau qdidereferensi saya mendapatkan int, ketika rdireferensikan saya mendapatkan int). Juga, sintaks penunjuk fungsi masuk akal: int (*f)()(ketika fdidereferensi dan dipanggil I get an int). Dan ini masuk akal: int *p, (*f)().
Druesukker
2
Ini membantu saya menyadari ada validitas di sisi lain dari argumen tersebut. Menjadi, sebagian besar, seorang programmer tingkat tinggi, saya menekankan tipe; dan lebih suka int*. Bagi saya, int *p, (*f)()itu tidak masuk akal, tetapi saya bisa melihat bagaimana itu akan terjadi pada beberapa orang dalam beberapa situasi.
Assimilater
1
@Druesukker, menurut saya pernyataan Anda lebih masuk akal daripada yang disebutkan di atas.
Muntashir Akon
1
@Druesukker Tetapi logikanya tidak benar-benar berfungsi void*(dan tidak berfungsi sama sekali untuk referensi C ++).
jamesdlin
57

Saya pribadi lebih suka menempatkan *dengan tipe lainnya

char* p;  // p is a pointer to a char.

Orang-orang akan berdebat "tapi kemudian char* p, q;menjadi menyesatkan", yang saya katakan, "jadi jangan lakukan itu".

ikegami
sumber
Argumen yang sangat bagus untuk karakter * p; pilihan :) Saya tidak keberatan salah satu dari mereka selama tidak menjadi sulit untuk dibaca seperti contoh yang Anda tunjukkan dalam hal ini mereka tidak boleh melakukan itu.
Jesus Ramos
1
Dan kapan Anda ingin menampilkan nilainya? Kamu lakukan cout << *p;. Jadi mengapa tidak menempatkan bintang sebelum p saat deklarasi: *p? Menurut saya itu tidak terlalu membingungkan.
pengguna1170330
13
@ user1170330, Karena di satu tempat itu adalah bagian dari definisi tipe, dan itu adalah operator dereferensi di tempat lain. Tidak ada hubungan. Jika ada, itu hal yang baik bahwa mereka terlihat berbeda, karena hal yang berbeda harus terlihat berbeda.
ikegami
33

Tidak ada perbedaan cara menulis. Tetapi jika ingin mendeklarasikan dua atau lebih pointer dalam satu baris lebih baik menggunakan (b) varian, karena sudah jelas apa yang diinginkan. Lihat ke bawah:

int *a;
int* b;      // All is OK. `a` is pointer to int ant `b` is pointer to int
char *c, *d; // We declare two pointers to char. And we clearly see it.
char* e, f;  // We declare pointer `e` and variable `f` of char type.
             // Maybe here it is mistake, maybe not. 
// Better way of course is use typedef:
typedef char* PCHAR;
PCHAR g, h;  // Now `g` and `h` both are pointers.
// If we used define construction for PCHAR we'd get into problem too.
George Gaál
sumber
5
typedefbukan cara yang lebih baik "tentu saja". Beberapa orang mungkin lebih suka, tetapi bermasalah jika ada beberapa orang yang bekerja dengan kode Anda. Jika saya tidak terbiasa PCHAR, saya mungkin menulis sesuatu seperti PCHAR *p;, yang akan menjadi char**dan bukan yang saya inginkan. Secara umum, jika Anda menginginkan a char**, Anda harus menulis PCHAR*atau mendefinisikan tipe baru, dan kemudian itu mulai menjadi bodoh.
BlackJack
3
Jika seseorang membutuhkan beberapa tipe penunjuk yang kompleks seperti penunjuk agar berfungsi, sangat baik untuk membuat typedefs. Mereka membuat kode lebih sederhana dalam kasus ini. Di sisi lain, menggunakan PCHAR adalah contoh yang lebih sintetis daripada praktik sehari-hari. Tapi itu jelas membuat apa yang Anda inginkan. dan kemudian itu mulai menjadi bodoh. Harap
serahkan
Jika Anda menulis PCHAR * p untuk mendefinisikan pointer ke char, akan jelas Anda tidak tahu apa yang Anda lakukan dan tidak membaca tipe def. Jawabannya ada menurut pendapatnya. Ada manfaat lain untuk typedef; di C itu tentang cara mudah untuk membuatnya buram. secara publik memiliki simbol yang didefinisikan sebagai VOID ptr, secara pribadi tipe def adalah sesuatu yang lain .... Saya lebih suka menyesuaikan typedef sesekali kemudian menyesuaikan semuanya di seluruh kode ketika kita mengubah sesuatu tentang salah satu jenis ... tapi C ++ 11 menangani sebagian besar itu dengan auto
UpAndAdam
Untuk seseorang yang baru mencoba kembali bermain-main dengan C ++ lima tahun setelah kuliah, ini adalah salah satu jawaban terbaik.
Panzercrisis
10

Komprominya adalah

char * p;

K&R menggunakan

char *p;

Terserah Anda kecuali Anda mengikuti standar pengkodean - dalam hal ini, Anda harus mengikuti apa yang dilakukan orang lain.

jnnnnn
sumber
4
Saya belajar dengan susah payah bahwa char * x, y tidak berarti y adalah char *. Sekarang saya dapat melihat mengapa K&R mengikuti gaya tersebut.
Rahul Kadukar
apa itu K&R dan mengapa penting apa yang digunakan satu sumber kode? Saya menggunakan char* p;. ini masalah gaya, bukan konvensi atau aturan. bagi saya lebih masuk akal bahwa p adalah tipe char*, jadi jelas * harus dengan tipe.
FalcoGer
@FalcoGer Saya telah menambahkan link untuk K&R. Tidak peduli apa yang digunakan satu sumber kode. Tim Anda mungkin akan kesal jika Anda tidak mengikuti standar mereka karena Anda membuat mereka bekerja lebih keras untuk memahami kode Anda. Hari-hari ini, saya berharap bahwa tim clang-formattetap menggunakan .
jnnnnn
2

Ini semua adalah masalah preferensi, secara pribadi pada proyek yang saya lihat karakternya * Saya cenderung mendeklarasikan banyak petunjuk pada baris terpisah. Tidak ada cara yang benar-benar "benar" untuk melakukan ini dan semuanya tergantung pada preferensi. Beberapa orang mengatakan lebih mudah untuk membaca (a) sementara yang lain mengatakan bahwa (b) lebih mudah untuk mendeklarasikan lebih banyak variabel dari tipe yang sama pada baris yang sama.

Saya menemukan (b) lebih umum, dan dalam beberapa kasus saya telah melihat

char * a;

atau sesuatu seperti ini. Sekali lagi preferensi. Apa pun yang Anda sukai atau apa pun proyek yang saya kerjakan akan saya gunakan (kecuali saya menulisnya sendiri dalam hal ini saya menggunakan (a))

Yesus Ramos
sumber