而(数组结束) - 如何识别
Posted
技术标签:
【中文标题】而(数组结束) - 如何识别【英文标题】:while (end of array) - how to recognize 【发布时间】:2011-10-12 14:23:40 【问题描述】:我有一个数字数组 1,2,3,4,5 或一个字符数组或其他。我想写一个模板方法来打印出完整的数组。它有效,只是有一些问题。也许我先发布代码:
template <typename A>
void printArray(A start)
int i = 0;
while (start[i] != 0)
std::cout << start[i] << std::endl;
i++;
int main(int argc, char **argv)
using namespace std;
int xs[] = 1,2,3,4,5,6,7; //works
//int xs[] = 1,0,3,6,7; of course its not working (because of the 0)
int *start = xs;
printArray(start);
return 0;
你能看出问题吗? while(start[i] != 0)
不是读取数组以结束的最佳方式;)我还有什么其他选择?
谢谢!
【问题讨论】:
你不是在传递一个数组,你是在传递一个指针。 不要将普通数组视为 C 风格的空终止数组。 【参考方案1】:选项1:传递一个指针和元素个数
template<class T>
void doSth(T* arr, int size)
优势 - 适用于动态和自动数组。劣势 - 您必须知道大小。你必须通过它。
选项2:将模板参数化为自动推导出的尺寸
template <class T, int N>
void doSth(T(&arr)[N])
缺点 - 无法传递动态数组
选项 3: 成为一名优秀的程序员并使用 std::vector
's
【讨论】:
所有合理的解决方案,但建议是最好的部分。【参考方案2】:由于您使用的是 C++,所以从长远来看,vector<int>
和 iterators
会更好。
【讨论】:
【参考方案3】:如果你想使用数组,而不是指针,那么你可以将函数模板写成:
template <typename T, size_t N>
void printArray(T (&start)[N])
int i = 0;
while ( i < N)
std::cout << start[i] << std::endl;
i++;
int xs1[] = 1,2,3,4,5,6,7;
int xs2[] = 1,0,3,6,7;
printArray(xs1); //okay
printArray(xs2); //okay
int *start = xs1;
printArray(start); //error - cannot pass pointer anymore!
所以更好的解决方案是:std::vector<T>
。
或者甚至更好地使用 range (pair of iterators) 这是非常惯用的,如:
template <typename FwdIterator>
void printArray(FwdIterator begin, FwdIterator end)
while (begin != end)
std::cout << *begin << std::endl;
begin++;
int xs1[] = 1,2,3,4,5,6,7;
int xs2[] = 1,0,3,6,7;
printArray(xs1, xs1 + sizeof(xs1)/sizeof(xs1[0])); //okay
printArray(xs2, xs2 + sizeof(xs2)/sizeof(xs2[0])); //okay
int *start = xs1;
printArray(start, start + sizeof(xs1)/sizeof(xs1[0])); //okay!
printArray
现在也可以与std::vector<T>
一起使用:
std::vector<int> vec; //you can use std::list as well!
//populate vec
printArray(vec.begin(), vec.end());
【讨论】:
两个 cmets:除非您指望将它与几种不同类型的容器一起使用,否则将其用作函数模板是没有意义的;一个正常的功能就可以了。其次,当然,不是xs1, xs1 + sizeof(xs1)/sizeof(xs1[0])
,而是通常的begin(xs1), end(xs1)
。
@James Kanze:1) OP 使用了模板,所以我也制作了这个模板,假设他想让它适用于许多不同的类型。2) std::begin()
和 std::end()
可用使用 C++0x,我没有在我的解决方案中假设。 :-)
好的,然后是模板:-)。至于begin
和end
,我(我怀疑许多其他人)没有等待标准。 10 多年来,它在大多数人的工具包中或多或少已经成为标准。
@James:确实如此。诸如begin
和end
之类的实用程序可以用更少的努力实现,即使在C++03 中也是如此。【参考方案4】:
同时传递数组的地址和长度。
【讨论】:
【参考方案5】:如果您使用的是编译时数组,则可以使用模板来执行此操作:
template <typename T, size_t N>
static inline void print_array(const T (&a)[N])
for (size_t i = 0; i < N; ++i)
std::cout << a[i] << std::endl;
int main()
int a[] = 1,2;
print_array(a);
如果您只需要打印数组,还请查看pretty printer,它在内部使用了这种东西。
【讨论】:
@iammilind:Armen 也以 30 秒的优势击败了我 :-)以上是关于而(数组结束) - 如何识别的主要内容,如果未能解决你的问题,请参考以下文章
如何识别 T-SQL 中每个不同成员的多个开始和结束日期范围中的第一个间隙