İşaretçi değişkenlerini C / C ++ [kapalı] olarak bildirmenin doğru yolu


92

Bazı kişilerin işaretçi değişkenlerini bildirmek için aşağıdaki gösterimi kullandığını fark ettim.

(a) char* p;

onun yerine

(b) char *p;

(B) kullanıyorum. (A) işaretinin arkasındaki mantık nedir? (B) notasyonu bana daha mantıklı geliyor çünkü karakter gösterici bir tür değil. Bunun yerine tür karakterdir ve değişken, karaktere bir gösterici olabilir.

char* c;

Görünüşe göre char * türü var ve c değişkeni bu türden. Ama aslında tür char'dir ve * c (c ile gösterilen bellek konumu) bu türdendir (char). Aynı anda birden fazla değişken bildirirseniz, bu ayrım belirgin hale gelir.

char* c, *d;

Bu tuhaf görünüyor. Hem c hem de d bir karaktere işaret eden aynı tür işaretçilerdir. Bunda bir sonrakinden daha doğal görünüyor.

char *c, *d;

Teşekkürler.


7
Ne demek char gösterici bir tür değil? Bir işaretçinin bir tür olmadığını mı söylüyorsunuz?
Benjamin Lindley

1
Belirli bir stil kılavuzuna bakmadığınız sürece bunun bir tercih meselesi olduğuna inanıyorum (yani, şirketinizin uymanız gereken belirli bir kodlama standardı olabilir). Ben bunu seçim b ile ortadaki bazı arasında karıştırma eğilimindeyim. Bazen char *tdüzgün görünmüyorum , char * t;onun yerine yapabilirim. Ancak ben de sık sık gördüm char* t;.
raged

1
Ayrıca, "tür bir char ve * c (c ile gösterilen bellek konumu) bu türden (char)" mantığınız , gerçekte olmadığı halde, bildirilen bir karakter olduğunu gösterir gibi görünecektir. Bazen yeni başlayanlar tarafından olduğu gibi ele alınırsa, kesinlikle hafıza erişim ihlallerine yol açacaktır.
Benjamin Lindley

1
Her ikisi de hala yeterince açıklayıcıdır, (b) * p'nin tipinde olduğunu chargösterir ve (a) p'nin apointer to a char
A Kişi

1
On yılı aşkın sektör deneyimiyle, bugün bu ilk kez ortaya çıktı ve yalnızca diğer endüstri profesyonellerinin makalelerini okurken. Açıkçası, o halde, sekmeler v boşlukları, def veya dec ile yapılan yorumlar veya diğer "tartışacak daha önemli hiçbir şeyin olmaması iyi" konularla yaptığım gibi bunlar hakkında hiçbir zaman dini bir konuşma yapmadım . Bu benim bakış açım olduğundan, kariyerimin çok geç safhalarında "char * p" ile gitmeyi hiç olmamasından daha çok tercih ettim. Evet, önce boşluk, sonra boşluk. İşaretçiliği daha belirgin hale getirdiği için çoğunlukla hataları azalttığını görüyorum.
Kit10

Yanıtlar:


102

Bjarne Stroustrup şunları söyledi:

"İnt * p;" arasındaki seçim ve "int * p;" doğru ve yanlışla ilgili değil, üslup ve vurgu ile ilgilidir. C ifadeleri vurguladı; beyanlar genellikle gerekli bir kötülükten biraz daha fazlası olarak kabul edildi. Öte yandan C ++, türlere yoğun bir vurgu yapar.

"Tipik bir C programcısı" "int * p;" yazar. ve sözdizimini vurgulayan "* p int nedir" olarak açıklar ve stilin doğruluğunu tartışmak için C (ve C ++) bildirimi dilbilgisine işaret edebilir. Gerçekten de *, gramerdeki p ismine bağlanır.

"Tipik bir C ++ programcısı" "int * p;" yazar. ve "p, int için bir göstericidir" vurgulayan yazı tipini açıklar. Aslında p türü int * 'dir. Açıkça bu vurguyu tercih ediyorum ve C ++ 'ın daha gelişmiş kısımlarını iyi kullanmak için önemli görüyorum.

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

İkinci stili tavsiye ederim çünkü tek bir satırda birden çok işaretçi bildirdiğiniz durumda (4. örneğiniz), değişkenle birlikte yıldız işaretine sahip olmak alıştığınız şey olacaktır.


34
Diğerleri asla aynı bildirimde birden fazla nesnenin bildirilmemesini önerir. :-)
Bo Persson

5
Sözdiziminin arkasındaki mantığı vurgularım, bu nedenle tercih ederim:, int *pyani: pbaşvurulmadığında bir int. Sonra birden beyanlar ile ayrılmış ,markaları anlamda: int *p, *q, r(zaman pveya qben bir olsun duruma gelmiş int, ne zaman rbaşvuruda bulunulan Ben olsun int). Ayrıca, işlev işaretçisi sözdizimi mantıklıdır: int (*f)()(ne zaman fbaşvurulduğunda ve anladım diye adlandırıldığında int). Ve bu mantıklı: int *p, (*f)().
Druesukker

2
Bu, argümanın diğer tarafı için geçerli olduğunu anlamama yardımcı oldu. Çoğunlukla üst düzey bir programcı olarak, yazı tipini vurguluyorum; ve tercih edin int*. Bana göre int *p, (*f)()pek bir anlam ifade etmiyor, ama bazı durumlarda bazı insanlara nasıl olacağını anlayabiliyorum.
Assimilater

