C türü güçlü mü?


88

Wikipedia'dan alıntı yapmak için :

Pek çok türde örtük dönüşümü destekleyen yaygın olarak kullanılan iki dil C ve C ++ 'dır ve bazen bunların zayıf yazılmış diller olduğu iddia edilir. Bununla birlikte, diğerleri, bu dillerin, farklı türlerdeki işlenenlerin nasıl karıştırılabileceğine dair yeterince kısıtlama getirdiğini, ikisinin güçlü tipte diller olarak görülmesi gerektiğini savunuyor.

Daha kesin bir cevap var mı?


190
Bir C programcısı için güçlü yazma, tuşlara daha sert basmak anlamına gelir.
Dan Dyer

2
C, yazım sürekliliğinde zayıf taraftadır. Ancak her iki tarafta da her iki şekilde de tartışabileceğiniz kadar öğe var. Hazır oradayken sorabilirsiniz (vi veya emacs, net fasulyesi veya tutulma vb.)
Cervo

4
Wikipedia'daki oyun durumu yeterince kötüydü ki birkaç Wikipedia sayfasını düzenlemeye mecbur hissettim. Belki işler şimdi biraz daha iyidir. Olabilir.
Norman Ramsey

40
Re: Dan'in yorumu (olması gereken yere atıfta bulunmak için) Peter van der Linden'in "Uzman C Programlama" kitabı şu satırı içeriyor: "Bugüne kadar, birçok C programcısı 'güçlü yazmanın sadece klavyeye fazladan sert vurmak anlamına geldiğine inanıyor."
Alexandros Gezerlis

Çok güzel soru !!!
Destructor

Yanıtlar:


154

"Kesin tipli" ve "zayıf tipli", üzerinde genel olarak mutabık kalınan teknik anlamı olmayan terimlerdir. İyi tanımlanmış bir anlamı olan terimler şunlardır:

  • Dinamik olarak tür, türlerin çalışma zamanında değerlere eklendiği ve farklı türlerdeki değerleri karıştırma girişiminin "çalışma zamanı türü hatasına" neden olabileceği anlamına gelir. Örneğin, Scheme'de yazarak doğruya bir tane eklemeye çalışırsanız, (+ 1 #t)bu bir hataya neden olur. Hatayla yalnızca sorun teşkil eden kodu çalıştırmaya çalışırsanız karşılaşırsınız.

  • Statik olarak yazılmış , türlerin derleme zamanında kontrol edildiği ve statik türü olmayan bir programın derleyici tarafından reddedildiği anlamına gelir. Örneğin, ML'de yazarak doğruya bir tane eklemeye çalışırsanız 1 + true, program (muhtemelen şifreli) bir hata mesajıyla reddedilecektir. Kod hiçbir zaman çalıştırılmasa bile her zaman hatayı alırsınız.

Farklı insanlar, kısmen esnekliğe ne kadar değer verdiklerine ve çalışma zamanı hataları konusunda ne kadar endişelendiklerine göre farklı sistemleri tercih eder.

Bazen "güçlü tip", "statik olarak yazılmış" anlamında gevşek bir şekilde kullanılır ve "zayıf yazılan", "dinamik olarak yazılan" anlamında yanlış kullanılır. "Kesin tipli" teriminin daha iyi bir kullanımı, "tip sistemini çözemezsiniz veya alt edemezsiniz", oysa "zayıf tip", "tip sisteminde boşluklar vardır" anlamına gelir. Çarpıcı bir şekilde, statik tip sistemlere sahip çoğu dilde boşluklar bulunurken, dinamik tip sistemlere sahip birçok dilde boşluk yoktur.

Bu terimlerin hiçbiri, bir dilde mevcut olan örtük dönüştürme sayısıyla hiçbir şekilde bağlantılı değildir.

Programlama dillerinden tam olarak bahsetmek istiyorsanız, "güçlü yazılmış" ve "zayıf yazılmış" terimlerinden kaçınmak en iyisidir. C'nin statik olarak yazılmış, ancak birçok boşluk içeren bir dil olduğunu söyleyebilirim. Boşluklardan biri, herhangi bir işaretçi türünü başka herhangi bir işaretçi türüne serbestçe çevirebilmenizdir. Ayrıca, söz konusu türlerin her biri için bir tane olmak üzere iki üyesi olan bir C birleşimi bildirerek, seçtiğiniz herhangi iki tür arasında bir boşluk da oluşturabilirsiniz.

