C değişkenleri ve işlevleri için kullanılan adlandırma kuralları [kapalı]


13

CI'de büyük bir projeyi kodlarken bir sorun ortaya çıktı. Daha fazla kod yazmaya devam edersem, kodu düzenlememin benim için zor olacağı bir zaman olacaktır. Demek istediğim, programın farklı bölümleri için işlevler ve değişkenler için adlandırma karışık görünebilir.

Bu yüzden C değişkenleri ve işlevleri için kullanabileceğim faydalı adlandırma kuralları olup olmadığını düşünüyordum?

Çoğu dil bir adlandırma kuralı önerir. Ancak C için şimdiye kadar okuduğum tek şey isimlerin kod okunabilirliği için açıklayıcı olması.

DÜZENLE:

Önerilen adlandırma kurallarına ilişkin bazı örneklere örnekler:

Bir yerlerde java için bazı adlandırma kuralları okudum ama nerede olduğunu hatırlayamadım.


Önerilen adlandırma kurallarına sahip bazı dil örneklerinden bahsedin. Ve bu adlandırma kurallarını nerede bulabiliriz.
Philip

@Philip Eklenen örnekler
Aseem Bansal

1
Globalleri kullanmadığınız için değişkenlerle ilgili bir sorun olmamalıdır. Ve işlev adları için: modülün ismi ise order.c, sen fonksiyonları sayabilirim order_add(), order_del()ve bu tür. Adın ilk 8 karakter içinde benzersiz olması gerektiğini söyleyen eski sistemler olabilir. Daha sonra yanlışlıkla c ++ 'a geçtiğinizde yazmayı order::add()ve order::del()sonra yazmayı seveceksiniz .
ott--

Yanıtlar:


17

Daha fazla kod yazmaya devam edersem, kodu düzenlememin benim için zor olacağı bir zaman olacaktır.

Bu sizin probleminiz: organizasyonu doğru yapın ve stil daha kolay akmalıdır.

Etmeyin bekleyin kodunuzu düzenlemek için: sen giderken kodunuzu düzenli tutmak. Dil sizin için yapmasa da, kod yine de düşük kuplaj ve yüksek uyum içeren modüller halinde organize edilmelidir.

Bu modüller doğal olarak bir ad alanı sağlar. Çarpışmaları önlemek için modül adını (uzunsa) kısaltın ve işlev adlarını modülleriyle birlikte önekleyin.

Bireysel tanımlayıcılar düzeyinde, bunlar kabaca artan öznellik düzenindedir:

  1. bir kongre seç ve ona uy
    • örneğin, function_like_this(struct TypeLikeThis variable)yaygın
  2. kesinlikle Macar gösteriminden kaçının (üzgünüm JNL)

    • başlangıçta amaçlandığı gibi kullanmayacaksanız , korkunç sistem sürümü yerine Simonyi'nin uygulama gösterimi anlamına gelir

      Neden? Bununla ilgili bir deneme yazabilirim, ancak bunun yerine Joel Spolsky'nin bu makalesini okumanızı ve daha sonra ilgileniyorsanız biraz daha avlanmanızı öneririm . Altta Simonyi'nin orijinal gazetesine bir bağlantı var.

  3. gerçekten opak çerez türleri olmadıkça işaretçi tip tanımlarından kaçının - yalnızca şeyleri karıştırırlar

    struct Type *ok;
    typedef struct Type *TypePtr;
    TypePtr yuck;
    

    Opak çerez türü ile ne demek istiyorum ? İstemci koduna iletilmesi gereken bir modül (veya kitaplık ya da her neyse) içinde kullanılan bir şey kastediyorum, ancak bu istemci kodu doğrudan kullanamaz . Sadece kütüphaneye geri veriyor.

    Örneğin, bir veritabanı kitaplığı aşağıdaki gibi bir arabirim gösterebilir

    /* Lots of buffering, IPC and metadata magic held in here.
       No, you don't get to look inside. */
    struct DBContextT;
    /* In fact, you only ever get a pointer, so let's give it a nice name */
    typedef struct DBContexT *DBContext;
    
    DBContext db_allocate_context(/*maybe some optional flags?*/);
    void db_release_context(DBContext);
    int db_connect(DBContext, const char *connect);
    int db_disconnect(DBContext);
    int db_execute(DBContext, const char *sql);
    

    Şimdi, içerik istemci koduna opaktır , çünkü içeriye bakamazsınız. Sadece kütüphaneye geri ver. Gibi bir FILEşey de opak ve bir tamsayı dosya tanımlayıcı da bir çerez , ancak opak değil.


