数组是C和C ++的内置容器。 本文假定读者有一定的经验
数组和数组语法,但在(a)多维数组的工作原理上不清楚,b)如何调用
具有多维数组的函数,c)如何从函数返回多维数组,
或d)如何从光盘文件读取和写入阵列。
给C ++程序员的注意事项:您应该使用向量而不是数组。 您需要的保护码
在阵列周围编写是在STL中围绕阵列编写的保护性代码的重复。
STL只是将其数组加管理代码称为向量。
C程序员注意:本文中的所有内容都符合ANSI-C,堆分配除外。
这些示例使用C ++
C程序员将在其中调用malloc()的新运算符 。 如何定义数组首先,在C或C ++中只有一维数组。 元素的数量放在方括号之间:
int array[5];
这是5个元素组成的数组,每个元素都是一个int。
int array[];
不会编译。
您需要声明元素的数量。
其次,此数组:
int array[5][10];
仍然是5个元素的数组。
每个元素都是10个int的数组。
int array[5][10][15];
仍然是5个元素的数组。
每个元素是10个元素的数组,其中每个元素是15个int的数组。
int array[][10];
不会编译。
您需要声明元素的数量。
第三,数组的名称是元素0的地址
int array[5];
这里的array是array [0]的地址。
由于array [0]是一个int,所以array是一个int的地址。
您可以将名称数组分配给int *。
int array[5][10];
这里的array是array [0]的地址。
由于array [0]是10个int的数组,所以array是10个int的数组的地址。
您可以将name 数组分配给一个指向10 int数组的指针:
int array[5][10];
int (*ptr)[10] = array;
第四,当在编译时不知道元素数时,可以动态创建数组:
int* array = new int[value];
int (*ptr)[10] = new int[value][10];
int (*ptr)[10][15] = new int[value][10][15];
在每种情况下, 值都是元素的数量 。
任何其他方括号仅描述元素。
对数组数组使用int **是不正确的,并且使用指针算法会产生错误的答案。 编译器知道这一点,因此不会编译此代码:
int** ptr = new int[value][10]; //ERROR
new返回由10个int组成的数组的地址,它与int **不相同。
同样地:
int*** ptr = new int[value][10][15]; //ERROR
new返回由10个元素组成的数组的地址,其中每个元素都是由15个int组成的数组,并且与int ***不同。
考虑到上面的这个数组:
int array[10] = {0,1,2,3,4,5,6,7,8,9};
的内存布局为
0 1 2 3 4 5 6 7 8 9
数组如下:
int array[5][2] = {0,1,2,3,4,5,6,7,8,9};
的内存布局为
0 1 2 3 4 5 6 7 8 9
有点像吧?
因此,如果您的光盘文件包含
0 1 2 3 4 5 6 7 8 9
当您读入一维数组或二维数组时,它会有所不同吗? 没有。
因此,当您进行读取时,请使用数组[0] [0]的地址,并进行读取,就好像您有一个
一维数组,值将在正确的位置。
将多维数组传递给函数该数组:
int arr[3][4][5];
如果func()的参数是指向[4] [5]数组的指针,则可以将其传递给函数:
void func(int (* arg)[4][5], unsigned int x);
int main()
{
int arr[3][4][5];
func(arr, 3);
}
但是,如果func参数是一个指向[5] int数组的指针,则需要传递&arr [0] [0]:
void func(int (* arg)[5], unsigned int x, int y);
int main()
{
int arr[3][4][5];
func(&arr[0][0], 3, 4);
}
但是,如果func参数是一个指向int的指针,则需要传递&arr [0] [0] [0]:
void func(int * arg, unsigned int x, int y, int z);
int main()
{
int arr[3][4][5];
func(&arr[0][0][0], 3, 4, 5);
}
省略尺寸时,请注意,由于“ array-ness”为
在通话中迷路了。 这就是所谓的
数组的衰减,只要传递数组就发生功能。 在函数内部,您看到的只是地址而不是数组。 那迫使你通过
“维度”中元素的数量。
从函数返回多维数组从数组返回数组仅在数组由函数创建时才有意义。 除此以外,
由于地址传递了现有数组,因此无需返回。 但是,如果函数具有
在堆上创建数组时,可以返回元素0的地址。
这里的问题是,除非您a)返回类型,否则不能使用函数返回类型。
b)返回一个指向类型的指针。 也就是说,您不能返回指向数组的指针,因为数组不是
一种。 因此,如果您创建一个int数组,则可以将该数组作为int *返回:
int* func(int arg)
{
int* temp = new int[arg];
return temp;
}
int main()
{
int* arr = func(5);
}
创建多维数组时,这不起作用:
int (*)[5] func(int arg) // ERROR: Cannot return an array
{
int (* temp)[5] = new int[arg][5];
return temp;
}
int main()
{
int (* arr)[5] = func(4);
}
在这种情况下,您可以将指针的地址传递给5 int数组:
void func(int arg, int (**rval)[5])
{
int (* temp)[5] = new int[arg][5];
*rval = temp;
}
int main()
{
int (* arr)[5] = 0;
func(4, &arr);
//arr is now a [4][5] array of int
}
但是,如果需要将该函数用作RVAL,则需要返回一个类型。
在这里,最简单的方法是将类型定义为指向多维数组元素的指针。
在此示例中,您将需要一个指向5个int数组的指针:
typedef int (*IntArray5Ptr)[5];
现在,您可以返回一个类型:
IntArray5Ptr func(int arg)
{
int (* temp)[5] = new int[arg][5];
return temp;
}
int main()
{
int (* arrA)[5] = func(4);
}
除了返回类型之外,您还可以返回指向类型的指针。
因此,您可以将类型定义为数组的元素(在示例中,这是一个5 int的数组)并返回指向该类型的指针:
typedef int IntArray5[5];
IntArray5* funcB(int arg)
{
int (* temp)[5] = new int[arg][5];
return temp;
}
int main()
{
int (* arr)[5] = func(4);
}
最后,如本文开头所述:C ++中没有多维数组。
因此,一个函数可以只创建一个具有正确数目的元素的一维数组,然后返回
元素0的地址。在这种情况下,元素0是一种类型,您可以使用函数的返回类型
返回指向类型的指针。 然后,调用函数可以对返回值进行类型转换,以便可以将数组
用于多尺寸:
int* func(int arg)
{
int * temp = new int[arg];
return temp;
}
int main()
{
//This is arr[60]
int* arr = func(60);
//This is arr[12][5] --> 12 x 5 = 60
int (*arr1)[5] = (int(*)[5])func(60);
//This is arr[3][4][5] -> 3 * 4 * 5 = 60
int (*arr2)[4][5] = (int(*)[4][5])func(60);
//This is arr[1][3][4][5] -> 1*3*4*5 = 60;
int (*arr3)[3][4][5] = (int(*)[3][4][5])func(60);
}
修订记录
2010/04/11-添加了从RVAL函数返回多维数组的示例。
版权所有2010 Buchmiller Technical Associates美国北华盛顿本德
From: https://bytes.com/topic/c/insights/772412-arrays-revealed