Neden-yorumlanan diller-çoğunlukla ördek-tipli iken-derlenmiş-güçlü-yazıma-sahip-neden-yorumlu-dillerde- statik ve dinamik yazım hakkında daha fazla yazdım .


2
Güçlü / zayıf yazım (boşluk meselesi) için önerdiğiniz tanımları nereden aldınız?
Sydius

2
Dinamik bir yazım ortamında neden bir "boşluk" a ihtiyacınız var?
Chris Conway

4
@Sydius: Son 20 yılın büyük bir kısmını programlama dilleri ve yazım sistemleri tasarlayan, inşa eden ve analiz eden insanlarla geçirmekten. Bu benim ücretli işim :-)
Norman Ramsey

@Chris: Dinamik olarak yazılmış 'boşluk deliği' olan bir dil görmedim. Boşluğun yaygın kullanımı, bir çalışma zamanı sistemi veya işletim sistemi ile çalışmaktır, örneğin, ham bir adres almak ve onu iyi davranılmış bir dil değerine bir işaretçiye dönüştürmektir. Bunu dinamik bir ortamda yapabilirsiniz ama ben herhangi bir teşebbüs bilmiyorum.
Norman Ramsey

1
@NormanRamsey Sanırım Chris'in sorusuna atıfta bulunduğunu düşünüyorum:whereas "weakly typed" means "there are loopholes in the type system
Nir Alfasi

23

Her dili 'zayıf' veya 'güçlü' tipli olarak sınıflandırmak zordur - bu daha çok bir sürekliliktir. Ancak, diğer dillerle karşılaştırıldığında, C oldukça güçlü bir şekilde yazılmıştır. Her nesnenin bir derleme zamanı türü vardır ve derleyici, türünün yapmanıza izin vermediği bir nesne ile bir şey yapıyorsanız size (yüksek sesle) haber verecektir. Örneğin, yanlış türde parametrelerle, var olmayan yapı / birleşim üyelerine erişim vb. İle işlevleri çağıramazsınız.

Ancak birkaç zayıflık var. Tipik yayınlardan biri büyük bir zayıflıktır - esasen nesne türleriyle uğraşacağınızı söylerler ve derleyici sessiz olmalıdır (mümkün olduğunda). void*aynı zamanda başka bir zayıflıktır - bilinmeyen bir türün genel bir göstergesidir ve bunları kullandığınızda, doğru şeyi yaptığınıza çok dikkat etmelisiniz. Derleyici, çoğu kullanımı statik olarak kontrol edemez void*. void*ayrıca bir başka zayıflık olan, herhangi bir türe (yalnızca C'de, C ++ 'da değil) bir göstericiye dönüştürülebilir.


Güzel cevap, "typecasts ... ve derleyici sessiz olmalı" beni rahatsız etse de. Typecast, bir uyarıyı kapatmak gibi değildir, aslında referans verilen değerin yorumunu değiştirir.
Tall Jeff

15
Yazmakla ilgili olarak "statik" ve "güçlü" kafa karıştırıyorsunuz. Bu iki kavram birbirinden bağımsızdır.
bendin

1
Dennis Richie (C yazarı) C'yi 'güçlü şekilde yazılmış ve zayıf bir şekilde kontrol edilmiş' olarak
nitelendirdi

11

Literatür bu konuda net değil. Bence güçlü yazım evet / hayır değil, değişen derecelerde güçlü yazım var.

Bir programlama dili, programları nasıl çalıştırdığına dair bir özelliğe sahiptir. Bazen belirli programlarla nasıl çalıştırılacağı net değildir. Örneğin, bir dizeyi bir sayıdan çıkarmaya çalışan programlar. Veya sıfıra bölen programlar. Bu koşullarla başa çıkmanın birkaç yolu vardır. Bazı dillerin bu hataları ele almak için kuralları vardır (örneğin, bir istisna atarlar). Diğer dillerin bu durumlarla başa çıkmak için kuralları yoktur. Bu diller genellikle belirtilmemiş davranışlara yol açan programların derlenmesini önlemek için tür sistemlerine sahiptir. Ayrıca belirtilmemiş davranışa sahip olan ve derleme zamanında bu hataları önlemek için bir tür sistemine sahip olmayan diller de vardır (belirtilmemiş davranışa çarpan bir program yazarsanız, füzeleri fırlatabilir).

