9

所以,我正在阅读指针,并遇到了指向数组的指针的概念。问题是指向数组的指针似乎根本没有用,因为我可以直接获取元素,而不是使用指针来获得偏移量来访问数组元素。但是,我觉得好像我错过了这些有用的原因。

所以,简而言之,指向数组的指针有什么意义?应该如何以及为什么要使用它们,它们有什么实际应用吗?

编辑:我的意思是在普通/简单数组的上下文中,例如:

int array[5];

编辑:正如基思指出的那样,我特别询问指向数组的指针,例如char (*ptr)[42],它是指向 char 的 42 元素数组的指针。

4

6 回答 6

11

不幸的是,您收到的一些答案显示了对 C 中的指针和数组的误解,简而言之:

1) 指向数组的指针与指向第一个元素的指针不同。

2) 声明数组类型与声明指针不同。

您可以在与指针和数组之间的常见混淆相关的 C 常见问题部分中找到完整描述:http: //c-faq.com/aryptr/index.html

解决您的问题-指向数组的指针对于传递整个编译时已知大小的数组并在参数传递期间保留有关其大小的信息很有用。当您对某个数组的子数组进行操作时,它在处理多维数组时也很有用。

于 2013-10-05T16:57:03.790 回答
7

在大多数表达式中,类型为“T 的数组”的对象将降级为第一个数组元素的地址,其类型为“指向 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));
于 2013-10-05T16:33:39.967 回答
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();

我认为我从未在野外遇到过这种应用程序,但至少是可能的(并且是合法的)。

于 2013-10-06T06:55:42.687 回答
2

如果您有一个数组数组,则指向数组的指针会很有用,如下所示:

typedef float Point[3];
Point points[10];

Point *p;
for (p=points;p<points+10;++p) {
   ...
}
于 2013-10-05T16:18:56.240 回答
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 ];
            }
        }
    }
};

多亏了AB指针,我们可以避免在M1和/或M2不一样的情况下出现多余的内存副本Result

于 2013-10-06T11:27:25.810 回答
-1

我目前能想到的一个是(我相信还有其他人)you want to make multidimensional array但是您目前没有任何数据可以保存在数组的第二维或第三维中。您不想通过为数组的第 2 维和第 3 维保留空间来浪费内存,但是您计划稍后在有要存储的数据时分配内存,那就是指向数组的指针派上用场的时候。

例如。

for (int i=0; i<10; i++)
   (*x)[i] = malloc(N * sizeof(*x));


   // take input or put data in the array

C中二维数组的表示:

这个网站解释得很好。这应该可以帮助您消除任何混淆。

于 2013-10-05T16:28:26.423 回答