C语言详解 - 指针与数组

本文深入探讨了一维、二维及三维数组与指针的关系,包括它们的声明、使用方法及如何通过指针操作数组元素等内容。

本文转载http://www.cnblogs.com/JCSU/articles/1487666.html

 对于数组int a[5],a[0]表示的是数组中的第1个元素,那a指的又是什么呢?由于数组名表示数组从什么地方开始存放。因此,数组名a表示的是一个地址。指针存放的也是地址值,那么数组名与指针之间似乎存在某种相似性。

 

1、一维数组与指针

 

例1. 初识数组和指针 - 单个字符的输出与多个字符的输入

#include  < stdio.h >

int  main()
{
     char  single;
     char  multiple[ 10 ];

    scanf( " %c " ,  & single);  
    fflush(stdin);  // 清除键盘缓冲区,准备下一次输入
    scanf( " %s " , multiple);

    printf( " single: %c \n " , single);
    printf( " multiple: %s \n " , multiple);

     return   0 ;
}

 

例2. 使用数组名和指针分别访问数组中的元素

#include  < stdio.h >

int  main()
{
     int  pos[ 5 ]  =  {  1 ,  3 ,  5 ,  7 ,  9  };
     int   * p  =  pos;

     //  &pos[0], pos, p三者都是数组第1个元素的首地址
     for ( int  i = 0 ; i < 5 ; i ++ )
        printf( " %d %d %d %d \n " , pos[i],  /*  元素访问方式:数组名+索引  */
        
         /*  元素访问方式:首地址+偏移量  */
         * ( & pos[ 0 ]  +  i),
         * (pos  +  i),
         * (p  +  i)

        );

     return   0 ;
}

 

运行结果:

1 1 1 1
3 3 3 3
5 5 5 5
7 7 7 7
9 9 9 9
Press any key to continue

分析:数组名pos表示的是数组中元素从什么地方开始存储,它实际上是一个常量指针,它指向数组中第一个元素的地址。它的类型取决于数组元素的类型。在本实例中,数组元素的类型为int类型,那pos的类型是“指向int的常量指针”。这样我们可以声明一个与pos同类型的变量p,然后将pos赋给该变量p。因此p的声明方法必须是:int *p;

 

例3. 数组名作为函数参数传递 - 形参的类型必须与实参一致

#include  < stdio.h >

/*  函数声明时,变量名,数组名,指针名可省略  */
void  print_v1( int  [],  int );
void  print_v2( int   * ,  int );

int  main()
{
     int  pos[ 5 ]  =  {  1 ,  3 ,  5 ,  7 ,  9  };

     /*  输出数组元素以及各元素地址  */
     for ( int  i = 0 ; i < 5 ; i ++ )
        printf( " %p pos[%d]:%d *(pos+%d):%d\n " , pos + i, i, i, pos[i],  * (pos + i) );

    print_v1(pos,  5 );  // 调用形参为版本1的函数
    print_v2(pos,  5 );  // 调用形参为版本2的函数

     return   0 ;
}

void  print_v1( int  x[],  int  count)  // 形参为数组
{
    printf( " \n " );
     /*  输出数组元素以及各元素地址  */
     for ( int  i = 0 ; i < count; i ++ )
        printf( " %p x[%d]:%d *(x+%d):%d\n " , x + i, i, i, x[i],  * (x + i) );
}

void  print_v2( int   * p,  int  count)  // 形参为指针
{
    printf( " \n " );
     /*  输出数组元素以及各元素地址  */
     for ( int  i = 0 ; i < count; i ++ )
        printf( " %p p[%d]:%d *(p+%d):%d\n " , p + i, i, i, p[i],  * (p + i) );
}

 

输出结果:

0012FF6C pos[0]:0 *(pos+1):1
0012FF70 pos[1]:1 *(pos+3):3
0012FF74 pos[2]:2 *(pos+5):5
0012FF78 pos[3]:3 *(pos+7):7
0012FF7C pos[4]:4 *(pos+9):9

0012FF6C x[0]:0 *(x+1):1
0012FF70 x[1]:1 *(x+3):3
0012FF74 x[2]:2 *(x+5):5
0012FF78 x[3]:3 *(x+7):7
0012FF7C x[4]:4 *(x+9):9

0012FF6C p[0]:0 *(p+1):1
0012FF70 p[1]:1 *(p+3):3
0012FF74 p[2]:2 *(p+5):5
0012FF78 p[3]:3 *(p+7):7
0012FF7C p[4]:4 *(p+9):9
Press any key to continue

