Genç beyinlerin işaretçi kavramlarını öğrenmeye ihtiyacı var mı?


89

C ustası Dennis Ritchie neden C'ye işaretçiler getirdi? Ve neden VB.NET veya Java veya C # gibi diğer programlama dilleri onları ortadan kaldırdı? Google’da bazı noktalar buldum ve yorumlarınızı da dinlemek istiyorum. Modern dillerde işaretçi kavramlarını neden yok ediyorlar?

İnsanlar, C'nin temel dil olduğunu ve işaretçilerin, C'yi güçlü ve üstün kılan ve C'yi daha modern dillerle rekabet edebilecek bir kavram olduğunu söylüyor. Öyleyse neden daha modern dillerde işaretçileri ortadan kaldırdılar?

Yeni programcılar için işaretçi bilgilerinin hala önemli olduğunu düşünüyor musunuz? İnsanlar bugünlerde VB.NET veya Java kullanıyor, bu da C'den daha gelişmiş özellikleri destekliyor (ve herhangi bir işaretçi konseptini kullanmıyor) ve şimdi gördüğüm gibi birçok kişi (arkadaşlarım) bu özellikleri C'yi yok sayarak gelişmiş özellikleri desteklediklerini söylüyor. Onlara C ile başlamalarını söylüyorum. VB.NET veya Java’da C’de mümkün olmayan gelişmiş şeyleri yaparken işaretçiler kavramlarını öğrenmenin boşa olduğunu söylüyorlar.

Ne düşünüyorsun?

Güncelleme :

Google'da okuduğum yorumlar:

  1. Önceki bilgisayarlar çok yavaştı ve optimize edilmedi.

  2. İşaretçileri kullanmak, bir adrese doğrudan erişmeyi mümkün kılar ve bu, işlev çağrılarında bir kopyasını yapmak yerine zaman kazandırır.

  3. İşaretçiler kullanılarak güvenlik önemli ölçüde daha kötüdür ve bu nedenle Java ve C # bunları içermez.

Bunlar ve biraz daha ne buldum. Hala bazı değerli cevaplara ihtiyacım var. Bu çok takdir edilecektir.


52
Java'da işaretçiler yok mu? Bu doğru değil. Java'daki her nesne referansı, temel olarak bir işaretçidir.
quant_dev

20
Quant_dev'in anlamı, Java'nın saydamlıkla kullanılan işaretçilerle doludur, programcılar açıkça kullanamazlar.
sakisk

9
İşte Joel Spolsky'den
Joe Internet

11
“C ustası Dennis Ritchie neden c’de işaretçiler getirdi?” İşaretçiler edildi değil c tanıtılan, bunlar montaj pratikte düz rastladı, adı dahil.
dmckee

