我看了很多关于这个主题的回复,但还是没能收到。请理解我正在学习。
有人告诉我,一个向量就是它的第一个元素的地址,所以是一个二维向量。
那么,如果我用指针传递一个2D向量,为什么我会失去使用索引的能力呢?
int vec[10][10] = { 1, 2, 3, 4 };
int *v = vec;
字符串
我为什么不能说
int a = v[1][1]
型
就像我会做的
int a = vec[1][1]
型
如果v
,指向int
的指针,正好指向vec
,指向int
的指针,它们不都是一样的东西,一样的对象吗?
我读到
int (*v)[N] = vec;
型
其中N
是列数。但这对初学者来说似乎是一件超级棘手的事情。
为什么会这样呢?
编辑:
我的大脑对int (*vec)[N]
做出了这样的解释,它的意思是 * 指向10int
* 的向量的指针。
在一个二维数组中,指向第一个元素的指针是指向N
个元素的数组的指针,这是我给自己的解释。
如果int *var = &int
的lhs必须从右向左读取,变成“var
is a pointer
to int
“,那么我希望int [N] * var = &2darray
从右向左是“var是指向N个int元素的数组的指针”。
但这在语法上对编译器是不正确的,所以我必须使用int (* vec) [N] = 2darray
的技巧,从右到左,记住括号优先级变成:
括号在前,从右到左:vec
为a pointer
。
剩下的,从右到左,就是int [N]
.
最后的结果是vec
是a pointer
到an array of N
的int
。
这有一点道理吗?
5条答案
按热度按时间mxg2im7a1#
编译器应该发出一条消息,
字符串
使用不兼容指针类型的指针来初始化类型为
int *
的指针v
。作为初始化器的数组
vec
被隐式转换为指向其第一个元素的指针。这个二维数组的元素类型是int[10]
。因此指向数组元素的指针将具有int ( * )[10]
类型。你不能在你的代码片段中使用像
v[1][1]
这样的表达式,因为子表达式v[1]
的类型是int
。也就是说,子表达式v[1]
产生的标量对象不是数组。所以这样的表达式v[1][1]
是无效的。如果你愿意写
型
然后子表达式
v[1]
产生一个类型为int[10]
的对象,它是一个数组。所以你可以对获得的数组应用一个下标运算符,如v[1][1]
。如果你有一个一维数组,
型
然后这个数组的元素具有类型
int
。并且在表达式中使用的数组有罕见的例外(例如使用insizeof
运算符)被转换为指向类型int *
的第一个元素的指针。另一方面,如果你有一个二维数组,
型
那么数组的元素是类型为
int[n]
的一维数组,并且指向数组元素的指针具有类型int ( * )[n]
。cgvd09ve2#
C
中的多维数组是数组的数组字符串
定义两个元素的数组,由3个
int
元素组成。x
衰减为指向3个int
元素的数组的指针。x[0]' decays to pointer to
int`1.你需要使用指向数组的指针(这没什么特别的)。它是一个具有数组类型的指针。
型
将
p
定义为指向3个int元素的数组的指针。slhcrj9b3#
很多C语言的设计都是围绕着数组来进行的,当在大多数表达式中使用数组时,数组会衰减为指向第一个元素的指针。
[]
运算符就是围绕着这样一个假设来设计的--它实际上不能使用数组作为操作数,它总是使用指针。参见Do pointers support "array style indexing"?传递给
[]
操作符的指针参数会导致在取消引用的类型上执行指针运算。给定int* ptr;
,则ptr[n]
会在int
类型的项上执行指针运算。所以对于一个普通数组
int vec[10]
,我们可以写int* ptr = vec;
,这很好,因为vec
会衰减成指向第一个元素的指针。int vec[10][10];
.int* v = vec;
是无效的C。int [10][10]
的第一个元素是int [10]
。因此,然后vec
衰减,它衰减为指向int [10]
的指针,此类型与int*
不兼容,因此发布得代码违反了赋值约束,编译器必须发出诊断消息。在我们输入
vec[n]
的情况下,vec
衰减为int(*)[10]
,因此我们得到int [10]
类型的项上的指针算术。关于数组指针的语法,指向数组
int vec[10][10]
的指针将被声明为int (*ptr)[10][10]
。当我们已经有了指针而不是数组时,就没有衰减这回事了,所以ptr[n]
实际上会给予我们类型为int [10][10]
的 nth 数组项......这是没有帮助的。我们没有一个int [10][10]
项的数组。要真正得到一个int [10]
项,这更可能是我们想要的,我们首先必须取消对指针的引用:(*ptr)[n]
。语法相当繁琐。因此,最简单的方法是将指针声明为一维短指针:
int (*ptr)[10]
。这直接对应于一个数组int vec[n][10]
。我们可以使用ptr[i][j]
来访问二维数组中的int
项。或者,我们可以使用vec[i][j]
,在这种情况下,vec
会衰减,并且我们也会在二维数组中获得一个int
。mm5n2pyu4#
我为什么不能说
字符串
因为
v
是指向int
的指针,你只能访问一个元素,使用一个访问[]
操作符,而不是两个。如果你正确地声明了它,那么你就可以做到:型
那么你可以正确地使用
v[1][1]
甚至v[9][9]
,因为现在v是一个指向10个整数的10个数组的指针。这里的问题是,当你只说
vec
时,C语言将其解释为 * 指向第一个元素的指针 *(具有指向访问数据的指针类型)这也是一个数组,所以它(再次)衰减为指向第一个元素的指针,这是指向int
的指针。甚至,你可以使用一个指向完整内容的指针:
型
但是,你必须使用2D数组的地址。这也是有效的。
注意:
括号是必要的,因为
v
必须是指向数组的指针,而不是指针数组(如果您没有使用它们,它应该是)xoshrz7s5#
正如其他答案中所指出的,
int *v = vec;
是一个类型不匹配,应该生成一个诊断。编译时使用高级警告并使这些警告出错是一个很好的做法,可以尝试避免导致未定义行为或其他bug的错误。使用gcc -Wall -Wextra -Werror或对clang使用相同的标志。
正如你的问题所述,正确的定义是:
字符串
要破译这些定义,您应该学习并使用spiral rule。