1-d指向2-d数组的指针

时间:2017-11-18 12:56:43

标签: c arrays function pointers

#include<stdio.h>

void display(int (*p)[3],int,int);

int main()
{
    int a[3][4] = {1,2,3,4,
                   5,6,7,8,
                   9,0,1,6};

    display(a,3,4);
}

void display(int (*p)[3],int r,int c)
{
    int i,j,*q;
    for(i=0;i<r;i++)
    {
        q=p+i;
        for(j=0;j<c;j++)
        printf("%d",*(q+j));
        printf("\n");
    }
} 

这不起作用,但如果我们写 void dis(int(* p)[4],int,int); 有用 也就是说,如果我们有一个数组指针,其列数为数组中元素的数量

3 个答案:

答案 0 :(得分:1)

在极少数例外的表达式中使用的数组将转换为指向其第一个元素的指针。

来自C标准(6.3.2.1 Lvalues,数组和函数指示符)

  

3除非它是sizeof运算符或一元&amp;的操作数。   operator,或者是用于初始化数组的字符串文字,a   具有类型''数组类型''的表达式将转换为   带有''指向类型'的指针的表达式,指向初始值   数组对象的元素,而不是左值。如果是数组对象   具有寄存器存储类,行为未定义。

所以如果你有一个声明为

的数组
T a[N];

其中T是某种类型而N是一个整数表达式,那么数组可以通过以下方式转换为指针。

首先,让我们按照以下方式重写声明

T ( a[N] );

现在获取指针只是用括号a[N]中的声明符替换*p。例如

T ( a[N] );
T ( *p ) = a;

所以如果你有像这样的多维数组

T a[N1][N2];

然后可以通过以下方式定义指向其第一个元素的指针

T ( a[N1] )[N2];
T ( *p )[N2] = a;

一般情况下,您可以使用规则

T a[N1][N2]...[Nn];

相当于

T ( a[N1] )[N2]...[Nn];

并且指针定义为

T ( a[N1] )[N2]...[Nn];
T ( * p )[N2]...[Nn] = a;

在你的程序中你有声明

int a[3][4] = {1,2,3,4,
    5,6,7,8,
    9,0,1,6};

可以重写,如上面所示,如

int ( a[3] )[4] = {1,2,3,4,
    5,6,7,8,
    9,0,1,6};

因此指向数组第一个元素的指针将具有类型int ( * )[4] 因此,该函数应至少声明为

void display( int (*)[4], int, int);

考虑到功能

void display(int (*p)[4],int r,int c)
{
    int i,j,*q;
    for(i=0;i<r;i++)
    {
        q=p+i;
        for(j=0;j<c;j++)
        printf("%d",*(q+j));
        printf("\n");
    }
} 

分配了不兼容的类型

q=p+i;

表达式p + i的类型为int ( * )[4],而指针q的类型为int *

应写成

q = *( p + i );

在这种情况下,表达式*( p + i )的类型int[4]隐式转换为int *类型的指针

同样根据C标准,没有参数的函数main应声明为

int main( void )

如果仅使用指针而不是索引来访问数组的元素,那么函数可以按照以下方式查看,如演示程序中所示

#include <stdio.h>

#define COLS    4

void display( int (*)[COLS], size_t );

int main( void )
{
    int a[][COLS] = 
    {
        { 1, 2, 3, 4 },
        { 5, 6, 7, 8 },
        { 9, 0, 1, 6 }
    };

    const size_t ROWS = sizeof( a ) / sizeof( *a );

    display( a, ROWS);
}

void display( int (*p)[COLS], size_t rows )
{
    for ( int ( *p_row )[COLS] = p; p_row != p + rows; ++p_row )
    {
        for ( int *p_col = *p_row; p_col != *p_row + COLS; ++p_col )
        {
            printf( "%d ", *p_col );
        }

        putchar( '\n' );
    }
} 

它的输出是

1 2 3 4 
5 6 7 8 
9 0 1 6 

答案 1 :(得分:0)

数组自然衰落到指向第一个元素的指针。也就是说,a会衰减为指向a[0]的指针,即&a[0]

什么是a[0]?它是四个 int元素的数组。因此&a[0]是指向四个int元素数组的指针,或int (*)[4]

答案 2 :(得分:0)

你应该写出完全相同的void display(int(* p)[4],int,int)。 因为当你编写int [3] [4] c时,请看三个指针,每个指向3个4个元素的数组。