14
@quaint_dev: Peki, Java gerçekten işaretçilere sahip değil. Referanslar, işaretçilerin yapabileceği her şeyi yapamaz; bu nedenle, işaretçileri referanslar olarak anlamaya çalışmak, yolun yolu değildir (ve C veya C ++ 'ı öğrenen bir çok programcının hatasıdır). İşaretçiler aritmetik işlem yapabilir. Referanslar olamaz. (Her seferinde Java kullanmaya zorlandığımda gerçekten kokan bir sınırlama)
Billy ONeal

Yanıtlar:


128

O günlerde, geliştiriciler metale çok daha yakın çalışıyorlardı. C aslında montaj için neredeyse mümkün olan en yakın donanıma sahip olan daha üst seviye bir değiştirmeydi, bu yüzden kodlama problemlerini çözmede etkin olması için işaretçilere ihtiyacınız vardı. Ancak, işaretçiler dikkatsizce kullanılırsa büyük hasara neden olabilecek keskin araçlardır. Ayrıca, doğrudan işaretçilerin kullanılması, o zamanlar sorun olmayan pek çok güvenlik sorununun ortaya çıkmasına neden oluyor (1970'de, internet birkaç üniversitede birkaç düzine makineden oluşuyordu ve bu şekilde çağrılmadı bile). ...), ancak o zamandan beri daha önemli hale geldi. Bu nedenle günümüzde yüksek seviye diller, ham bellek işaretçilerinden kaçınmak için bilinçli olarak tasarlanmıştır.

"VB.Net veya Java’da C: C’de yapılması mümkün değildir" demek, çok az bir şey söylemek için çok sınırlı bir bakış açısı gösterir.

Her şeyden önce, tüm bu diller (hatta meclis) tamamlanmıştır, böylece teoride mümkün olan her dilde mümkün olan her şey mümkündür. Sadece bir parça VB.Net veya Java kodu derlendiğinde ve çalıştırıldığında ne olacağını düşünün: sonunda, makine koduna çevrilir (veya haritalanır), çünkü makinenin anladığı tek şey budur. C ve C ++ gibi derlenmiş dillerde, bir veya daha fazla çalıştırılabilir dosya / kitaplık olarak, orijinal üst seviye kaynak koduna eşdeğer makine kodunun tamamını alabilirsiniz. VM tabanlı dillerde, programınızın tüm eşdeğer makine kod gösterimini elde etmek daha zordur (ve mümkün olmayabilir), ancak çalışma zamanı sisteminin ve JIT'in derin girintileri içinde yine de bir yerdedir.

Şimdi, elbette, bazı çözümlerin belirli bir dilde uygulanabilir olup olmadığı tamamen farklı bir sorudur. Hiçbir mantıklı geliştirici montajda bir web uygulaması yazmaya başlamaz :-) Ancak, bu üst düzey dillerin çoğunun veya tamamının çok miktarda çalışma zamanı ve sınıf kitaplığı kodunun, büyük bir yığınının üzerine kurulu olduğunu akılda tutmak yararlıdır. daha düşük bir dilde, tipik olarak C dilinde uygulanır.

Yani soruya ulaşmak için,

Gençlere yönelik işaretçiler hakkındaki bilgilerin […] önemli olduğunu düşünüyor musunuz?

İşaretçilerin arkasındaki kavram dolaylıdır . Bu çok önemli bir kavram ve IMHO her iyi programcının belli bir seviyede kavramasını sağlamalı. Birisi yalnızca daha yüksek seviyeli dillerle çalışsa bile, aktarma ve referanslar hala önemlidir. Bunun anlaşılmaması, uzun vadede bir kişinin problem çözme yeteneğini ciddi şekilde sınırlayan, çok güçlü bir araç sınıfının tamamını kullanamamak anlamına gelir.

Bu yüzden cevabım evet, gerçekten iyi bir programcı olmak istiyorsanız, işaretçileri de anlamalısınız (özyinelemenin yanı sıra - bu, tomurcuklanan geliştiriciler için diğer tökezleyen bloktur). Başlamanız gerekmeyebilir - C'nin bugünlerde ilk dil olarak uygun olduğunu düşünmüyorum. Ancak bir noktada, bir dolaylı anlatıma aşina olunmalıdır. Onsuz, kullandığımız araçların, kütüphanelerin ve çerçevelerin gerçekte nasıl çalıştığını asla anlayamayız. Ve aletlerinin nasıl çalıştığını anlamayan bir zanaatkar çok kısıtlıdır. Yeterince adil, bir de bunu daha üst seviye programlama dillerinde kavrayabilir. İyi bir turnusol testi, iki kat bağlantılı bir listeyi doğru şekilde uygulamaktır - eğer en sevdiğiniz dilde yapabilirseniz, dolaylı olarak yeterince iyi anladığınızı iddia edebilirsiniz.

Ancak, başka hiçbir şey için değilse, sahip oldukları gülünç basit araçları kullanarak inanılmaz şeyler inşa etmeyi başarmış yaşlı programcılara saygı duymayı öğrenmeliyiz. Hepimiz devlerin omuzlarında duruyoruz ve devleri kendimizmiş gibi davranmak yerine, bunu kabul etmemiz bize iyi geliyor.


5
Bu iyi bir cevap ama aslında şu soruyu cevaplamıyor: "Genç beyinlerin işaretçi kavramlarını öğrenmesi gerekiyor mu?"
Şahin

11
+1 İyi cevap. Yine de, bütünleme argümanını reddederdim - pratik programlama için, daha sonra not ettiğiniz gibi kırmızı bir ringa balığı. Bu hesaplanabilirlik teorisidir, yani sadece tamamlama, aslında uygulanabilir veya hatta insanca mümkün olmasa bile, aynı algoritmayı uygulayan potansiyel programların (birçok dil için, sonsuz) alanında bir program olduğu anlamına gelir. Sonunda tüm makine kodunu işaret ederek sadece aptallığa gerek duymadan, “Her şeyi aynı, her şeyi aynı harhar! tohum.

5
"Ve bir usta kim onun / onu araçları eser çok sınırlı biridir nasıl anlamıyor" için 1
quickly_now

6
Ayrıca, işaretçilerin (ve uzatma referansları ile) mekaniğinin anlaşılmaması, bu nedenle, izlenmesi zor olan ciddi hatalara neden olabilecek sığ / derin veri yapı kopyası kavramlarını anlamadığınız anlamına gelir. "Modern" yüksek seviyeli dillerde bile.
Mavrik

1
C, Unix için, yani metale yakın, portatif bir montaj elemanı olarak tasarlandı .

39

Bence farklı olmalısın.

Java ve diğer yüksek seviye dilleri, işaretçileri kaldırmadı. Yaptıkları, düz gösterici aritmetiğini kaldırmaktı.

Aslında, Java korunan ve kısıtlanmış bir işaretçi aritmetiğine izin verir : dizi erişimi. Düz eski C'de, dizi erişimi kural dışı bırakmadan başka bir şey değildir. Yaptığınız şeyi açık bir şekilde iletmek, yapacaksanız farklı bir gösterimdir, sözdizimsel bir şekerdir.
Yine de, array[index]eşdeğerdir *(array+index). Bundan dolayı, index[array]bazı C derleyicilerinin bunu yaparsanız size bir uyarı verebileceğini varsayalım.
Sonuç pointer[0]olarak eşdeğerdir *pointer. Bunun sebebi "bir diziye işaretçi" nin dizinin ilk girişinin adresi olması ve izleyen elemanların adreslerinin indeks eklenerek hesaplanmasıdır.

Java'da, düz işaretçi aritmetik (referanslama ve yeniden düzenleme) artık mevcut değil. Ancak işaretçiler var. Onlara referans derler, fakat ne olduğunu değiştirmez. Ve dizi erişimi hala tam olarak aynı şey: Adrese bakın, dizini ekleyin ve bu bellek konumunu kullanın. Ancak, Java’da, endekste ayırdığınız dizinin sınırları dahilinde olup olmadığını kontrol eder. Değilse, bir istisna atar.

Şimdi Java yaklaşımının avantajı, kodunuzun olmaması, sadece rasgele baytları rasgele bellek konumlarına yazma kabiliyetine sahip olmasıdır. Bu, güvenliği ve güvenliği de artırır, çünkü arabellek taşmalarını ve benzeri şeyleri kontrol etmekte başarısız olursanız, çalışma zamanı sizin için yapar.

Bunun dezavantajı, basitçe daha az güçlü olmasıdır. C de güvenli bellek programlama yapmak mümkündür. Java’daki güvenli olmayan programlamanın hızından ve olanaklarından yararlanmak mümkün değildir.

Aslında, işaretçiler veya işaretçi aritmetiği ile ilgili hiçbir zor şey yoktur. Sadece normalde açık bir şekilde açıklanırlar, tüm işaretçi tek bir dev dizinin indeksidir (bellek alanınız), bir değere yapılan tüm referanslar size onu nerede bulacağınıza dair indeks verir, tüm referansların kaldırılması ne yapar verilen bir dizindeki değer. (Bu biraz basitleştirilmiştir, çünkü değerlerin türlerine bağlı olarak bellekte farklı boyutta oldukları dikkate alınmaz. Ancak bu, gerçek konseptin bir parçası olmaktan çok, bir detay niteliğindedir)

IMHO, işimizdeki herkes bunu anlayabilmeli ya da sadece yanlış alanda bulunmalı.


13
+1 Java ve C # hala işaretçilere sahiptir ve tabii ki NullPointerExceptions
jk.

5
Ayrıca, çöp toplayıcı madde etrafta hareket ederken referansların zaman içinde farklı alanlara işaret edebileceğini de unutmayın. İşaretçiler genellikle statiktir.

3
+1: bu! Ve ben olduğunu düşünüyorum iki (C olur, C #, Java, ...) indirection ve (işaretçi aritmetiği: (genel olarak) önerilerle ilgili kavramak zor şeyler değil aynı şekilde Java olur). Bence hem öğrenmesi gereken önemli kavramlar hem de yeni başlayanlar için büyük engeller. Ancak bunların karıştırılmaması gerekir: dolaylı işaretçi aritmetik olmadan gerçekleşebilir .
Joachim Sauer

2
Aslında, back2dosilk kez haklıydı, çünkü (array + index)cisimlerin büyüklüğü zaten göz önünde bulundurulmuştu (C cinsinden).
Matthew Flaschen

4
@CyberSkull, cevap, sözdizimsel eşdeğerini veriyordu array[index]ve bu *(array+index). Derleyicinin işleri dahili olarak nasıl yaptığını göstermek istiyorsanız, açıkça baytlardan bahsedebilir veya derleme verebilirsiniz.
Matthew Flaschen 7:11

24

İşaretçiler kavramı, genel bilgisayar programlama bilgisinde önemlidir. Kavramı anlamak, dil doğrudan desteklemese bile, programcı veya herhangi bir dilin programcıları için iyidir.

İşaretçiler, Veri Yapıları (bağlantılı listeler) ve Veritabanı tasarımında (Yabancı Anahtar) kullanım alanına sahiptir.

VB ve C # gibi diller, verileri bir işaretçi türü olarak düşünülebilecek yöntemlere "referans" yaparak iletebilir.

Verilerin bellekte nereye dağıldığını anlamak (yığın-yığın) algoritmaların etkinliği için hala önemlidir.

Temel bilgileri doğru öğrenmek bence önemlidir.


Genel konsepti faydalı buluyorum ama bir işaretçiye ihtiyacım olan bir durum bulamadım (çoğunlukla Java ve PHP kullanıyorum). Sadece örnek benim C ++ dersleri hiç göstericiler için başlamak herhangi bir yüksek seviyeli programlama dilinde mevcut listeler ve sözlükler gibi daha karmaşık veri yapılarını oluşturmak için bunları kullanıyordum ile geldi ..
Ben Brocka

2
Bir şekilde haklısınız, ancak verileri yöntemlere ilettiğinizde, bazı durumlarda değişkene bir işaretçi geçiriyor olabilirsiniz. Ancak, bir işaretçi kavramı (benim görüşüme göre) bir yazılım dilinde uygulanmasından bağımsız olarak yararlıdır.
NoChance

1
@SirTapTap: Çünkü bir tür C ++ 'ı öğrendiyseniz, size C ++' ı öğretiyorlar. C ++ kullanmanın en iyi yolu değil. Pointer aritmetiği genellikle açıklanmıştır, çünkü C ++ ile geçen ve bilmediğiniz bir bilgiye sahip olabilirsiniz. Ancak, genel bir koleksiyon üzerinde yineleme yapmak gibi şeyler bile gerçek / deyimsel C ++ işaretçilerle yapılır. (Standart Şablon Kütüphanesinin nasıl çalıştığının temeli olduğu gibi)
Billy ONeal

@BillyONeal İşaretçiler dersin neredeyse yarısıydı, gerçekten, (akıllı) işaretçiler için hiçbir zaman bir uygulayıcı olarak pratik bir kullanım bulamadım, hakikaten de yaptığım hiçbir şeyde bellek üzerindeki kontrolün doğrudan gerekli olmamasını sağladı. Elbette her zaman kursun kötü bir şekilde öğretildiği ihtimal vardır, bu kesinlikle benim favorim değildi.
Ben Brocka

1
@SirTapTap: Pratik kullanım: STL'deki her koleksiyon ve algoritma. std::sort, std::partition, std::find, Vb Bunlar işaretçiler ile çalışmak ve onlar işaretçiler (Yineleyicilerin) gibi hareket nesnelerle çalışır. Ve herhangi bir genel koleksiyon üzerinde çalışırlar; bağlantılı listeler, dinamik diziler, dequeağaçlar, veya kullanıcı tarafından tanımlanmış herhangi bir koleksiyon. İşaretçiler olmadan böyle bir soyutlama yapamazsınız.
Billy ONeal

19

Evet, evet, evet, evet ve evet !!!

Temel bilgileri bilmiyorsanız, yolunuza çıkan gerçekten zor, garip, zor ve karmaşık sorunları ASLA çözemezsiniz.

Temel bilgileri gerçekten iyi anlarsanız, iş piyasasında ÇOK daha pazarlanabilirsiniz.


Bir keresinde 10 senedir programlama yapan bir adamla çalıştım ve işaretçilerin nasıl çalıştığını bilmiyordum. Ben (çok daha küçük) onu eğiten bir beyaz tahtada saatler geçirdim. Bu gözlerimi açtı. Birçok temel şey hakkında IDEA'sı yoktu.

Olabildiğince çok şey bil.


Ama temel şey nedir? Montaj, ikili kod?
SiberianGuy

5
Genel nokta "mümkün olduğu kadar çok şey biliyorsun", sağlam bir soru olsa da, "yoluna çıkan gerçekten zor, garip, zor ve karmaşık sorunları ASLA çözemezsiniz" fikrini sorgulardım. işaretçiler anlamıyorum. Bu, bir şekilde, tüm bu zor sorunların, böyle olmayan “sihirli” işaretçiler kullanılarak çözülebileceğini ima ediyor. İşaretçiler arasındaki kavramları bilmek faydalıdır, ancak birçok programlama alanı için doğrudan gerekli değildir.
Dan Diplo

4
@ Idsa: hayır, daha da basit, çoğu programcı bugünlerde transistörlerin ve mantık kapılarının goo 'ole' yongalarında nasıl çalıştığını bile bilmiyor ve elektronların nasıl hareket ettiğini ve kuantum belirsizliğin minyatürleştirme üzerindeki etkisini kesinlikle bilmeleri gerekiyordu; Şarlatanlara, liptonlara ve bizonlara bile başlamadım! ve Hıçkırıklar da parçacıklar!
Yalan Ryan

2
Temelleri .... şeyler nasıl depolanır gibi şeyler. Bir bayt, bir kelime, nasıl imzalanmış ve imzasız iş arasındaki fark. İşaretçiler nasıl çalışır? Bu ne karakter ASCII'de işlerin nasıl kodlandığı (ve bugünlerde Unicode). Bağlantılı bir liste sadece basit yapılar kullanılarak bellekte nasıl oluşturulabilir. Dize gerçekten çalışıyor. Bu küçük şeylerden daha büyük şeyler büyür.
hızlı bir şekilde

5
Yapabildiğin kadarını bilmek iyi bir ilke, ama sanırım attan önce araba var. İyi geliştiriciler, ne yapabileceklerini öğrenmek için gayret gösterirler çünkü iyi geliştiricilerdir. Bilgi özlemi, iyi bir geliştiricinin özelliğidir. İyi bir geliştiricinin nedeni değil. Dışarı çıkmak ve elinizden geldiğince öğrenmek sizi iyi bir geliştirici yapmaz. Seni yürüyen bir ansiklopedi yapacak, daha fazla değil. Eğer iyi bir geliştiriciyseniz, problemleri çözmek için edindiğiniz bilgiyi UYGULAMALIDIR. Ama eğer zaten iyi bir geliştirici olmasaydın, bilgi seni fazla alamaz.
corsiKa

18

Evet, anlayış önemlidir.

Birkaç ay önce C # ile programlama yaptım ve bir listenin kopyasını almak istedim. Elbette yaptığım şeydi NewList = OldList;ve sonra değişmeye başladı NewList. Her iki listeyi de basmaya çalıştığımda, ikisi de aynıydı, çünkü bir kopya NewListiçin bir işaretçidi OldList, bu yüzden aslında baştan başa değişiyordum OldList. Bunu anlamak çok uzun sürmedi, ancak sınıf arkadaşlarımdan bazıları o kadar hızlı değildi ve bunun neden olduğunu açıklamak zorunda kaldılar.

Örnek:

List<int> a = new List<int>();
a.Add(2);
a.Add(9);
a.Add(8);
a.Add(1);
List<int> b = new List<int>();
b = a; //Does not make a copy, b is just a synonym!
b.Sort();
for (int i = 0; i < a.Count; i++)
{
    Console.WriteLine("a: " + a[i] + " b: " + b[i]);
}

Ve elbette, sonuç şöyle:

a: 1 b: 1
a: 2 b: 2
a: 8 b: 8
a: 9 b: 9

Onları nasıl kullanacağını bilmek o kadar önemli değil, ama onları anlamak çok önemlidir!


2
Bunun yerine neden kullanmaları ve ne zaman kullanmaları en önemlileridir :)
niko

5
" NewListSadece işaretçi OldList" , kesin olarak, her iki - NewListve OldListaynı atıfta bulunarak, sadece işaretçileri Listnesne.
Péter Török,

Ayrıca, oluşturduğunuz yeni listenin bartık referansı olmadığını ve artık çöp olduğunu anlamak da önemlidir .
TMN

14

İşaretçi kavramı! = İşaretçi aritmetiği! = İşaretçi işaretçisi

İlk önce her zaman, derin / sığ kopyanın anlaşılması (ve buna ihtiyacınız olduğunda), referansa göre / değere göre geçme, vb. Anlamayı öğrenirseniz önemlidir.


1
Günümüzde, işaretçi sözdizimi / matematiği değil, sadece temel referans kavramlarını bilmeniz gerekir. Ben işaretçiler (aritmetik ve sözdizimi ile) geri gün içinde C öğrendim. Şimdi programladığım diller, güvenli olmayan şeyler yapmanızı sağlayan C tarzı işaretçilerle ilgilenmiyor. Python Bir neden anlayabileceği a=[1,2]; b=a; a.append(3)de o ave bhem gidiyoruz aynı nesneye başvuran [1,2,3]C gibi şeyler bilmeden ibir dizinin inci elemanı tarafından başvurulan olabilir arr[i]veya i[arr]her ikisi olarak *(arr+i). Dilin i[arr]kullanılmasına izin vermediğinde tercih ederim .
dr jimbob

Diğer iki mesele, eğer sadece dil uzmanınız onları kullanmanıza izin veriyorsa. ” - Bu cümle kendi kendini imha eden kişiyi taşıyor. Du jour dili, tanımı gereği, yarın kullanılan dilin olması pek mümkün değil. Ve yarın, işaretçi özellikli bir dille karşılaşabilirsiniz. Alt çizgi? Daha iyi olanı, şimdi, bir kez ve sonsuza dek kavradı. O kadar zor değil, ama buna değer.
JensG

14

C ustası Dennis Ritchie neden C'ye işaretçiler getirdi?

Çünkü işaretçiler birçok yönden kullanılabilecek çok güçlü bir mekanizmadır.

Ve neden VB.NET veya Java veya C # gibi diğer programlama dilleri onları ortadan kaldırdı?

Çünkü işaretçiler birçok yönden kötüye kullanılabilecek çok tehlikeli bir mekanizmadır.

Programcıların işaretçiler hakkında bilgi edinmesi gerektiğini düşünüyorum, ancak eğitim açısından bakıldığında, bunları erken tanıtmak pek akıllıca değil. Bunun nedeni, birçok farklı amaç için kullanılmalarıdır, bir işaretleyiciyi neden belirli bir durumda kullandığınızı yeni başlayanlar olarak söylemek zordur.

İşaretçilerin ne için kullanıldığı tam bir liste:

  • dinamik ayırma ( new T)
  • özyinelemeli veri yapıları ( struct T { T* next; /* ... */ };)
  • dizilerde yineleyiciler ( for (T* p = &a[0]; p != &a[0] + n; ++p) { ... })
  • nesnelere paylaşılan erişim ( T* new_pointer = existing_pointer;)
  • Türü Polimorfizmi ( T* pointer_to_base = pointer_to_derived;)
  • reference ( mutate(&object);) tarafından eski arama
  • isteğe bağlı türleri ( if (p) { /* ... */ })

Tüm bu kavramlar için tek bir mekanizma kullanmanın, deneyimli programcının hem gücünü hem de zerafetini ve programlamaya yeni başlayan biri için büyük karışıklık potansiyelini gösterdiğine dikkat edin.


C ustası Dennis Ritchie neden C'ye işaretçiler getirdi ? Çünkü işaretçiler birçok şekilde kullanılabilecek çok güçlü bir mekanizmadır.” - Bir gerçeği bilmiyorum, ama C diline sarılacak makine talimatlarıyla bir ilgisi olduğunu ve C Assembler programcılarının işaretçilerde düşünmek için kullanıldığını sanıyordum. Bu iyi bilinen güçlü mekanizmaları kullanmamış olsaydı bir sürpriz. Başka bir şey 1978, hatta 1960'lar için çok uzak olurdu.
JensG

12

Neden? Form tasarımcısı ve kod üreticisi ile büyük bir sistem yazabilirsiniz. Yeterli değil mi? (hiciv, alay, ince alay)

Ve şimdi ciddiyetle, işaretçiler birçok alanda programlamanın çok önemli bir parçası değildir, ancak insanların iç işlerin nasıl yürüdüğünü anlamalarına izin verir. İnternalların nasıl çalıştığını anlayabilecek hiç kimseye sahip olamayacaksak, SQL2020, Windows 15 ve Linux 20.04'ün, IDE aracılığıyla oluşturulan kodla JavaScript üzerinden, 30 soyutlama katmanının üzerinde çalışan çöp toplanan sanal makineye yazılacağı bir durum olacaktır. .

Kesinlikle görmek istediğim bu değil.

Yani evet, kesinlikle yapmak zorundalar!


2
İyi mizah! +1 ve tamamen katılıyorum.
heltonbiker

7

Ne Java, ne de C # işaretçileri yok etti, neredeyse aynı olan referansları var. Elimine edilen şey, tanıtıcı bir derste çıkarılabilecek işaretçi aritmetiktir.
İşaretçiler veya referanslar kavramı olmadan önemsiz bir uygulama yapılamaz, bu yüzden öğretmeye değer (onlarsız dinamik hafıza tahsisi yapılamaz).

C ++ ve Java'da aşağıdakileri göz önünde bulundurun ve C # 'da çok farklı olmadığını tahmin ediyorum:
aClass *x = new aClass();
aClass x = new aClass();
İşaretçiler ve referanslar arasında gerçekten çok fazla fark yok, değil mi?
Gerekmedikçe ve yüksek seviye modellerle programlama yaparken, işaretçi aritmetik özelliklerinden kaçınılmalıdır, bu nedenle orada fazla bir sorun yoktur.


6

Profesyonel programcı işaretçilere hakim olmalıdır.

Programlamayı bilmek isteyen insanlar varlığını ve sonuçlarını öğrenmeli, ancak bunları mutlaka kullanmamalıdır.

Kişisel problemleri programlama yoluyla çözmek isteyen insanlar (benim gibi, çok fazla Python senaryosu kullananlar), onları çok iyi görmezden gelebilirler.

Peki, bu benim düşüncem ...; o)


