指针和多维数组
pointers and multi-dimensional arrays
可能的重复项:
如何在C++中使用数组?
二维数组是双指针吗?
二维数组和指针
我知道这是一个非常基本的问题,但没有多少谷歌搜索为我清除了这一点。这就是我在这里发布它的原因。在 c++ 中,请考虑声明int x[10];
这是一个一维数组,其中 x 是基本指针,它包含数组第一个元素的地址。所以x
给了我这个地址,*x
给了第一个元素。
宣言也是如此
int x[10][20];
这里x
什么样的变量。当我这样做时
int **z = x;
编译器说它无法将int (*)[20]
转换为int **
。为什么cout<<x;
和cout<<*x;
给出相同的价值?而且如果我将指针数组声明为
int *p[10];
那么x
和p
之间有区别吗(在它们的类型上(?? 因为当一个人声明int x[10]
和int *p
时,将x
分配给p
是有效的,但在二维数组的情况下并非如此? 为什么?有人可以为我清除这一点,或者为此提供很好的资源材料。
和指针不是一回事。 在 C 和 C++ 中,多维数组只是"数组的数组",不涉及指针。
int x[10][20];
是一个由 10 个数组组成的数组,每个数组包含 20 个元素。 如果您在上下文中使用x
,它将衰减为指向其第一个元素的指针,那么您最终会得到一个指向这些 20 个元素数组之一的指针 - 这就是您的int (*)[20]
。 请注意,这样的东西不是指针到指针,因此转换是不可能的。
int *p[10];
是一个由 10 个指针组成的数组,所以是的,它与 x 不同。
特别是,您可能会遇到麻烦,因为您似乎认为数组和指针是一回事 - 您的问题说:
这是一个一维数组,其中 x 是基本指针,它包含数组第一个元素的地址。所以x给了我这个地址,*x给了第一个元素。
这不是真的。 一维x
是一个数组,只是在某些情况下,数组衰减为指向其第一个元素的指针。
阅读常见问题解答,了解您想知道的有关此主题的所有信息。
多维数组只是语法糖。在幕后,这只是一个 10 * 20 int
s 长的一维数组。当您在x[5][6]
访问元素时,编译器会生成等效的 x[5 * 20 + 6]
;
以下是它的实际工作原理,请参阅代码和注释:
#include <stdio.h>
int x[3][5] =
{
{ 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 },
{ 11, 12, 13, 14, 15 }
};
int (*pArr35)[3][5] = &x;
// &x is a pointer to an array of 3 arrays of 5 ints.
int (*pArr5a)[5] = x;
// x decays from an array of arrays of 5 ints to
// a pointer to an array of 5 ints,
// x is a pointer to an array of 5 ints.
int (*pArr5b)[5] = &x[0];
// &x[0] is a pointer to 0th element of x,
// x[0] is an array of 5 ints,
// &x[0] is a pointer to an array of 5 ints.
int *pInta = x[0];
// x[0] is 0th element of x,
// x[0] is an array of 5 ints,
// x[0] decays from an array of 5 ints to
// a pointer to an int.
int *pIntb = *x;
// x decays from an array of arrays of 5 ints to
// a pointer to an array of 5 ints,
// x is a pointer to an array of 5 ints,
// *x is an array of 5 ints,
// *x decays from an array of 5 ints to
// a pointer to an int.
int *pIntc = &x[0][0];
// x[0][0] is 0th element of x[0],
// where x[0] is an array of 5 ints,
// x[0][0] is an int,
// &x[0][0] is a pointer to an int.
int main(void)
{
printf("&x=%p x=%p &x[0]=%p x[0]=%p *x=%p &x[0][0]=%pn",
pArr35, pArr5a, pArr5b, pInta, pIntb, pIntc);
return 0;
}
示例输出:
&x=0040805c x=0040805c &x[0]=0040805c x[0]=0040805c *x=0040805c&x[0][0]=0040805c
所有生成的指针在值方面都是相同的,因为我显式或隐式地使用了 0 的索引,并且因为数组是连续的,并且它们的第一个(IOW,0th(元素始终位于数组中的最低地址。因此,即使有 3 种不同的指针类型,它们都有效地指向 x[0][0],指向等于 1 的元素。
数组到指针的衰减是 C 和 C++ 的一个非常重要的特征,尽管很难立即掌握。
它允许我们在将指针传递给数组时编写更紧凑的代码,我们可以只编写数组的名称,而不是获取其第一个元素的地址:
char str1[] = { 's', 't', 'r', '1', ' ' };
char str2[] = "str2";
printf("%s %s %s %sn", &str1[0], str1, &str2[0], str2);
输出:
str1str1 str2 str2
它还让我们做疯狂的事情:
int y[3] = { 10, 20, 30 };
printf("%d %d %d %dn", y[2], *(y+2), *(2+y), 2[y]);
输出:
30 3030 30
这一切都是因为a[b]
在数组和指针方面等同于*(a+b)
。
- 添加到数组指针
- C++语法差异:二维和一维数组(指针算术)
- 数组指针表示法C++(移动数组时)
- 复制后删除原始数组指针将前 3 个字节设置为 0
- C++访问指向结构的指针中的类数组指针
- C++编译时使用 constexpr 字符数组指针分配静态数组?
- std::flush可以用于将对象指针转换为其封闭数组指针吗
- 创建<int>对整数数组指针的矢量引用 (C++)
- 将 2D 数组指针传递给 C++ 中的函数
- 创建指针是否超过非数组指针的末尾,而不是从 C++17 中的一元运算符和未定义的行为派生?
- 队列数组指针 (C++)
- C++数组指针上的删除操作
- 对于循环不循环和检测字符数组 [指针和字符数组]
- 如何初始化数组指针对象
- 如何正确传递 2D 数组指针作为参数
- 从数组指针中获取怪异的数字
- 初始化std :: unique_ptr作为原始数组指针的初始化
- 将结构数组指针从C#传递到C
- STD :: Sort将数组指针设置为NULL
- C++数组指针错误无法将“int*”转换为“int**”