Tasarım üzerine bir not

Hiçbir açıklama yapmadan yukarıda düşük bağlantı ve yüksek uyum ifadesini kullandım ve bu konuda biraz kötü hissediyorum. Bunu arayabilir ve muhtemelen bazı iyi sonuçlar bulabilirsiniz, ancak kısaca ele almaya çalışacağım (tekrar, bir deneme yazabilirim ama etmemeye çalışacağım).

Yukarıda çizilen DB kütüphanesi , dış dünyaya küçük bir arayüz açığa çıkardığı için düşük kuplaj gösterir . Uygulama ayrıntılarını (kısmen opak çerez hile ile) gizleyerek, istemci kodunun bu ayrıntılara bağlı olmasını önler.

Opak çerez yerine, içerik yapısını içeriği görünür olacak şekilde ve veritabanına bir TCP bağlantısı için bir soket dosyası tanımlayıcısı içeren beyan ederiz. Daha sonra DB aynı makinede çalışırken paylaşılan bir bellek segmentinin kullanımını desteklemek için uygulamayı değiştirirsek, istemcinin yeniden bağlanmak yerine yeniden derlenmesi gerekir. Daha da kötüsü, istemci dosya tanımlayıcısını kullanmaya başlamış olabilir , örneğin setsockoptvarsayılan arabellek boyutunu değiştirmek için arama yapıyor ve şimdi de bir kod değişikliğine ihtiyacı var. Tüm bu detaylar, mümkün olan yerlerde modülümüzün içinde gizlenmelidir ve bu, modüller arasında düşük bağlantı sağlar .

Örnek ayrıca modüldeki tüm yöntemlerin aynı görevle (DB erişimi) ilgili olması nedeniyle yüksek uyumu gösterir . Bu, yalnızca uygulama ayrıntıları hakkında bilgi sahibi olması gereken kodun (yani, çerezimizin içeriği) bunlara gerçekten erişebileceği anlamına gelir, bu da hata ayıklamayı basitleştirir.

Ayrıca, tek bir endişeye sahip olmanın, bu işlevleri birlikte gruplandırmak için bir önek seçmeyi kolaylaştırdığını görebilirsiniz.

Şimdi, bu örneğin iyi olduğunu söylemek kolaydır (özellikle tam olmadığı için), ancak hemen size yardımcı olmaz. İşin püf noktası, kodunuzu yazarken ve genişletirken, benzer şeyler yapan veya aynı türlerde (kendi modülleri için aday olabilecek) işlevler için ve ayrıca birçok ayrı şey yapan işlevler için t gerçekten ilgili ve bölünmek için aday olabilir.


Macarca neden önlendiğini anlamama yardımcı olabilir misiniz? Bunun hakkında daha fazla bilgi edinmek istiyor. :)
JNL

@JNL: Bir yorum doğru şekilde açıklanamayacak kadar kısa. Yeni bir soru olarak göndermenizi öneririm.
Bart van Ingen Schenau

with low coupling and high cohesion. Bu ne anlama geliyor? Ve lütfen opak çerez türleri hakkında açıklama yapın. Bunun ne anlama geldiği hakkında hiçbir fikrim yok.
Aseem Bansal

Her ikisine de kısaca hitap etmeye çalıştım ve açıkçası başarısızlıkla başarısız oldum. Umarım başlamanız gerekir.
Yararsız

Birkaç gün sonra cevap veriyorum. Bunun için özür dilerim. Açıklamasını okudum low coupling and high cohesion. Bu yüzden temelde yapabildiğim zaman bir şeyleri kapsüllemek anlamına gelir ve gerçekten ihtiyaç duyulan fonksiyonların erişebileceği şekilde yapılmalıdır. Bazı şeyler kafamın üstünden geçti ama sanırım hala anladım.
Aseem Bansal

5

Bence, üç şeyi aklınızda tutarsanız, adlandırma sorununun% 90'ı çözülür: a) değişken ve işlev adlarınızı olabildiğince açıklayıcı hale getirin, b) kodunuz boyunca tutarlı olun (yani, bir işlev addNumbers olarak adlandırılmışsa, ikinci işlev, numbersMul) değil multiplyNumbers olarak adlandırılmalıdır) ve c) yazmamız gerektiğinden , adları mümkünse kısa yapmaya çalışın.

Bu konuyla ilgili diğer yönlere bakmak isterseniz, Adlandırma Kuralları hakkındaki Wikipedia sayfasının aklınızda bulundurmanız gereken şeylerin iyi bir listesine sahiptir. Ayrıca C ve C ++ üzerinde bir bölüm var:

