欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C: 第5章 指向数组的指针

程序员文章站 2022-07-01 22:34:12
...

指向数组的指针

指向数组的指针也是一个指针,和之前的指针不同的是它指向的是一个数组。这样可以像指针那样访问数组,通过指向数组的指针访问数组,在操作指针的时候和之前的指针不一样。

先看一个数组

int a[] = {1, 2, 3, 4, 5, 6};

 

在访问数组元素的时候,通常是通过数组变量加上元素下标来访问,如a[i], i=0,1,2,3,...,n。a表示分配给数组的一块连续内存空间的起始地址,所以也可以像指针那样访问,如*(a+i), i=0,1,2,3,...n。

 

int *p = a;

这里将a直接赋值给指针p,所以也可以像指针那样访问,如*(p+i), i=0,1,2,3,...n。。这和之前的没什么不一样。

 

int (*p)[6] = &a;

这里的p也是一个指针,这个指针和之前的指针就不一样了。

 

int a[][6] = 
       {{1, 2,  3,  4,  5,  6},
       {11,12,13,14,15,16},

       {21,22,23,24,25,26},
       {31,32,33,34,35,36},
       {41,42,43,44,45,46},
       {51,52,53,54,55,56}};

int (*p)[6] = a;

 

int (*p)[6][6] = &a;

 

先看如下代码:

函数matrix_from_n原型为:

int matrix_from_n(matrix *matrix, int n, int** data);

函数matrix_from_n的第3个参数为int **类型。但在调用matrix_from_n函数的时候传的是int matrix_data[][6]。

 

  int matrix_data[][6] = 
      {{0, 50, 75, 80,  0, 30}, 
      {50,  0, 35,  0,  0,  0}, 
      {75, 35,  0, 40,  0, 90}, 
      {80,  0, 40,  0, 45, 60}, 
      { 0,  0,  0, 45,  0, 15}, 
      {30,  0, 90, 60, 15,  0}};

  matrix_from_n(&matrix, 6, matrix_data);

 

上述代码会提示一个警告:

warning: passing argument 3 of ‘matrix_from_n’ from incompatible pointer type

note: expected ‘int **’ but argument is of type ‘int (*)[6]’

 

也就是虽然matrix_data定义的是int matrix_data[][6]类型,但是在传递的时候其实是int (*)[6]类型,这也是一种指针类型,它是一个指向一维数组的指针类型,具体点应该是指向6个元素的一维数组的指针类型。虽然也是指针类型,但和int **也是不一样的。

 

将上述代码改为如下:

  int matrix_data[][6] = 
      {{0, 50, 75, 80,  0, 30}, 
      {50,  0, 35,  0,  0,  0}, 
      {75, 35,  0, 40,  0, 90}, 
      {80,  0, 40,  0, 45, 60}, 
      { 0,  0,  0, 45,  0, 15}, 
      {30,  0, 90, 60, 15,  0}};

  int (*p)[6] = matrix_data;

  matrix_from_n(&matrix, 6, p);

这段代码其实和上面的代码是一样的,同样会提示上面的警告:

warning: passing argument 3 of ‘matrix_from_n’ from incompatible pointer type

 

note: expected ‘int **’ but argument is of type ‘int (*)[6]’

 

继续,将上述代码改为如下:

  int matrix_data[][6] = 
      {{0, 50, 75, 80,  0, 30}, 
      {50,  0, 35,  0,  0,  0}, 
      {75, 35,  0, 40,  0, 90}, 
      {80,  0, 40,  0, 45, 60}, 
      { 0,  0,  0, 45,  0, 15}, 
      {30,  0, 90, 60, 15,  0}};

  int **p = matrix_data;

  matrix_from_n(&matrix, 6, p);

因为要求的是int **类型,所以这里将matrix_data赋值给int **类型的指针:int **p = matrix_data;但在这个地方也会提示警告。在int **p = matrix_data;处提示如下:

warning: initialization from incompatible pointer type

这里其实就是试图将int (*)[6]类型转换为int **类型。问题本质上和上面的一样。

 

所以

int matrix_data[][6]

这个数组类型定义除了按照数组的方式访问,如果按照指针的方式去访问的话,matrix_data其实是一个指向6个元素的一维数组的指针类型,其定义形式为:int (*matrix_data)[6]。

 

 

 

继续,将上述代码改为如下:

 

  int matrix_data[] = 
     { 0, 50, 75, 80,  0, 30, 
      50,  0, 35,  0,  0,  0, 
      75, 35,  0, 40,  0, 90, 
      80,  0, 40,  0, 45, 60, 
       0,  0,  0, 45,  0, 15, 
      30,  0, 90, 60, 15,  0};

  matrix_from_n(&matrix, 6, matrix_data);

提示如下:

warning: passing argument 3 of ‘matrix_from_n’ from incompatible pointer type

 

note: expected ‘int **’ but argument is of type ‘int *’

 

也就是现在将matrix_data定义为int matrix_data[]类型,但是在传递的时候其实是int *类型,也就是matrix_data按照指针的方式访问的话其实是int *类型。

 

继续,将上述代码改为如下:

 

  int matrix_data[] = 
     { 0, 50, 75, 80,  0, 30, 
      50,  0, 35,  0,  0,  0, 
      75, 35,  0, 40,  0, 90, 
      80,  0, 40,  0, 45, 60, 
       0,  0,  0, 45,  0, 15, 
      30,  0, 90, 60, 15,  0};

  matrix_from_n(&matrix, 6, &matrix_data);

提示如下:

warning: passing argument 3 of ‘matrix_from_n’ from incompatible pointer type

 

note: expected ‘int **’ but argument is of type ‘int (*)[36]’

 

也就是现在将matrix_data定义为int matrix_data[]类型,但是在传递的时候传的是&matrix_data,&matrix_data其实是int (*)[36]类型,其实是一个指向36个元素的一维数组的指针类型,其定义形式为:int (*matrix_data)[36]。

 

int (*p)[6];

这是一个指向6个元素的一维数组的指针。

 

例子:

int matrix_data[][6]

int (*matrix_data_p)[6] = matrix_data;

 

 

另外:

int matrix_data[] = {...}

如果按照指针的方式去访问的话,如果是直接matrix_data,其定义形式为:int *matrix_data。如果是&matrix_data,其实是一个指向一维数组的指针类型,其定义形式为:int (*matrix_data)[N], N为{...}中实际指定的元素的个数。

 

int matrix_data[6];

int *matrix_data_p1 = matrix_data;

int (*matrix_data_p2)[6] = &matrix_data;