İnsanlar bu kadar tehlikeliyse neden C kullanıyorlar?


132

C öğrenmeyi düşünüyorum

Ancak insanlar 'tehlikeli' olarak kullanılıyorsa neden C (veya C ++) kullanıyorlar?

Tehlikeli olarak, işaretçilerle ve benzeri şeylerle kastediyorum.

Yığın Taşması sorusu gibi Alınan işlev neden kullanılmaması gerektiği kadar tehlikelidir? . Programcılar neden Java veya Python veya Visual Basic gibi derlenmiş başka bir dil kullanmıyorlar?


152
Aşçılar neden 'tehlikeli' olarak kullanılıyorsa bıçak kullanıyorlar?
oerkelens

78
Büyük güç büyük sorumluluk getirir.
Pieter B

10
Joe Blow, çok şey biliyor musun?
Matthew James Briggs

4
Çünkü “Günün Dönüşü” C, Seçim Dili haline geldiğinde, böyle şeylerle başa çıkabilmemiz bekleniyordu, çünkü yapmak zorundaydık. Yorumlanan veya bayt kodlu diller çok yavaştı çünkü günün işlemcileri çok daha yavaştı. (Bugün 2+ GHz çok çekirdekli işlemciye ve Dell'den 279 dolara 4 GB belleğe sahip düşük kaliteli bir masaüstü bilgisayar satın alabiliyorum . 4 MHz'lik bir bilgisayar için benim için kesinlikle inanılmaz görünen bir ID IDEA'nız yok. 640 kilobayt bellek ile mutluluk ...). Kabul et - Moore Yasası kazandı. Oyun. Bitmiş!
Bob Jarvis

6
@ Jar Jarvis: Oyun daha bitmedi. 2 + GHz, 4GB PC'niz - ya da bu konuda, en son CUDA GPU'ları olan ya da her neyse - birkaç yüz 4 GHz bilgisayar kümenizin yeterince hızlı çalışamayacağını düşünüyorsanız :-)
jamesqf

Yanıtlar:


246
  1. C, düşündüğünüz diğer dillerin çoğundan önce gelir. Programlamayı "daha güvenli" hale getirme konusunda şimdi bildiklerimizin çoğu C gibi dillerden geliyor

  2. C'den beri ortaya çıkan daha güvenli dillerin çoğu, daha geniş bir çalışma süresine, daha karmaşık bir özellik kümesine ve / veya hedeflerine ulaşmak için sanal bir makineye dayanıyor. Sonuç olarak, C tüm popüler / ana diller arasında "en düşük ortak payda" olarak kalmıştır.

    • C uygulaması çok daha kolay bir dildir çünkü nispeten küçüktür ve en zayıf ortamda bile yeterince performans gösterme olasılığı yüksektir, bu nedenle kendi derleyicilerini ve diğer araçlarını geliştirmesi gereken birçok gömülü sistemin işlevsel bir derleyici sunması daha olasıdır C için

    • C çok küçük ve çok basit olduğundan, diğer programlama dilleri, C benzeri bir API kullanarak birbirleriyle iletişim kurma eğilimindedir. Bu, muhtemelen çoğumuzla sarmalayıcılar aracılığıyla etkileşime girse bile, C'nin asla gerçekten ölmemesinin ana nedenidir.

  3. C ve C ++ 'da geliştirmeye çalışan "daha güvenli" dillerin birçoğu, programınızın bellek kullanımı ve çalışma zamanı davranışları üzerinde neredeyse tamamen kontrol sahibi olan "sistem dilleri" olmaya çalışmıyor. Günümüzde gittikçe artan sayıda uygulamanın bu kontrol seviyesine ihtiyaç duymadığı doğru olsa da, gerektiğinde her zaman küçük bir avuç gerekli olacaktır (özellikle, tüm bu güzel, güvenli dilleri uygulayan sanal makineler ve tarayıcılar içinde). geri kalanımız).

    Bugün, C veya C ++ 'dan daha güvenli olan birkaç sistem programlama dili (Rust, Nim, D, ...) vardır. Gezinme avantajlarına sahipler ve çoğu zaman, böyle ince kontrolün gerekli olmadığını anlıyorlar, bu yüzden gerçekten gerekli olduğunda değiştirilebilecek birkaç güvenli olmayan kanca / mod ile genel olarak güvenli bir arayüz sunun.

  4. C içinde bile, pratikte ortaya çıkan sinsi böcek sayısını büyük ölçüde azaltma eğiliminde olan birçok kural ve kılavuz öğrendik. Bu kuralları geriye dönük olarak uygulamak için standardın elde edilmesi genellikle imkansızdır, çünkü bu çok fazla varolan kodu kıracaktır, ancak bu kolayca önlenebilir sorunları saptamak için derleyici uyarıları, çizelgeleri ve diğer statik analiz araçlarını kullanmak yaygındır. Bu araçları uçan renklerle geçen C programlarının alt kümesi zaten "sadece C" den çok daha güvenlidir ve bu günlerde herhangi bir yetkili C programcısı bazılarını kullanacaktır.


Ayrıca, hiçbir zaman şaşkın bir Java yarışması yapmak, şaşkın bir C yarışması kadar eğlenceli olmayacaktır .


7
"en düşük ortak payda", aşağılayıcı sesler. Çok daha ağır olan dilin aksine, C'nin ihtiyaç duymadığın bir ton ekstra bagajı zorlamadığını ve sana ihtiyaç duyduğun şeylerin uygulanacağı yıldırım hızında bir temel sağladığını söyleyebilirim. Demek istediğin bu muydu?
underscore_d 11

9
“Gerçekten diğeri olmadan birisine sahip olamazsınız.”: Aslında birçok yeni dil (Rust, Nim, D, ...) dener. Bu, temel olarak, dilin "güvenli" bir alt kümesini, bu kontrol düzeyinin kesinlikle gerekli olduğu durumlarda, bir kaç "güvensiz" ilkel ile eşleştirmekle sonuçlanır. Bununla birlikte, bunların hepsi C ve C ++ 'dan toplanan bilgiler üzerine kuruludur, bu nedenle, belki de C ve C ++' ın geliştirildiği sırada, diğeri olmadan da sahip olamayacağınız söylenmeli ve bugünlerde ayrılmaya çalışan bir dil olduğu söylenebilir. "güvensiz" bitleri, ancak henüz yetişmediler.
Matthieu M.

6
1) geçerli bir nokta değil! C, bu anlamda "güvenli" bir dil olan Algol 68'den özellikler aldı; Böylece yazarlar bu tür dilleri biliyordu. Diğer noktalar harika.
reinierpost

4
@MatthieuM. Microsoft Research’e de bakmak isteyebilirsiniz. Bazıları, gerçek hayattaki iş yükleri için eşdeğer bir yönetilmeyen işletim sisteminden daha hızlı (tamamen kazayla - bu araştırma işletim sistemlerinin çoğunun birincil hedefi, hız değil) güvenlik dahil olmak üzere, son on yılda birkaç yönetilen işletim sistemi ürettiler. . Hızlanma, çoğunlukla güvenlik kısıtlamaları nedeniyle gerçekleştirilir - statik ve dinamik çalıştırılabilir kontrol, yönetilmeyen kodda bulunmayan optimizasyonlara izin verir.
Sonuç

3
@Luaan: Midori çok harika görünüyor; Her zaman Joe'nun blog yazılarını bekliyorum.
Matthieu M.

41

İlk olarak, C bir sistem programlama dilidir. Örneğin, eğer bir Java sanal makinesi veya bir Python yorumlayıcısı yazarsanız, bunları yazmak için bir sistem programlama diline ihtiyacınız olacaktır.

İkincisi, C, Java ve Python gibi dillerin sunmadığı performansı sağlar. Genellikle, Java ve Python'daki yüksek performanslı bilgi işlem, ağır kaldırma işlemini yapmak için C gibi yüksek performanslı bir dilde yazılmış kütüphaneleri kullanır.

Üçüncüsü, C Java ve Python gibi dilden çok daha az yer kaplar. Bu, büyük çalışma zamanı ortamlarını ve Java ve Python gibi dillerin bellek taleplerini desteklemek için gerekli kaynaklara sahip olmayabilir gömülü sistemler için kullanılabilir.


Bir "sistem programlama dili", endüstriyel güç sistemlerini oluşturmak için uygun bir dildir; Durdukları gibi, Java ve Python sistem programlama dilleri değildir. "Tam olarak bir sistem programlama dili yapan şey" bu sorunun kapsamı dışındadır, ancak bir sistem programlama dili temel platformla çalışmak için destek sağlamalıdır.

Öte yandan (yorumlara yanıt olarak) günü, bir sistem programlama dili yok değil kendi kendine barındırmayı olması gerekir. Sorulan orijinal soru "neden insanlar C kullanırım" çünkü bu sorun, PYPY olduğunda ilk açıklama "neden C gibi bir dil gerekir" sordu, ben PyPy kaydetti, geldi geliyor aslında Yani C kullanın onu Başlangıçta soru ile ilgiliydi, fakat ne yazık ki (ve kafa karıştırıcı olarak) “kendini barındırma” aslında bu cevaba bağlı değil. Üzgünüm, ben büyüttüm.

Yani, özetlemek gerekirse: Java ve Python, birincil uygulamaları yorumlandığından ya da yerel olarak derlenen uygulamalar kendiliğinden barındırılmadığından, temel platformla çalışmak için gerekli desteği sağlamadıkları için programlamaya uygun değildir.


19
"bir Java sanal makinesi veya bir Python tercüman yazarsanız, bunları yazmak için bir sistem programlama diline ihtiyacınız olacak." Ah? PyPy'i nasıl açıklarsınız? Derleyici, tercüman veya sanal bir makine yazmak için neden C gibi bir dile ihtiyacınız var?
Vincent Savard

10
Java sanal makinesi veya Python tercümanı yazmak için "Java sanal makinesi veya Python tercümanı yazarsanız, bunları yazmak için bir sistem programlama diline ihtiyacınız olacak" deyince, bir Java programlama makinesi veya Python yorumlayıcıya ihtiyacınız olduğunu iddia ettiğinize inanıyorum. PyPy sizi tatmin etmiyorsa, Haskell ile yazılmış herhangi bir tercümana veya derleyiciye de bakabilirsiniz. Ya da gerçekten, sadece talebinizi destekleyen bir referans ekleyin.
Vincent Savard

16
Baştan aşağı kaplumbağa olsa bile, PyPy gibi bir şey başka bir dilde yazılmış bir Python yorumlayıcısı olmadan olamazdı.
Blrfl

18
@Birfl Ama bu pek bir şey demiyor. C bir derleme derleyicisi olmadan yazılamazdı ve onu uygulayan donanım olmadan derleme yazamazsınız.
gardenhead,

11
PyPy bir sistem derleme dili değilse, bir C derleyicisi bir yere dahil olduğundan, o zaman C bir derleyici bir yerde kullanıldığı için de bir sistem programlama dili değildir. Aslında, bugünlerde C'yi başka bir dile çevirmek popüler değil mi? örneğin, LLVM

30

Başka bir cevap eklediğim için üzgünüm, fakat mevcut cevapların hiçbirinin doğrudan ilk cümlenizi belirttiğini sanmıyorum:

'C öğrenmeyi düşünüyorum'

Neden? C'nin günümüzde genellikle kullandığı şeyleri yapmak ister misiniz (örn. Aygıt sürücüleri, sanal makineler, oyun motorları, medya kütüphaneleri, gömülü sistemler, işletim sistemi çekirdekleri)?

Eğer evet ise, o zaman evet, hangisinin ilgilendiğinize bağlı olarak C veya C ++ öğrendiğinden emin olun. Bunu öğrenmek ister misiniz, böylece üst düzey dilinizin ne yaptığını daha iyi anlarsınız?

Daha sonra güvenlik kaygılarını dile getirmeye devam edin. Mutlaka bir gerekmez derin bir üst düzey dilde bir kod örneği üretim hazır olmadan size özünü verebilir, aynı şekilde, ikincisi yapılacak güvenli C anlaşılmasını.

Özü bulmak için bir miktar C kodu yaz. Sonra tekrar rafa koyun. Üretim C kodunu yazmak istemediğiniz sürece güvenlik konusunda çok fazla endişelenmeyin .


