我试图理解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;
}
答案 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
是一个整数值,其值在0
和4
之间。 (i
的其他值将导致未定义的行为。)
指针是一个变量,它保存一个值作为内存中的地址。例如,int *p
将p
定义为指向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,这里没有指针算法。)