我想获得一个数组的长度。我有这段代码:
#include <iterator>
#include <iostream>
#include <string>
using namespace std;
void printArrLen(int arr[]);
int testArr [3] = {1, 4, 5};
int main() {
printArrLen(testArr);
cout << "main/testArr; Memory address: " << testArr << ", value: " << *testArr << endl;
cout << end(testArr) << endl;
}
void printArrLen(int arr[]) {
cout << "printArrLen/arr; Memory address: " << arr << ", value: " << *arr << endl;
cout << "printArrLen/testArr; Memory address: " << testArr << ", value: " << *testArr << endl;
// This works:
cout << end(testArr) << endl;
// This doesn't work - no matching function for call to 'end(int*&)':
// cout << end(arr) << endl;
// Doesn't work:
// cout << "arrLen: " << end(arr) - begin(arr) << endl;
}
输出:
printArrLen/arr; Memory address: 0x601318, value: 1
printArrLen/testArr; Memory address: 0x601318, value: 1
0x601324
main/testArr; Memory address: 0x601318, value: 1
0x601324
在printArrLen中取消注释cout << end(arr) << endl;
会产生no matching function for call to 'end(int*&)'
我知道如果begin/end(arr)
是指针,arr
将无效。
为什么它们在printArrLen和main中的testArr上运行,如果testArr似乎也是指针呢?如何在printArrLen中证明testArr
不是指针而arr
是在它们似乎都包含内存地址的时候?
答案 0 :(得分:2)
我知道如果arr是一个指针,开始/结束(arr)将无法工作。为什么它们在printArrLen和main中的testArr上运行,如果testArr似乎也是一个指针呢?
指针不是数组。
在您的代码中,
arr
是已使用3个元素初始化的数组。decays
是数组参数。数组参数在数组printArrLen
到指针的意义上是特殊的,因此实际传递给函数arr
的是指针(到int testArr[] = {1, 4, 5};
第一个元素)。顺便说一句,初始化时不必提供数组大小。这也可以(并且更好):
{{1}}
答案 1 :(得分:1)
testArr
不是指针,它是一个包含3
元素的数组。
arr
是一个指针 - 没有足够的知识使begin
和end
工作,因为编译器不知道它指向一个数组(以及假设数组的大小是)。
我的建议是:使用std::array
或std::vector
,具体取决于您需要做什么。如果要使用旧式数组,请更改printArrLen
以获取数组引用:
template <size_t N>
void printArrLen(int (&arr)[N]) {
/* ... */
}
答案 2 :(得分:1)
我希望得到一个数组的长度。
[...]
void printArrLen(int arr[]);
不喜欢这样。此函数中的arr
实际上是指向数组的第一个元素的指针。或者更确切地说,可能指向数组的第一个元素。它只是一个int*
,可以指向任何地方。在任何情况下, 在函数内部都不再有大小信息。你根本无法得到它。
[]
语法可以让您感到困惑。但是不要接受我的话 - 通过尝试这段代码来询问编译器:
void printArrLen(int arr[]) {}
void printArrLen(int* arr) {}
你会发现它会抱怨重新定义。
int testArr [3] = {1, 4, 5};
testArr
,与上面的arr
参数相比,是一个数组,并且在其类型中包含大小信息。
int main() { printArrLen(testArr);
在这里,您向函数传递一个指向testArr
的第一个元素的指针,即int*
指向&#34; 1&#34;元件。
// This works: cout << end(testArr) << endl;
因为testArr
是一个数组。
// This doesn't work - no matching function for call to 'end(int*&)': // cout << end(arr) << endl;
因为arr
是指针。
如果数组的大小仅在运行时已知,则使用std::vector
;如果在编译时已知数组std::array
,则使用testArr
。两个容器总是知道自己的大小。
如何在printArrLen中证明
arr
不是指针 和int main() { int i = 0; double d = 0.0; }
是什么时候它们似乎都包含一个内存地址?
这个问题没有看起来那么有意义。
考虑一下:
i
现在,你怎么能证明&#34; double
不是d
但是#include <typeinfo>
#include <typeindex>
#include <iostream>
void printArrLen(int arr[]);
int testArr [3] = {1, 4, 5};
int anotherTestArr [3] = {1, 4, 5};
int yetAnotherTestArr [4] = {1, 4, 5, 6};
int main() {
printArrLen(testArr);
}
void printArrLen(int arr[]) {
std::cout << (std::type_index(typeid(arr)) == std::type_index(typeid(testArr))) << "\n";
std::cout << (std::type_index(typeid(anotherTestArr)) == std::type_index(typeid(testArr))) << "\n";
std::cout << (std::type_index(typeid(yetAnotherTestArr)) == std::type_index(typeid(testArr))) << "\n";
}
是
答案是你没有必要证明&#34;它,因为,显然,你已经知道了。
从技术上讲,当然,你的问题还有另一个答案,那就是使用typeid
......
0
1
0
这对您没有任何直接用途,但具有很高的教育价值。它会打印出来:
-- drop table #me
create table #ME (memid int , EffectiveDate datetime , termdate datetime)
Insert into #ME values ('123','3-Dec-16','10-Jan-17')
Insert into #ME values ('123','11-Jan-17','6-Feb-17')
Insert into #ME values ('123','7-Feb-17','5-Mar-17')
Insert into #ME values ('123','8-Mar-17','15-Apr-17')
Insert into #ME values ('123','16-Apr-17','24-May-17')
--drop table #dim
select * from #ME
declare @StartDate datetime , @CutoffDate datetime
select @StartDate= min(effectivedate),@CutoffDate = max(termdate) From #me where termdate<>'9999-12-31 00:00:00.000'
SELECT d
into #dim
FROM
(
SELECT d = DATEADD(DAY, rn - 1, @StartDate)
FROM
(
SELECT TOP (DATEDIFF(DAY, @StartDate, @CutoffDate))
rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
-- on my system this would support > 5 million days
ORDER BY s1.[object_id]
) AS x
) AS y;
--drop table #MemEligibilityDateSpread
select MemID, D As DateSpread Into #MemEligibilityDateSpread From #Dim dim JOIN #me ME on dim.d between ME.effectivedate and me.termdate
--drop table #DateClasified
WITH CTE AS
(
SELECT MEmID,
UniqueDate = DateSpread,
DateGroup = DATEADD(dd, - ROW_NUMBER() OVER (PARTITION BY Memid ORDER BY Memid,DateSpread), DateSpread)
FROM #MemEligibilityDateSpread
GROUP BY Memid,DateSpread
)
--===== Now, if we find the MIN and MAX date for each DateGroup, we'll have the
-- Start and End dates of each group of contiguous daes. While we're at it,
-- we can also figure out how many days are in each range of days.
SELECT Memid,
StartDate = MIN(UniqueDate),
EndDate = MAX(UniqueDate)
INTO #DateClasified
FROM cte
GROUP BY Memid,DateGroup
ORDER BY Memid,StartDate
select ME.MemID,ME.EffectiveDate,ME.TermDate,DC.StartDate,DC.EndDate from #DateClasified dc join #me ME ON Me.MemID = dc.MemID
and (ME.EffectiveDate BETWEEN DC.StartDate AND DC.EndDate
OR ME.TermDate BETWEEN DC.StartDate AND DC.EndDate)
此示例演示了不同大小的数组是不同类型,指针是所有数组类型的不同类型。