Bir C programcısı ne bilmeli? [kapalı]


12

Her iyi C programcısının bilmesi / farkında olması gereken bazı kavramlar / teknikler / dil özellikleri nelerdir (genel yazılım mühendisliğini ve benzerini hariç tutun ve sadece C'ye özgü şeylere odaklanın). Bilmek istiyorum, böylece C bilgimdeki bazı olası boşlukları doldurabileceğim.


9
Stack Overflow'un C sorularıyla başlayın ve bilmediğiniz bir şey olup olmadığına bakın.
chrisaycock

3
AC programcısı muhtemelen şunu bilmelidir2 + 2 = 4
Edward Strange

21
Kurşun geçirmez ayakkabılar satan bir mağaza bilmeliler.
Adam Crossland

1
Bu konuda yüzlerce kitap var. Sorunuz gerçekten oldukça belirsiz. Sadece bir liste olmayan iyi cevaplar almak için daha spesifik olmalısınız. Ve bu sorudan bugüne kadar ortaya çıkan cevapları gördüğümde, bunun yeniden ele alınması ya da kapatılması gerektiğini düşünürdüm.
Walter

2
Başka bir programlama dili mi?
Muhammad Alkarouri

Yanıtlar:


19

C'ye özgü mü? Çoğu prosedürel dilde ortak olan standart yapıların dışında şunu söylemeliyim:

  • (ab) önişlemciyi kullanma
  • bağlayıcı vs derleyici
  • İşaretçiler işaretçiler!
  • Diziler nasıl işaretçilerdir diziler
  • C dizeleri nasıl çalışır ve ayrıca işaretçiler ve dizilerdir
  • Ne kadar kötü C string kullanımı arabellek taşmasına neden olabilir?
  • Bir şeye bir şey nasıl dökülür (sonuçta hepsi sadece 1s ve 0s :))
  • Manuel bellek yönetimi malloc / free
  • Yığın ve Öbek
  • İşaretçi takma adı, (neden C99'da yasadışı)
  • Kesinlikle sınıflar yerine kamuya açık bir dizi işlev içeren modüller (.h / .c dosyaları) açısından gelişimi düşünmek
  • Sendikalar
  • Sprintf neden ayağını havaya uçurabilir?
  • İşlev işaretçileri

Listeye "arabellek taşmaları" eklerdim.
Aidan Cully

@Aidan, iyi yakaladın. Katma.
Doug T.

2
C dizileri ve işaretçileri nasıl aynı değildir: books.google.ca/…
Matthieu

işaretçiler en az 3 kez daha tekrarlanmalıdır
Gaurav

8

İşaretçileri anlayın ve bilgisayarları anlayın.


12
Hayır, sadece bilgisayarları anladığınız bir yanılsama alacaksınız.
İş

5

Pisagor mükemmel cevabına ek olarak,

gibi karmaşık bildirimlerin nasıl yazılacağı (veya en azından okunacağı) char (*(*funcs[4])())[10]

funcs, işaretçiyi char [10] dizisine geri döndüren bir işleve işaretçiler dizisidir [4]


1
Bu kadar karmaşık hale gelirse, belki de bu bir yoruma aittir?
İş

7
belki böyle yazmayı nasıl önleyeceğini öğrenmeli?
FabianB

3
  1. Tam sayı tanıtım kuralları
  2. Her şeyi bilinen bir değere başlatın
  3. GOTO özellikle istisnaları / hataları ele almak için kullanıldığında kötü değildir
  4. malloc ve / veya calloc NULL döndürebilir ... çek dönüş değerlerinizden emin olun
  5. Sık sık küçük bellek ayırmaları yığın üzerinde parçalanmaya neden olabilir.
  6. İşaretçi aritmetiği
  7. Bit maskeleri senin arkadaşın
  8. x >> 1, işaretsiz tamsayılar için x / 2'ye eşdeğerdir

GOTO değil varlık +1 için +1 :)
zvrba

2

AC programcısı bilmeli ... diğer diller! ;-) OOP, fonksiyonel programlama ve benzeri gibi çeşitli paradigmaların dillerinden kavramları bilmek her zaman verimli olur.

Daha da ciddisi, gizlenmiş programlama yarışmasına bakmak eğlenceli ve merakla da iyi bir deneyim.


2

Pythagras'ın cevabına yaptığı bir yorumda "arabellek taşması" ndan bahsettim, muhtemelen biraz ne demek istediğimi açıklığa kavuşturmalıyım. C'de, doğrudan bellekle çalışmanın tehlikeli olduğunu bilmek yeterli değildir - aynı zamanda tehlikeli olmasının kesin yollarını da anlamalısınız. Gerçekten bu durumlarda tümü için "ayak kendinizi çekim" metafor gibi değil - çok zaman, o değil sen tetiği çeken, ancak çoğu zaman sizinkine ve / veya kullanıcıları aykırı çıkarları bir aktör .

Örneğin, azalan yığına sahip bir mimaride (en popüler mimariler bu faturaya uyar - x86 ve ARM genellikle dahil), bir işlevi çağırdığınızda, işlevin dönüş adresi, öğede tanımlanan yerel değişkenlerden sonra yığına yerleştirilir. işlev gövdesi. Dolayısıyla, bir arabelleği yerel değişken olarak bildirir ve bu değişkeni, arabellek taşmasını denetlemeden dış dünyaya maruz bırakırsanız, şöyle:

void myFn(void) {
    char buf[256];
    gets(buf);
}

harici bir kullanıcı size yığından dönüş adresinin üzerine yazan bir dize gönderebilir - temel olarak, programınızın geçerli işleve yönlendiren çağrı grafiği çalışma zamanı fikrini değiştirebilir. Böylece kullanıcı size mimariniz için bazı yürütülebilir kodların ikili temsili, yığının taşması için yeterli dolgu myFnve myFnsize verdiği kodu göstermek için dönüş adresinin üzerine yazmak için bazı ek veriler sağlar . Böyle bir durumda, myFnnormalde arayanın denetimini döndürdüğü zaman , bunun yerine kötü niyetli kullanıcının sağladığı kodu kodlar. Güvenilmeyen kullanıcılara maruz kalma potansiyeli olan C (veya C ++) kodu yazarsanız , bu saldırı vektörünü anlamanız gerekir. Yığına karşı bir arabellek taşmasının neden yığına karşı genellikle daha kolay (ama her zaman değil) neden olduğunu ve yığındaki belleğin nasıl düzenlendiğini (çok fazla ayrıntıda değil, mutlaka, ama malloc()'bir bölgenin onu çevreleyen kontrol yapılarına sahip olduğu fikri, programınızın neden bir başkasına malloc()veya içine çöktüğünün anlaşılmasına yardımcı olabilir free()).

C sizi makinenizin nasıl çalıştığı hakkında düşük seviyeli ayrıntılara maruz bırakır ve makineniz üzerinde günümüzde yaygın olarak kullanılan diğer kullanıcı tarafından düzenlenmiş diğer dillerden daha fazla doğrudan kontrol sağlar. Büyük güçle büyük sorumluluk gelir - C ile güvenli ve etkili bir şekilde çalışmak için aslında bu düşük seviyeli ayrıntıları anlamanız gerekir.


0

Diğer iyi cevaplara ek olarak listeye defansif programlama teknikleri eklemek istiyorum .

Örneğin, sözleşmeyi doğrulamak için işlevlerin başında / sonunda ekleri kullanma.

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.