分析:该程序中的三种输出都是针对同一地址进行。传递的是数组名pos,形参的声明必须和pos的类型相同。pos为一个“指向int型的指针”,因此形参也必须是一个“指向int型的指针”。这样可以将形参声明为一维int类型的数组,也可以声明为一个指向int型的指针int *。

 

 

2、二维数组与指针

 

与一维数组相比,二维数组名与指针之间的差异更大一些。为了理解二维数组与指针之间的对应关系,往往把二维数组看成一维数组,该一维数组中的元素也是一元数组。如:二维数组int pos[2][3]可以理解为一维数组int3 pos[2],int3是我们为方便理解而定义的一种新数据类型,一个int3包含3个int型元素。

 

例1. 二维数组的输出

#include  < stdio.h >

int  main()
{
     int  pos[ 2 ][ 3 ]  =  {  1 ,  3 ,  5 ,  7 ,  ' 9 '  };

    printf( " 元素访问方式:数组名+索引:pos[i][j] \n " );
     for ( int  i = 0 ; i < 2 ; i ++ )
         for ( int  j = 0 ; j < 3 ; j ++ )
            printf( " pos[%d][%d]: %p %d \n " , i, j,  & pos[i][j], pos[i][j]);

    printf( " \n " );
    printf( " 元素访问方式:首地址+元素偏移地址:*(&pos[0][0]+3*i+j) \n " );

     for (i = 0 ; i < 2 ; i ++ )
         for ( int  j = 0 ; j < 3 ; j ++ )
            printf( " pos[%d][%d]: %p %d \n " , i, j,  & pos[i][j],  * ( & pos[ 0 ][ 0 ] + 3 * i + j));

     return   0 ;
}

 

程序输出:

元素访问方式:数组名+索引:pos[i][j]
pos[0][0]: 0012FF68 1
pos[0][1]: 0012FF6C 3
pos[0][2]: 0012FF70 5
pos[1][0]: 0012FF74 7
pos[1][1]: 0012FF78 57
pos[1][2]: 0012FF7C 0

元素访问方式:首地址+元素偏移地址:*(&pos[0][0]+3*i+j)
pos[0][0]: 0012FF68 1
pos[0][1]: 0012FF6C 3
pos[0][2]: 0012FF70 5
pos[1][0]: 0012FF74 7
pos[1][1]: 0012FF78 57
pos[1][2]: 0012FF7C 0
Press any key to continue

 

例2. 二维数组的地址情况

#include  < stdio.h >

int  main()
{
     int  boo[ 3 ]  =  {  10 ,  20 ,  30  };
     int  pos[ 3 ][ 4 ]  =  {  1 ,  3 ,  5 ,  7 ,  9 ,  11 ,  13 ,  15 ,  17 ,  19 ,  21 ,  23  };

    printf( " 元素地址(方法一): \n " );
    printf( " &pos[0][0~3]: %p %p %p %p\n " ,  & pos[ 0 ][ 0 ],  & pos[ 0 ][ 1 ],  & pos[ 0 ][ 2 ],  & pos[ 0 ][ 3 ]);
    printf( " &pos[1][0~3]: %p %p %p %p\n " ,  & pos[ 1 ][ 0 ],  & pos[ 1 ][ 1 ],  & pos[ 1 ][ 2 ],  & pos[ 1 ][ 3 ]);
    printf( " &pos[2][0~3]: %p %p %p %p\n " ,  & pos[ 2 ][ 0 ],  & pos[ 2 ][ 1 ],  & pos[ 2 ][ 2 ],  & pos[ 2 ][ 3 ]);

     /*  三种方法获取二维数组中各行的首地址  */
    printf( " 行地址(方法一): \n " );
    printf( " pos+0: %p \n " , pos + 0 );
    printf( " pos+1: %p \n " , pos + 1 );
    printf( " pos+2: %p \n " , pos + 2 );

    printf( " 行地址(方法二): \n " );
    printf( " *(pos+0): %p \n " ,  * (pos + 0 ));
    printf( " *(pos+1): %p \n " ,  * (pos + 1 ));
    printf( " *(pos+2): %p \n " ,  * (pos + 2 ));

    printf( " 行地址(方法三): \n " );
    printf( " pos[0]: %p \n " , pos[ 0 ]);
    printf( " pos[1]: %p \n " , pos[ 1 ]);
    printf( " pos[2]: %p \n " , pos[ 2 ]);

     /*  对比:对一维数组进行的相同操作  */
    printf( " 一维数组: \n " );
    printf( " *(boo+0): %d \n " ,  * (boo + 0 ));
    printf( " *(boo+1): %d \n " ,  * (boo + 1 ));
    printf( " *(boo+2): %d \n " ,  * (boo + 2 ));

    printf( " boo[0]: %d \n " , boo[ 0 ]);
    printf( " boo[1]: %d \n " , boo[ 1 ]);
    printf( " boo[2]: %d \n " , boo[ 2 ]);

    printf( " 元素地址(方法二): \n " );
    printf( " pos[0]+0~3: %p %p %p %p\n " , pos[ 0 ], pos[ 0 ] + 1 , pos[ 0 ] + 2 , pos[ 0 ] + 3 );
    printf( " pos[1]+0~3: %p %p %p %p\n " , pos[ 1 ], pos[ 1 ] + 1 , pos[ 1 ] + 2 , pos[ 1 ] + 3 );
    printf( " pos[2]+0~3: %p %p %p %p\n " , pos[ 2 ], pos[ 2 ] + 1 , pos[ 2 ] + 2 , pos[ 2 ] + 3 );

    printf( " 元素地址(方法三): \n " );
    printf( " *(pos+0)+0~3: %p %p %p %p\n " ,  * (pos + 0 ),  * (pos + 0 ) + 1 ,  * (pos + 0 ) + 2 ,  * (pos + 0 ) + 3 );
    printf( " *(pos+1)+0~3: %p %p %p %p\n " ,  * (pos + 1 ),  * (pos + 1 ) + 1 ,  * (pos + 1 ) + 2 ,  * (pos + 1 ) + 3 );
    printf( " *(pos+2)+0~3: %p %p %p %p\n " ,  * (pos + 2 ),  * (pos + 2 ) + 1 ,  * (pos + 2 ) + 2 ,  * (pos + 2 ) + 3 );

     return   0 ;
}

 

