我有一个二维整数数组,它代表图中的几个点。
int16_t myPoints[][3] = {
{0, 0},
{20, 40},
{14, 92}};
如何将指针传递给能够读取这些坐标的函数?
就像是?
void foo(int16_t *coordinates[][]) {
drawPoint(x[0], y[0]);
drawPoint(x[1], y[1]);
...
谢谢您的帮助。
声明函数时只有第一个维度是未知的,因此您必须像这样声明/定义函数:
void foo(int16_t coordinates[][3])
{
drawPoint(coordinates[0][0], coordinates[1][0]);
drawPoint(coordinates[0][1], coordinates[1][1]);
drawPoint(coordinates[0][2], coordinates[1][2]);
}
然后你可以像普通函数一样调用它:
foo(myPoints);
编辑:您的数组声明不正确,我也错过了。它应该是:
int16_t myPoints[][2] = {
/* List of points */
};
现在你有了一个合适的坐标数组,它可以是任意长的。
为了让函数知道条目的数量,你必须将它传递给函数,所以新的函数声明将是:
void foo(int16_t coordinates[][2], int number_of_points);
不要担心复制,编译器足够聪明,只将指针传递给数组,所以它不会复制整个数组。
规则是当“N-element array of T
”类型的表达式出现在大多数上下文中时,它将被转换为“pointer to T
”类型的表达式。
myPoints
是“3 元素数组的 3 元素数组int16_t
”类型的表达式。因此,当myPoints
出现在大多数上下文1(例如函数调用)中时,它将被替换为“指向 3 元素数组的指针”类型的表达式int16_t
,或者int16_t (*)[3]
。
如果你想调用foo
as foo(myPoints)
,那么原型需要是
void foo(int16_t (*coordinates)[3])
或者
void foo(int16_t coordinates[][3])
在函数参数声明的上下文中T a[N]
,T a[]
、 和T *a
都是等价的,并且都声明a
为指向 的指针T
。请注意,这只适用于函数参数声明。
1 - 该规则的例外情况是数组表达式是一元运算符sizeof
或一元运算符的操作数&
,或者是用于在声明中初始化另一个数组的字符串文字。
通过对函数的参数重复正确的声明:
void foo(int16_t coordinates[][3])
{
...
}
您必须包括所有数组维度,除了紧跟在变量名称之后的维度,这是可选的。
但这会将整个数组复制到 foo 还是只是将指针传递给它?我也只知道每个条目总是有两个坐标,但我不知道会有多少条目。
如果要传递可变长度数组,则必须将元素的数量作为单独的参数传递,或者数组的最后一个元素必须以某种方式指示它是最后一个元素,以便您可以使用 while( ) 循环(例如添加 NULL 来终止字符串)。
enum STATUS { OK, END };
STATUS bar(int16_t x, int16_t y); /* bar() checks to see if this is the last element */
void foo(int16_t coordinates[][2])
{
int i = 0;
while( END != bar(coordinates[i][0], coordinates[i][1]) )
{
drawPoint(coordinates[i][0], coordinates[i][1]);
++i;
}
}