假设我有一个 QString 数组和一个 QString 指针。我想用指针遍历整个数组;我可以这样做吗?
QString * strPointer;
QString data[100];
strPointer = & data[0]; //address to first element
strPointer ++; //address to second element
这是有效的还是我做错了什么?
你在正确的路线上。这是一种方法
QString data[100];
for (QString* strPointer = &data[0]; strPointer != &data[100]; ++strPointer)
{
...
}
是的,只要指针的类型与数组中实际指向的类型相匹配就可以了。通过递增指针,您正在执行指针算术。
值得注意的是,由于标准库中的迭代器在许多方面都被编写成看起来和感觉像指针,并且所有标准库算法都将迭代器指定为模板参数,因此使用这些算法是合法且定义明确的原始指针也是如此。例如,这是完全合法的,即使有你的指针:
const size_t num_data = sizeof(data)/sizeof(data[0]);
std::copy( &data[0], &data[num_data], ostream_iterator<QString>(cout,"\n") );
...当然假设您已经operator<<
为一个QString
对象实现了。
现在,说了这么多,看看这个:
QString data[100];
这100
就是所谓的幻数。幻数的使用被广泛认为是一种反模式,或者是一种不好的做法。问自己几个问题:
最好尽可能避免使用幻数。您在100
这里的选择是任意的。最好使用随着您添加和删除对象而增长和缩小的集合类型。 std::vector
是一个很好的起点:
std::vector<QString> data;
现在您可以添加项目:
data.push_back( ... );
...删除它们,并使用迭代器轻松迭代:
std::copy( data.begin(), data.end(), ostream_iterator<QString>(cout,"\n") );
是的,增加指向数组元素的指针将产生指向下一个元素或指向数组末尾后一个位置的指针。
当具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向与原始元素偏移的元素,使得结果和原始数组元素的下标之差等于积分表达式。换句话说,如果表达式 P 指向数组对象的第 i 个元素,则表达式 (P)+N(等价于 N+(P))和 (P)-N(其中 N 的值 n)指向,分别是数组对象的第 i + n 个和第 i - n 个元素,前提是它们存在。此外,如果表达式 P 指向数组对象的最后一个元素,则表达式 (P)+1 指向数组对象的最后一个元素,如果表达式 Q 指向数组对象的最后一个元素,则表达式 (Q)-1 指向数组对象的最后一个元素。如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为未定义。
— [expr.add] 5.7 /5
是的。请记住检查索引 - operator++ 可能会“走得太远” - 超出数组。