我最近才开始学习C ++,并且由于大多数人(根据我一直在阅读的内容),我一直在努力使用指针。
不是传统意义上的,我了解它们的含义,为什么使用它们,以及它们如何有用,但是我无法理解递增指针的使用方式,谁能提供一个解释如何递增指针的解释。有用的概念和惯用的C ++?
在我开始阅读Bjarne Stroustrup 的《A C ++之旅》一书之后,就提出了这个问题,我被推荐这本书,因为我对Java非常熟悉,Reddit的家伙告诉我这将是一本很好的“转换”书。 。
我最近才开始学习C ++,并且由于大多数人(根据我一直在阅读的内容),我一直在努力使用指针。
不是传统意义上的,我了解它们的含义,为什么使用它们,以及它们如何有用,但是我无法理解递增指针的使用方式,谁能提供一个解释如何递增指针的解释。有用的概念和惯用的C ++?
在我开始阅读Bjarne Stroustrup 的《A C ++之旅》一书之后,就提出了这个问题,我被推荐这本书,因为我对Java非常熟悉,Reddit的家伙告诉我这将是一本很好的“转换”书。 。
Answers:
当您拥有一个数组时,可以设置一个指向数组元素的指针:
int a[10];
int *p = &a[0];
这里p
指向的第一个元素a
是a[0]
。现在,您可以增加指针以指向下一个元素:
p++;
现在p
指向第二个元素a[1]
。您可以使用在此处访问元素*p
。这不同于Java,在Java中,您必须使用整数索引变量来访问数组的元素。
在C ++中增加一个指针(该指针未指向数组元素)的未定义行为。
指针的递增是惯用的C ++,因为指针的语义反映了C ++标准库(基于Alexander Stepanov的STL)背后设计哲学的基本方面。
这里的重要概念是STL是围绕容器,算法和迭代器设计的。指针仅仅是迭代器。
当然,增加或减少指针的能力可以追溯到C。许多C字符串操作算法都可以使用指针算法简单地编写。考虑以下代码:
char string1[4] = "abc";
char string2[4];
char* src = string1;
char* dest = string2;
while ((*dest++ = *src++));
此代码使用指针算法复制以空值结尾的C字符串。遇到空值时,循环会自动终止。
使用C ++,指针语义被概括为迭代器的概念。大多数标准C ++容器都提供迭代器,可以通过begin
和end
成员函数进行访问。迭代器的行为类似于指针,因为它们可以递增,解引用,有时可以递减或高级。
要遍历一个std::string
,我们会说:
std::string s = "abcdef";
std::string::iterator it = s.begin();
for (; it != s.end(); ++it) std::cout << *it;
我们增加迭代器,就像增加指向普通C字符串的指针一样。这个概念之所以强大,是因为您可以使用模板来编写适用于满足必要概念要求的任何类型的迭代器的函数。这就是STL的强大功能:
std::string s1 = "abcdef";
std::vector<char> buf;
std::copy(s1.begin(), s1.end(), std::back_inserter(buf));
此代码将字符串复制到向量中。该copy
函数是一个模板,可与任何支持增量的迭代器(包括普通指针)一起使用。我们可以copy
在普通的C字符串上使用相同的函数:
const char* s1 = "abcdef";
std::vector<char> buf;
std::copy(s1, s1 + std::strlen(s1), std::back_inserter(buf));
我们可以copy
在支持迭代器的std::map
或std::set
或任何自定义容器上使用。
请注意,指针是迭代器的一种特定类型:随机访问迭代器,这意味着它们支持使用+
and -
运算符进行递增,递减和前进。其他迭代器类型仅支持指针语义的子集:双向迭代器至少支持递增和递减;一个前向迭代器支持至少递增。(所有迭代器类型都支持解引用。)该copy
函数需要一个至少支持增量的迭代器。
您可以在此处了解不同的迭代器概念。
因此,递增指针是在C数组上进行迭代或访问C数组中的元素/偏移量的一种惯用的C ++方法。