理解c ++中数组和指针的差异/相似之处

时间:2017-09-15 21:39:54

标签: c++ arrays pointers

我试图理解c ++中的数组和指针。 在过去的项目中,我做到了。我创建了一个指针,然后将该指针分配给相同类型的数组。我读过以前的帖子,说你不能指定一个指向数组的指针。同样从指针,我能够使用索引来获取某个元素(方括号[])。

所以我想知道是否有人可以向我解释C ++中的数组和指针以及为什么这样的事情是可能的,我已经尝试在网上寻找它,但没有找到任何东西。     例如,

    #include <iostream>
    using namespace std;

    int main()
    {
    int *pointer = new int[10];

    for (int i = 0; i < 10; i++)
    {
        pointer[i] = i;
    }

    for (int i = 0; i < 10; i++)
    {
        cout << pointer[i];
    }

    return 1;
    }

3 个答案:

答案 0 :(得分:0)

现实中的指针是一个变量,它保存它指向的内存地址。内存本身可以通过其中一个堆管理功能进行分配,例如&#39; malloc&#39;或者&#39; new&#39;或其他一些人。因此,一般来说,您要求函数分配一定量的内存并返回其地址。你将后者保留为变量中指向它的指针。

&#c; c ++ / c&#39;中的数组是连续的记忆块。因此,在数组中分配40个字节或10个整数之间没有区别(假设int长度为4个字节)。

&#39; C / C ++&#39;还了解分配的内存包含的数据类型。这些语言提供了一个名为&#39;指针算术的功能。这实际上意味着您可以添加指针或从中减去指针。该语言将按类型的大小对值进行分解。即。

int *a = new ...
int b = *(a+4);

在上述情况下,&#39; b&#39;将与存储器中保存的值相同&#39; a&#39;偏移量为16个字节。

以上与数组索引算法非常相似,并且该语言允许您使用数组索引而不是上述:

b = a[4];

因此,在这个意义上,两个世界相交,你可以在语言中交替使用指针算术或数组算法。

不必在堆上分配数组,并且热指针只需要解决堆。您可以在堆栈或全局范围内分配一个数组,并指向它:

int myarray[10];
int *pointer = myarray;

如何将指针算术或数组算法应用于指针。以下是等效的(如果你没有推进指针)

myarray[3]
pointer[3]
*(pointer + 3)

希望它为您澄清问题。

答案 1 :(得分:0)

数组和指针之间的主要区别在于它们完全不同。

由于数组是一个对象集合,它在内存中是连续排列的。例如,int x[5]定义了一个名为x的数组,它是5整数的集合,在内存中并排排列。可以使用x[i]形式的“数组语法”访问数组中的各个元素,其中i是一个整数值,其值在04之间。 (i的其他值将导致未定义的行为。)

指针是一个变量,它保存一个值作为内存中的地址。例如,int *pp定义为指向int的指针,并且可以使用int类型的变量的地址对其进行初始化。例如,p = &some_int会导致p包含some_int的地址。完成后,符号*p(称为解除引用)提供对指向变量的访问。例如,*p = 42会将some_int设置为值42

你会注意到,在上面的描述中,我没有在描述数组时使用“指针”这个词,也没有使用“数组”这个词来描述指针。它们完全不同。

然而,由于语言中的一些规则,它们可以以使它们看起来相同的方式使用。首先,有一种称为“数组到指针”转换的转换。因此,可以做到

  int x[5];
  int *p = x;

p的初始化实际上可以通过使用数组到指针的转换来实现。因为它用于初始化指针,所以编译器会隐式地将x转换为指针,等于x[0]的地址。要明确地执行此操作(没有编译器静默地,偷偷地进行转换),您可以编写

  int *p = &x[0];

并得到完全相同的效果。无论哪种方式,作业*p = 42随后都会将x[0]分配给42

这表明涉及指针和表达式的表达式之间存在关系,涉及(数据名称)数组。如果p等于&x[0],那么

  • p + i相当于&x[i]; AND
  • *(p + i)相当于x[i]

C和C ++的语言规则使这些关系对称,所以(仔细看这里)

  • x + i相当于&x[i]; AND
  • *(x + i)相当于x[i]

和指针

  • p + i相当于&p[i]; AND
  • *(p + i)相当于p[i]

这基本上意味着指针语法可用于处理数组(由于指针到数组的转换)和数组语法可用于处理指针。

非常糟糕的教科书然后从这里开始并得出结论,指针是数组,而数组是指针。但他们不是。如果你发现说这些东西的教科书,就把它们烧掉。数组和指针完全不同。我们这里有一个语法等价 - 即使数组和指针完全不同,它们也可以使用相同的语法。

其中一个区别 - 语法等价不适用 - 是不能重新分配数组。例如;

 int x[5];
 int y[5];
 int *p = y;    //   OK  - pointer to array conversion

 x = y;       // error since x is an array
 x = p;       // error since x is an array

最后两个语句将由C或C ++编译器诊断为错误,因为x是一个数组。

你的例子

 int *pointer = new int[10];

再次有点不同。 pointer仍然不是数组。它是一个指针,用“new expression”初始化,动态分配10整数数组。但是由于指针和数组的句法等价,pointer可以在句法上处理,因为它是10元素的数组。

注意:上面涉及原始数组。 C ++标准库还有一个名为std::array的类型,它是一个包含数组的数据结构,但行为与此处描述的有所不同。

答案 2 :(得分:-2)

来自维基百科:

  

指针引用内存中的某个位置,并获取该值   存储在该位置的内容称为取消引用指针

数组是连续的内存位置,它们在内存中的位置由指针引用。

int *pointer = new int[10];

for (int i = 0; i < 10; i++)
{
    pointer[i] = i;
}

上面的代码实际上是访问pointer + i * sizeof(int),这要归功于operator [](假设变量pointer是一个整数或类似的smth,这里没有指针算法。)