Fonksiyonlarla ilgili bu cevaplardan hangisi yanlıştır?


17

Bazı uzun derlemeler yaparken ODesk C ++ genel testi yapmaya karar verdi ve bu soruya rastladı.

Bu soru

Yanılmıyorsam, ifadeler (veya eksiklikleri) göz önüne alındığında, bunların hepsi doğru olabilir.

a.

int Foo() { }
int Foo(int bar) { }

b. return void;Anlamsal olarak yanlış olur , ancak fonksiyonlar açıkçavoid dönüş türleri olabilir.

void Foo() { }

c.Bu, satır içi işlevlerin tanımıdır, evet.

d. Aşağıdaki öğelerin yerleşimi hakkında çok fazla ayrıntıya girmeden,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Ayrıca, bunu her zaman kullanarak yapabilirsiniz lambdas ve functor .

e.

void Foo(int& bar)
{
    ++bar;
}

int foobar = 5;
Foo(foobar);

f.

int bar = 5;

int& GetBar()
{
    return bar;
}

GetBar() = 6;

g.

int bar = 5;

int* GetBar()
{
    return &bar;
}

(*GetBar()) = 5;

Bu sorunun nerede olduğunu göremiyorum gerçekte yanlış cevaplara . Bir şey mi kaçırıyorum?

Söylemeye gerek yok, zamanım bitti ve her şeyi başaramadım. Sanırım ben kötü bir C ++ programcısıyım. :(


18
Bazı çocuklara ödev yapıştırma diye bağırmak için buraya geldi, hoş bir sürpriz oldu.
SomeKittens

Aslında tüm diller satır içi işlevlerin genişletilmesini gerektirmez. "satır içi" Delphi bir komut yerine bir derleyici ipucu ve C, C ++ istisnalar vardır . Yani "c" de yanlış olabilir. Her ifadenin nasıl yanlış olabileceğini gösteren bir cevap yazmak daha eğlenceli olabilir.
Moz

1
@ Ӎσᶎ Yalnızca bir metin kutusu olsaydı. Geri dönüp "Bu soruyla ilgili bir sorunu bildir" e tıklamak istiyorum.
Qix

5
Bu bir dizi işlev değil. Bu bir dizi fonksiyon işaretçisi.
user253751

@immibis Doğru, ama soru gerçekten netleşmiyor (en azından benim için değil).
Qix

Yanıtlar:


21

Bütün bu soru çok tehlikeli. Soru ifadesi çoklu seçenek olasılığını ifade ederken, radyo düğmeleri tek bir seçeneği belirtir.

Dahası, boş fonksiyonlar hiçbir şey döndürmediği için b oldukça şüphelidir.

D de sorgulanabilir, bildiğim kadarıyla bir dizi fonksiyona sahip olamazsınız. Tabii, bir dizi fonksiyon işaretçisi olabilir, ama bu tam olarak aynı şey değildir.


Sağ; D, bir int. Elbette, bir işaretçiye
başvurursa

1
D'nin aradığı cevap olduğuna bahse girmeye hazırım, ama evet, soru zayıf.
Robot Gort

İken voidişlevleri herhangi dönmüyor değeri , hala dönüş türü void . Böylece B'nin doğru olduğunu söylüyorum.
Thomas Eding

@ThomasEding Bu hala kendi adına gerçekten kötü bir ifade. Yapmazsın return void;ama onun yerine return;.
Qix

10

C) cevabı da tartışmalıdır.

"Satır içi işlevleri, çağırma yükünü önlemek için derleme süresi boyunca genişletilir."

İlk olarak, C ++ derleyicisinin inlineişlevleri hiç genişletmeyerek ipucunu görmezden gelmesine izin verilir .

İkinci olarak, genişleme yapmanın belirtilen "nedeni" aşırı basitleştirmedir. Aslında, genişleme yapmanın (veya yapmamanın) gerçek nedeni tamamen derleyici yazarının elindedir.


