理智检查问题:
我做了一些谷歌搜索并发现了在C中返回一维整数数组的正确方法
int * function(args);
int * function(int * a);
这是一个合法的职能机构吗?
int * b;
b = a;
return b;
我们是否允许将数组分配给其他类似的数组?int a[10];
传达的信息比
int * a;
但他们不是两种声明阵列的方式吗?如果我使用后一个声明,我可以将值赋给[10000000]吗?主要问题:
感谢你的帮助!
a[i]
定义为*(a + i)
;我们在i
之后找到a
'th元素的地址并取消引用结果。所以a
可以声明为指针或数组。3
强制转换为指针,因为int
和int *
类型的值不兼容。malloc
调用或另一个数组的结果),否则它的值将是不确定的,并且可能不指向有效的内存。指针不包含有关它们指向的元素数量的元数据,因此您必须将其作为单独的参数传递。
对于2D数组,你可以做类似的事情
void foo(size_t rows, size_t columns, int (*a)[columns])
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < columns; j++)
a[i][j] = some_value;
}
这假设您使用的是C99编译器或支持可变长度数组的C2011编译器;否则列数必须是常量表达式(即,在编译时已知)。
这些答案肯定需要更深入一些。你理解指针越好,你写的代码就越少。
数组和指针不相同,除非它们是。脱离我的头顶:
int a[2][2] = { 1, 2, 3, 4 };
int (* p)[2] = a;
ASSERT (p[1][1] == a[1][1]);
数组“a”的功能与指针“p”完全相同。并且编译器同样知道每个,特别是地址,以及如何计算索引地址。但请注意,数组a在运行时不能采用新值,而p可以。所以a的“指针”方面在程序运行时就消失了,只留下了数组。相反,p本身只是一个指针,它可以在运行时指向任何内容或任何内容。
请注意,指针声明的语法很复杂。 (这就是为什么我今天首先来到stackoverflow。)但需要很简单。您需要告诉编译器如何计算第一列之后的元素的地址。 (我正在使用“column”作为最右边的索引。)在这种情况下,我们可能假设它需要将地址((2 * 1)+ 1)递增到索引[1] [1]。
但是,编译器知道(希望)还有一些事情,你可能不会。
编译器知道两件事:1)元素是否按顺序存储在内存中; 2)是否确实有额外的指针数组,或者只是一个指向数组开头的指针/地址。
通常,编译时数组是按顺序存储的,与维度无关,没有额外的指针。但是,请务必查看编译器文档。因此,如果编译器允许您索引[0] [2],它实际上是[1] [0]等。然而,运行时数组是你做的。您可以制作任意长度的一维数组,并将其地址放入其他数组,也可以选择任何长度。
而且,当然,使用其中任何一个的一个原因是因为您选择使用运行时乘法,移位或指针解引用来索引数组。如果指针解引用最便宜,则可能需要生成指针数组,因此不需要算术来计算行地址。一个缺点是它需要内存来存储addtional指针。请注意,如果列长度为2的幂,则可以使用shift而不是乘法来计算地址。所以这可能是填补长度的一个很好的理由 - 编译器至少在理论上可以在不告诉你的情况下这样做!它可能取决于您是选择速度还是空间优化。
任何被描述为“现代”和“强大”的架构可能会像解除引用一样快速地增加,并且这些问题会完全消失 - 除了您的代码是否正确。