运行结果:

元素地址(方法一):
&pos[0][0~3]: 0012FF44 0012FF48 0012FF4C 0012FF50
&pos[1][0~3]: 0012FF54 0012FF58 0012FF5C 0012FF60
&pos[2][0~3]: 0012FF64 0012FF68 0012FF6C 0012FF70
行地址(方法一):
pos+0: 0012FF44
pos+1: 0012FF54
pos+2: 0012FF64
行地址(方法二):
*(pos+0): 0012FF44
*(pos+1): 0012FF54
*(pos+2): 0012FF64
行地址(方法三):
pos[0]: 0012FF44
pos[1]: 0012FF54
pos[2]: 0012FF64
一维数组:
*(boo+0): 10
*(boo+1): 20
*(boo+2): 30
boo[0]: 10
boo[1]: 20
boo[2]: 30
元素地址(方法二):
pos[0]+0~3: 0012FF44 0012FF48 0012FF4C 0012FF50
pos[1]+0~3: 0012FF54 0012FF58 0012FF5C 0012FF60
pos[2]+0~3: 0012FF64 0012FF68 0012FF6C 0012FF70
元素地址(方法三):
*(pos+0)+0~3: 0012FF44 0012FF48 0012FF4C 0012FF50
*(pos+1)+0~3: 0012FF54 0012FF58 0012FF5C 0012FF60
*(pos+2)+0~3: 0012FF64 0012FF68 0012FF6C 0012FF70
Press any key to continue

有了例2中的多种地址获取方式,就很容易通过这些方式获得数组中的元素了。注意:p[i] 与 *(p+i) 是等价的。

 

例3. 在例2的基本上使用解除引用操作符*输出二维数组中的元素

#include  < stdio.h >

int  main()
{
     int  pos[ 3 ][ 4 ]  =  {  1 ,  3 ,  5 ,  7 ,  9 ,  11 ,  13 ,  15 ,  17 ,  19 ,  21 ,  23  };
     int  i, j;

    printf( " 数组的输出(方法一): \n " );
     for (i = 0 ; i < 3 ; i ++ )
    {
         for (j = 0 ; j < 4 ; j ++ )
            printf( " pos[i][j]: %d\n " , pos[i][j]);
        printf( " \n " );
    }

    printf( " 行首元素的输出(方法一): \n " );
     for (i = 0 ; i < 3 ; i ++ )
        printf( " **(pos+i): %d \n " ,  ** (pos + i));

    printf( " 行首元素的输出(方法二): \n " );
     for (i = 0 ; i < 3 ; i ++ )
        printf( " *pos[i]: %d \n " ,  * pos[i]);

    printf( " 数组的输出(方法二): \n " );
     for (i = 0 ; i < 3 ; i ++ )
         for (j = 0 ; j < 4 ; j ++ )
            printf( " *(pos[i]+j): %d\n " ,  * (pos[i] + j));

    printf( " 数组的输出(方法三): \n " );
     for (i = 0 ; i < 3 ; i ++ )
         for (j = 0 ; j < 4 ; j ++ )
            printf( " *(*(pos+i)+j): %d\n " ,  * ( * (pos + i) + j));
     return   0 ;
}

 

