Могу ли я получить доступ к типу int (*) [] с помощью [] []? - PullRequest
1 голос
/ 04 июня 2010

исходя из этого вопроса " Что означает (int (*) []) var1? " Я пытался получить доступ к результату приведения как многомерный массив. Но я получаю следующую ошибку: «assignment from incompatible pointer type», за которой следует ошибка сегментации. Я пробовал также некоторые другие варианты, но ни один из них не работал. Как получить доступ к элементам var1 в функции example напрямую?

Спасибо!

 #include <stdlib.h>

int i(int n,int m,int var1[n][m]) {
  var1[0][0]=5;
  return var1[0][0];
}

int example() {
  int *var1 = malloc(100);

  // works
  int var2;
  var2 = i(10,10,(int (*)[])var1);
  printf("var2=%i",var2);
  //doesn't work I
  int *var3;
  var3=(int (*)[])var1; //"assignment from incompatible pointer type"
  printf("var3[0][0]=%i",var3[0][0]);


  //doesn't work II
  int *var4;
  var4=var1;
  printf("var4[0][0]=%i",var4[0][0]); //" error: subscripted value is neither array nor pointer"

  //doesn't work III
  int **var5;
  var5=var1;
  printf("var5[0][0]=%i",var5[0][0]); // assignment from incompatible pointer type


  return(1); 

} 

int main(){
  int a;
  a=example();
  return(1);
}

Ответы [ 5 ]

3 голосов
/ 04 июня 2010
int *var3;
var3 = (int (*)[])var1;

Вы приводите var1, который уже int* к int(*)[] (указатель на массив int), и присваиваете его var3, который снова равен int*.

Просто сделай

var3 = var1
1 голос
/ 04 июня 2010

Дайте этому шанс. Следующее скомпилировано без предупреждений и работает под C99 (gcc -std=c99 -pedantic -Wall):

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

int i(int n, int m, int (*var1)[m]) // C89 requires constant expression for
{                                   // array size
  int j, k;
  for (j = 0; j < n; j++)
    for (k = 0; k < m; k++)
      var1[j][k] = j*m+k;
  return var1[0][0];
}

int example(void)
{
  int *var1 = malloc(100 * sizeof *var1);   // Thanks, Joseph!
  int var2 = i(10, 10, (int (*)[10]) var1); // note the cast of var1 includes
                                            // the array size
  int (*var3)[10] = (int (*)[10]) var1;     // note the type of var3

  int j, k;
  for (j = 0; j < 100; j++)
    printf("var1[%2d] = %d\n", j, var1[j]);

  for (j = 0; j < 10; j++)
    for (k = 0; k < 10; k++)
      printf("var3[%2d][%2d] = %d\n", j, k, var3[j][k]);

  free(var1);
  return var2;
}

int main(void)
{
  int x = example();
  printf("x = %d\n", x);
  return 0;
}

Прежде всего, обратите внимание на типы и броски (самое главное, отметьте, как они совпадают). Обратите внимание, что я указываю размер измерения массива при приведении указателя к массиву. Также обратите внимание, что я объявляю var3 как указатель на массив, а не как простой указатель.

0 голосов
/ 04 июня 2010

Возможно, то, что вы ищете:

int (*var1)[10][10] = malloc(sizeof *var1); // 400 bytes
i(10, 10, *var1);
printf("var1[0][0]=%i\n", (*var1)[0][0]);

Добавлено: Полный фрагмент кода для gcc может быть:

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

void i(int n, int m, int var1[][m]) { // n not needed
    var1[0][0] = 5;
    var1[1][2] = 6;
}

int main(void) {
    int n = 10, m = 10;
    int (*var1)[n][m] = malloc(sizeof *var1); // 400 bytes
    i(n, m, *var1);
    printf("var1[0][0]=%i\n",(*var1)[0][0]);
    printf("var1[1][2]=%i\n",(*var1)[1][2]);
    return 0;
}

Для msvc вам необходимо задать n и m констант , например:

enum {n = 10, m = 10};

void i(int var1[][m]) {
    var1[0][0] = 5;
    var1[1][2] = 6;
}

int main(void) {
    int (*var1)[n][m] = malloc(sizeof *var1);
    i(*var1);
    // ...
}
0 голосов
/ 04 июня 2010
int example() {
    int *var1 = malloc(100);

    ...

    int *var3;
    var3=var1;
    printf("var3[0][0]=%i",var3[0][0]); //" error: subscripted value is neither array nor pointer"

    return(1); 
} 

Здесь var1 и var3 имеют тип int*, что примерно аналогично int[]. Вы создали одномерный массив и пытаетесь получить к ним доступ как к двумерному массиву. Измените их тип на int**, выделите необходимую память, и это должно решить вашу проблему.

0 голосов
/ 04 июня 2010

var3 должно быть int** вместо int*.

Редактировать

Вы пытаетесь использовать синтаксис 2D-массива, в котором фактически созданные вами данные фактически являются одномерным массивом. Вы можете использовать функцию i(), чтобы получить необходимую семантику, но доступ к данным необходимо преобразовать в одномерное индексирование внутри функции. Просто сделайте так, чтобы ваша функция выглядела так:

int i(int n,int m,int* var1, int maxM) {
  return var1[(maxM * n) + m];
}
...