2
Gerçek mesele neyin cevap verdiğini gösteren iyi bir iş! Gerçekten C / C ++ ve "daha güvenli" dilleri takdir etmenin harika bir yolu basit bir veritabanı motoru gibi bir şeyler yazmayı denemektir. Çalıştığınız yaklaşımların her biri için iyi bir fikir edineceksiniz ve sizi nereye götürdüğünü görün. Her ikisinde de neyin doğal olduğunu göreceksiniz ve doğal yaklaşımın nerede başarısız olduğunu göreceksiniz (örn. C'deki ham verileri "seri hale getirmek" çok kolaydır - sadece verileri yazın !; ancak sonuç taşınabilir değildir, bu nedenle sınırlı kullanım olabilir). Güvenliği anlamak zordur, çünkü sorunların çoğuyla karşılaşmak zor olabilir.
Luaan

1
@Luaan tam olarak, işaretçileri kullanarak bir dize kopyalamayı öğrenmek size fikir verir, bunu güvenli bir şekilde yapmayı öğrenmek başka bir seviyedir ve birinin hedeflerine bağlı olarak belki de gereksiz bir şeydir.
Jared Smith,

2
Bu gerçekten soru değildi. Ancak bir diseksiyon yapmak için yararlı oldu. Yapmaya karar verdim. Üzerindeki her şeyin içsel işleyişi hakkında daha fazla şey öğrenmeye istekliyim. Ve ben sadece programlamayı seviyorum. Bu şekilde, bilgisayarların iç işleyişini daha iyi anlamayı umuyorum. Sadece eğlence için.
Tristan

10
Son cümleyle aynı fikirde değilim. Kötü alışkanlıklar geliştirmeden önce nasıl yapabileceğinizi öğrenin.
glglgl

2
@glglgl IDK, web’de bir JavaScript pasajı okuduğumda (veya yazdığımda) üretime hazır olmadığı anlayışıyla yapıyorum: istisna işlemesi olmayacak, O (n ^ 2) vb. Bu noktaya geçmek için bu gereklidir. Hepsi üretim kodu için gereklidir. Bu neden farklı? Entelektüel olarak anlarken, kendi düzenlemelerim için saf C yazabilirim , eğer ortaya koymak istersem çok daha fazla iş yapmam gerekir.
Jared Smith,

14

Bu, tonlarca cevabı olan BÜYÜK bir sorudur, ancak kısa versiyon, her programlama dilinin farklı durumlar için uzmanlaşmış olmasıdır. Örneğin, web için JavaScript, düşük seviyeli şeyler için C, Windows için C #, vb. Hangi programlama dilini seçeceğinize karar vermeyi öğrendikten sonra ne yapmak istediğinizi bilmenize yardımcı olur.

Son noktanıza hitap etmek için, neden C / C ++ ile Java / Python kullanıyorsunuz? Oyunlar yapıyorum ve Java / C # son zamanlarda oyunların çalışması için yeterince iyi olan hızlara ulaşıyor. Sonuçta, oyununuzun saniyede 60 kare hızında çalışmasını istiyorsanız ve oyununuzun çok çalışmasını istiyorsanız (renderleme özellikle pahalıdır), kodun mümkün olduğu kadar çabuk çalıştırılması gerekir. Python / Java / C # / Pek çok kişi, "tercümanlar" üzerinde çalışıyor, C / C ++ 'nın kullanmadığı tüm sıkıcı işleri yapan, bellek ve çöp toplama gibi ek bir yazılım katmanı. Bu ek yükü işleri yavaşlatır, bu yüzden hemen hemen her büyük oyun (son 10 yılda, yine de) C veya C ++ ile yapıldı. İstisnalar var: Unity oyun motoru C # * kullanıyor ve Minecraft Java kullanıyor, ancak kural dışı durum onlar. Genel olarak,

* Birlik bile tüm C # değil, bunun büyük parçaları C ++ ve oyun kodunuz için sadece C # kullanıyorsunuz.

EDIT Bunu yayınladıktan sonra ortaya çıkan yorumların bir kısmına cevap vermek için: Belki de fazlasıyla basitleştiriyordum, sadece genel resmi veriyordum. Programlama ile cevap asla basit değildir. C tercümanları var, Javascript tarayıcının dışında çalışabilir ve C # Mono sayesinde hemen hemen her şeyi çalıştırabilir. Farklı programlama dilleri, farklı alanlar için uzmanlaşmıştır, ancak bazı yerlerdeki bir programcı, herhangi bir dilin herhangi bir bağlamda nasıl çalışacağını çözmüştür. OP fazla programlama bilmiyor gibi göründüğü için (benim açımdan varsayım, yanılıyorsam özür dilerim), cevabımı basit tutmaya çalışıyordum.

C # hakkındaki yorumlara gelince, neredeyse C ++ kadar hızlı olduğu için anahtar kelime neredeyse var. Üniversitedeyken birçok oyun şirketini gezdik ve öğretmenim (bizi yıl boyunca C # ve C ++ 'dan uzaklaşmaya teşvik eden) öğretmenim her şirkette programcılara neden C ++' dan C # 'ya gittiğini sordu. dedi C # çok yavaş. Genelde hızlı çalışır, ancak çöp toplayıcı performansa zarar verebilir, çünkü ne zaman çalıştığını kontrol edemezsiniz ve ne zaman çalıştırmanızı istemediğinizi belirtmek istemiyorsa sizi görmezden gelme hakkına sahiptir. Yüksek performansa sahip bir şeye ihtiyacınız olursa, tahmin edilemez bir şey istemezsiniz.

"Sadece hızlara ulaşma" yorumuma cevap vermek için evet, C # hız artışlarının çoğu daha iyi bir donanımdan geliyor, ancak .NET framework ve C # compiler ilerledikçe, orada bazı hızlandırmalar oldu.

"Oyunlar motorla aynı dilde yazılmış" hakkında, yorumuna bağlı. Bazıları, ancak birçoğu dillerin melezinde yazılmıştır. Unreal, UnrealScript ve C ++ yapabilir, Unity C # Javascript ve Boo yapar, C veya C ++ ile yazılmış birçok motor Python veya Lua'yı betik dili olarak kullanır. Orada basit bir cevap yok.

Ve "oyununuz 200fps veya 120fps'de çalışıyorsa kimin umurunda olduğunu umursam" demem için beni rahatsız ettiğinden dolayı, eğer oyun 60fps'den daha hızlı çalışıyorsa, ortalama monitör bile yenileyemediğinden muhtemelen cpu zamanını boşa harcıyorsunuzdur. hızlı. Bazı yüksek sonlar ve yeni olanlar bunu yapar, ancak standart değildir (henüz ...).

Ve "onlarca yıllık teknolojiyi görmezden gelme" sözleriyle ilgili olarak, hala 20'li yaşlarımın başındayım, bu nedenle geriye doğru ekstrapolasyon yaparken, çoğunlukla daha yaşlı ve daha deneyimli programcıların söylediklerini tekrarlıyordum. Açıkçası, böyle bir sitede itiraz edilecek, ancak dikkate değer.


4
" Windows için herhangi bir şey C # " - Ah, bu yanlış bir durum. Hatta bir örnek bile sunuyorsun. Birlik. AFAIK C # API sağladığı için yazılmaz, çünkü dil uyarlanabilir. Gerçekten iyi tasarlanmış. Ve c ++ 'dan daha çok hoşlanıyorum, ancak kredilerin verildiği yerde verilmesi gerekiyor. Belki C # 'yı .NET ile karıştırdınız? Sık sık beraber takılıyorlar.
luk32,

2
"Hatta Birlik bile tüm C # değil, onun büyük parçaları C ++" Ve? Unity'deki oyunlar sıklıkla C # kullanır ve şimdilerde oldukça uzun zamandır kullanılmaktadır. C # 'nın yakın zamanda hızlara ulaştığını öne sürmek ya daha fazla içeriğe ihtiyaç duyuyor ya da bu on yıllardır teknolojiye kör olma riskini taşıyor.
NPSF3000,

2
Neredeyse her büyük oyun kullandığı motorun dilinde yazılmıştı: çoğaltılması gereken iş miktarı o kadar büyüktü ki, başka hiçbir teknik kaygı bile dikkate almaya değer değildi. Rendering gerçekten pahalıdır, ancak günümüzde hepsi gölgelendiricilere yazılmıştır ve mantık döngüsünün dili anlamsızdır.
Peter Taylor

2
C # her zaman JIT tarafından derlendi (Java'nın aksine, yorumunuzun doğru olduğu yer) ve ne yaptığınızı biliyorsanız, C ++ 'a gitmek için çok benzer bir işlem hızına sahipti. Bu 2003 - yakın zamanda düşüneceğim bir şey değil. Ham hız, oyunlar için ana sorun değildir (özellikle GPU'da programlanabilir gölgelendiricilerle), C # gibi dilleri zaman zaman az ya da çok popüler yapan başka şeyler de vardır. İki ana konu API (yoğun C-yönelimli ve arayüz oluşturma pahalı olabilir) ve GC'dir (çoğunlukla gecikme sorunları için ham verim değil).
Luaan

1
@gbjbaanb Sadece CPU'ların daha hızlı olması önemli değil; büyük bir sorun, C ++ ve C'nin derleyicilerini ve çalışma sürelerini mükemmelleştirmek için yıllarca sürdüğü, Java ise temelde sıfırdan başlayarak (öncelikle çok platformlu bir platform olarak tasarlandı). Sanal Makine geliştikçe (örneğin, tercümandan bir JIT derleyicisine geçiş, gelişmiş GC ...), Java uygulamalarının performansı da arttı. C / C ++ 'un hala sahip olduğu birçok şey "hiçbir şeyin kırılmamasını ümit edelim" yaklaşımı içindedir - "gereksiz" olarak kabul edilen birçok kontrolden kaçınır. Ama yine de çok büyük bir hafıza domuz - aslında, CPU kullanımındaki gelişmeler genellikle daha kötü bellek performansı anlamına geliyordu :)
Luaan

13

C’nin güvenilmez olduğunu iddia etmeniz komik, çünkü "göstericileri var". Bunun tersi doğrudur: Java ve C # pratik olarak sadece işaretçilere sahiptir (yerel olmayan türler için). Java’daki en yaygın hata muhtemelen Null Pointer İstisnasıdır (bkz. Https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare ). İkinci en yaygın hata, muhtemelen kullanılmayan nesnelere (örneğin, kapalı Diyaloglar atılmamıştır) bu nedenle bırakılamayan, sürekli büyüyen bir bellek ayak izi ile uzun süre çalışan programlara yol açan gizli referanslar tutmaktır.

C # ve Java'yı daha güvenli ve iki farklı şekilde daha güvenli hale getiren iki temel mekanizma vardır:

  • Çöp toplama, programın atılan nesnelere erişme girişiminde bulunma olasılığını azaltır. Bu, programın beklenmedik şekilde sonlandırılması olasılığını azaltır. C'nin aksine, Java ve C # varsayılan olarak yerel olmayan verileri dinamik olarak tahsis eder. Bu, program mantığını aslında daha karmaşık hale getirir, ancak yerleşik çöp toplama - bir ücret karşılığında - zor kısmı üstlenir.

Son C ++ 'akıllı işaretçiler, programcılar için bu işi kolaylaştırıyor.

  • Java ve C #, ayrıntılı bir çalışma süresi tarafından yorumlanan / yürütülen bir ara kod oluşturur. Bu, bir güvenlik düzeyi ekler çünkü çalışma zamanı bir programın yasadışı faaliyetlerini tespit edebilir. Program güvenli bir şekilde kodlanmış olsa bile (her iki dilde de mümkündür), teoride ilgili çalışma süresi sisteme “dağılmasını” önler.
    Çalışma süresi, örneğin denenmiş tampon taşmalarına karşı koruma sağlamaz, ancak teoride bu tür programların istismarına izin vermez. C ve C ++ ile ise, programcının istismarları önlemek için güvenli bir şekilde kodlaması gerekir. Bu genellikle hemen elde edilemez, ancak gözden geçirmeler ve yinelemeler gerekir.

Ayrıntılı çalışma zamanının aynı zamanda bir güvenlik riski olduğunu da belirtmekte fayda var. Bana göre, yeni keşfedilen güvenlik sorunları nedeniyle Oracle JVM'yi birkaç haftada bir güncelliyor. Elbette, JVM'yi doğrulamak tek bir programdan daha zordur .

Bu nedenle, ayrıntılı bir çalışma süresinin güvenliği belirsizdir ve bir dereceye kadar aldatıcıdır: Ortalama C programınız, incelemeler ve yinelemeler ile makul derecede güvenli hale getirilebilir. Ortalama Java programınız sadece JVM kadar güvenlidir; bu, gerçekten değil. Asla.

Hakkında gets()yazdığınız makale , temel dilden değil, bugün farklı şekilde uygulanacak olan tarihi kütüphane kararlarını yansıtmaktadır.


3
Bence asıl yazarın amacı, C’de bu işaretçiler üzerinde denetlenmeyen bir eylemde bulunabildiğiniz. Java’da hemen hoş bir istisna elde edersiniz - C’de, uygulama durumunuz bozulana kadar geçersiz bir konum okuduğunuzu fark etmeyebilirsiniz.
Sam Dufel,

1
Ayrıca, stackoverflow.com/questions/57483/… - Java'nın "pratik olarak yalnızca referansları" olduğunu söylemek daha doğru olacaktır.
Sam Dufel

4
Açıkça işaretçilerden kaçınma girişimlerinden kaynaklanan her türlü ilginç böceği gördüm. Genellikle asıl mesele, kopya ve referans arasındaki karışıklıktır. C'de, size bir imleci ilettiğimde, değiştirmenin orijinali etkileyeceğini biliyorsunuzdur. İşaretçilerden kaçınma girişimlerinin bazıları, bu ayrımın önüne geçerek, derin kopyaların labirentine, sığ kopyalara ve genel karışıklığa yol açmaktadır.
Arlie Stephens,

Oracle’ın JVM’nin (sömürülebilir güvenlik açığı kanaması açısından) berbat olduğunu ve bu nedenle genel olarak yönetilen dillerin çalışma sürelerinin, yönetilen bir dil kullanmaktan kaçınmaktan daha fazla güvenlik kaygısı getirdiğini iddia etmek, Adobe Flash’ın bir güvencesizlik ve program kaynağı olarak korkunç olduğunu söylemek gibi Bir web sitesinden video ve animasyon oynatma işleminin gülünç derecede güvensiz olması gerekir. Java çalışma sürelerinin tümü neredeyse Oracle / Sun'ın 1990'ların vintage JVM'nin kötü kullanımı kadar kötü değildir ve yönetilen tüm diller Java değildir. (Açıkçası, açıkçası.)
çoğunlukla

@halfinformed Kuyu; Bir programın sadece çalışma zamanı kadar güvenli olduğunu ve "ortalama" (okuma: küçük-ish) programının bir çaba ile bir bayt kodu yorumlayıcısı gibi herhangi bir büyük çalışma zamanından daha güvenli yapılabileceğini söyledim. Bu ifade inkar edilemez görünüyor. Belirli bir tek başına çalışan bir programın veya belirli bir çalışma süresinin diğerinden daha az ya da çok güvenli olup olmadığı, karmaşıklık ve tasarım, kodlama ve bakım kalitesine bağlıdır. Örneğin, sendmail’in Oracle’ın Java VM’sinden daha güvenli olduğunu söyleyemem; ancak qmail olabilir.
Peter A. Schneider

10

"Güvenlik" hızlandığından, "daha güvenli" diller daha yavaş performans gösterir.

Neden C veya C ++ gibi "tehlikeli" bir dil kullandığınızı, birisinin size Python veya Java gibi bir video sürücüsü veya benzeri bir şey yazmasını ve "güvenlik" hakkında ne düşündüğünüzü görmesini isteyin.

Cidden, pikselleri, kayıtları vb. İşleyebilmek için makinenin çekirdek belleğine yakın olmanız gerekir ... Java ya da Python bunu herhangi bir performansa uygun hızda yapamaz ... C ve C ++ işaretçiler ve benzerleriyle bunu yapmanıza izin verin ...


20
Genel olarak emniyet maliyetlerinin hızlandığı doğru değildir . En güvenli diller, çeklerin çoğunu derleme zamanında yapar. O'Caml, Ada, Haskell, Rust hepsi ortalama çalışma zamanı hızı açısından C'nin çok arkasında izlemiyor. Genellikle yaptıkları şey , program büyüklüğü, bellek verimliliği, gecikme ve açık bir şekilde derleme süresinde önemli bir ek yüktür. Ve evet, metale yakın şeylerle ilgili güçlükleri var. Ama bu gerçekten bir hız sorunu değil.
leftaroundabout

6
Ayrıca, C düşündüğünüzü yapmaz. C soyut bir makinedir . Size hiçbir şeye doğrudan erişim sağlamaz - bu iyi bir şeydir. Sizden ne kadar C'nin saklandığını görmek için modern meclise bile bakamazsınız - modern meclis (örn. TASM), C geliştirildiğinde yüksek bir dil olarak kabul edilirdi. Birisi "güvenli" bir dilde sürücüler yazarsa çok mutlu olurum, teşekkür ederim - bu BSOD'lardan ve donmalardan kaçınmaya yardımcı olur, güvenlik deliklerinden bahsetmeden :) :) Ve en önemlisi, çok daha güvenli olan sistem dilleri var. C den
Luaan

3
@Wintermute Güvenlik özelliklerinin nasıl bir hız gerektirdiğine ilişkin yorumlar yapmadan önce gerçekten Rust'a bakmak istiyorsunuz. C'nin düşük seviyeli tip sistemi aslında , derleyicilerin yapabileceği çok faydalı optimizasyonları engeller (özellikle büyük bir projenin hiçbir yerde katı takma adlarını ihlal etmekten kaçınmayı engellediğini düşünürken ).
Voo

7
@Wintermute Evet, C / C ++ 'ı genel bir performansa neden olmadan daha güvenli hale getiremediğiniz efsanesi çok ısrarcıdır, bu yüzden bunu oldukça ciddiye alıyorum (bunun kesinlikle doğru olduğu bazı alanlar var ( sınır kontrolü)). Şimdi, Rust neden daha yaygın değil? Tarihçe ve karmaşıklık. Rust hala nispeten yeni ve Rust icat edilmeden önce C dilinde yazılan en büyük sistemlerin çoğu - çok daha güvenli olsalar bile, bir milyon LOC'yi yeni bir dilde tekrar yazmayacaksınız. Ayrıca her programcı ve köpeği C, Rust biliyor mu? Yeterli insanı bulmak için iyi şanslar.
Voo,

3
@Voo Dogs C yapıyor mu? to Rust doğru yapmak ... "D" için de aynı arttırmayı yapabilirim :)
Wintermut3

9

Yukarıdakilerin yanı sıra, C'yi diğer diller için ortak bir kütüphane olarak kullanan oldukça yaygın bir kullanım durumu vardır.

Temel olarak, hemen hemen tüm dillerin C için bir API arayüzü var.

Basit bir örnek, Linux / IOS / Android / Windows için ortak bir uygulama oluşturmaya çalışın. Dışarıdaki tüm araçların yanı sıra, sonuçta C'de bir çekirdek kütüphanesi yapmak ve her ortam için GUI'yi değiştirmek oldu.

  • IOS: ObjectiveC, C kütüphanelerini yerel olarak kullanabilir
  • Android: Java + JNI
  • Linux / Windows / MacOS: GTK / .Net ile yerel kütüphaneleri kullanabilirsiniz. Python, Perl, Ruby kullanıyorsanız, her birinin yerel API arayüzleri vardır. (JNI ile tekrar Java).

Benim iki Sentim,


PHP'yi kullanmayı sevmemin nedenlerinden biri, PHP'nin hemen hemen tüm kitaplıklarının aslında C dilinde yazılmış olması - neyse ki öyle ya da PHP dayanılmaz derecede yavaş olurdu çünkü :) PHP korkusuzca özensiz kod yazmak için harika 'tehlikeli' bir şey yapmak (ve bu yüzden her şeyden çok daha fazla PHP kodu yazmaya meyilliyim - özensiz kodu severim !: D), ancak bu işlev çağrılarının birçoğunun altında iyi olmanın güvenilir olduğunu bilmek güzel C, bazı performans artışı sağlamak için C kütüphaneleri ;-) Buna karşın, C'ye özensiz kod yazmak büyük bir
hayırdır

7

C ile ilgili temel bir zorluk, adın aynı sözdizimine sahip fakat çok farklı bir anlambilimine sahip bir dizi lehçeyi tanımlamak için kullanılmasıdır. Bazı lehçeler diğerlerinden daha güvenlidir.

Aslen Dennis Ritchie tarafından tasarlandığı gibi C ifadesinde, C ifadeleri genellikle makine talimatlarıyla öngörülebilir şekilde eşleştirilirdi. C imzalı aritmetik taşma gibi şeyler gerçekleştiğinde farklı davranış gösteren işlemciler üzerinde çalışabildiğinden, aritmetik taşma durumunda bir makinenin nasıl davranacağını bilemeyen bir programcı, o makinede çalışan C kodunun da nasıl davranacağını bilemezdi. Bir makinenin belirli bir şekilde davrandığı biliniyorsa (örneğin, sessiz ikinin tamamlayıcı sarımı), o zaman bu makine üzerindeki uygulamalar da aynı şekilde olacaktır. C'nin hızlı olmasının ünü kazanmasının sebeplerinden biri, programcıların bir platformun son vaka senaryolarındaki doğal davranışının kendi gereksinimlerine uygun olacağını bilmesi durumunda, programcının veya derleyicinin bu tür senaryolar oluşturmak için kod yazmasına gerek olmamasıydı. .

Ne yazık ki, derleyici yazarları, Standardın bu gibi durumlarda ne yapılması gerektiği konusunda bir zorunluluk getirmediği için (öngörülebilir şekilde davranamayan donanım uygulamalarına izin vermek amaçlanan gevşeklik), derleyicilerin yasaları ihlal eden kodlar üretmekte özgür hissetmeleri gerektiği görüşündedir. zaman ve nedensellik.

Gibi bir şey düşünün:

int hey(int x)
{
   printf("%d", x);
   return x*10000;
}
void wow(int x)
{
  if (x < 1000000)
    printf("QUACK!");
  hey(x);    
}

Hyper-modern (ancak modaya uygun) derleyici teorisi derleyicinin "QUACK!" koşulsuz bir şekilde, koşulun yanlış olduğu herhangi bir durumda, program, sonuçta yine de göz ardı edilecek olan bir çarpma gerçekleştiren tanımsız davranışa neden olacaktı. Standart, böyle bir durumda bir derleyicinin sevdiği bir şeyi yapmasına izin vereceğinden, derleyicinin "QUACK!" Çıktısına izin verir.

C, montaj diline göre daha güvenliyken, hiper-modern derleyiciler kullanıldığında bunun tersi geçerlidir. Assembly dilinde, tamsayı taşması bir hesaplamanın anlamsız bir sonuç vermesine neden olabilir, ancak çoğu platformda etkilerinin kapsamı olacaktır. Sonuçlar yine de göz ardı edilirse, taşma önemli olmaz. Bununla birlikte, hiper-modern C'de, normalde Tanımlanmamış Davranışın “iyi huylu” formları bile olsa (örneğin, yok sayılan biten bir hesaplamada bir tamsayı taşması gibi) keyfi programın yürütülmesine neden olabilir.


1
hiper-modern bir derleyicide bile, C diziler üzerinde sınır kontrolü yapmaz. Öyle olsaydı, bu dilin tanımı ile uyumlu olmazdı. Bu gerçeği bazen dizinin ortasına ek bir gösterici ile negatif indislere sahip olmak için diziler yapmak için kullanıyorum.
robert bristow-johnson

1
“QUACK!” Üreten örneğinizin kanıtını görmek isterim. kayıtsız şartsız. x kesinlikle karşılaştırma noktasında 1000000'den büyük olabilir ve daha sonra taşma ile sonuçlanacak değerlendirme bunu engellemez. Dahası, taşma çarpanının kaldırılmasını sağlayan inline etkinse, örtülü aralık kısıtlamaları hakkındaki argümanınız geçerli olmaz.
Graham