C ve C ++ 'da, anahtar kelimeler ve standart kütüphane tanımlayıcıları çoğunlukla küçük harflidir. C standart kitaplığında, kısaltılmış adlar en yaygın olanıdır (örneğin, bir karakterin alfasayısal olup olmadığını test eden bir işlev için isalnum), C ++ standart kitaplığı ise sözcük ayırıcısı olarak genellikle alt çizgi kullanır (örn. Out_of_range). Makroları temsil eden tanımlayıcılar, kural olarak, yalnızca büyük harfler ve alt çizgiler kullanılarak yazılır (bu, sabitler için tümüyle büyük harfli tanımlayıcıların kullanıldığı birçok programlama dilinde kuralla ilgilidir). Çift alt çizgi içeren veya alt çizgi ve büyük harf içeren adlar uygulama için ayrılmıştır (derleyici, standart kütüphane) ve kullanılmamalıdır (örn. Ayrılmış__ veya _Kaydedildi). [5] [6] Bu yüzeysel olarak okşamaya benzer, ancak anlambilim farklıdır:


3
"isimleri mümkünse kısaltmaya çalışın" Otomatik tamamlamalı bir IDE kullanın, işlev adlarınız yalnızca bir kez yazmanız gerektiği kadar uzun ve açıklayıcı olabilir.
Joel

1
@Kötü tavsiye tavsiye. Herkes sizinle aynı IDE'yi kullanmayacak.
James

6
@James İhtiyaçları yok, sadece iyi bir IDE kullanabilirler. O zaman verimlilik için netlikten ödün vermek zorunda kalmazsınız.
Joel

IDE terimi şimdi bir gün biraz daha geriliyor. Teknik olarak Notepad ++ bir IDE'dir, çünkü projenizi derlemek ve çalıştırmak için yapılandırabilirsiniz, ancak öncelikle bir metin düzenleyicisidir. Ve otomatik olarak tamamlanır.
Philip

5

C'deki tek zor kısıtlama, isim alanı olmamasıdır. Bu nedenle, bir yolunu bulmak zorunda rename()senin işlevi dosya sistemi gelen kütüphanede ayrı rename()senin fonksiyonu medya kitaplığına. Genel çözüm, bir önektir, örneğin: filesystem_rename()ve media_rename().

Diğer genel öneriler: bir proje veya ekip içinde tutarlı kalmak. Okunabilirlik artırılacaktır.


+1: Bu özellikle bir kitaplıkta dışa aktarılan semboller için geçerlidir. "Üzgünüm, ancak bu dosya sistemi kitaplığı bu medya kitaplığıyla gitmiyor, çünkü her ikisinin de dışa aktarılan bir işlevi yeniden adlandırması var.
Residuum

2

KÜRESEL KABUL EDİLMİŞ BİR FORMAT ARIYORSANIZ

MISRA / JSF / AUTOSAR, C / C ++ kodunu adlandırmak ve düzenlemek için her endüstri standardının yaklaşık% 100'ünü kapsar. Sorun onlar almak için ücretsiz olmayacak yani kılavuz kitapların her biri biraz para maliyeti. MISRA 2008 C / C ++ kodlama standart kitabının muhtemelen yaklaşık 50 USD olduğunu biliyorum.

Bunları, bir dergi yazarken bibliyografya ve ek okuma için Harvard Referansı olarak düşünebilirsiniz. MISRA'yı kullandım ve işlevlerinizi ve değişkenlerinizi adlandırmanın ve bunları doğru kullanım için organize etmenin iyi bir yoludur.

GEÇİCİ BİR ŞEY ARIYORSANIZ

Sanırım Python ve Java için verdiğiniz referanslar iyi. Javadoc tarzı yorumlama, adlandırma ve kod düzenlemeyi benimseyen insanlar gördüm. Nitekim, son projemde, Java benzeri işlevlere / değişken adlarına C ++ kodu yazmak zorunda kaldım. Bunun iki nedeni var:

1) Görünüşe göre takip etmek daha kolaydı.

2) Üretim kodu gereksinimleri, güvenlik açısından kritik yazılım sistemi standartlarının temeline değmemiştir.

3) Eski kod (her nasılsa) bu biçimdeydi.

4) Doxygen, Javadoc sytle yorumlamasına izin verdi. O anda üretim adamlarına dokümantasyon yapmak için doxygen kullanıyorduk.

