而(数组结束) - 如何识别

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&lt;int&gt;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&lt;T&gt;

或者甚至更好地使用 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&lt;T&gt; 一起使用:

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,我没有在我的解决方案中假设。 :-) 好的,然后是模板:-)。至于beginend,我(我怀疑许多其他人)没有等待标准。 10 多年来,它在大多数人的工具包中或多或少已经成为标准。 @James:确实如此。诸如beginend 之类的实用程序可以用更少的努力实现,即使在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 秒的优势击败了我 :-)

以上是关于而(数组结束) - 如何识别的主要内容,如果未能解决你的问题,请参考以下文章

如何从开始日期和结束日期识别和聚合序列

如何更好地识别 SQL 中指定的开始和结束端点内的表冲突?

如何识别 T-SQL 中每个不同成员的多个开始和结束日期范围中的第一个间隙

Oracle SQL 或 PL/SQL:如何仅在上升趋势或下降趋势结束时识别烛台形态并在列中设置标志?

python:如何识别变量是数组还是标量

如何以最小的复杂性识别数组中的重复数字?