2
@ robertbristow-johnson: Aslına bakılırsa, Standart açıkça açıkça belirtildiği gibi, örneğin int arr[5][[5], bir erişim girişiminin arr[0][5]Tanımsız Davranışa yol açacağını söylüyor . Böyle bir kural , değeri göz önüne alınmaksızın, 4'e eşit olacak arr[1][0]=3; arr[0][i]=6; arr[1][0]++;çıkarım gibi bir şey verilen bir derleyiciyi mümkün kılar . arr[1][0]i
supercat,

2
@ robertbristow-johnson: Derleyici, boşlukları olmayan bir yapıya diziler dizilse bile, bu dizilerden birinin endekslenmesinin bir diğerini etkilemesi garanti edilmez. Gcc'nin bu kodu nasıl ele alacağına dair bir örnek için godbolt.org/g/Avt3KW adresine bakın .
Supercat,

1
@ robertbristow-johnson: Meclisin ne yaptığını açıklamak için yorum yaptı. Derleyici, kodun 1'i s-> arr2 [0] 'da sakladığını ve ardından s-> arr2 [0]' ı artırdığını görür, bu nedenle gcc bu iki işlemi birleştirerek yazma yazma olasılığını göz önünde bulundurmadan kodun değerini 2 değerine kaydederek birleştirir. s-> arr1 [i], s-> arr1 [0] değerini etkileyebilir (çünkü Standarda göre yapamaz).
Supercat

5

Tarihsel sebepler. Sık sık yeni kod yazmak istemiyorum, çoğunlukla on yıllardır devam eden eski şeyleri sürdürüp genişletiyorum. Sadece C ve Fortran olmadığı için mutluyum.

Bir öğrenci "dediği zaman neden bu kadar korkunç X yapıyorsun?" Diyorsa sinirlenebilirim. X, sahip olduğum iş ve faturaları çok iyi ödüyor. Ara sıra Y yaptım ve eğlenceliydi, ama X çoğumuzun yaptığı şey.


5

"Tehlikeli" nedir?

C'nin "tehlikeli" olduğu iddiası, dil ateşi savaşlarında (çoğunlukla Java ile karşılaştırıldığında) sıkça bir konuşma noktasıdır. Bununla birlikte, bu iddia için kanıt belirsizdir.

C, belirli özelliklere sahip bir dildir. Bu özelliklerden bazıları, diğer dil türlerinde izin verilmeyen bazı hata türlerine izin verebilir (C'nin bellek yönetimi riski genellikle vurgulanır). Ancak, bu C diğer dillere daha tehlikeli bir argüman olarak aynı değildir genel . Bu konuda ikna edici kanıtlar sunan hiç kimsenin farkında değilim.

Ayrıca, "tehlikeli" içeriğe bağlıdır: ne yapmaya çalışıyorsun ve ne tür risklerden endişe ediyorsun?

Birçok bağlamda C'yi üst düzey bir dilden daha "tehlikeli" olarak kabul ediyorum, çünkü temel işlevsellikten daha fazla manüel uygulama yapmanız ve hata riskini artırmanız gerekiyor. Örneğin, bazı temel metin işlemlerini yapmak veya C dilinde bir web sitesi geliştirmek genellikle aptalca olacaktır, çünkü diğer dillerde bunu çok daha kolaylaştıran özelliklere sahiptir.

Bununla birlikte, görev kritik sistemler için C ve C ++ yaygın olarak kullanılır, çünkü daha doğrudan kontrol kontrolü olan daha küçük bir dil bu bağlamda "daha güvenli" olarak kabul edilir. Gönderen çok iyi yığın taşması cevap :

Her ne kadar C ve C ++ bu tür bir uygulama için özel olarak tasarlanmamış olsa da, çeşitli nedenlerden dolayı gömülü ve güvenlik açısından kritik öneme sahip yazılımlar için yaygın olarak kullanılırlar. Notun ana özellikleri bellek yönetimi (örneğin, çöp toplamak zorunda kalmamanızdan kaçınmanızı sağlar), basit, iyi hata ayıklanmış çekirdek çalışma zamanı kitaplıkları ve olgun araç desteğidir. Günümüzde kullanımda olan gömülü geliştirme aracı zincirlerinin çoğu, ilk olarak 1980'lerde ve 1990'larda, bunun şu andaki teknoloji olduğu ve o dönemde yaygın olan Unix kültüründen geldiği için geliştirilmiştir, bu nedenle bu araçlar bu tür çalışmalar için popüler olmaya devam etmektedir.

Hataları önlemek için manuel bellek yönetimi kodunun dikkatlice kontrol edilmesi gerekirken, çöp toplamaya bağlı dillerde bulunmayan uygulama yanıt süreleri üzerinde bir dereceye kadar kontrol sağlar. C ve C ++ dillerinin temel çalışma zamanı kitaplıkları nispeten basit, olgun ve iyi anlaşılır, bu nedenle mevcut en kararlı platformlar arasında yer alıyor.


2
Hiper-modern C'nin aynı zamanda, doğal makine kod işlemlerinin olacağı kenar durumlardan bağımsız olarak sürekli olarak C işlemlerini makine kodu işlemlerine çeviriyor gibi sürekli davranan sanki gerçek C düzeyini içeren C düzeyindeki lehçelerini meclis dilinden ya da orijinal düşük seviye lehçelerinden daha tehlikeli olduğunu söyleyebilirim. Davranış tanımlamış ancak C standardı herhangi bir şart getirmemiştir. Bir tamsayı taşmasının zaman ve nedensellik kurallarını azaltabildiği hiper-modern yaklaşım, güvenli kod üretmeye daha az elverişli görünmektedir.
supercat

5

Mevcut cevaplara eklemek için, göreceli güvenliklerinden dolayı projeniz için Python veya PHP'yi seçeceğinizi söylemek gayet iyi ve güzel. Fakat birileri bu dilleri uygulamalı ve bunu yaptıklarında muhtemelen C'de yapacaklardır (Ya da onun gibi bir şey.)

- insanlar C kullanın Yani bu yüzden daha az tehlikeli araçları oluşturmak için size kullanmak istiyorum.


2

Sorunuzu tekrar ifade etmeme izin verin:

[Aracı] öğrenmeyi düşünüyorum.

Fakat insanlar [tehlikeli] olarak kullanabiliyorlarsa neden [araç] (veya [ilgili araç]) kullanıyorlar?

Herhangi bir ilginç araç, programlama dilleri dahil, tehlikeli bir şekilde kullanılabilir. Sen öğrenmek sen böylece daha yapmak (Aracı kullandığınızda daha az tehlike oluşturulduğunu ve bu yüzden) daha fazlası. Özellikle, aleti, o alet için iyi olan şeyi yapabilmeniz için öğrenirsiniz (ve belki de bu alet, tanıdığınız aletlerin en iyi aleti olduğunda bunu tanır).

Örneğin, 6 mm çapında, 5 cm derinliğinde, bir tahta parçası içine silindirik bir delik açmanız gerekirse, bir matkap LALR ayrıştırıcısından çok daha iyi bir araçtır. Bu iki aracın ne olduğunu biliyorsanız, hangisinin doğru araç olduğunu bilirsiniz. Zaten matkap kullanmayı biliyorsanız, boşluk !, delik.

C sadece başka bir araçtır. Bazı görevler için diğerlerinden daha iyidir. Buradaki diğer cevaplar buna değiniyor. Biraz C öğrenirseniz, ne zaman doğru alet olduğunu ve ne zaman olmadığını tanımaya başlayacaksınız.


Bu sorunun cevabı neden soruların “öncelikli görüşe dayalı” olarak atılmasının nedenidir. C'nin avantajları olduğunu söyleme, onların ne olduğunu söyleme!
reinierpost

1

C öğrenmeyi düşünüyorum

C'yi öğrenmemek için belirli bir neden yok ama C ++ 'ı önerebilirim. C'nin yaptığı şeylerin çoğunu sunar (çünkü C ++, C'nin süper bir kümesidir) ve büyük miktarda "ekstra" içerir. C ++ 'dan önce C öğrenmesi gerekli değildir - onlar etkili bir şekilde ayrı dillerdir.

Başka bir deyişle, C bir ağaç işleme aletleri seti olsaydı, muhtemelen şöyle olurdu:

  • çekiç
  • çiviler
  • el testeresi
  • Matkap
  • blok zımpara makinesi
  • keski (belki)

Bu araçlarla her şeyi inşa edebilirsiniz - ama güzel olan her şey potansiyel olarak çok zaman ve beceri gerektirir.

C ++, yerel nalburdan elektrikli el aletleri topluluğudur.

Başlamak için temel dil özelliklerine sadık kalırsanız, C ++ 'ın ek öğrenme eğrisi azdır.

Ancak insanlar 'tehlikeli' olarak kullanılıyorsa neden C (veya C ++) kullanıyorlar?

Çünkü bazı insanlar IKEA'dan mobilya istemiyor. =)

Cidden, C veya C ++ 'dan "daha yüksek" olan birçok dil, bazı yönlerden onları (potansiyel olarak) "kolay" yapan şeylere sahip olsa da, bu her zaman iyi bir şey değildir. Bir şeyin yapılmasından hoşlanmazsanız veya bir özellik sağlanmazsa, bu konuda yapabileceğiniz fazla bir şey yoktur. Öte yandan, C ve C ++, birçok şeye doğrudan erişebildiğiniz (özellikle donanım ya da OS-akıllıca) ya da başka bir şekilde yapamayacağınız şekilde kendi başınıza yaratabileceğiniz yeterli "düşük seviye" dil özellikleri (işaretçiler dahil) sağlar. uygulandığı gibi diller.

Daha spesifik olarak, C, birçok programcı için arzu edilen kılan aşağıdaki özelliklere sahiptir:

  • Hız - Yıllar boyunca göreceli basitliği ve derleyici optimizasyonları nedeniyle, doğal olarak çok hızlıdır. Ayrıca, birçok insan dili kullanırken, hedefleri daha da hızlı kılan özel hedeflere giden birçok kısayol bulmuşlardır.
  • Boyut - Hız için listelenenlere benzer nedenlerle, C programları çok küçük yapılabilir (hem uygulanabilir boyutta hem de bellek kullanımı açısından), bu da sınırlı belleğe sahip ortamlarda (yani gömülü veya mobil) istenebilir.
  • Uyumluluk - C uzun zamandır etrafta ve herkesin bunun için araçları ve kütüphaneleri var. Dilin kendisi de seçici değildir - bir işlemciden bir şeyleri tutmak için talimatlar ve hafıza yürütmesini bekler ve bu onunla ilgilidir.

    Ayrıca, bir Uygulama İkili Arabirimi (ABI) olarak bilinen bir şey var . Kısacası, programların bir Uygulama Kodu Arabirimi'ne (API) göre avantajları olabilecek makine kodu düzeyinde iletişim kurmasının bir yoludur . C ++ gibi diğer diller bir ABI'ye sahip olsa da, genellikle bunlar C'lerden daha az aynıdır (üzerinde anlaşılırlar), bu nedenle C, bir sebepten dolayı başka bir programla iletişim kurmak için bir ABI kullanmak istediğinizde iyi bir temel dili oluşturur.

Programcılar neden Java veya Python veya Visual Basic gibi derlenmiş başka bir dil kullanmıyorlar?

Verimlilik (ve bazen belleğe nispeten doğrudan erişim olmadan uygulanamayan bellek yönetimi programları).

İşaretçilerle doğrudan belleğe erişme, kirli pençelerinizi küçükler ve sıfırlar üzerine doğrudan dolabınızdaki sıfırlar ve sıfırlar üzerine koyabileceğiniz ve öğretmenlerin sadece oyuncakları dağıtması için beklemek zorunda kalmayacağınız bir çok temiz (genellikle hızlı) hileci sunar çalma saatinde tekrar toplayın.

Kısacası, malzeme eklemek potansiyel olarak gecikme yaratır veya istenmeyen karmaşıklığı beraberinde getirir.

Komut dosyası dilleri ve bu ilklerle ilgili olarak, ikincil programların C (veya herhangi bir derlenmiş dilin) ​​olduğu kadar verimli çalışmasını gerektiren dilleri almak için çok çalışmak zorundasınız. Hareket halindeyken bir tercüman eklemek doğal olarak azaltılmış çalıştırma hızı ve arttırılmış bellek kullanımı olasılığını ortaya çıkarır çünkü karışıma başka bir program ekliyorsunuz. Programlarınızın verimliliği, bu programın verimliliğine, orijinal program kodunuzu ne kadar iyi yazdığınıza (zayıf =) bağlıdır. Programınızdan bahsetmiyorum bile ikinci programa bile tamamen bağımlıdır. Bu ikinci program belirli bir sistemde bir nedenden dolayı yok mu? Kod yok git.

Aslında, "ekstra" bir şey eklemek, potansiyel olarak kodunuzu yavaşlatır veya karmaşıklaştırır. "Korkutucu işaretçiler olmadan" dilde, her zaman arkanızda temizlemek veya başka şeyler yapmak "güvenli" yollarını anlamaya kod diğer bit bekliyor - Programınız çünkü hala yapılabilir olabilir aynı bellek erişimi işlemlerini yapıyor işaretçileri. Sen sadece bunu yapan kişi değilsin (bu yüzden bunu yapamazsın, dahi = P).

Tehlikeli derken, işaretçilerle ve benzeri şeylerle demek istiyorum. [...] Yığın Taşması sorusu gibi Alınan fonksiyon neden kullanılmaması gereken çok tehlikelidir?

Kabul edilen cevaba göre:

"1999 ISO C standardına kadar dilin resmi bir parçası olarak kaldı, ancak 2011 standardı tarafından resmen kaldırıldı. Çoğu C uygulaması hala onu destekliyor, ancak en azından gcc kullanan herhangi bir kod için bir uyarı veriyor."

Bir dilde bir şey yapılabileceği için yapılması gereken aptalcadır. Dillerin düzeltilen kusurları vardır. Eski kod ile uyumluluk nedenleriyle, bu yapı hala kullanılabilir. Ancak bir programcının kullanmaya zorlayan hiçbir şey yoktur () ve () aslında bu komut daha güvenli alternatiflerle değiştirilir.

Daha da önemlisi, gets () ile olan sorun başlı başına bir işaretçi sorunu değildir. Belleği nasıl güvenli bir şekilde kullanacağınızı bilmeyen bir komutla ilgili bir sorun. Soyut anlamda, tüm bunlar işaretçi meseleleridir - sizin yapmanız gerekmeyen şeyleri okumak ve yazmak. İşaretçilerle ilgili bir sorun değil; işaretçi uygulamasında bir sorun var.

Netleştirmek için, işaretçiler yanlışlıkla istemediğiniz bir hafıza konumuna erişene kadar tehlikeli değildir. Ve o zaman bile bu, bilgisayarınızın erimesini veya patlamasını garanti etmez. Çoğu durumda, programınız işlevini kesecektir (doğru).

Bunun nedeni, işaretçilerin bellek konumlarına erişim sağlaması ve veri ile yürütülebilir kodun birlikte bellekte bulunması nedeniyle, belleği doğru şekilde yönetmek istediğinizde yanlışlıkla bozulma tehlikesi vardır.

Bu noktada, gerçekten doğrudan belleğe erişim işlemleri genellikle yıllar önce sahip olduklarından genel olarak daha az fayda sağladığından, C ++ gibi çöp toplanmamış diller bile, bellek verimliliği ile güvenlik arasındaki boşluğu doldurmaya yardımcı olmak için akıllı işaretçiler gibi şeyler ortaya koymuştur .

Özet olarak, güvenle kullanıldığı sürece işaretçiden korkmak için çok az neden vardır. Sadece South Park'ın Steve "The Crocodile Hunter" (Irwin) sürümünden bir ipucu alın - baş parmağınızı croc'ların çukurlarına sokmayın .


2
C yerine C ++ öğrenme önerisiyle aynı fikirde değilim. İyi C ++ yazmak iyi C yazmaktan daha zor, C ++ okumak C okumaktan daha zor. Bu nedenle C ++ 'nın öğrenme eğrisi çok daha zor. "C ++ süper bir C kümesidir" Bu, botların bir üst terlik marketi olduğunu söylemek gibi. Farklı avantajları ve kullanım alanları vardır ve her biri diğerinin sahip olmadığı özelliklere sahiptir.
martinkunev

"İyi C ++ yazmak, iyi C yazmaktan daha zordur" - Kesinlikle. =) "[R] C ++ 'ı okumak, C okumaktan çok daha zor." - Herhangi bir gelişmiş programlama sihirden ayırt edilemez ;-) İki kuruşum, C ++' ın kendisine yardımcı olacak fazla bir şey yapmamasına rağmen, dile bağlı olarak programlayıcıya bağlı olması. Bu kategoride. “C ++ 'nın öğrenme eğrisi çok daha dik.” - Uzun vadede, evet. Kısa vadede, daha az yani (benim görüşüme göre). Önceden, C ve C ++ 'daki çoğu temel dil kursunun, C ++ için sınıflar hariç, kabaca aynı genel malzeme türlerini kapsaması olasıdır.
Anaksunaman

