2016-04-10 15 views
0

C++ eğitmenim, sınıfta C++'da bir dizi boyutunu belirleyecek bir işlev olmadığını ve bundan memnun olmadığımızı söyledi. Ben bu kodu (sizeof(array)/sizeof(*array)) verdi ve ben tam olarak anlamadığım halde stackoverflow üzerinde bir soru buldum, anladım ki, bu diziye tahsis edilen toplam bellek miktarını alır ve varsayılan bellek ayırma olduğunu varsaydığım şey ile böler. veri tipi ... (???) Yazma işlevlerini (CS 111 - Temel Bilgiler 1) uygulamamı istedim ve onu ilettiğim herhangi bir dizideki öğe sayısını döndüren bir işlev yazmaya karar verdim. Yazdıklarımız buydu:Bir diziyi C++ uygulamasında geçirirken, sizeof() neden ana işlevdekiyle aynı çalışmaz?

#include <iostream> 
using namespace std; 

int length_of_array(int some_list[]) 
{ 
    // This only returns the integer 1 for some reason 
    return (sizeof(some_list)/sizeof(*some_list)); 
} 

int main() 
{ 
    // Declare and initialize an array with 15 elements 
    int num_list[] = {2,4,6,8,10,12,14,16,18,20,22,24,26,28,30}; 

    //Outputs what I assume is the total size in bytes of the array 
    cout << sizeof(num_list) << endl; 

    //Outputs what I assume to be size of memory set aside for each in element in an array 
    cout << sizeof(*num_list) << endl; 

    //This extrapolates array's number of elements 
    cout << "This is the output from direct coding in the\nint main function:\n" << 
      (sizeof(num_list)/sizeof(*num_list)) << endl; 

    //This function should return the value 15 but does not 
    int length = length_of_array(num_list); 

    cout << "This is the length of the array determined\n"; 
    cout << "by the length_of_array function:\n" << length << endl; 



    return 0; 
} 

Ne yaptığımın bir önemi yok. Birisi bana C++ özel bir geçici çözüm ve nasıl çalıştığını açıklar mı? Teşekkür ederiz. Temelde

int length_of_array(int some_list[]); 

Eğer bir fonksiyonun argüman olarak bir dizi geçirilecek zaman, sen int arr[] veya int arr[42] gibi geçerse olursa olsun, dizi ONE ile (bir işaretçi bozunur:

+0

C fonksiyonları aslında diziler olarak argümanlar alamaz. Diziler yerine * işlevlere geçirildiğinde imleçlere * dönüşürler. Bkz. Http://www.c-faq.com/aryptr/ – jamesdlin

+0

Bu, tam olarak bu sorunun bir kopyası değildir. Bu C hakkında, bu C++ hakkında. Ve cevabın gösterdiği gibi, önemli bir fark var. C.'de bu şablon numarasını kullanamazsınız. Yeniden açılmak için oy veriyorum. –

+0

Eğer tamamen farklı bir cevabı varsa, nasıl bir kopyası olur - kabul edilen cevap çoğaltıldığını söylediğiniz soruya uygulanabilir mi? – Sinux1

cevap

2

sorun burada imza yukarıdaki

int length_of_array(int* some_list); 

eşdeğerdir yüzden dizi için çürümüş pointer büyüklüğü ve tipi repres büyüklüğü arasındaki oranı alacak sizeof(some_list)/sizeof(*some_list) yaparken elbette Yani iSTİSNA,) aşağıya bakınız ilk unsuru Durumunuzda, makinenizde göründüğü gibi 1, bir işaretçinin büyüklüğü, bir int boyutunda olduğu gibi 4 baytlık (32 bit) olabilir.

Bu yüzden C++ eğitmenim C++'daki bir dizi boyutunu belirlemek için herhangi bir fonksiyonun bulunmadığını ve bundan memnun olmadığımızı sınıfta anlattı.

ÖĞRETMENİZ YANLIŞ! referans olarak dizisi geçirerek ve boyutunu almanın bir yolu yoktur:

template<size_t N> 
int length_of_array(int (&arr)[N]) 
{ 
    std::cout << N << std::endl; // WORKS! 
    return N; 
} 
+0

Bu tam olarak yanlış değil. Dizi boyutunu belirlemek için * işlevi yoktur. Bunu yapmak için bir * yol * değeri bulmuş olabilirsiniz, ancak daha sonra dinamik olarak ayrılmış diziler için çalışmayacaktır. Ama neyse, iyi bir numara. Merak etmeden neden işe yaramadığını merak ediyorum? Büyüklüğünü açıkça beyan etsem bile bir işaretçiye zıt olduğu için mi? –

+0

@SergeyTachenov Teknik olarak haklısınız, ancak öğretmenimin diziyi nasıl geçerseniz edin, büyüklüğünü elde edemeyeceğiniz anlamına geldiğinden eminim. Referans olarak aktarılırken, işlev aslında argümanın tam * tipini * kullanır, yani bu durumda int [N] 'dir. Örneğin, şablondan kurtulursanız, ancak 'f (int (& arr) [10]) 'ı geçersiz kılarsanız,' 10''dan farklı boyuttaki dizileri geçemezsiniz. Bir şablon kullanmak, N'yi algılamasına izin verdiği için biraz daha hoştur. – vsoftco

+0

@disk_Error Diziler C ve C++ 'da biraz zor.Bunlar güçlü türlerdir, başka bir deyişle, “int arr1 [10]” ve “int arr2 [20]” iki farklı uyumsuz türü temsil eder. Ancak, bir diziyi bir işleve değere geçirirken, dizi bir göstericiye dönüşür, bu nedenle tip bilgisi "silinir" ve basitçe bir işaretçi olur. Istisna referans ile geçerken. int (& arr) [10] '' arr' 'ın bir int (10)' dizisine bir referans olduğunu gösterir. Kodumda bir şablon kullandım, böylece herhangi bir boyuttan geçebileceksiniz (derleyici, dizinin tam türünü bildiği için 'N' sonucunu çıkaracaktır). – vsoftco

İlgili konular