为什么这段代码会出现编译错误?

时间:2016-05-26 12:13:55

标签: c double-pointer

我正在尝试学习双指针。我试图通过将数组的地址传递给函数来打印2d数组。但是编译错误即将来临。我无法理解为什么?

以下是代码。

#include<stdio.h>
#include<stdlib.h>
void print(int **,int,int);
int main()
{

    int i,j;
    int a[][3]={
                {1,0,1},{1,1,1},   {1,1,1}
            };
            print(a,3,3);
            return 0;
}
void print(int **A, int n11, int n12)
{
    int i,j;
   for(i=0;i<3;i++)
            {
                for(j=0;j<3;j++)
                {
                    printf("%d  ",*((A+i*n12)+j);
                }
                printf("\n");
            }
}

错误日志---

set_matrix.c: In function 'main':
set_matrix.c:29:19: warning: passing argument 1 of 'print' from incompatible poi
nter type [-Wincompatible-pointer-types]
             print(a,3,3);
                   ^
set_matrix.c:9:6: note: expected 'int **' but argument is of type 'int (*)[3]'
 void print(int **,int,int);
  ^

2 个答案:

答案 0 :(得分:1)

当我测试您的代码时,我会收到这些错误和警告。

/home/dac/ClionProjects/gnu/main.c: In function ‘main’:
/home/dac/ClionProjects/gnu/main.c:11:9: warning: passing argument 1 of ‘print’ from incompatible pointer type [-Wincompatible-pointer-types]
   print(a,3,3);
         ^
/home/dac/ClionProjects/gnu/main.c:3:6: note: expected ‘int **’ but argument is of type ‘int (*)[3]’
 void print(int **,int,int);
      ^
/home/dac/ClionProjects/gnu/main.c: In function ‘print’:
/home/dac/ClionProjects/gnu/main.c:21:35: error: expected ‘)’ before ‘;’ token
       printf("%d  ",*((A+i*n12)+j);
                                   ^
/home/dac/ClionProjects/gnu/main.c:21:14: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
       printf("%d  ",*((A+i*n12)+j);
              ^
/home/dac/ClionProjects/gnu/main.c:22:5: error: expected ‘;’ before ‘}’ token
     }
 ^

如果您只想打印矩阵,可以使用您创建的矩阵并重新声明打印方式,类似于以下代码。

#include <stdio.h>
#define size 3
void print_matrix(int x, int y, int a[size][size]) {

  int i, j;
  for(i = 0; i < x; i++) {
    for(j = 0; j < y; j++)
      printf("%d\t", a[i][j]);
    putchar('\n');
  }
}

int main()  {
  int a[size][size]={
          {1,0,1},{1,1,1},   {1,1,1}
  };
  print_matrix(size,size, a);
  return 0;
}

<强>输出

/system/cmake/generated/gnu-fadf49ce/fadf49ce/Debug/gnu
1   0   1   
1   1   1   
1   1   1   

Process finished with exit code 0

如果你想了解双指针,尝试使用和操作程序的argv - 它已经是一个双指针。或者动态创建新矩阵:int **matrix = malloc(size * sizeof(int *));

或者,如果您想使用原始问题的指针版本(使用指针打印矩阵)。

#include <stdio.h>
#define size 3

void print_matrix(int (*a)[size], int n) {
  int i, j;
  for(i = 0; i < n; i++) {
    for(j = 0; j < n; j++)
      printf("%d\t", a[i][j]);
    putchar('\n');
  }

}
int main()  {
  int a[][size]={
          {1,0,1},{1,1,1},   {1,1,1}
  };
  print_matrix(a, size);
  return 0;
}

上面的代码使用指针并打印相同的矩阵:

1   0   1   
1   1   1   
1   1   1   

要学习指针,可以声明一个指针矩阵并尝试操作它,下面使用指针创建并打印一个随机数矩阵。

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

#define size 3

void print_matrix(int ***matrix) {
  for (unsigned row = 0; row < size; row++) {
    for (unsigned column = 0; column < size; column++) {
      printf("%d ", matrix[row][column]);
    }
    printf("\n");
  }
}

int main() {
  int ***matrix = malloc(size * sizeof(int **));
  if (!matrix) abort();
  srand(time(NULL));
  for (unsigned row = 0; row < size; row++) {
    matrix[row] = calloc(size, sizeof(int *));
    if (!matrix[row]) abort();
    for (unsigned column = 0; column < size; column++) {
      matrix[row][column] = rand();
    }
  }
  print_matrix(matrix);
  return 0;
}

<强>输出

2058554958 959327445 396140031 
214331704 706399125 124749117 
1280566165 206604059 668072276 

答案 1 :(得分:1)

  

我正在尝试学习双指针

我不确定术语是否正确,但我不会将指针指向double pointer,因为您很容易与double*&amp; **

考虑int x=1.0。你可以:

int *ptr=&x; // You make ptr point to x(ie x's memory address).

但请记住,指针也是一种类型 - 准确地说是一个对象。一个对象占用内存。要存储ptr的地址(即&amp; ptr),你需要一个指向指针的指针,所以:

int **ptr_to_ptr=&ptr; // says ptr_to_ptr is a pointer to an (int*)

这里更大的问题是我们如何声明指向int a[][]的指针。

对于数组说,int a [3],应该表示它的指针应该是以下格式 - int (*p)[3]。我们说p是一个指向3个整数数组的指针。

不同之处在于您拥有一组数组,即int a[][3]。 指向此数组的指针应采用此格式 - int (*p)[][3]。我们说p是指向数组的指针,这个数组本身的每个元素都是一个3个整数的数组。

现在比较int a [3]和int a [3] [3]

        int a[3]                    |           int a[3][3]
________________________________________________________________________
      &a[0] ~ a (1)                 |   &a[0][0] ~ &a[0] ~ a
                                    |               |------> follows (1)
                                    |              
     a[0] is an int                 |        a[0] is an int[3]
                                    |
                                    |
 you pass '&a' to int(*)[]          |     you pass '&a' to int(*)[][]
 (You omit the &, you get-but the   |   (You omit the &, you get-but the 
 argument is of type int * error)   |argument is of type int (*)[3] error)
                                    |
________________________________________________________________________

因此,实施程序的正确方法是:

#include<stdio.h>
#include<stdlib.h>
void print(int (*)[][3],int); //You need to pass only the  rows
int main()
{
  int i,j;
  int a[][3]={
    {1,0,1},{1,1,1},{1,1,1}
  };
  print(&a,3); // You can programmtically determine the number of rows
  return 0;
}
void print(int (*A)[][3], int x) // You cannot have int (*A)[][]
{
  int i,j;
  for(i=0;i<3;i++)
  {
    for(j=0;j<3;j++)
    {
      printf("%d\t",(*A)[i][j]);
    }
    printf("\n");
  }
}