3

Değişken adres işaretçileri, daha genelleştirilmiş dolaylı aktarım kavramının özel bir örneğidir. İndirme, çoğu (tümü?) Modern dilde delegeler ve geri aramalar gibi birçok yapıda kullanılır. Dolaylılık kavramını anlamak, bu araçların ne zaman ve nasıl kullanılacağını bilmenizi sağlar.


3

Absufreakinglutely EVET ! Program yapan herkesin işaretçileri ve dolaylı ifadeleri anlaması gerekir.

İşaretçiler, tüm dillerde büyük miktarda veri erişiminin nasıl yapıldığını gösterir. İşaretçiler tüm mikroişlemcilerin bir donanım özelliğidir. Java, VB ve C # gibi yüksek seviyeli diller, esas olarak referanslarla dilin kullanıcılarının işaretçilerine doğrudan erişim sağlar. Referanslar, dilin bellek yönetimi şeması aracılığıyla nesnelere atıfta bulunur (örneğin, meta verileri olan bir işaretçi veya bir bellek tablosu için sadece bir sayı olabilir).

İşaretçilerin nasıl çalıştığını anlamak, bilgisayarların gerçekte nasıl çalıştığını anlamak için çok önemlidir . İşaretçiler de referanslardan daha esnek ve güçlüdür.