2
"Farklı avantajları ve kullanımları var ve her biri diğerinin sahip olmadığı özelliklere sahip." - Belirtildiği gibi "C [.] 'Yi öğrenmemek için özel bir sebep yok." C iyi bir dil ve buna bağlı kalıyorum. OP ya da başka birine uygunsa, öğrenmeyi tamamen destekliyorum. =)
Anaksunaman

C öğrenme, makinenin nasıl çalıştığını öğretir (tamamen aşağı, ancak metale bir adım daha yakın). Bu onu öğrenmek için çok iyi bir sebep.
Ajan_L

1

Her zaman olduğu gibi, programlama dili sadece problem çözmenin bir sonucudur. Aslında sadece C'yi değil, bir çok farklı dili (ve bir bilgisayarı programlamanın diğer yollarını (GUI araçları veya komut yorumlayıcıları da olabilir)) problem çözerken kullanmak için iyi bir araç kutusuna sahip olmayı öğrenmelisiniz.

Bazen bir sorunun Java varsayılan kitaplıklarında bulunan bir şeye iyi bir şekilde katlandığını göreceksiniz, bu durumda, kaldıraç için Java'yı seçebilirsiniz. Diğer durumlarda, Windows'ta .NET çalışma zamanlarında çok daha basit olan bir şey yapmanız gerekebilir, bu nedenle C # veya VB kullanabilirsiniz. Sorununuzu çözen grafiksel bir araç veya komut dosyası olabilir, sonra bunları kullanabilirsiniz. Belki birden fazla platformda bir GUI uygulaması yazmanız gerekir, Java JDK'da bulunan kütüphaneler göz önüne alındığında bir seçenek olabilir, ancak daha sonra yine bir hedef platformda bir JRE olmayabilir, bu nedenle belki C ve SDL (veya benzerlerini) seçin.