程序输出:

数组的输出(方法一):
pos[i][j]: 1
pos[i][j]: 3
pos[i][j]: 5
pos[i][j]: 7

pos[i][j]: 9
pos[i][j]: 11
pos[i][j]: 13
pos[i][j]: 15

pos[i][j]: 17
pos[i][j]: 19
pos[i][j]: 21
pos[i][j]: 23

行首元素的输出(方法一):
**(pos+i): 1
**(pos+i): 9
**(pos+i): 17
行首元素的输出(方法二):
*pos[i]: 1
*pos[i]: 9
*pos[i]: 17
数组的输出(方法二):
*(pos[i]+j): 1
*(pos[i]+j): 3
*(pos[i]+j): 5
*(pos[i]+j): 7
*(pos[i]+j): 9
*(pos[i]+j): 11
*(pos[i]+j): 13
*(pos[i]+j): 15
*(pos[i]+j): 17
*(pos[i]+j): 19
*(pos[i]+j): 21
*(pos[i]+j): 23
数组的输出(方法三):
*(*(pos+i)+j): 1
*(*(pos+i)+j): 3
*(*(pos+i)+j): 5
*(*(pos+i)+j): 7
*(*(pos+i)+j): 9
*(*(pos+i)+j): 11
*(*(pos+i)+j): 13
*(*(pos+i)+j): 15
*(*(pos+i)+j): 17
*(*(pos+i)+j): 19
*(*(pos+i)+j): 21
*(*(pos+i)+j): 23
Press any key to continue

 

例4:用指向数组的指针输出数组元素

指向数组的指针,或数组指针是多维数组中的一个概念。对于一维数组的情况往往是:

int pos[10];
int *p = pos;

如果要声明一个指向二维数组的指针,该怎么办?这时候要用到数组指针。

我们知道,数组名是一个地址。对于一维数组pos[10]而言,对数组名pos使用*号解除引用后可直接得到该数组的第一个元素,如:int b = *pos;对pos+1解除引用后得到该数组的第二个元素,如可以这样操作:int c = *(pos+1); 这些元素的类型为int型。因此,声明的p指针也必须是int型,从而保持类型的一致性。

假设有二维数组int pos[3][4]; 应该怎样声明一个指向数组名pos的指针呢?对数组名pos使用*号解除引用后实际上是数组第一行元素的首地址,该行是一个包含4个int元素的数组。因此,声明的指针其类型必须也是一个指向包含4个int元素的类型。

所以声明方法为:

int pos[3][4];

int (*p)[4] = pos;

以下实例声明一个指向二维数组名的数组指针,其中的sizeof操作符更有助于理解int (*p)[4]的含义。

#include  < stdio.h >

int  main()
{
     int  pos[ 3 ][ 4 ]  =  {  1 ,  3 ,  5 ,  7 ,  9 ,  11 ,  13 ,  15 ,  17 ,  19 ,  21 ,  23  };
     int  i, j;
     int  ( * p)[ 4 ]  =  pos;

    printf( " sizeof(pos): %d bytes \n " ,  sizeof (pos));

    printf( " sizeof(pos[0]): %d bytes \n " ,  sizeof (pos[ 0 ]));
    printf( " sizeof(pos[1]): %d bytes \n " ,  sizeof (pos[ 1 ]));
    printf( " sizeof(pos[2]): %d bytes \n " ,  sizeof (pos[ 2 ]));

    printf( " sizeof(pos[0][0]): %d bytes \n " ,  sizeof (pos[ 0 ][ 0 ]));
    printf( " sizeof(pos[0][1]): %d bytes \n " ,  sizeof (pos[ 0 ][ 1 ]));
    printf( " sizeof(pos[0][2]): %d bytes \n " ,  sizeof (pos[ 0 ][ 2 ]));

    printf( " sizeof(p): %d bytes \n " ,  sizeof (p));

    printf( " 数组的输出(方法一): \n " );
     for (i = 0 ; i < 3 ; i ++ )
    {
         for (j = 0 ; j < 4 ; j ++ )
            printf( " p[i][j]: %d\n " , p[i][j]);
        printf( " \n " );
    }

    printf( " 行首元素的输出(方法一): \n " );
     for (i = 0 ; i < 3 ; i ++ )
        printf( " **(p+i): %d \n " ,  ** (p + i));

    printf( " 行首元素的输出(方法二): \n " );
     for (i = 0 ; i < 3 ; i ++ )
        printf( " *p[i]: %d \n " ,  * p[i]);

    printf( " 数组的输出(方法二): \n " );
     for (i = 0 ; i < 3 ; i ++ )
         for (j = 0 ; j < 4 ; j ++ )
            printf( " *(p[i]+j): %d\n " ,  * (p[i] + j));

    printf( " 数组的输出(方法三): \n " );
     for (i = 0 ; i < 3 ; i ++ )
         for (j = 0 ; j < 4 ; j ++ )
            printf( " *(*(p+i)+j): %d\n " ,  * ( * (p + i) + j));
     return   0 ;
}

 

