Yapılar hakkında özel olan nedir?


81

C'de bir işlevden bir dizi döndüremeyeceğimizi, bir diziye göstericiyi döndüremeyeceğimizi biliyorum. Ancak structs, diziler içerse bile, onları fonksiyonlar tarafından döndürülebilir kılan özel şeyin ne olduğunu bilmek istiyorum .

Neden structsarma aşağıdaki program geçerli kılan?


1
Aynı şeyi a ile de yapabilirsiniz union. Sendikaları özel kılan nedir?
user253751

19
C de dizilerin neden bu kadar tuhaf olduğunu sormayı tercih etmelisiniz.
CodesInChaos

bir yapı döndürülürken, yapı birkaç kütüğe sığmayacaksa, derleyici tarafından ayrılan 'gizli' bir bellek, yapı (memcpy () aracılığıyla) gizli belleğe kopyalanır ve sonra tekrar kopyalanır (memcpy ( )) Arayanların yapı değişkeni. Bu 'gizli' hafıza diğer tüm işlevler için kaybolur. İki ekstra çağrı memcpy()ve 'gizli' belleğin kaybı, bir yapının passed toveya returned frombir işlevin olmaması gereken ana nedendir . En iyi ilke, yapıya bir işaretçi iletmektir.
user3629249

üç cevabın hiçbiri bir yapının geçişini ele almıyor (daha ziyade sadece geçen dizileri tartışıyorlar), ancak soruyu cevaplamıyorlar.
user3629249

1
@ user3629249 - Soruyu cevaplamak imkansız çünkü soru anlayış eksikliğine dayanıyor. Soruyu cevaplamanın tek yolu, sorunun neden sorulmadığını açıklamaya çalışmaktır. Size "Mavi neden Kırmızı ile aynı renk?" Diye sorduğumu hayal edin. Soruyu neden cevaplayamadığınızı hızlıca açıklarsınız.
Hogan

Yanıtlar:


100

Aynı soruyu sormanın daha iyi bir yolu, "diziler hakkında özel olan nedir" olacaktır, çünkü diziler kendilerine bağlı olan dizilerdir, structs değil .

İşaretçi ile dizileri geçirme ve döndürme davranışı, C'nin orijinal uygulamasına kadar uzanır. Diziler işaretçilerde "bozunur" ve özellikle dile yeni olan kişiler arasında büyük bir kafa karışıklığına neden olur. Öte yandan yapılar, ints, doubles, vb. Gibi yerleşik türler gibi davranır . Bu, kopyalanmayan esnek dizi üyeleristruct dışında, içine gömülü olan tüm dizileri içerir .


