所以,我正在阅读关于指针的内容,并且遇到了指向数组的指针。问题是指向数组的指针根本没有用,因为我可以直接获取元素,而不是使用指针来获取数组元素的偏移量。但是我觉得好像我错过了为什么这些有用的原因。
因此,简而言之,指向数组的重点是什么?如何以及为什么要使用它们,它们是否有任何实际应用?
编辑:我的意思是在普通/简单数组的上下文中,例如:
int array[5];
编辑:正如Keith指出的那样,我特别询问有关数组的指针,例如char (*ptr)[42]
,它指向42个元素的char数组。< / p>
答案 0 :(得分:11)
不幸的是,你收到的一些答案显示了对C中指针和数组的误解,简而言之:
1)指向数组的指针与指向第一个元素的指针不同。
2)声明数组类型与声明指针不同。
您可以在C faq部分找到与指针和数组之间常见混淆相关的完整描述:http://c-faq.com/aryptr/index.html
解决您的问题 - 指向数组的指针有助于传递整个编译时已知大小的数组,并在参数传递期间保留有关其大小的信息。当你在某些数组的子数组上操作什么时处理多维数组时,它也很有用。
答案 1 :(得分:7)
在大多数表达式中,类型为“T of array”的对象将降级为第一个数组元素的地址,该数组元素的类型为“指向T的指针”。从这个意义上讲,指针类型可用于表示项目数组,并在需要动态分配数组时用于执行此操作。
// ptr used to dynamically allocate array [n] of T
T *ptr = malloc(n * sizeof(*ptr));
在指向数组的指针的情况下,它可用于表示数组数组,和/或动态分配数组数组。因此,指向数组的指针可用于表示二维数组。
// ptr used to dynamically allocate 2 dimensional array [n][10] of T
T (*ptr)[10] = malloc(n * sizeof(*ptr));
答案 2 :(得分:5)
指向数组的真指针(到目前为止尚未真正解决)并不常见,因为数组在大多数上下文中衰减为指向其第一个元素的指针,并且由于数组在内存中是连续的,因此定义通常只需要。与其他指针类型相比,它们也有些不切实际,因为无法分配数组类型。在这方面,它们与函数指针类似。
最大的实际差异来自于它们在指针衰减(例如函数调用和返回)丢失的情况下保留数组的大小。以下面的代码为例
void function(char (*array)[10]) {
for(size_t i = 0; i < sizeof(*a); i++);
(*a)[i] = i;
}
...
char a[10];
function(&a);
除了允许sizeof的这个应用程序(由于大小被称为参数的一部分,这不是非常有用),这会强制传递参数的确切大小作为类型的一部分,function(char array[10])
即使使用[static 10]
,也不会这样做。
返回有一个不寻常的语法:
char (*function(void))[10] {
static char array[10];
// do something with our static array
return &array;
}
char (*a)[10] = function();
// or even
char (*b)[sizeof(*function())] = function();
我认为我没有在野外遇到过这种应用,但它至少是可能的(合法的)。
答案 3 :(得分:2)
如果你有一个数组数组,那么指向数组的指针就会变得很有用,如下所示:
typedef float Point[3];
Point points[10];
Point *p;
for (p=points;p<points+10;++p) {
...
}
答案 4 :(得分:1)
以下是使用指针指向数组的真实示例:
typedef double t_matrix33[3][3];
// Result = AB
// const double (* M1)[3], const double (* M2)[3], double (* Result)[3]
void Matrix33xMatrix33( const t_matrix33 M1, const t_matrix33 M2, t_matrix33 Result ) {
t_matrix33 copy;
const t_matrix33 * A = ( const t_matrix33 * )M1; // const double (* A)[3][3] = const double (* M1)[3]
const t_matrix33 * B = ( const t_matrix33 * )M2; // const double (* B)[3][3] = const double (* M2)[3]
int Raw;
int Col;
int i;
// !!! Make copies if Result is the same as M1 and/or M2!
//const double (* A)[3][3] == double (* Result)[3]
if( A == ( const t_matrix33 * )Result ) { // cast is must -- to get rid of gcc warnings
memcpy( copy, A, sizeof( t_matrix33 ) );
A = ( const t_matrix33 * )copy;
if( B == ( const t_matrix33 * )Result ) {
B = ( const t_matrix33 * )copy;
}
}
else if( B == ( const t_matrix33 * )Result ) {
memcpy( copy, B, sizeof( t_matrix33 ) );
B = ( const t_matrix33 * )copy;
}
for( Raw = 0; Raw < 3; ++Raw ) {
for( Col = 0; Col < 3; ++Col ) {
Result[ Raw ][ Col ] = 0;
for( i = 0; i < 3; ++i ) {
Result[ Raw ][ Col ] += (*A)[ Raw ][ i ] * (*B)[ i ][ Col ];
}
}
}
};
感谢A
和B
指针,我们可以避免在M1
和/或M2
与Result
<不同的情况下出现多余的内存错误/ p>
答案 5 :(得分:-1)
我现在能想到的是(我相信还有其他人),you want to make multidimensional array
,但是你目前没有任何数据可以保存在第二个或者数组的第三维。您不希望通过节省数组的第二维和第三维空间来浪费内存,但是当您有数据存储时,您计划稍后分配内存,这就是当指向数组的指针派上用场时。
<强>例如强>
for (int i=0; i<10; i++)
(*x)[i] = malloc(N * sizeof(*x));
// take input or put data in the array
C代表2d数组:
This site解释得很清楚。这可以帮助您消除任何混淆。