程序输出:

sizeof(pos): 48 bytes
sizeof(pos[0]): 16 bytes
sizeof(pos[1]): 16 bytes
sizeof(pos[2]): 16 bytes
sizeof(pos[0][0]): 4 bytes
sizeof(pos[0][1]): 4 bytes
sizeof(pos[0][2]): 4 bytes
sizeof(p): 4 bytes
数组的输出(方法一):
p[i][j]: 1
p[i][j]: 3
p[i][j]: 5
p[i][j]: 7

p[i][j]: 9
p[i][j]: 11
p[i][j]: 13
p[i][j]: 15

p[i][j]: 17
p[i][j]: 19
p[i][j]: 21
p[i][j]: 23

行首元素的输出(方法一):
**(p+i): 1
**(p+i): 9
**(p+i): 17
行首元素的输出(方法二):
*p[i]: 1
*p[i]: 9
*p[i]: 17
数组的输出(方法二):
*(p[i]+j): 1
*(p[i]+j): 3
*(p[i]+j): 5
*(p[i]+j): 7
*(p[i]+j): 9
*(p[i]+j): 11
*(p[i]+j): 13
*(p[i]+j): 15
*(p[i]+j): 17
*(p[i]+j): 19
*(p[i]+j): 21
*(p[i]+j): 23
数组的输出(方法三):
*(*(p+i)+j): 1
*(*(p+i)+j): 3
*(*(p+i)+j): 5
*(*(p+i)+j): 7
*(*(p+i)+j): 9
*(*(p+i)+j): 11
*(*(p+i)+j): 13
*(*(p+i)+j): 15
*(*(p+i)+j): 17
*(*(p+i)+j): 19
*(*(p+i)+j): 21
*(*(p+i)+j): 23
Press any key to continue

 

例5. 二维数组作函数参数

#include  < stdio.h >

void  print_v1( int  p[][ 4 ]);
void  print_v2( int  ( * p)[ 4 ]);
// void print_v1(int [][4]);
// void print_v2(int (*)[4]);

int  main()
{
     int  pos[ 3 ][ 4 ]  =  {  1 ,  3 ,  5 ,  7 ,  9 ,  11 ,  13 ,  15 ,  17 ,  19 ,  21 ,  23  };
    
    print_v1(pos);
    print_v2(pos);

     return   0 ;
}

void  print_v1( int  p[][ 4 ])
{
    printf( " 行首元素的输出: \n " );
     for ( int  i = 0 ; i < 3 ; i ++ )
        printf( " **(p+i): %d \n " ,  ** (p + i));

    printf( " 数组的输出: \n " );
     for (i = 0 ; i < 3 ; i ++ )
         for ( int  j = 0 ; j < 4 ; j ++ )
            printf( " p[i][j]: %d\n " , p[i][j]);
}

void  print_v2( int  ( * p)[ 4 ])
{
    printf( " 数组的输出: \n " );
     for ( int  i = 0 ; i < 3 ; i ++ )
         for ( int  j = 0 ; j < 4 ; j ++ )
            printf( " *(*(p+i)+j): %d\n " ,  * ( * (p + i) + j));
}

 

注意:函数声明时,参数列表中的数组名,变量名等可以省略。形参可以为一个省略最左边维数的二维数组,也可以是一个数组指针。

 

 

3、解引用方法输出三维数组

 