Örneğin, dizilerin sıfır dizininde başlatılmasının nedeni, dizgelerin işaretçi aritmetiği için kısa yol olmasıdır. İşaretçilerin nasıl çalıştığını öğrenmeden, pek çok başlangıç ​​programcısı dizileri tam olarak elde edemez.

int a, foo[10];
foo[2] = a;

İşaretçi aritmetiğindeki 2. satır:

*(foo + sizeof(int) * 2) = a;

İşaretçileri anlamadan kimse bellek yönetimini, yığını, yığını ve hatta dizileri anlayamaz! Ek olarak, fonksiyonların ve nesnelerin nasıl iletildiğini anlamak için işaretçileri ve referanslardan çıkarmaları anlamak gerekir.

TL: DR : İşaretçileri anlamak, gerçekten çalışan bilgisayarları anlamak için temeldir .


2

Programcılar üzerinde çalıştıkları doğrudan donanım ile daha az uğraşırken, işaretçilerle başa çıkma ihtiyacının azaldığını düşünüyorum. Örneğin, bir bağlantılı liste veri yapısının, uzmanlaşmış donanımın sahip olduğu 640 bayt bellek modülü sırasına tam olarak uyacak şekilde tahsis edilmesi.

İşaretçilerle manuel olarak ilgilenmek hataya eğilimli olabilir (bellek sızıntılarına ve sömürü koduna neden olabilir) ve doğru olması zaman alıcıdır. Böylece Java ve C # etc artık hafızanızı ve işaretçilerinizi Sanal Makineler (VM'ler) aracılığıyla sizin için yönetiyor. Bu tartışmalı olarak, VM'lerin sürekli olarak iyileştirilmesine rağmen, ham C / C ++ kullanmaktan daha az etkilidir.

