我理解不可能将数组传递给C中的函数并修改它而不使用发送对该数组的引用,那么国际象棋方法如何初始化数组,并且正在主数据中正确打印? / p>
int chess(int rows, int cols, int array[rows][cols])
{
/* Go through the rows and colums in the array */
for (int i = 0; i < rows;i++)
{
for (int j = 0; j < cols; j++)
{
/* If the location is even, then print a 0, else print a 1. */
if (((i + j) % 2) ==0)
{
array[i][j] = 0;
}
else
{
array[i][j] = 1;
}
}
}
/* return */
return 0;
}
int main(void)
{
int arrayDimensions;
int noOfTests = 7;
/* run the program for the given amount of tests */
/*for (arrayDimensions = 0; arrayDimensions <= noOfTests; arrayDimensions++)*/
{
/* Declare an array for each dimension */
int array[6][5];
/* call the chess method passing it the arguments specified. */
chess(6, 5, array);
/* Print out the array according to the size of the array. */
for (int i = 0; i < 6; i++)
{
printf("\n");
for (int j = 0; j < 5; j++)
{
printf("%d", array[i][j]);
}
}
/* Create a new line after each row */
printf("\n");
}
}
答案 0 :(得分:3)
虽然你可能已经知道了大部分内容,但后一部分是相关的,所以请坚持一下。
您可能知道的内容
C是一种按值传递的语言。这意味着当你这样做时:
void foo(int x)
{
x = 5;
}
称为
int n = 1;
foo(n);
printf("%d\n", n); // n is still 1
调用者传递一个值,参数x
接收它。但是更改x
对调用者没有影响。如果要修改调用者的数据变量,则必须通过 - 地址执行此操作。您可以通过将形式参数声明为指向类型的指针,取消引用指针来修改指向的数据,最后传递变量的地址来修改:
void foo(int *p)
{
*p = 5;
}
称为:
int n = 1;
foo(&n);
printf("%d\n", n); // n is now 5
你为什么关心?
那么任何与你的数组有什么关系呢? C中的数组是数组底层类型的连续数据序列,数组的表达式 value 是其第一个元素的地址。
在最后一句话上咀嚼一分钟。这意味着int
变量具有存储在其中的int值的方式相同,数组变量将其第一个元素的地址作为其“值”。到现在为止,您知道指针包含地址。知道这一点以及之前的描述意味着:
int ar[10];
int *p = ar;
是合法的。 ar
的“值”是它的第一个元素地址,我们将该地址分配给指针p
。
好的,所以语言专门定义数组为参数,只是指向它们的第一个元素。因此,这两者都是等价的:
void foo(int *p)
{
*p = 5;
}
void bar(int ar[])
{
ar[0] = 5;
}
来电方:
int ar[10];
foo(ar); // legal, ar's "value" is its first element address
bar(ar); // legal, identical to the above.
在解释指针和数组的基本原理时,我常常使用的一句话就是:
指针是持有地址的变量;数组是 地址的变量。
那么这种破坏性的语法怎么样?
<强> int chess(int rows, int cols, int array[rows][cols])
强>
阿。有一些有趣的东西。您的编译器支持VLA s (variable length arrays)。在编译此函数的代码时,编译器会生成适当的逻辑以执行对传递的数组的正确访问。即它知道这个:
array[1][0]
是cols
超过数组开头的int
个值。如果没有VLA的特性(并且某些C编译器没有它们),您必须自己手动进行逐行数学运算。不是不可能的,而是单调乏味的。我只是简单地提到C ++不支持VLA; C语言没有的少数几个特性之一。
<强>摘要强>
数组是按地址传递的,因为当涉及到它们的“价值”时,就是所有的:地址。
注意:我非常努力地避免在本说明中使用“衰变”或“衰减到指针”这个词,因为动词意味着一些神秘的功能操作当实际上不存在时。数组不会“衰减”到任何。他们只是是;根据C标准,它们的“价值”是它们的第一个元素的地址。期。您使用该地址做的内容是另一回事。并且作为一个地址,指针可以保存它们的“值”并取消引用以访问所述相同的(例如函数参数)。
个人:我曾经在这个论坛上问过这个术语(衰变)在C-engineer白话中有多长时间被嗡嗡声,因为在C标准的600多页中它看起来完全是ZERO次。任何人发现的最远的后面是1988年在一些显眼的在线期刊的编年史。我总是好奇地注意到谁开始了这个地方,然后说 - 任务继续让我望而却步。
无论如何,我希望这会有所帮助,甚至一点点。
答案 1 :(得分:1)
处理数组时,你正在处理一个地址,所以如果你把一个数组传递给一个函数并且你在函数中改变了数组,那么真正的数组就会改变。
换句话说,如果您知道pointers
,则数组是指针。
我没有阅读代码,但你明确误解了将数组传递给函数。
答案 2 :(得分:0)
数组引用是一个地址(说它是指针的用词不当,但它会表现如此)。它的工作原理是因为声明函数接受一种int [] []类型,它允许函数与数组引用进行交互,就好像你传递了一个指向函数的指针一样。
答案 3 :(得分:0)
参考手册:
当函数参数声明为数组时,编译器会处理 声明作为指向数组第一个元素的指针。对于 例如,如果x是一个参数并且旨在表示一个数组 整数,它可以声明为以下任何一个声明:
int x []; int * x; int x [10];
所以你传递了一个参考文献。编译器将您的声明转换为指针引用,同时还有一些大小限制。