C-передать матрицу для работы без непостоянного значения столбца - PullRequest
0 голосов
/ 17 ноября 2018

Я хочу передать матрицу функции в C. Если я хочу сделать размер матрицы непостоянным (например, позволить пользователю вставить с клавиатуры измерение NxM), у меня нет проблем в этом.Однако, когда я пытаюсь передать это функции, я сталкиваюсь с некоторыми проблемами:

- Номер столбца ДОЛЖЕН быть указан в заголовке функции (функций), у которой матрица является параметром.Если я опускаю это значение, я получаю:

ошибка: тип массива имеет неполный тип элемента 'int []' void trasposeMatrix (int M [] [], int n, int m) esercizi.c:282: 25: примечание: объявление 'M' как многомерного массива должно иметь границы для всех измерений, кроме первого

с этой функцией:

void trasposeMatrix(int M[][],int n,int m)
{
    int temp=0;
    int M2[n][m];

    printf("La matrice prima della trasposizione è: \n");
    printMatrix(M,3,3);

    for (int i=0;i<n;i++)
    {
        for (int j=0;j<m;j++)
        {
            M2[i][j]=M[j][i];
        }
    }

    printf("La matrice dopo la trasposizione è: \n");
    printMatrix(M2,3,3);
}

с этим вызовом:

trasposeMatrix(M,3,3);

-Это значение ДОЛЖНО быть постоянным, в противном случае, если я поставлю параметр в качестве значения в этих скобках, я получу эту ошибку:

esercizi.c: На верхнем уровне: esercizi.c: 282: 29: ошибка: здесь не объявлено 'm' (не в функции) void trasposeMatrix (int M [] [m], int n, int m)

с тем же вызовом иэтот код:

void trasposeMatrix(int M[][m],int n,int m)
{
    int temp=0;
    int M2[n][m];

    printf("La matrice prima della trasposizione è: \n");
    printMatrix(M,3,3);

    for (int i=0;i<n;i++)
    {
        for (int j=0;j<m;j++)
        {
            M2[i][j]=M[j][i];
        }
    }

    printf("La matrice dopo la trasposizione è: \n");
    printMatrix(M2,3,3);
}

Этого можно избежать, используя константы для указания размеров матрицы.Однако мне не нравится этот вид "ограничения".Наконец, что если я распечатал бы матрицу с помощью функции: что я должен написать в заголовке функции, если размер является переменной ??Функция, которую я написал для печати матрицы, хорошо работает для матрицы 3x3, но что делать для матриц 2x2 и для 3x4.Может быть, вы получили точку

Примечание: это не происходит с массивами, где я просто пишу заголовок вроде: void printArray(int a[], int dimension){}, и это работает.Я не знаю почему.Возможно, это дизайнерское поведение C, решенное его изобретателем, но я надеюсь, что это не так, потому что это так tediuos

Примечание 2: :) Я использую linux mint с gcc (Ubuntu 7.3.0-27ubuntu1 ~ 18.04) 7.3.0, но с VS для Win10 я даже не могу поместить переменную в качестве измерения массива: (

Мне очень жаль очень длинное сообщение, но я надеюсь получить ответ. Спасибо за чтение

Ответы [ 3 ]

0 голосов
/ 17 ноября 2018

тип массива имеет неполный тип элемента ‘int []’

Чтобы объявить массив, компилятор должен знать, насколько велики элементы массива.

Представьте себе int arr[2][]; Насколько велики элементы массива? Компилятор должен знать, сколько байтов нужно «перепрыгнуть» между &arr[0] и &arr[1]. Как увеличить указатель на arr?

Представьте себе int (*arr)[2]; Это указатель на массив из 2-х целых. Между &arr[0] и &arr[1] есть 2 целых числа: arr[0][0] и arr[0][1] точно. Таким образом, компилятор знает, что &arr[1] находится в позиции (uintptr_t)(void*)&arr[0] + 2 * sizeof(int).

Объявления массива переменной длины (int M[]) и все объявления массива (int M[5]) "подгоняются" ("равны") указателю на типы (int *M) внутри списка параметров функции (* 1026) * см. C11 6.7.6.3p7 ). Это означает, что каждый раз, когда вы пишете void func(int a[500*1000*320100]), он совпадает с void func(int *a).

Вы не можете объявить int *(a[]); указатель на массив с неизвестным количеством элементов. Элементы массива должны быть законченного типа. Таким образом, компиляторы знают, сколько памяти резервировать для них.

ошибка: здесь не указано "м"

Представьте себе такую ​​функцию:

int main() {
  int m[i];
  int i = 5;
}

Вы получите i undeclared here. Хорошо, теперь представьте себе такую ​​функцию:

int func(
  int m[i],
  int i
) {}

Вы получите ту же ошибку, но в списке параметров функции. Это то же самое, переменная должна быть объявлена ​​перед использованием.

0 голосов
/ 17 ноября 2018

Передайте размеры массива перед массивом в вызове функции.Эта функция была добавлена ​​в C99 (и поэтому в C11 и C18);это не часть стандартного C ++.Это означает, что есть некоторые компиляторы, которые все еще не поддерживают нотацию.

У вас есть:

void trasposeMatrix(int M[][m],int n,int m)
{

Вам необходимо:

void trasposeMatrix(int n, int m, int M[n][m])
{

Или, возможно:

void trasposeMatrix(int n, int m, int M[][m])
{

, но я думаю, что предыдущая версия с обоими указанными измерениями более ясна в отношении намерения.

В объявлениях функций (например, в заголовке) вы можете использовать нотацию определения (где extern является необязательным и иногда спорным - есть те, кому это не нравится, и те, кому это нравится, например я):

extern void trasposeMatrix(int n, int m, int M[n][m]);

или вы можете пойти эксцентрично и использовать:

extern void trasposeMatrix(int n, int m, int M[*][*]);

Это говорит компилятору, что размеры матрицы будут определены во время выполнения, но не указывает, гдеони из.Я предпочитаю версию «копия определения», потому что цель более ясна.Вы не можете использовать нотацию * в определении функции.

Если вы хотите узнать «все об этом», вы можете прочитать стандарт - C11 §6.7.6.2 Деклараторы массива и §6.7.6.2 Деклараторы функций (включая прототипы) - но язык трудно разобрать.

0 голосов
/ 17 ноября 2018

"Объявление 'M' как многомерного массива должно иметь границы для всех измерений, кроме первого"

Это говорит о том, что вам необходимо указать значение в первой скобке:

M[] <- может быть пустым [x] <- не может быть пустым и должно быть постоянным. </p>

Если вы не хотите получать «ограничение», используйте malloc и free для выделения динамической памяти во время выполнения.

...