Sen doğru, ama ben anlamında bunu düşünüyordum 'tamam derleyici kendisi tarafından belirlenmiş gelmez bir işlevi satır içi istiyorum' yerine inlineipucu.
Qix

Derleyici ipucunu tamamen görmezden gelemez. En azından ODR için bir istisna yaparak zorunlu bir etki.
Tekilleştirici

@Deduplicator - Evet yapabilir. "Bir işlevi satır içi olarak nasıl tanımlasanız da, derleyicinin yoksaymasına izin verilen bir istektir: derleyici satır içi olarak adlandırılan bir işlevi çağırdığınız yerlerin bir kısmını, tümünü veya hiçbirini satır içinde genişletebilir." - kaynak isocpp.org/wiki/faq/Inline-Functions
Stephen C

@StephenC: Satır içi genişletme isteği yok sayılabilir, evet. Ben sadece ODR için istisnai istisna yapamayacağını söyledim.
Tekilleştirici

Anlıyorum. Cevabımın ifadesini güncelledim
Stephen C

7

c. Bu, satır içi işlevlerin tanımıdır, evet.

Bu tamamen doğru değil.
Adına rağmen, anahtar kelime inlinebir işlevin satır içine alınacağını garanti etmez. Emin olabileceğiniz tek şey, derleyicinin bir satır içi işlev tanımını birden çok kez görmesi durumunda şikayet etmeyeceğidir.

Açıkçası, seçenek C yanlıştır, ancak sınavın yazarlarının beklediği cevap olduğunu düşünmüyorum, çünkü daha da yanlış bir cevap var.

d. Aşağıdaki öğelerin yerleşimi hakkında fazla ayrıntıya girmeden,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Dahası, bunu her zaman lambdas ve functor kullanarak yapabilirsiniz.

Örneğin, functionsbir işlevler dizisi değil, işlevler için bir işaretçi dizisidir. Benzer şekilde, lambdalar ve functorlar da gerçekten işlev görmezler. Bunlar, işlev çağrısı işlecine yanıt veren sınıflardır, ancak bu onları C ++ dil tanımının gözünde işlev yapmaz.

C ++ 'daki işlevler ikinci sınıf vatandaşlara benzer. Bunları tanımlayabilir ve çağırabilirsiniz, ancak bir işlev türüyle (bunlardan bir dizi oluşturmak gibi) başka bir şey yapmaya çalıştığınızda, bir hata alırsınız veya sessizce bir işaretçi haline dönüşürler.


D biti ile aynı fikirdeyim, ancak anahtar kelimenin kendisine cgöre satır içi çizgi için zaten pozitif olarak işaretlenmiş işlevler olarak okuyordum inline. Anlıyorum inlinebir ipucu.
Qix

4

Bir şey olursa, b olmalı . Yapamazsınız returnbir void, ama bir dönebilirsiniz null. İşlev beyanında geçersizlik derleyiciye iade edilen bir değerin olmadığını bildirmek için orada olmalıdır.

Boş Tip

C ve C ++ 'da

Void sonuç türüne sahip bir işlev, işlevin sonuna ulaşarak veya döndürülen değeri olmayan bir döndürme ifadesi yürüterek sona erer. Void türü, işlevin bağımsız değişken almadığını gösteren bir işlev prototipinin tek bağımsız değişkeni olarak da görünebilir. İsme rağmen, tüm bu durumlarda, boş türün, tek veya gerçek bir birim türünün aksine, sıfır veya alt tür olarak değil, bir birim türü olarak hizmet verdiğine dikkat edin, boş türün boş bir içerdiği söylenir. değerler kümesi kullanırsanız ve dil, bir nesne bildirmek veya void türünde bir değeri temsil etmek için herhangi bir yol sağlamaz.


2
-1: voidİşlevler herhangi bir değer döndürmezken, yine de türü döndürür void. Böylece B'nin doğru olduğunu söylüyorum.
Thomas Eding

Bazı durumlarda geri dönüş boşluğuna izin verilir. Buraya bakın .
Josh Kelley
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.