Передача в массив функции - PullRequest
       4

Передача в массив функции

0 голосов
/ 08 сентября 2010
int main(){

    int right[2][3] = {
    {1,4,6}, {2,7,5}
    }

    ....


    calc(right);
}

int calc(int ** right){
    printf("%i", right[0][0]);
}

Я вычисляю функцию, которая вычисляет некоторые числа на основе матрицы, но я не знаю, почему я получаю ошибку сегмента, когда получаю доступ к переменной прямо в функции calc.Кто-нибудь знает решение?

edit: сейчас это все, что он делает в функции calc.У меня есть кое-что для калька, но все это закомментировано, пытаясь выяснить, как получить доступ к этой переменной.

Ответы [ 2 ]

7 голосов
/ 08 сентября 2010

Двумерные массивы в C не работают так, как вы думаете. (Не волнуйтесь, вы не одиноки - это распространенное заблуждение.)

В коде подразумевается, что right - это массив int * указателей, каждый из которых указывает на массив int. Это может быть сделано таким образом - и, что сбивает с толку, синтаксис для доступа к такому массиву будет таким же, что, вероятно, является причиной этого заблуждения.

Что на самом деле C делает , так это делает right массивом из 12 int с, расположенным непрерывно в памяти. Доступ к массиву, подобный этому

a=right[i][j];

фактически эквивалентно этому:

int *right_one_dimensional=(int *)right;
a=right[i*3 + j];

Чтобы передать ваш массив в функцию calc, вам нужно сделать это:

int calc(int *right, size_t d){
    // For example
    a=right[i*d + j];
}

и затем назовите это так:

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

calc(&right[0][0], 3);

Редактировать: Для получения дополнительной информации об этом, вопрос, связанный с в комментарии Binary Worrier, безусловно, стоит посмотреть.

2 голосов
/ 08 сентября 2010

Хотя одномерный массив автоматически преобразуется в указатель, он не сохраняется для многомерного массива и многоуровневых указателей.

Если изменить порядок calc иmain функций (или если вы предоставите прототип для calc до main), вы получите жалобу от компилятора, что он может преобразовать right в тип int**.

.причина в том, что right объявлен как "массив из 4 массивов по 3 int".Это может быть автоматически преобразовано в «указатель на массив 3 int» (int (*)[3]), но на этом преобразование прекращается.calc, с другой стороны, ожидает «указатель на указатель на int», который совершенно отличается от «указателя на массив 3 int».

Существует два возможных решения:

  1. Изменить calc, чтобы принимать указатель на массив (или массив массивов):
   int calc(int right[][3])
Измените right на указатель на указатель:
    int temp_array[4][3];
    int* temp_array2[4] = { temp_array[0], temp_array[1], temp_array[2], temp_array[3] };
    int** right = temp_array2;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...