1
@Druesukker, ifadenizin yukarıdakilerden daha mantıklı olduğunu düşünüyorum.
Muntashir Akon

1
@Druesukker Ancak mantık tam olarak işe yaramıyor void*(ve C ++ referansları için hiç çalışmıyor).
jamesdlin

58

Ben şahsen *türün geri kalanıyla birlikte yerleştirmeyi tercih ederim

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

İnsanlar "tartışacak ama sonra char* p, q;yanıltıcı olacak", ben buna "öyleyse bunu yapma" diyorum.


Char * p için çok iyi bir argüman; seçim :) Gösterdiğiniz örnek gibi okumak zor olmadıkça hiçbirini umursamıyorum, bu durumda yapmamalılar.
Jesus Ramos

1
Ve değeri ne zaman çıkarmak istiyorsunuz? Yaparsın cout << *p;. Öyleyse neden yıldızı koyarak değil önce p beyanı sırasında: *p? Bence daha az kafa karıştırıcı olur.
user1170330

13
@ user1170330, Çünkü bir yerde bu tür tanımının bir parçası ve diğerinde bir referans operatörü. İlişki yok. Bir şey olursa, farklı görünmeleri iyi bir şey çünkü farklı şeyler farklı görünmelidir.
ikegami

34

Nasıl yazılacağı konusunda hiçbir fark yok. Ancak bir satırda iki veya daha fazla işaretçi bildirmek istiyorsanız, (b) varyantını kullanmak daha iyidir, çünkü ne istediğiniz açıktır. Aşağı bak:

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.

5
typedef"elbette" daha iyi bir yol değil. Bazı insanlar bunu tercih edebilir, ancak kodunuzla çalışan birden fazla kişi varsa sorunludur. Alışkın değilsem PCHAR, şöyle bir şey yazabilirim PCHAR *p;, ki bu a olurdu, char**niyet ettiğim gibi değil. Genel olarak, eğer a istiyorsanız char**, PCHAR*yeni bir tür yazmanız veya tanımlamanız gerekir ve sonra bu aptal olmaya başlar.
BlackJack

3
İşleve işaretçi gibi karmaşık bir işaretçi türüne ihtiyaç duyulursa, typedef'ler yapmak çok iyi bir fikirdir. Bu durumda kodu çok daha basit hale getiriyorlar. Öte yandan, PCHAR kullanımı günlük uygulamadan daha sentetik bir örnektir. Ama açıkça istediğini yapıyor. ve sonra aptal olmaya başlıyor Lütfen tüm şikayetlerinizi Stroustrup'a yönlendirin :-)
George Gaál

Karakter için bir gösterici tanımlamak için PCHAR * p yazdıysanız, ne yaptığınızı bilmediğiniz ve def türünü okumadığınız açık olacaktır. Cevap ona göre. Typedef'in başka bir faydası daha var; C'de işleri opak hale getirmenin kolay yolları üzerindedir. halka VOID ptr olarak tanımlanan sembole sahip olun, özel olarak def türü başka bir şeydir .... Arada bir typedef'i ayarlamayı ve ardından türlerden biri hakkında bir şeyi değiştirdiğimizde kod boyunca her şeyi ayarlamayı tercih ederim ... ama C ++ 11,
auto'ların

Üniversiteden beş yıl sonra C ++ ile oynamaya geri dönmeye çalışan biri için bu en iyi cevaplardan biridir.
Panzercrisis

10

Uzlaşma

char * p;

K&R kullanır

char *p;

Bir kodlama standardına uymadığınız sürece size kalmış - bu durumda, herkesin ne yaptığını izlemelisiniz.


4
Char * x, y'nin y'nin char * olduğu anlamına gelmediğini zor yoldan öğrendim. Şimdi K & R'nin neden söz konusu stili takip ettiğini anlayabiliyorum.
Rahul Kadukar

K&R nedir ve tek bir kod kaynağının ne kullandığı neden önemlidir? Ben kullanıyorum char* p;. bu bir tarz meselesi, konvansiyon veya kurallar değil. bana göre p'nin tipinde olması daha mantıklı char*, bu yüzden açıkça * tipi ile birlikte olmalı.
FalcoGer

@FalcoGer K&R için bir bağlantı ekledim. Tek bir kod kaynağının ne kullandığı önemli değil. Standartlarına uymazsanız ekibiniz size kızabilir çünkü kodunuzu anlamaları için onları daha çok çalıştırıyorsunuz. Bu günlerde, umarım takımlar clang-formatyine de kullanır .
jnnnnn

2

Bu tamamen bir tercih meselesi, şahsen karakterini gördüğüm projelerde * Ayrı satırlarda birden çok işaretçi bildirme eğilimindeyim. Bunu yapmanın gerçek bir "doğru" yolu yoktur ve hepsi tercihe bağlıdır. Bazıları (a) 'yı okumanın daha kolay olduğunu söylerken, diğerleri (b)' nin aynı satırda aynı türden daha fazla değişken belirtmenin daha kolay olduğunu söylüyor.

(B) 'yi daha yaygın buluyorum ve bazı durumlarda

char * a;

veya bunun gibi bir şey. Yine tercih. Neye karşı rahat olursanız olun veya üzerinde çalıştığım proje ne kullanırsa kullanırım (kendim yazmazsam bu durumda (a) kullanırım)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.