C genel olarak, küçük ve hızlı olduğu ve aynı zamanda makine kodunu derlediği için bu araç setinde önemli bir konuma sahiptir. Aynı zamanda güneş altındaki her platformda desteklenir (ancak yeniden derlenmeden).

Alt satırda, mümkün olduğunca çok sayıda araç, dil ve paradigma öğrenmelisiniz.

Lütfen zihniyetten uzak durun: "Ben bir X programcısıyım" (X = C, C ++, Java, vb.)

Sadece "Ben programcıyım" kullanın.

Bir programcı sorunları çözer ve iş yükünü gerçekleştirmeleri için makinelere talimat vererek algoritmalar tasarlar. Hikayenin sonu. Bu dille alakası yok. En önemli yeteneğiniz, problem çözme ve yapılandırılmış problemlerin mantıksal dağılmasıdır, dil becerisi / seçimi her zaman ikincil ve / veya problemin niteliğinin bir sonucudur.

C ile ilgileniyorsanız ilginç bir yol, beceri setinizi Go ile genişletmektir. Go, çöp toplama ve ara yüzleri ile gerçekten geliştirilmiş bir C'dir, ayrıca C'nin birçok faydasını da (işaretçi aritmetik ve makine kodunu derleme gibi) ortaya çıkaran güzel bir iş parçacığı modeli / kanalına sahiptir.


0

Ne yapmak istediğine bağlı. C, montaj dili için bir yedek olarak tasarlanmıştır ve makine diline en yakın olan en üst düzey dildir. Bu nedenle, boyut ve performans açısından düşük genel giderlere sahiptir ve sistem programlaması ve küçük bir alan kaplayan ve altta yatan donanıma yaklaşan diğer görevler için uygundur.


0

En verimli ayırıcıları ve veri yapılarını etkin bir şekilde uygulamak için sıklıkla gerekli olacak şekilde, homojen veri toplama belleği olarak bellek, bit ve bayt düzeyinde çalışırken, sahip olunacak hiçbir güvenlik yoktur. Güvenlik, ağırlıklı olarak güçlü bir veri türü ile ilgili kavramdır ve bir bellek ayırıcısı veri türleriyle çalışmaz. Potansiyel olarak bir veri türünü temsil eden aynı bit ve baytlarla bir dakika ve sonra bir araya gelmek için bit ve baytlarla çalışır.

Bu durumda C ++ kullanmanızın bir önemi yoktur. İşaretçilerden static_castsyayın yapmak void*ve hala bit ve baytlarla çalışmak için hala tüm kodun üzerine serpiyor ve bu bağlamda tip sistemine saygı duymayla ilgili daha fazla güçlükle uğraşıyorsunuz. için memcpybit ve tip sistemini üzerinde buldozerle endişesi duymadan etrafında bayt.

Aslında, genel olarak daha güvenli bir dil olan C ++ 'ta çalışmak, bu tür düşük seviyeli bit ve bayt bağlamlarında, C +' dan türden bir sistem üzerinde buldozerlik yapabileceğinizden ve daha fazlasını yapabileceğinizden daha tehlikeli bir kod yazmadan çalışmak zordur. vptr'lerin üzerine yazmak ve uygun zamanlarda kopya kurucularını ve yıkıcıları çağırmamak. Bu türlere saygı duymak için doğru zaman ayırırsanız ve yeni ve manuel olarak yeni bir yerleşim yerleştirirseniz, RAII için pratik olması ve istisnaya ulaşması için çok düşük bir bağlamda istisna işleme dünyasına maruz kalırsınız. Böyle düşük seviyeli bir bağlamda güvenlik çok zordur (herhangi bir fonksiyonun tüm olasılıkları fırlatabilmesi ve yakalayabilmesi ve herhangi bir şey olmamış gibi bölünemez bir işlem olarak herhangi bir yan etkiyi geri alabilmesi gibi). C kodu genellikle "

Ve bu tür ayırıcıları burada "tehlikeli" olmanıza izin vermeyen dillerde uygulamak imkansız olurdu; Sağladıkları her tahsisatçıya (C veya C ++ 'da uygulanacak olan) ne kadar dayanmanız ve amaçlarınız için yeterince iyi olacağını ummanız gerekir. Neredeyse her zaman daha verimli ancak daha az genel tahsisatçı ve özel amaçlarınıza uygun veri yapıları var, ancak sizin amaçlarınız için özel olarak tasarlandıkları için çok daha dar uygulanabilirler.

Çoğu insan, C veya C ++ 'dan hoşlanmaya ihtiyaç duymaz, çünkü sadece C veya C ++' ta uygulanmış olan kodu, hatta onlar için daha önce uygulanmış olan montajı bile çağırabilir. Birçoğu, C'de uygulanmış olan görüntü işleme fonksiyonlarının kütüphanelerini kullanan, tek tek pikseller arasında en düşük döngü seviyesinde çok fazla inovasyon yapmadıkları, ancak belki de en düşük seviyede döngü oluşturma kullanan bir görüntü programını bir araya getirmek gibi, üst düzeyde yenilikçilikten faydalanabilir. daha önce hiç görülmemiş çok kullanıcı dostu bir arayüz ve iş akışı sunuyor. Bu durumda, yazılımın amacı sadece düşük seviyeli kütüphanelere yüksek seviyeli çağrılar yapmaksa ( "bu görüntüyü benim için işlem, her piksel için değil, bir şeyler yap" ), o zaman muhtemelen erken bir optimizasyon olabilir. Hatta C'ye böyle bir uygulama yazmaya başlamak için

Ancak, daha önce hiç görülmemiş yepyeni bir görüntü filtresi gibi gerçek zamanlı olarak HD video üzerinde çalışmak için yeterince hızlı olan verilere erişmeye yardımcı olduğu düşük seviyede yeni bir şey yapıyorsanız, genellikle elde etmeniz gerekir. biraz tehlikeli.

Bu şeyleri kabullenmek için almak kolaydır. Düşük seviyeli dillerin modası geçmiş hale geldiğini ima eden Python ile bir 3D video oyunu yaratmanın ne kadar mümkün olduğunu belirten biriyle bir facebook gönderisini hatırlıyorum. Ancak Python, tüm ağır kaldırma işlerini yapmak için C'de uygulanan kütüphanelere üst düzey çağrılar yapıyordu. Unreal Engine 4'ü mevcut kütüphanelere sadece yüksek seviyeli çağrılar yaparak gerçekleştiremezsiniz. Unreal Engine 4 olduğunukütüphane. Diğer kütüphanelerde ve motorlarda asla aydınlatmayan, hatta kendi nodal plan sistemine kadar varolmayan her türlü şeyi yaptı ve anında nasıl derleyebildiğini ve çalıştırabildiğini söyledi. Düşük motor / çekirdek / çekirdek seviyesi türünde yenilik yapmak istiyorsanız, düşük seviyeye sahip olmalısınız. Tüm oyun geliştiricileri yüksek seviyeli güvenli dillere geçerse, Unreal Engine 5 veya 6 veya 7 olmayacaktı. Büyük olasılıkla hala on yıllar sonra Unreal Engine 4 kullanan insanlar olabilirdi çünkü gelmek için gereken seviyede yenilik yapamazsınız. Sadece yeni nesil bir motorla eskiden yüksek seviyeli aramalar yaparak.

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.