標籤:

C++獲取數組長度只返回1?

#include &
using namespace std;

template&
int GetArrayLength(T a)
{
return sizeof(a)/sizeof(a[0]);
}

int getlen(int ary[]) {
return GetArrayLength(ary);
}

int main() {
int ary[] = {1,2,3};
cout &<&< getlen(ary) &<&< endl; }

以上代碼輸出1,理想應為輸出3。

中間出了什麼問題嗎?


見C++11的http://en.cppreference.com/w/cpp/types/extent 實現。


在 int getlen(int ary[])

的時候,ary其實已經是指針了

所以最後 sizeof(a)/sizeof(a[0]);

其實等同於 sizeof(int *)/sizeof(int) 在32位編譯環境下當然就是 1 了。


返回數組長度的正確模板寫法

// 在編譯的時候返回數組的長度(數組參數沒有名字,
// 因為只關心數組包含的元素的個數)
template&
constexpr std::size_t arraySize(T ()[N]) noexcept
{
return N;
}

int keyVals[] = { 1, 3, 7, 9, 11, 22, 35 }; // keyVals有七個元素

int mappedVals[arraySize(keyVals)]; // mappedVals長度也是七

參考C++11其中模板類型推導關於數組的處理。

注意上面的代碼沒法在VS2013下面編譯通過,如果想在VS2013下面編譯通過的話,需要去掉constexpr和noexcept關鍵字,去掉constexpr關鍵字會導致arraySize模板函數返回的結果無法作為新數組的初始化大小數值


數組作為函數參數時退化為指針.


給一個c++實現。

template&

struct dim_helper {

};

template&

struct dim_helper &< T[N] &> {

char c[N];

};

template&

dim_helper& make_dim(T(a)[N]);

#define dim(x) sizeof(make_dim(x))


這個問題似乎沒有任何意義(說下理由,別噴,可以交流)

數組本來就是定長的,而這個長度要麼是你顯式定義的int list[10]——你知道數組的長度還要獲取它幹什麼

要麼是編譯器推斷的int list[]={1,2,3}——你自己寫的三個數難道你自己不知道他有多長?

就算是new開闢的數組,也是要求確定長度,這個長度要麼是你寫的常量,要麼是程序運行時的變數——前者你自己本來就知道,後者可以拷貝給另一個變數保存起來。

而傳進函數里的數組就是個指針,你可以隨意取指針+n的解引用值,是否越界要你自己控制,這還是要你自己清楚數組在定義時是有多長。

字元數組的長度是由末尾的字元作為標記而確定的,C風格數組沒有類似的標記,除非你自己用一個約定好的數字作為數組結尾,然後用循環確定長度。


其實這個問題是 sizeof的問題。這樣的問題就不要在知乎上問了吧。

int a[100]; sizeof(a) 是數組a的長度*sizeof(int) ;但是 int * b = a; sizeof(b)的話就不是a的大小了,而這個時候轉換為了求b指針類型的大小了。詳情請去了解sizeof


數組作為函數參數時會退化為指針。(這都是為了兼容 C

你需要用數組的引用作為參數

#include &
using namespace std;

template &
size_t getlen(T ()[N]) {
return N;
}

int main() {
int ary[] = {1,2,3};
cout &<&< getlen(ary) &<&< endl; }


有兩個解決辦法。第一個,就是不要把數組名當參數傳進函數,直接在main里用sizeof算。第二個,就是傳指向數組的指針或者引用,不過這個辦法是要你知道數組大小的~


為了避免複製操作,所以編譯器會把形參中的數組退化為指針,所以你的結果永遠是1,無論你的數組有多長。數組的長度是一個編譯期常量,為什麼要調用一個運行期的函數去完成這項工作。事實上,在函數內部是無法獲得數組的長度的。回憶一下學C語言的時候,數組做參數為什麼還要傳遞長度這個參數,如果在函數內部可以獲得長度,那麼是不是可以少用一個形參。


一個指針也就4個位元組,整數四個。4除以4等於一。返回1。程序很正確


樓上已經說了,作為參數之後數組退化為指針,所以就是說在函數里a和a[0]代表的都是一個東西,a不能知道數組的長度,它只是作為數組的起始地址存在


我是初學者,不懂模板,看不懂第一個函數的參數的類型。不過數組作為函數參數的時候肯定是退化為指針的。

按照c++ primer的方法,求數組的長度用迭代器。

另外,c++ primer是不推薦用數組的,書裡面基本都是用容器的(數組不能改變長度,每次要弄一個夠用的數組經常要用 int a[10000],b[10000]這種聲明,感覺非常醜陋)。數組在c++似乎作為c的遺產,已經是一個被淘汰的落伍產物了。(再次聲明我是初學者,觀點未必對...)


推薦閱讀:

構造函數不能是虛函數?
C++ 對象是如何完成成員函數的調用的?
vs2013 有必要 使用 visual assist或resharper嗎?
如何閱讀protobuf源碼?

TAG:編程 | C |