2016-05-26 3 views
3

Я пытаюсь узнать о двойных указателях. Я пытаюсь напечатать массив 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

Посмотрите также на [это SO post] (http://stackoverflow.com/questions/7586702/is-2d-array-a-double-pointer) – LPs

+2

У вас также отсутствует закрывающая скобка для printf –

+0

@LPs. Это лучший дубликат iof [\ [this \]] (http://stackoverflow.com/questions/1052818/create-a-pointer-to-two-dimensional-array) вопроса. – sjsam

ответ

1

Я пытаюсь узнать о двойных указателей

Я не уверен, что терминология является правильным, но я бы не ссылается указатель для указателя как double pointer, потому что вы можете легко путать с double* & **.

Рассмотрите int x=1.0. Вы можете:

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

Но помните, что указатель также является типом - если быть точным объектом. Объект занимает память. Для того, чтобы сохранить адрес PTR (т.е. & PTR), вам нужен указатель на указатель так:

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

Чем больше проблема здесь состоит в том, как мы можем объявить указатель на int a[][].

Для массива say, int a [3], указатель, который должен представлять его, должен иметь следующий формат: int (*p)[3]. Мы говорим, что p является указателем на массив из 3 целых чисел.

Здесь разница в том, что у вас есть массив массивов, то есть int a[][3]. Указатель на этот массив должен этого формата - int (*p)[][3]. Мы говорим, что p - указатель на массив, каждый элемент этого массива - массив из 3 целых чисел.

Сравнивая теперь Int А [3] и Int в [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"); 
    } 
} 
+0

sjsam, Спасибо за помощь ур. Но когда я объявляю массив (1d) целых чисел как «int (* p) [3]» и пытаюсь распечатать, он не выполняется. Попросите вас объяснить. – a874

+0

@ a874: объявить? Если вы просто делаете int (* ptr) [3]; как и в утверждении, тогда ptr не может использоваться, если только не указывается на массив, скажем int a [3], или вы явно выделяете для него некоторую память, используя malloc – sjsam

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 
+0

, Thaks, но мне нужно еще немного help.Ur-объявление 'int (* a) [size]' означает, что 'a - это массив из числа« числа »целых чисел. А я правильно? Исправьте меня, если я неправильно. – a874

 Смежные вопросы

  • Нет связанных вопросов^_^