繁体   English   中英

一维指针指向二维数组

[英]1-d pointer to a 2-d array

#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); 它的工作原理是,如果我们有一个数组指针,其列数作为数组中的元素数

表达式中使用的数组在极少数情况下会被转换为指向它们的第一个元素的指针。

来自 C 标准(6.3.2.1 左值、数组和函数指示符)

3 除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为“array of type”的表达式将转换为类型为“pointer”的表达式键入 '' 指向数组对象的初始元素并且不是左值。 如果数组对象具有寄存器存储类,则行为未定义。

所以如果你有一个数组声明如下

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 

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

什么是a[0] 它是一个包含四个int元素的数组。 所以&a[0]是一个指向四个int元素数组的指针,或者int (*)[4]

你应该像这样写 void display(int (*p)[4],int,int) 。 因为当你写 int a[3][4] c 时,这就像三个指向 3 个数组的指针,每个数组有 4 个元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM