指向数组 int (*ptr)[] 的指针

问题描述

我试图了解指向数组的指针是如何工作的。一段代码

#include<stdio.h> 
  
int main() 
{ 
  int arr[3] = { 0,8,10 };
  int (*ptr)[3] = &arr;
  int i = 0;
  for (i = 0; i < 3 ; i++)
  printf("Address (%p) - value( %d)\n",(*ptr+i),*(*ptr + i));
  return 0; 
} 

星号 * 取消引用 ptr 。如果 i = 1,为什么 (*ptr+i) = ith value 不是 value at ptr + i

解决方法

ptr 的类型是 int (*)[3](指向 int 长度为 3 的数组的指针)。 *ptr 的类型是 int[3]int 的数组长度为 3)。在大多数表达式中,int[3] 类型的操作数被转换为指向数组第一个元素的 int *(指向 int 的指针)。表达式 (*ptr+i) 通过指针运算生成指向数组第 i 个元素的指针。在表达式 *(*ptr+i) 中,指向数组第 i 个元素的指针被取消引用以生成数组的第 i 个元素的值,该值的类型为 {{1} }.

,

以下是这些表达之间的关系:

   ptr  ==  &arr  // int (*)[3] == int (*)[3]
  *ptr  ==   arr  // int [3]    == int [3]

除非它是 sizeof 或一元 & 运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则类型为 表达式T 的 N 元素数组”将被转换或“衰减”为“指向 T 的指针”类型的表达式,表达式的值将是第一个元素的地址数组。因此,在下面的表达式中,*ptrarr 从类型“int 的 3 元素数组”“衰减”到“指向 int 的指针”,它们的值是arr 的第一个元素的地址:

 (*ptr + i)  ==  (arr + i) == &arr[i]  // int * == int * == int *
*(*ptr + i)  == *(arr + i) ==  arr[i]  // int   == int   == int 
,

这里使用了malloc,但概念与分配一维数组的地址相同。

阅读内联评论,以便更好地理解。

#include <stdio.h>
#include <stdlib.h>

#define NCOLS 5
#define NROWS 2

void function( int (*_2D_ptr_Array)[NCOLS],int nrows,int ncols );

//enable this to see the demo of accessing elements using pointer to an array 
//disabling this will demo how to pass 2-D array and collect using pointer to an array.

//#define _DEMO_MAIN 

int main()
{
    // a is a pointer to an array of 5 ints
    int (*a)[NCOLS];
    int _2D_Array[NROWS][NCOLS] =   {   
                                        { 10,20,30,40,50},{ 60,70,80,90,100}
                                    };
    int i,j;
    
    #ifdef _DEMO_MAIN
    printf("Enter 10 elements\n");
    
    a = malloc(sizeof(int)*5*2);
    
    printf("a got address at %p\n",a);
    
    for(i=0;i<2;i++)
        for(j=0;j<5;j++)
            scanf("%d",a[i]+j);

    //printing one dimentional array values
    // *a is equivalent to a[j],when j = 0
    for(j=0;j<5;j++)
        printf("value  %d is at addr %p\n",*(*a+j),(*a+j));
    
    putchar('\n');
    
    //printing multi-dimentional array values
    // adding j to a[i] or *a gives the next element address in a given row.
    for(i=0;i<2;i++)
        for(j=0;j<5;j++)
            printf("value %d is at %p\n",*(a[i]+j),a[i]+j);
    
    #else
        //a most common use of pointer to an array is to collect the 2-d array as an argument in function
        function( _2D_Array,NROWS,NCOLS );
    #endif
    
    return 0;
}

void function( int (*_2D_ptr_Array)[NCOLS],int ncols ) {
    for(int r = 0; r < nrows ; r++) {
        for(int c = 0; c < ncols ; c++) 
            printf("%d ",_2D_ptr_Array[r][c]);
        printf("\n");
    }
}

注意:scanfmalloc 等函数的返回检查不是有目的地处理