【问题标题】:What is the point of pointers to arrays?指向数组的指针有什么意义?
【发布时间】:2013-10-05 16:10:59
【问题描述】:

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

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

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

int array[5];

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

【问题讨论】:

  • 什么样的数组? int* myArray = malloc(5 * sizeof(int) ); 也是一个数组...
  • @LihO,我的意思是简单的数组,比如 int array[5];我会编辑它..
  • 从什么时候开始有 5 个连续的整数组成一个数组?
  • @Paulpro:语法上它不是数组,但语义上它是。
  • @LihO:您写道:“int* myArray = malloc(5 * sizeof(int) ); 也是一个数组”。是和不是。 malloc 调用如果成功,则为 int 的匿名 5 元素数组分配空间。但是myArray 是一个指针对象,类型为int*myArray 在任何意义上都不是数组。它只是恰好指向数组的第一个元素。

标签: c arrays pointers


【解决方案1】:

很遗憾,您收到的一些答案简要说明了对 C 中的指针和数组的误解:

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

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

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

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

【讨论】:

  • 对,这里有很多虚假的答案。唯一一个把它带到我所看到的地步。
  • 我认为我的回答中的例子与这个一致。
  • @mfxm 问题,因为我似乎无法理解,指向数组的指针与指向第一个元素的指针有何不同,是否有不同的代码方式? ?
  • @Link 简而言之,指向 T 数组的指针指向由 T 类型元素组成的整个数组,而指向 T 的指针仅指向 T 类型的特定对象,该对象可能是数组的一部分,也可能只是唯一的对象.通过将此问题与指向结构的指针(包含多个成员,包括 int)与指向 int 的指针进行比较,您可能会更好地理解。虽然指向结构的指针应该指向整个结构,但指向 int 的指针可以引用结构的该成员,数组元素而不是 int 变量。考虑查看 C 常见问题解答:c-faq.com/aryptr/ptrtoarray.html
【解决方案2】:

在大多数表达式中,类型为“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));

【讨论】:

    【解决方案3】:

    真正指向数组的指针(到目前为止还没有真正解决)并不常见,因为在大多数情况下,数组会衰减为指向其第一个元素的指针,而且根据定义,数组在内存中是连续的,这通常是需要的.与其他指针类型相比,它们也有些不切实际,因为无法分配数组类型。它们在这方面类似于函数指针。

    最大的实际区别在于它们保留了数组的大小,否则它会因指针衰减而丢失,例如函数调用和返回。以如下代码为例

    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();
    

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

    【讨论】:

      【解决方案4】:

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

      typedef float Point[3];
      Point points[10];
      
      Point *p;
      for (p=points;p<points+10;++p) {
         ...
      }
      

      【讨论】:

      • points 是一个由 3 个浮点数组成的 10 个数组的数组。所以它是一个数组数组。如果要遍历点,请使用指向数组的指针。
      • 索引访问需要求和,指针访问效率稍高。
      【解决方案5】:

      这是使用数组指针的真实示例:

      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 和/或M2Result 不同的情况下避免冗余内存副本

      【讨论】:

        【解决方案6】:

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

        例如

        for (int i=0; i<10; i++)
           (*x)[i] = malloc(N * sizeof(*x));
        
        
           // take input or put data in the array
        

        二维数组在 C 中的表示:

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

        【讨论】:

        • 要明确一点,第一行代码是声明一个指针数组吗?还是一个指向数组的指针?
        • 第一个代码只是为了表明你可以像这样表示一个二维数组,它是一个指向数组的指针。在第二个代码中,我为数组的第二维分配内存。
        • 好吧,但是二维数组的表示究竟是如何工作的?
        • 几乎类似于一维数组。我无法在评论部分详细解释它,我想最好在 bing/google 上搜索它
        • 您不是在回答中描述多维数组,而只是对这种事物的模拟。
        猜你喜欢
        • 2018-02-09
        • 1970-01-01
        • 1970-01-01
        • 2011-12-04
        • 1970-01-01
        • 2011-12-16
        • 1970-01-01
        • 2016-12-02
        • 1970-01-01
        相关资源
        最近更新 更多