Yani:

Her durumda çalışma zamanında ne olacağını belirten dillere (bir dizeye bir sayı eklemek gibi) dinamik olarak yazılan denir. Derleme zamanında hatalı programların çalıştırılmasını engelleyen diller statik olarak yazılmıştır. Ne olacağını belirtmeyen ve ayrıca hataları önlemek için bir tür sistemine sahip olmayan dillere zayıf yazım adı verilir.

Öyleyse Java statik olarak yazılıyor mu? Evet, çünkü onun tür sistemi bir dizgeyi bir sayıdan çıkarmaya izin vermez. Hayır, çünkü sıfıra bölmenize izin verir. Bir tür sistemi ile derleme zamanında sıfıra bölünmeyi önleyebilirsiniz. Örneğin, sıfır olamayacak bir sayı türü oluşturarak (ör. NonZeroInt) ve yalnızca bu türe sahip sayılara bölmeye izin vererek.

Öyleyse C tipi güçlü mü yoksa zayıf mı? Tip sistemi bazı tip hatalarına izin vermediği için C kesinlikle yazılmıştır. Ancak, ne olacağı tanımlanmadığında (ve tür sistemi sizi korumadığında) diğer durumlarda zayıf bir şekilde yazılır.


Güçlü ve zayıf formlar olarak dinamik ve statik hizalamanızı seviyorum. Ancak, sıfıra bölünmeyi durduran statik olarak yazılmış sistemlerle ilgili fikrinizi anladığımdan emin değilim. Statik olarak yazdığım intkullanıcı veya komut satırı argümanlarından veya bir dosyadan bir değer alırsa, derleyicinin sıfır olmasını durdurmak için yapabileceği hiçbir şey yoktur!
Rikki

1
Bunu engelleyen statik tip sistemler vardır, ancak çoğu dil sıfıra bölmeye göre ya zayıf ya da dinamik olarak "yazılmıştır" çünkü bu tanımsız bir davranış (C) veya bir istisna (Java) atıyorlar.
Jules

11

C'nin zayıf yazılmış olduğu düşünülür, çünkü herhangi bir türü, bir derleyici hatası olmadan bir dönüştürme yoluyla başka bir türe dönüştürebilirsiniz. Sen konu hakkında daha fazla bilgi bulabilirsiniz burada .


2
wikipedia burada yanıltıcıdır. C güçlü bir şekilde yazılmıştır, türler çok geçerlidir ve yanlış anlarsanız derleyici kusacaktır, ancak C ayrıca bunu atlamanız için özellikler de sağlar. BCPL gibi yalnızca 'bayt' türü olan dillerle karşılaştırın.
gbjbaanb

13
Zayıf yazılmış, bir dilin herhangi bir türü olmadığı anlamına gelmez, sadece türlerin bir türden diğerine dolaylı olarak zorlanabileceği anlamına gelir. Türleri işlev çağrılarıyla açıkça dönüştürmeniz gereken güçlü yazılmış bir dil olan Python ile karşılaştırın.
mipadi

C de bir şey yapabilmek, onun zayıf bir tip olmasına da katkıda bulunur. ?? Sonsuza dek böyle bir şüphem var
Suraj Jain

8

C, Javascript'ten daha güçlü ve Ada'dan daha az güçlü bir şekilde yazılmıştır.

Sürekliliğin güçlü yazılmış tarafına daha çok düştüğünü söyleyebilirim. ama bir başkası aynı fikirde olmayabilir (yanlış olsa bile).

Bu nasıl kesin?


Biraz yanıltıcı bir cevaptı. Ancak yanlışlığı ayrıntılarıyla anlatın.
Michael Burr

1
Javascript güçlü bir şekilde yazılmıştır. Sadece statik olarak yazılmamış. Tüm tür kontrolleri çalışma zamanında gerçekleşir (dinamik, statik değil) ancak gerçekleşir ve hafızayı bozmanızı engeller (güçlü yazmanın bir yönü).
bendin