4
gerçekten de "epey kafa karışıklığına neden oluyor". 'x' ve '& x' aynı değer / adres olmak çok çılgınca. Yenilerin yanlış yönlendirilmesi şaşırtıcı değil :(
Martin James

1
Hafızam beni aldatıyor olabilir, ancak structs değerine göre geçmenin mümkün olmadığı zamanlar olmadı mı?
alk

5
@alk Bence yapılar dile ilk eklendiğinde, başlangıçta onları işlevlere geçirme / işlevlerden geri döndürme konusunda bazı kısıtlamalar vardı, ancak bunlar derleyicide açıkça bir eksiklik olarak işaretlendi ve kısa süre sonra düzeltildi, bir gösterge değil Onları geçmek ve geri vermek istemekte yanlış bir şey olduğunu.
Steve Zirvesi

8
@jamesqf: struct Point {short x, y, z;};. Onları hareket ettirmek için gerçekten işaretçileri kullanmak istiyor musun? Bu şekilde kesinlikle yerden tasarruf etmiyorsunuz.
Mark VY

6
@jamesqf Bunun bir yanıtı hak ettiğinden emin değilim. C'nin montajdan çok daha fazlası olmadığına inanıyorsanız, bir işaretçi kullanmamak için hiçbir zaman bir neden olmadığına inanıyorsanız, yapıları geçirmenin işe yaramaz olduğunu nasıl düşündüğünüzü görebilirim. Ancak, C'yi yüksek seviyeli bir dil olarak (düşük seviyeli olsa da, HLL'ler gibi) ve C'nin tip sistemini genel olarak gören (dizilerin ikinci sınıf statüsü dışında, ), neden olmaz biz geçmesi veya yapılar dönmek istiyorum? (BTW, IIRC, K & R1, yapı geçişinin yolda olduğunu söyledi ve kitap çıktığında V7 cc'de çalıştı.)
Steve Summit

38

Öncelikle alıntı yapmak C11gerekirse, bölüm §6.8.6.4, returnaçıklama ( vurgu benim )

İfadeli bir returnifade çalıştırılırsa, ifadenin değeri işlev çağrısı ifadesinin değeri olarak çağırana döndürülür .

Yapı değişkeninin döndürülmesi mümkündür (ve doğrudur), çünkü yapı değeri döndürülür. Bu, herhangi bir ilkel veri türünü döndürmeye benzer ( intörneğin, döndürme ).

Bir dönerseniz Öte yandan, dizi , kullanarak return <array_name>, aslında döner birinci elemanın adresini dizisi ait NOT dizisi denir işlevlerine yerel olsaydı arayan geçersiz hale gelir. Yani diziyi bu şekilde döndürmek mümkün değildir.

Yani TL; DR , s ile özel bir şey yok struct, özellik dizilerde .


NOT:

C11Tekrar alıntı yapmak , bölüm §6.3.2.1, ( vurgu )

sizeofOperatörün, _Alignofoperatörün veya tekli &operatörün işleneni olduğu veya bir diziyi başlatmak için kullanılan bir dize değişmezi olduğu durumlar dışında, '' dizi türü '' türüne sahip bir ifade, '' türünde bir ifadeye dönüştürülür. dizi nesnesinin ilk öğesine işaret eden ve bir lvalue olmayan '' tipine işaretçi . [...]


OTOH tam olarak nedir ?!

1
Bu :) "Öte yandan" kısaltmasıdır @Sukl
Sourav Ghosh

1
@Sukl Bu kısaltmaların kabaca İnternet kadar eski olduğunu düşünüyorum. Usenet zafer günlerinde kesinlikle çok kullanıldılar ve çoğu forumda hala hayatta kalıyorlar. Neyse ki, habersiz olanlar için bile, Google bunları çözebilir ;-) Ve bugün sıkça kullanılan (en yaygın olanları) yalnızca bir avuç dolusu var
chi

@chi yes.Google oldukça zekidir ve bunların kodunu çözebilir.

1
@Sukl: Kısaltmaları takip etmek için AcronymFinder'ı yararlı bulabilirsiniz .
Jonathan Leffler

11

Türlerle ilgili özel bir şey yok struct; doğrudan bir işlevden döndürülmelerini engelleyen dizi türlerinde özel bir şey vardır .

Bir structifade, herhangi bir dizi olmayan türden bir ifade gibi ele alınır; değerine göre değerlendirir struct. Böylece şöyle şeyler yapabilirsiniz

İfade , nesnenin değerine göre someFoodeğerlendirilir ; nesnenin içeriği işlevden döndürülür (bu içerikler diziler içerse bile).struct foo

Bir dizi ifadesi farklı şekilde ele alınır; Bu işlenen değilse sizeofya da tekli &türünden ( "bozunmaktadır") "dizisi operatörler ya da bir beyanda bir diziyi başlatmak için kullanılan hazır bir dize değilse, ifade dönüştürülmüş olan T" işaretçi için " T" ve ifadenin değeri, ilk öğenin adresidir.

Dolayısıyla , bir işlevden değere göre bir dizi döndüremezsiniz , çünkü bir dizi ifadesine yapılan herhangi bir başvuru otomatik olarak bir işaretçi değerine dönüştürülür.


-5

Yapılar varsayılan olarak herkese açık veri üyelerine sahiptir, bu nedenle struct durumunda verilere ana olarak erişmek mümkündür, ancak sınıf durumunda değil. Yani, yapı sarma geçerlidir.


1
Sorunun C ile ilgili olduğunu gördünüz mü? C'de ayrım public/ privateayrım yoktur ve classes yoktur . Soru, structbir dizinin değerini döndürmek için C'de neden a'nın gerekli olduğuyla ilgilidir.
PJTraill
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.