使用指针迭代数组元素

时间:2014-03-17 14:38:31

标签: c++ arrays pointers iterator

我尝试执行代码:

char* m[3] = {"123", "456", "789"};
for(char* st=*m; st!=0; st=*(m+1))
{
    cout <<st;
} 

但它挂断并打印:123456456456 ...

4 个答案:

答案 0 :(得分:3)

立即停止使用char*字符串并开始使用std::string。 C风格的数组也是如此:开始使用std::arraystd::vector。这将为您节省多年的生命和不必要的痛苦。

看看这段代码有多漂亮:

std::array<std::string, 3> m = {"123", "456", "789"};
for (auto& s : m) 
    std::cout << s;

here是实例。

答案 1 :(得分:2)

您编写的循环无效

char* m[3]={"123","456","789"};
for(char* st=*m;st!=0; st=*(m+1))
{
    cout <<st;
} 

表达式*m的类型为char *,而数组m不包含NULL指针。条件st!=0; 是错的。并且指针总是指向相同的元素,因为表达式st=*(m+1)总是给出数组的第二个元素

还要考虑到数组的正确定义是

const char* m[3] = { "123", "456", "789" };

因为它是一个指向字符串文字的指针数组,字符串文字可能不会改变。

您可以简单地使用基于声明的范围

const char* m[3] = { "123", "456", "789" };
for ( const char* st : m )
{
    cout <<st << std::endl;
} 

或者你可以在循环中使用迭代器。例如

const char* m[3] = { "123", "456", "789" };
for ( auto it = std::begin( m ); it != std::end( m ); ++it )
{
    cout << *it << std::endl;
} 

您可以使用标准算法std::copy

#include <iostream>
#include <algorithm>
#include <iterator>

//,,, 
const char* m[3] = { "123", "456", "789" };
std::copy( std::begin( m ), std::end( m ),
           std::ostream_iterator<const char *>( std::cout, "\n" ) ); 

答案 2 :(得分:1)

使用此处提供的代码是一种方法:

const char* m[3]={"123","456","789"};
const unsigned int element_count = sizeof(m) / sizeof(m[0]);
//not a nice to have sizeof here, but i used this to keep the code
// consistent with the code provided in the question

for( const char** st = m; st!= (m + element_count) ; st ++ )
{
    cout << *st;
}

正如您所看到的那样,通过char*元素数组进行迭代,您需要使用指向char*的指针,因此迭代变量char **的类型为st

你拥有的代码是一个无限循环,因为你为st分配了*(m+1),它永远不会等于0,实际上它每次都是第二个元素。

然而,通过使用std::vector例如:

,可以使用更安全的方法
std::vector<std::string> m = {"123", "456", "789"};
for (auto& st : m) 
    std::cout << st;
//or:
for(std::vector<std::string>::iterator i = m.begin(),e = m.end();i != e;i++)
    std::cout << *i;
//or:
for(std::size_t i = 0;i < m.size() ;i++)
    std::cout << m[i];

答案 3 :(得分:1)

问题是你在每次迭代中指向一个指向同一位置的指针:

char* m[ 3]={ "123","456","789"};
for( char* st = *m; st != 0; st = *( m + 1))
                               // ^^^^^^^^^  <- this doesn't change, 
                               //               st points to *(m+1)
{
    std::cout << st;
}

同样你不应该使用非const char *指向不可修改的字符串文字:

const char* m[ 3]={ "123","456","789"};
const unsigned int n = sizeof( m) / sizeof( m[ 0]);

for( const char** st = m; st != (m + n) ; st ++ )
{
    cout << *st;
}

即使是基于范围的迭代也可以工作:

const char* m[ 3] = { "123", "456", "789" };
for ( const char* st : m )
{
    std::cout << st << std::endl;
} 

如果出于某种原因你必须坚持简单的迭代,这也会有效:

const char* m[ 3]={ "123","456","789"};
const char* st;
int r = 0;
for( st = *m; r < 3; st = *( m+r))
{
    std::cout << st << std::endl;
    r++;
}

请考虑使用标准容器,即std::vectorstd::array。它将对您有所帮助,主要是动态内存管理。

std::vector< std::string> v = { "123", "456", "789"};
for ( auto& s : v) 
    std::cout << s;