Birçok programcı buna karşı olacak, ama şahsen C / C ++ 'da javadoc stili işlev / değişken adlandırma benimsemede yanlış bir şey olmadığını düşünüyorum. DERSİN EVETİ, akış kontrolü, iplik güvenliği vb. Ancak ben burada başvuru sahibi değilim. Üretim kodu formatı gereksinimlerinizin ne kadar katı olduğunu da bilmiyorum. Konu dışı bir alana yönlendirmeden, gereksinimlerinizi gözden geçirmenizi, belirli bir adlandırma kuralına ne kadar bağlı olduğunuzu öğrenmenizi ve benimki ve başkalarının cevaplarında belirtilen bir çözümle devam etmenizi öneririm.

Umarım bu yardımcı oldu !?


Aslında bunu kişisel C kodları için soruyordum. Ama önerinizi hatırlayacağım.
Aseem Bansal

@AseemBansal Kişisel veya profesyonel, bunlar öğrenmek için iyi ve CV'nizi koymak için iyi :) .... Size kalmış.
hagubear

0

Adlandırma sırasında dikkat edilmesi gereken birkaç önemli şey;

  1. ActionObject veya ObjectAction türüne bakın. (Nesne C için değil ama genel olarak diğer Nesne Tabanlı Dillere gittiğinizde) Bu yardımcı olacaktır

  2. Gerisi tutarlı, kısa ve açıklayıcı olacaktır.

  3. Ayrıca, tanımlanan her değişken ve işlevin tek bir amacı vardır, Örn: Bir değeri geçici olarak saklamak için, int için nTempVal olarak adlandırın.
  4. Değişkenler isim ve Yöntemler fiil olmalıdır.

6
Macarca gösterimi (bir değişkenin türünü gösteren harflerle önek olarak yazılması) ağrının sona ermesine yol açmaz. Neyse ki çoğunlukla modası geçmiş.
Robot Gort

@StevenBurnap Macarca formatın neden önlendiğini merak ediyor muydunuz? Bize okulda öğrettiklerinin bu olduğuna inanıyorum ve bazı işyerlerinde de böyle bir kod gördüm. Eğer Macar değilse hangisini tavsiye ederim. Teşekkürler
JNL

1
En iyi adlandırma kuralı, tutarlı bir şekilde sadece bir tanesidir, açık, açıklayıcı adlar, aşırı kısaltma olmadan ve kısa öneklerden kaçınarak ideal olarak nispeten kısa tutulur. Macarca gösterimin çok az fiili faydası vardır, kodu okumayı zorlaştırır ve değişen türleri zorlaştırır.
Robot Gort

2
İşte orijinal niyetin ve Macar notasyonunun haline geldiği iğrençliğin bir açıklaması: joelonsoftware.com/articles/Wrong.html
Residuum

@Residuum Bu iyi bir linkti. Çok yardımcı oldu. Teşekkür ederim.
JNL

0

Cevapların çoğu iyidir, ancak C ++ veya Java gibi diğer dillerde ad alanlarını kullanmaya benzer şekilde, libaries ve dahil edilen dosyalar için adlandırma kuralları hakkında bazı şeyler söylemek istiyorum:

Bir kitaplık oluşturursanız, dışa aktarılan sembolleriniz için genel bir önek bulun (ör. Global işlevler, typedefs ve değişkenler). Bu, diğer kütüphanelerle çakışmaları önleyecek ve işlevleri sizinkinden geliyor olarak tanımlayacaktır. Bu biraz uygulama Macar notaları.

Belki daha da ileri gidin ve dışa aktarılan sembollerinizi gruplayın: libcurl global semboller için curl_ *, farklı arayüzler için curl_easy_ *, curl_multi_ * ve curl_share_ * kullanır. Bu nedenle, tüm işlevler için curl_ * kullanmanın yanı sıra, farklı arabirimler için başka bir "ad alanları" düzeyi eklediler: curl_multi_ * tanıtıcısında bir curl_easy_ * işlevini çağırmak artık yanlış görünüyor, http: // curl'deki işlev adlarına bakın . haxx.se/libcurl/c/

Dışa aktarılan sembollerin kurallarını koruyarak, #includeed dosyalarındaki statik işlevler için kuralları kullanmalısınız : Bu işlevler için ortak bir önek bulmaya çalışın. Belki "my_string" adlı bir dosyada statik dize yardımcı programı işlevleriniz var? Tüm bu işlevlerin önüne my_string_ * ekleyin.


Dışa aktarılan sembollerle, doğru olduğumda global değişkenler, fonksiyonlar, typedefs vb. Dışa aktarılan sembolleri gruplandırmayla ilgili biraz açıklayabilir misiniz? Bunu daha önceki paragrafta açıkladığınızı sanıyordum. 3. paragrafa ne eklediniz?
Aseem Bansal
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.