Your Ad Here

24 Ocak 2008

C KODLAMA STANDARDLARI

  1. KAYNAK PROGRAM KÜTÜKLERİ

    1000 satırdan büyük kaynak programların hem derlemesi yavaş, hem de bakımı zordur. Programları 1000 satırlık kütüklere bölün.

    79 karakterden büyük satırlar her terminalde ve editörde kolay görüntülenmez. Bu nedenle çok uzun satırlar kullanmayınız.

    1. KÜTÜK ADI TANIMLAMA KURALLARI.

      Her kaynak program ana kütük adı ve ekten oluşur. Ekler genelde derleyici ve kullanılan programa göre düzenlenir ( .c, .cc, .l, .y gibi). Ana kütük adı sekiz karakterden oluşmalıdır.

      OKUBENİ (README) directory altındaki kütükleri ve derleme adımında kullanılan parametreleri içermelidir.

      make derleme işlemi için makefile yerine "Makefile" kullanın.

    2. PROGRAM KÜTÜKLERİ.

      1. Her programın başında kütük içinde ne olduğunu belirten ön bilgi (prologue) olmalıdır. Dizi içindeki işlevler, tanımlar burada kısaca anlatılır. Gerekirse yazar adı ve yazıldığı tarih belirtilir.
      2. Başlık (header) eklemeleri bu açıklamanın peşine yazılır (include files). Bazı sistemlerde sistemin kullanığı eklemeler, kullanıcınınkilerin önünde yer almalıdır.
      3. "define" ve "typedef" komutları bundan sonra yazılır. Önce değişmez "macro" tanımları daha sonra işlevsel tanımlar, en son "typedef" ve "enum" tanımları yapılır.
      4. Tanımlardan sonra tüm programda kullanılan "global/external" bilgi alanları tanımlanır. Genel sıramada önce "extern", static olamayan global tanımlar, ve sonra static tanımlar yer alır. Bir yapı tanımını ilgilendiren "define" varsa, bu yapı tanımının peşinde yer almalıdır.
      5. Program içinde kullanılan işlevler bu tanımlamaların sonunda yer alır. Belirli bir kural olarak, incelenmesi en kolay olan yönteme göre sıralanmalıdır. Aynı düzeyde çağırılan işlevlerin beraber bulunması yararlıdır.

      Genel program yapısı :

          /*
          *  ön açıklama (ön bilgi)
          */
          #include <system_kütükleri.h>
          #include <uygulama.h>
      
          #define DEGISMEZLER
      
          #define FUNC(x)
      
          typedef struct A {
                  ...
                  } a_t;
      
          enum { NO=0, YES};
      
          extern int  *p_external;
          extern struct A_EXT a_ext;
      
          int         *p_global;
          struct A_GLOBAL {
              ...
          } a_glob;
          #define A_GLOBSZ sizeof(struct A_GLOBAL);
      
          static int  *p_static;
      
          main(int argc, char **argv)
          {
          ...
          }
      
    3. HEADER KÜTÜKLERİ

      Başlık (header) tanımları her alt sistem için ayrı kütüklerde olmalıdır. Makina bağımlı tanımlar olası taşımalarda değiştirilmek üzere ayrı kütüklerde tanımlanmalıdır. Tanımlarda ve eklemelerde (include) kullanılmalı "kütükadı" gibi tanımlardan kaçınılmalıdır. C derleyicileri -I parametresi ile kütüğü nereden alacağını bulabilmektedir. Bu özellik başlık (header) kütüklerinin yerinin değişmesi durumunda programlarda değişiklik yapılmasını gerektirmez.

      İşlevleri ve "external" tanımları içeren başlık (header) kütükleri tanımın yapıldığı kaynak programa eklenmelidir. Böylece derleyici tip denetimini kolaylıkla yapabilir. başlık (header) kütükleri iç içe (nested) tanımlanmamalıdır. Her başlık (header) kütüğündeki ön bilgi alanınada bu başlık (header) kütüğünden önce hangilerinin eklenmesi gerektiği anlatılmalıdır.

    4. DİĞER KÜTÜKLER.

      OKUBENİ (README) adlı bir kütüğün hem genel görüntüyü tanımlaması, hem de program derleme ve kullanım biçiminin açıklanması açısından önemi çok büyüktür. Burada koşullu derleme adımları ve makina bağımlı kütükler veya programlar açıklanır.

  2. AÇIKLAMALAR HAKKINDA.

    Açıklamalar ne olduğunu, nasıl yapıldığını ve parametrelerin neler olduğunu bildirmelidir. Kısa açıklamalar ise işlemin ne olduğunu anlatmalıdır. Her işlevin başında 3-10 satırlık bir açıklama her satırda işlemin yapılışını ayrıntılayan açıklamadan daha iyidir. Blok açıklama

        /*
        *
        ...
        */
    
    biçiminde yazılmalıdır. Veri yapıları, algoritmalar blok açıklama içinde anlatılmalıdır.

  3. TANIMLAR HAKKINDA.

    Global tanımlar hemen birinci kolondan başlamalıdır. Tüm "external" tanımların önünde "extern" bulunmalıdır. Eğer bir "extern" dizi tanımı (array) varsa bu tanımın boyu her tanımda belirtilmelidir. Gösterge tanımında kullanılan '*' türün önünde değil, tanımın önünde yer almalıdır :

        char *s, *p;
    

    gibi.

    İlişkili olmayan tanımlar aynı türden olsalar da ayrı satırlarda tanımlanmalıdır.

    Tanımlarda kullanılan değişkenler, değerler ve açıklamalar alt alta gelecek şekilde "tab" tuşu ile ayrılmalıdır.

    Eğer "define" komutundaki değerin program içinde bir anlamı yoksa "enum" kullanmak daha iyidir. Örneğin :

        #define  KETCH     (1)
        #define  YAWL      (2)
        #define  SLOOP     (3)
        #define  SQRIG     (4)
        #define  MOTOR     (5)
    

    yerine :

        enum bt { KETCH=1, YAWL, SLOOP, SQRIG, MOTOR };
    

    Bir değişkenin ilk değeri önemli ise ilk değeri açıkça yazılmalı, C derleyicisinin değeri belirlemesi beklenmemelidir. "long" olarak tanımlanan değişmezlerde "l" yerine "L" kullanılmalıdır. Çünkü "2l" ile "21" kolaylıkla karışır.

    "static" tanımlar mutlaka belirtilmelidir. Hatta STATIC diye bir "define" kullanılması daha doğru olur.

    İşlevlerin geri döndürdüğü değerin tipi belirtilmelidir. En çok yapılan hata matemetiksel işlevlerin "double" döndürdüğünün unutulmasıdır.

  4. İŞLEV TANIMLARI HAKKINDA

    Her işlevinden önce açıklama alanı (prologue) bulunmalıdır. Burada işlevin ne yaptığı anlatılmalıdır.

    İşlevin döndürdüğü değer mutlaka belirtilmelidir. Eğer bir değer döndürmüyorsa "void" tanımlanmalıdır.

    İşlevin her parametresi tanımlanmalıdır. İşlev içinde kullanılan döngü değişkeni için 'i', karakter göstergeleri (pointer) için 's' ve karakter tanımlamalar için 'c' kullanımı tüm işlevlerde aynı amaç için kullanılmalıdır. Aynı gruptan olan işlevlerde de aynı tür değişkenleri ve parametreleri kullanmak, onları çağıran programlarda kodlama kolaylığı getirir.

    Değişken sayıda parametresi olan işlevlerde C dilinde tanımlanmış "varargs" kullanmak anlaşılması veya taşınması açısından önemlidir.

    Eğer işlev içinde kullanılan bir değişken kaynak programda tanımlı "global" değişkenlerden değil de başka kaynak programda yer alıyorsa "extern" kullanılarak tanımlanmalıdır.

    İçerlek yazma ve boşluklar işlevin blok yapısını gösterir. Her iç blok için en az üç boşluk bırakarak yazmak programı daha okunaklı yapar.

    Uzun koşullarda her ve/veya işleminden sonra kalanı başka bir satıra yazmak, "for" döngülerinde her bir döngü işlemini ayrı satıra yazmak ve "?" isleminde her bir koşulu ayrı satıra yazmak programı daha okunaklı yapar.

  5. BASİT KOMUTLAR (SIMPLE STATEMENTS) HAKKINDA.

    Her satırda mümkünse bir işlem, komut olsun. "while" döngülerinde döngü gövdesi boş ise ";" ayrı bir satırda olsun. "if" deyiminde test sonucunda sıfır olmama koşulu derleyicinin kabulüne bırakılmasın. Örneğin :

      if (f() != FAIL)

    her zaman

      if (f())

    biçiminden daha iyidir. Eğer FAIL değeri sıfır ise ve sonra birisi bu değeri -1 yapmak isterse tüm kodlamada ilgili satırların bulunup düzeltilmesi gerekebilir. Bu şekilde kullanım değeri değişmese bile diğer "if" deyimlerinde de yer almalıdır.

    Sıfır olamayan derleyici kabulü ancak aşağıdaki testler için kullanılmalıdır.

    - Sonuç yalnız sıfır ve başka bir şey olmuyorsa,
    - Sonuç daha önceden adlandırılmış (TRUE gibi) ve başka birşey olmuyorsa, örneğin "isvalid", "valid" veya "checkvalid" gibi işlevlerde

    kullanılabilir.

    Kodlama kolaylığı olsa bile birden çok atama ("=" işlemi) kullanılmamalıdır.

    "goto" deyimi hiç kullanılmamalıdır. Eğer bir döngüden çıkmak için gerekiyorsa, döngü içindeki bölüm işlev haline getirilmeli, bu işlevin döndürdüğü değer TRUE/FALSE olarak tanımlanmalı ve "goto" deyimi yerine dönen değer kullanılmalıdır.

    Ancak "goto" deyimi kullanmak gerekiyorsa, etiket (label) programın okunmasına kolaylık sağlaması açısından, kodlamanın daha solundan yazılmalıdır.

  6. BİRLEŞİK KOMUTLAR (COMPOUND STATEMENTS) HAKKINDA.

    Kıvrımlı prantez (brace) içindeki komutların tümüne birleşik komutlar denir. Birleşik komutlarda :

       kontrol {
               komut;
               komut;
       }
    

    stili kullanılır. Buna "K & R stili" denir.

    "switch" deyimde bir "case" seçeneğinden sonra "break" komutu yoksa buraya açıklama içinde bilgi yazın. Eğer son seçenek varsayılan (default) değilse mutlaka "break" kullanın ve her zaman son seçenek varsayılan (default) olsun.

    "if-else" deyiminde her koşul için komutlar (bir tane de olsa) mutlaka "brace" içine alınsın. Özellikle iç içe tanımlanmış "if" deyimlerinde "else" olmaması durumunda bu kodlama çıkabilecek sorun veya hatayı azaltır.

    "do-while" döngülerinde mutlaka "brace" kullanılmalıdır.

  7. İŞLEMLER HAKKINDA.

    Tüm ikili işlemler ile değişkenler arasında en az bir boşluk bırakın ('.' ve '->' hariç). Eğer bir deyimin okunması zor ise en az öncelikli işlemden deyimi satırlara bölmek gerekir. Gerekli olduğunda parantez kullanarak işlem önceliklerini gösterin. Ancak çok fazla parantez kullanmayın. İnsan gözü parantezleri okumaya alışık değildir.

    virgül (comma) işlemi en çok "for" döngülerinde birden çok değişkene ilk değer vermek için yararlıdır. Bunun dışında fazla kullanmamaya çalışın.

    "?:" işlemindeki '?' öncesindeki koşulu parantez içinde yazın.

    C dili deyimlerinden "sizeof" dışında kalanlardan sonra ilk parantezden önce bir boşluk bırakılmalıdır. İşlevlerin parameterlerindeki virgülden sonra da bir boşluk bırakılmalıdır. "macro" tanımlarında ilk parantezden önce boşluk bırakılmamalıdır. Yoksa ön derleyici (preprocessor) parametreleri algılayamaz.

  8. DEĞİŞKENLERİ ADLANDIRMA.

    Değişkenin adının başında ve sonunda '_' kullanmayın. Bu tür değişkenler kullanıcıya açık olmayan derleyici değişkenleri arasında bulunabilir.

    Tüm "define" ve "enum" komutlarında değişmezler için büyük harfli tanım kullanın.

    İşlev adları, değişken adları, "typedef", "struct", "union" ve "enum" tanımları için küçük harf kullanın.

    "macro" işlevleri büyük harf olmalıdır. Küçük harf "macro" tanımları eğer "macro" bir işlev gibi çalışıyorsa kabul edilebilir.

    Aynı programda yalnız büyük ve küçük harf farkı olan değişkenler ve çok benzer değişkenler kullanmayın (foo ve Foo gibi veya foobar ve foo_bar gibi).

    Başka anlama gelebilecek değişken adları kullanmayın. Mümkünse 'l' harfini hiç kullanmayın. Her zaman '1' ile karışabilir.

    "typedef" tanımlarının sonunda çoğu kez "_t" eki bulunur.

  9. DEĞİŞMEZLER HAKKINDA

    Sayısal değişmezler için "define" kullanmak ileride programın bakımını kolaylaştırır. Yalnız "define" tanımını değiştirmek yeterli olabilir.

    Değişmezler kullanım amaçlarına uyumlu tanımlanmalıdır. Örneğin "long" değişmez 'L' ile kayan noktalı değişmez '.0' ile.

    ASCII gösterilemeyen değişmezleri "define" altında tanımlayın veya sekizli (octal) tanımını tırnak içinde kullanın.

    NULL yerine '0' kullanmayın.

  10. "MACRO" HAKKINDA

    Karmaşık deyimler "macro" olarak tanımlanır. Eğer "macro" parametreleri etrafında parantezler yoksa işlem önceliklerinde sorunlar olabilir.

    Bazen hem "macro" hem de işlevler aynı adla tanımlanabilir. Bu durumda parametrelerin işleyişi önem kazanır. İşlevlerde kullanılan parametrelerin değerleri işleve geçerken, "macro" larda parametrenin açılımı kullanılır.

  11. KOŞULLU DERLEME

    Koşullu derleme işlemi makina bağımlı işlemler, "debug" ve derleme sırasında belirlenen seçeneklerin kullanımı için önemlidir.

    Mümkün ise "ifdef" tanımını başlık (header) kütüğüne koyun. Kaynak program içine koymamağa çalışın.

  12. DÜZELTME (DEBUG)

    "enum" kullanırken mümkünse ilk değer sıfırdan farklı olmalı. Eğer sistemde hata koşulu sıfır ise her zaman birinci değer hatayı gösterir.

    Her zaman hatayı görmek için eklemesindeki bilgiyi kullanın. Yeri geldiğinde "assert" olanağından yararlanın.

    Test amaçlı kodlamalarda her zaman başlık (header) içinde "define" ile "macro" kullanın. Böylece kodlamada değişiklik yapmanız gerekmez.

  13. "make" KOMUTU HAKKINDA

    "make" komutu için kullanılan bazı genel kavramlar aşağıda verilmiştir :

    all Her zaman tüm kütüphaneleri derler.
    clean ara kütüklerin tümünü siler.
    debug testler için kullanılan 'a.out' uretir.
    depend
    install programları ve kütüphaneleri gerçek yerine taşır.
    deinstall "install" işlemini geri alma adımıdır.
    mkcat yardım ekranlarını "man" komutu ile kullanılır hale getirir.
    lint "lint" programını çalıştırır.
    print/list tüm kaynak programların listesini almaya yarar.
    rdist kaynak programları başka bilgisayarlara taşımaya yarar.

    Bunlara ek olarak "Makefile" için komut satırından "DEBUG" veya "CFLAGS" tipi değerler girilebilir.

  14. PROJEYE BAĞIMLI STANDARDLAR

    Genelde bu bölümde proje bağımlı kütük adları, directory adları, başlık bilgisi adları gibi tanımlar yazılır.


Ana Sayfaya   Teknik Bilgiler Sayfasina


Aglar Aglink Agteknik C-Kodlama C-Önişleme CRC/LRC DEA etcsrv Çatal (fork) ilet inetd Make Msg Auth Özyinelemeli Robotlar için SDLC Güvenlik Seri uçlar SNA LU0 SNA LU6.2 tcp/ip tcp Programı Unix vi Editör