弄懂了二维数组的解引用方法输出,三维数组就很容易了。

例1. 三维数组的输出

#include  < stdio.h >
void  main()
{
     int  a[ 2 ][ 3 ][ 4 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ,\
     13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 };

     for ( int  i = 0 ;i < 2 ;i ++ )
         for ( int  j = 0 ;j < 3 ;j ++ )
             for ( int  k = 0 ;k < 4 ;k ++ )
                printf( " a[%d][%d][%d]: %d: %d \n " , i, j, k,  & a[i][j][k], a[i][j][k]);

    printf( " \na:%d \t ***a: %d \t **a: %d\n " , a,  *** a,  ** a);
    printf( " a[0]:%d \t **a[0]: %d \n " , a[ 0 ],  ** a[ 0 ]);
    printf( " a[1]:%d \t **a[1]: %d \n " , a[ 1 ],  ** a[ 1 ]);
    printf( " a[0][1]:%d \t *a[0][1]: %d \n " , a[ 0 ][ 1 ],  * a[ 0 ][ 1 ]);
}

 

运行结果:
a[0][0][0]: 1244960: 1
a[0][0][1]: 1244964: 2
a[0][0][2]: 1244968: 3
a[0][0][3]: 1244972: 4 
a[0][1][0]: 1244976: 5
   ...
a[0][1][3]: 1244988: 8

a[0][2][0]: 1244992: 9
   ...
a[0][2][3]: 1245004: 12

a[1][0][0]: 1245008: 13
a[1][0][1]: 1245012: 14
a[1][0][2]: 1245016: 15
a[1][0][3]: 1245020: 16

a[1][1][0]: 1245024: 17
   ...
a[1][1][3]: 1245036: 20
a[1][2][0]: 1245040: 21
   ...
a[1][2][3]: 1245052: 24

a:1244960      ***a: 1      **a: 1244960
a
a[0]:1244960   *a[0]: 1
a[1]:1245008   *a[1]: 13
a[0][1]:1244976   *a[0][1]: 5

 

 

4、应用举例

 

例1. 删除二维字符数组中所以长度超过k的字符串,返回所剩字符串个数

#include  < stdio.h >
#include  < string .h >
#define  N 6  // 二维数组中的字符串个数
#define  M 10  // 二维数组中字符串的最大长度

int  func( char  ( * a)[M],  int  k)  // 形参为指向字符串数组指针
{
     int  i, j = 0 , len;
     for (i = 0 ; i < N; i ++ )
    {
        len = strlen(a[i]);
         if (len <= k)
            strcpy(a[j ++ ], a[i]);  // 字符串复制函数
    }
     return  j;
}

main()
{
     char  fruit[N][M] = { " Pear " ,  " Banana " ,  " Apple " ,  " Orange " ,  " Grape " ,  " Lemon " };  // 二维字符数组
     int  i, f;
    printf( " The original string: \n " );
     for (i = 0 ; i < N; i ++ )
        puts(fruit[i]);  // puts库函数输出字符串,原型为:int __cdecl puts(const char *);
    printf( " \n " );
    f = func(fruit,  5 );  // 实参为数组名
    printf( " The string which length is less than or equal to 5: \n " );

     for (i = 0 ; i < f; i ++ )
        puts(fruit[i]);  // puts库函数输出字符串,原型为:int __cdecl puts(const char *);
    printf( " \n " );    

     return   0 ;
}

 

运行结果:

The original string:
Pear
Banana
Apple
Orange
Grape
Lemon

The string which length is less than or equal to 5:
Pear
Apple
Grape
Lemon

总结:当我们声明一个指向二维数组的指针后,我们可以跟使用二维数组一样,使用该指针对数组进行相应操作。如上例如示:主函数中声明了一个字符型的二维数组char fruit[N][M];被调用函数参数为一个指向该数组的数组指针 char (*a)[M];当该指针指向了fruit数组,我们就可以使用puts(a[i]),它与puts(fruit[i])一样,都是输出数组中的第i个字符串,或者说二维数组的第i行元素。在这里a[i]和fruit[i]是一个指向字符串的指针,它与puts(const char *)函数的参数类型const char *是一致的,所以可以调用puts()函数输出相应的字符串。同理,可以将a[j++], a[i]作为参数字符串复制函数strcpy(char * dest, const char * src),因为strcpy函数的参数都是指向字符串的指针,与a[j++]和a[i]的类型是一致的。

转载于:https://www.cnblogs.com/alaigle/archive/2012/04/27/2473616.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值