C (ve C ++), özellikle Yüksek Performanslı Bilgi İşlem, Oyun ve gömülü donanım alanlarında hala yaygın olarak kullanılan dillerdir. Java'nın referanslarına geçiş (işaretçilere benzer bir kavram) çok kolay olduğu ve ilk NullPointerException'ımı (gerçekten NullReferenceException olarak adlandırılması gerekir) gördüğümde, işaretçilerden öğrendim. .

Hala bir çok veri yapısını desteklediğinden, işaretçiler kavramını öğrenmeyi tavsiye ediyorum. Ardından, çalışmayı sevdiğiniz bir dili seçmeye devam edin, NPE gibi bir şey olursa, gerçekten neler olduğunu bildiğinizi bilin. .


0

Nesnel gerçek budur:

Bazı diller doğrudan belleğe erişimi (işaretçiler) destekler, bazıları desteklemez. Her durum için iyi sebepler var.

  1. Burada birinin söylediği gibi, C günlerinde, otomatik bellek yönetimi bugün olduğu kadar ayrıntılı değildi. Her nasılsa, insanlar buna alışmıştı. O zamanlar iyi programcılar, bilgisayar programlarını kuşağımızdan çok daha derin bir anlayışa sahiptiler (ben 21). Ana bilgisayarda bir derleme zamanı için delikli kartlar ve bekleme günleri kullanıyorlar. Muhtemelen kodlarındaki her bitin neden var olduğunu biliyorlardı.

  2. C gibi dillerin bariz avantajı, programınız üzerinde daha iyi kontrol sahibi olmanıza izin vermesidir. Bugünlerde gerçekten ne zaman ihtiyacın var? Yalnızca işletim sistemi ile ilgili programlar ve çalışma zamanı ortamları gibi altyapı uygulamaları oluştururken. Yalnızca iyi, hızlı, sağlam ve güvenilir bir yazılım geliştirmek istiyorsanız, otomatik bellek yönetimi genellikle daha iyi bir seçimdir.

  3. Gerçek şu ki, doğrudan hafızaya erişim çoğunlukla yazılım geliştirme tarihi boyunca kötüye kullanılıyor. İnsanlar bellek sızdıran programlar oluşturuyorlardı ve fazla bellek ayırma nedeniyle gerçekte daha yavaştırlardı (C'de işlemin her bir tahsis için sanal bellek alanını genişletmek kolay ve yaygındı).

  4. Bu günlerde, sanal makineler / çalışma süreleri, programlayıcıların% 99'undan bellek ayırma ve serbest bırakma konusunda çok daha iyi bir iş çıkarmaktadır. Bunun yanı sıra, programınızın sahip olmasını istediğiniz akışta size ekstra esneklik sağlarlar, çünkü (çoğunlukla) doğru zamanda ve yerde tahsis edilmiş belleği serbest bırakmakla meşgul değilsiniz.

  5. Bilgi gelince. Programcıların, programladıkları ortamların nasıl uygulandığını bilmesinin çok şaşırtıcı olduğunu düşünüyorum. En küçük detaylara değil, büyük resme.

İşaretçilerin nasıl çalıştığını (en azından) bilmenin ilginç olduğunu düşünüyorum. Polimorfizmin nasıl uygulandığını bilmek gibi. İşleminizin hafızasını nereden aldığı ve nasıl. Bunlar kişisel olarak her zaman ilgimi çeken şeyler. Dürüst olmak gerekirse, beni daha iyi bir programcı yaptığını söyleyebilirim, ancak iyi bir programcı olmak isteyen herkes için bir eğitim gerekliliği olduğunu söyleyemem. Her iki durumda da, daha fazlasını bilmek işinizi daha iyi hale getirecek .

  1. Gördüğüm gibi, yapmanız gereken tek şey Java veya C # ile bir uygulama oluşturmak ya da onun gibi bir şeyse, uygun tasarım ve uygulama tekniklerine odaklanmanız gerekir. Test edilebilir kod, temiz kod, esnek kod. Bu sırayla.

Çünkü tüm küçük ayrıntıları bilmeseniz bile, yapan kişi, yarattığınız şeyi, daha iyi performans gösteren bir şeyle değiştirebilir. Ve bu genellikle zor bir iş değildir; uygun, temiz ve test edilebilir bir tasarımınız olduğunda (ve genellikle işin çoğu budur).

Bir üst seviye dil başvurusu için birini işe almak isteyen bir görüşmeci olsaydım, bunlar en çok ilgilendiğim şeyler olurdu.

Düşük seviye bilgisi bir bonustur. Hata ayıklamak ve zaman zaman biraz daha iyi çözümler üretmek için iyidir. Bu sizi profesyonel olarak ilginç biri yapar. İş yerinizde size saygı duyulmasını sağlar.

Ancak günümüz dünyasında, bu kutsal bir gereklilik değildir.


-1

Yüksek düzeyde OO dillerinde referansları anlamak çoğu pratik amaç için yeterlidir, bu dillerin işaretçiler açısından referansları nasıl uyguladığını anlamanıza gerek yoktur.

Çok fazla fonksiyonel ve modern multi-paradigma yaklaşımı var, söyleyeceğiniz süslü işaretçi aritmetiğini yapabilmekten çok daha fazla değer veriyorum, muhtemelen std lib'inizin String.copy'sinden daha kötü performans gösteren 1000'inci optimize dize kopyalama fonksiyonunu yazın.

Öncelikle çok daha farklı, daha üst düzey konseptler öğrenmenizi ve donanıma yakın konularda uzmanlaşmaya başlamadan önce ufkunuzu genişletmek için farklı tasarımların dillerini öğrenmek isterim.

Önbellekleme (notlama), SQL-optimizasyon veya sadece web sunucusu yapılandırma ayarları az bir çaba ile% 100 veya daha fazla sonuç verirken, web servletini veya% 5 kazanç için benzer kodu mikro olarak optimize etmek için tamamen başarısız girişimler görüyorum. İşaretçilerle uğraşmak çoğu durumda erken optimizasyondur .


-1

Elbette, eğer gerçekten iyi bir programcı olmak istiyorsanız, kapsamlı bir işaretçi kavramına sahip olmamız gerekir. Pointer konseptinin sebebi, zaman kısıtlamaları ile daha verimli ve daha etkili hale gelen değere doğrudan erişim oldu ...

Ayrıca, Bugünlerde çok sınırlı bir Hafızası olan Mobil Uygulamalar düşünüldüğünde, kullanıcı yanıtıyla işleminin çok hızlı olması için onu çok dikkatli kullanmamız gerekiyor ... Bu nedenle, bu amaçla değere doğrudan bir referansa ihtiyacımız var ...

Yalnızca işaretçi konsepti ile çalışan Apple cihazlarını veya Objective C dilini göz önünde bulundurun. Amaç C'de belirtilen tüm değişken Pointer'a sahiptir. Sen geçmesi gerekir Amaç C'nin wiki


Bugünün mobil uygulamaları, C'nin tasarlandığı bazı veri merkezlerinden daha fazla belleğe sahip. Pek çok mobil uygulama, tümü işaretçiler olmadan Java'da veya doğrudan html + javascript'te yazılmıştır (REFERANSLARINIZ vardır). Çok özelleşmiş programcıların sadece küçük bir bölümü, temel işletim sistemi katmanlarını görebiliyor.
Jürgen Strobel
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.