5
Norm Ramsey'in çok iyi cevabının da belirttiği gibi, "güçlü yazılmış" ve "zayıf yazılmış" terimler özellikle iyi tanımlanmış terimler değildir. Ayrıca, Javascript güçlü bir şekilde yazıldığı sürece, bazıları ("4" / ​​"2") geçerli bir Javascript ifadesi olmanın aksini gösterebileceğine inanabilir.
Michael Burr

5

C statik olarak yazılmış kabul edilir (int'ten float'a değişken bir değişiklik yapamazsınız). Bir değişken tanımlandığında bu şekilde sıkışmış olur.

Ancak, türler ters çevrilebildiği için zayıf yazılmış kabul edilir.

0 nedir? "\ 0", YANLIŞ, 0.0 vb.

birçok dilde IF (değişken) diyemezsiniz, çünkü koşullar boole ifadelerinden yalnızca boole değerlerini alır. Bunlar daha güçlü bir şekilde yazılmıştır. Aynı şey karakterler ve tamsayılar arasında gidip gelmek için de geçerlidir.

temelde c'nin iki ana basit veri türü vardır, tam sayılar ve kayan nokta sayıları (çeşitli kesinliklerde olsa da). Diğer her şey boolean, enums (basit değil ama uyuyor), vb. Bunlardan biri olarak uygulanır. Karakterler bile temelde tam sayıdır.

Dize türlerinin, yalnızca tanımlanmış değerlere atanabilen enum türlerinin, yalnızca boole veya doğru / yanlış üreten ifadelerin kullanılabildiği boole türlerinin olduğu diğer dillerle karşılaştırın.

Ancak Perl C ile karşılaştırıldığında güçlü bir şekilde yazılmış olduğunu iddia edebilirsiniz. Yani bu meşhur argümanlardan biridir (vi - emacs, linux - windows, vb.). C #, C'den daha güçlüdür. Temelde her iki şekilde de tartışabilirsiniz. Ve cevaplarınız muhtemelen her iki yönde de olacaktır :) Ayrıca bazı ders kitapları / web sayfaları C'nin zayıf yazılmış olduğunu söyleyecek ve bazıları C'nin güçlü yazılmış olduğunu söyleyecektir. Wikipedia'ya giderseniz, C girişi "kısmen zayıf yazım" der. Python C ile karşılaştırıldığında zayıf bir şekilde yazılmış olduğunu söyleyebilirim. Yani Python / C #, C, Perl süreklilik üzerinde.


Lütfen Perl'in C'den daha az güçlü bir şekilde yazıldığına
dair gerekçenizi açıklayın

print "Test" + 0 # perl 0 yapacak; $ var = "dize"; $ var = 1; $ var = 123,4; Bu ne tür bir değişken?
Cervo

C karakterinde * test = "test"; printf (+ 0 testi); yine de bir dizge olacaktır, sadece C'de sıfır yerine bir sayı kullanırsam dizin değişecektir. Hala oldukça zayıf, ama perl'den biraz daha güçlü. char * testi; test = 0; test = 123.4; test = "c"; ... derleyicim hatalar üretiyor
Cervo

hata, bir aletin gerekli olduğunu söylüyor. Yine de, Perl'den biraz daha güçlü bir tür kontrolü, bu yüzden süreklilikte C'nin Perl'den daha güçlü bir şekilde yazıldığını söylemeliyim. Yine de test = (char *) yapabilir ve sonra 0, 123.4, 'C', vb. Kullanabilirsiniz. Ancak bunu yapmak bir hatadır.
Cervo

4

Burada birçok iyi cevap var. Real World Haskell'den önemli bir noktaya değinmek istiyorum :

Pek çok dil topluluğunun kendi “güçlü tip” tanımlarına sahip olduğunun farkında olmak yararlıdır. Yine de, tip sistemlerde güç kavramı hakkında kısaca ve geniş terimlerle konuşacağız.

(kırp)

Yazı tipi sistemlerin etrafındaki havai fişeklerin kökleri, insanların "zayıf" ve "güçlü" kelimelerine değer kavramları ekledikleri sıradan İngilizceye dayanır: genellikle gücü zayıflıktan daha iyi olarak düşünürüz. Pek çok programcı, akademik jargondan çok sade İngilizce konuşuyor ve çoğu zaman akademisyenler, istedikleri sisteme uymayan türden bir işe girişiyorlar. Sonuç genellikle o popüler İnternet eğlencesidir, bir alev savaşıdır.

Öyleyse, C ve C ++ ile ilgili yanıtlara bakın, ancak "güçlü" ve "zayıf" ın "iyi" ve "kötü" ile eşleşmediğini unutmayın.


4

Dennis Ritchie ( C'nin yaratıcısı ) ve Brian Kernighan'a göre, C güçlü bir şekilde yazılmış bir dil değildir. Aşağıdaki satırlar, C programlama dili sayfa 3 paragraf 5 kitabındandır

C türü güçlü bir dil değildir, ancak geliştikçe tür denetimi güçlendirilmiştir.


3

Bence, C / C ++ güçlü bir şekilde yazılmıştır. Türlerin dönüştürülmesine (void *) izin veren hack türleri, C'nin makineye yakınlığı nedeniyle vardır. Başka bir deyişle, Pascal'dan assembler komutlarını çağırabilir ve işaretçileri işleyebilirsiniz ve Pascal hala güçlü bir şekilde yazılmış bir dil olarak kabul edilir. JNI aracılığıyla assembler ve C çalıştırılabilir dosyalarını çağırabilirsiniz, ancak Java'nın zayıf yazılmasına neden olmaz.

C sadece ham işaretçiler ve benzeri ile "gömülü" bir araya getiriciye sahiptir.


3

Tipik olarak yazılmış terimin üzerinde anlaşılan bir tanımı yoktur. Bu nedenle, ne demek istediğinizi tanımlamadıkça "güçlü yazılmış" ile , sorunuza cevap vermeniz imkansızdır.

Deneyimlerime göre, "kesin olarak yazılmış" ve "zayıf yazılan" terimleri özel olarak kullanılmaktadır troller tarafından , çünkü tanım eksiklikleri trollerin onları tartışma ortasında gündemlerine uyacak şekilde yeniden tanımlamalarına izin verir. Alev savaşlarını başlatmak dışında, bu terimler oldukça faydasızdır.

Ayrıca , güçlü yazılmış bir dilin temel yönleri nelerdir? Konusuna da bakmak isteyebilirsiniz. burada StackOverflow'da.


3
Katılmıyorum. "Kesinlikle yazılmış", bir değerin veri türünü belirlemenin mümkün olduğu ve yalnızca bu tür için uygun işlemlere izin verildiği anlamına gelir. Bu belirleme yapılabildiğinde "dinamik" ve "statik olarak" adres.
joel.neely

2
Sen bunu hiç orada üzerinde anlaşılan olduğunu tanımı henüz başka tanımı, sağ tanıtarak görüşünü çürüten çalışmakla ironiyi fark?
Jörg W Mittag

1
@Jorg: Başka bir tanesini tanıtmaya çalışmıyorum; sadece içinde hareket ettiğim çemberlerde yaygın olarak kullanılanı belirterek.
joel.neely

1

İyi tanımlanmamış iki terim olan "zayıf tipli" ve "güçlü tipli" arasında birden fazla paralel caddeye sahip bir süreklilik vardır.

C statik olarak yazılmıştır, çünkü derleyici her yerel değişkenin ve yapı üyesinin bildirilen türünü bilir .

Her nesnenin belirli bir türü varsa, ancak derleyicinin bu türü bilmesinin bir yolu yoksa, dinamik olarak yazılmış diller yine de güçlü bir şekilde yazılabilir.


0

Sorgunuzun sebebi nedir? Sormamın nedeni, bu tür küçük bir fark ve sizin özel "güçlü tip" kullanımınız az ya da çok açıklamaya ihtiyaç duyabilir. Kesinlikle, Java ve diğer dillerin örtük tip konuşmada daha sıkı kısıtlamalara sahip olduğunu söyleyebilirim.


Çoğunlukla merakım, ancak bir C pozisyonuna başvuruyorum ve beni bu konuda sorgulamaları durumunda bilmek istedim.
Sydius

O zaman muhtemelen "güçlü biçimde yazılmış" nüanslarını veren daha uzun cevap, sadece "evet" veya "hayır" demekten ziyade en iyi yaklaşımdır.
BobbyShaftoe

0

"Tiplendirilmiş" in somut bir tanımı olmadığında somut bir cevap vermek zordur. C'nin güçlü bir şekilde yazıldığını söyleyebilirim, çünkü her değişken ve her ifadenin bir türü vardır, ancak türleri kullanarak türleri değiştirmenize ve bir türün temsilini başka bir tür olarak yeniden yorumlamanıza izin verdiği için zayıf bir şekilde yazılmıştır.


Resmi bir tanım var. için şiddetle yazdınız. Bir sys olduğunu söylüyor. çalışma süresi tipi hatası olmadığını garanti ettiğinde ST'dir. Örnek: ML, Haskell. Bu, sistemin nesnelerin içindeki tür etiketlerini atlamasını sağlamak ve ancak operatörleri doğru türlere uygulamak için kullanışlıdır. Çünkü yürütmeden önce nesnelerde etiketlere gerek olmadığını biliyoruz. C keyfi nota atama ve işaretçi erişimi sağladığından, C st
alinsoar

0

Derleyicinizin / platformunuzun belirttiği kadar C'nin güçlü bir şekilde yazılmış olduğunu söyleyebilirim. Örneğin, katı bir platform üzerine inşa ediyorsanız, bir tür cezalandırılmış göstericinin referansını kaldırmak muhtemelen başarısız olacaktır:

Şimdi, derleyiciye katı takma adlamayı atlamasını söylediyseniz, bu bir sorun olmazdı, ancak çok da taşınabilir değildir. Yani, bu anlamda, dilin sınırlarını zorlamak mümkün ama muhtemelen en iyi fikir değil. Bu, tipik dökümün bir adım ötesine geçer, yani int'i uzun süre kullanmak ve gerçekten boşluğun olası tuzaklarından birini gösterir.

Yani, C'nin temelde katı bir şekilde yazılmış olduğunu söyleyebilirim, ancak çeşitli derleyicileri, programcının en iyisini bildiğini ve biraz esnekliğe izin verdiğini varsayar. Bu gerçekten derleyiciye bağlıdır, bazıları bu potansiyel aksaklıkları anlamaz. Yani bu anlamda, tercih edilen derleyici soruyu cevaplarken gerçekten bir rol oynar. Doğru olan, genellikle derleyicinizin paçayı sıyırmanıza izin vereceğinden farklıdır.



-1

Kesinlikle yazılmamış.

Aşağıdaki fonksiyon prototipinin, argümanların veri türleri hakkında size ne söylediğini düşünün:

Hiçbir şey değil. Bu yüzden güçlü yazmanın burada geçerli olmadığını öneriyorum.


Huh? Size bir int, ardından bir karakter ve ardından herhangi bir türde herhangi bir sayıda argüman olduğunu söyler. Bu "hiçbir şey" değil.
Lawrence Dol

... size iletilen argümanların türleri hakkında hiçbir şey söylemez. İşlevin türünün kendisinin bildiği doğrudur . Software Monkey böyle söyledi.
Johannes Schaub -

Benim bahsettiğim "her türden herhangi bir sayıda argüman". Bir zincir ancak en zayıf halkası kadar güçlüdür.
joel.neely

-3

Her ifadenin değerinin fonksiyonu olmayan bir türü olduğu için güçlü bir tür olduğunu söyleyebilirim; ei çalışma zamanından önce bilinebilir.

OTOH Güçlü yazılmış ifadenin doğru tanımının bu olduğundan emin değilim. Bir dilin ortaya çıkmasının nedenini görebildiğim daha güçlü tek iddia, tür dökümlerini, birleşimleri, diğer dillere çağrı, işaretçiler, montaj dili vb. Yoluyla çalışma zamanında tür sistemini yıkamayacağınızın garantisidir. Bunun gibi diller var ama o kadar sakatlar ki, yüksek güvence ve akademi dışında programcıların ilgisini çekmiyor gibi görünüyorlar. Birinin belirttiği gibi, bunu gerçekten doğru yapmak için, benzer nonZeroIntve ne olmayacak türlere ihtiyaç duymaya başlarsınız . Yuck.


3
Ne değildir? Benim tanımım kesin olarak yazılmış mı yoksa C mi?
BCS
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.