2015-09-02 8 views
0

У меня вопрос о передаче массива в другую функцию.Понимание многомерных массивов для c

#include <stdio.h> 
void print (int ar[]); 

main() { 
    int array[2][2] = {1,2,3,4}; 
    print(array); 
} 

void print (int ar[]) { 
    printf("%d\n", ar[0]); 
    printf("%d\n", *(ar+1)); 
} 

Так, допустим, если я передаю массив для функции печати. Я передаю адрес первого 1-D массива (array [0]), или просто передаю адрес самой первой переменной (array [0] [0]).

А что касается функции печати, то в этом случае я могу сказать, что при печати ar [0] я печатаю массив [0] [0]?

Но почему это в случае печати * (ar + 1), я на самом деле печатаю массив [0] [1] вместо массива [1] [0]?

Спасибо всем заранее!

+1

Вы пытались скомпилировать, например, для gcc, '-Wall'? –

+0

Это дало предупреждение. Скомпилируйте и посмотрите. – ameyCU

+0

Прошли ли вы [этот вопрос] (http://stackoverflow.com/q/7784758/2706918)? Вам следует! :) –

ответ

1

Итак, допустим, если [I] отправляется array на функцию print. Я передаю адрес первого массива 1-D (array[0]) или am [I], просто передавая адрес самой первой переменной (array[0][0]).

Вы передаете указатель на первый элемент array, array[0], который сам по себе является массивом. Этот указатель имеет то же значение, что и указатель на array[0][0], но другой тип. На самом деле ваш код неверен в том, что тип аргумента и тип параметра функции не согласуются, но до тех пор, пока типы int(*)[] и int * будут иметь одинаковое представление, переинтерпретация будет работать на практике.

И как для функции print, в этом случае, я правильно сказать, что при печати ar[0], я печать array[0][0]?

Да, когда вы вызываете print(), как и в своем примере, при условии, что представления типов согласуются, как описано выше.

Но почему это, что в случае печати *(ar+1), я на самом деле печать array[0][1] вместо array[1][0]?

Поскольку ar является указателем на первый элемент array, т.е. массива 1D array[0]. Его элементами являются array[0][0], array[0][1] и т. Д. ar + 1 является поэтому указателем на второй элемент array[0], который является array[0][1].

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

print(array[0]); 

В качестве альтернативы, вы можете изменить объявленный тип аргумента print() «s, ти соответствующего изменения его использования:

void print(int (*ar)[2]) { 
    printf("%d\n", ar[0][0]); 
    printf("%d\n", *(ar+1)[0]); 
} 

или

void print(int ar[][2]) { 
    printf("%d\n", ar[0][0]); 
    printf("%d\n", *(ar+1)[0]); 
} 

Последние два изменить смысл *(ar + 1).

+0

'void print (int (*) [*])'? – EOF

+0

Хорошо сделал actaully, отвечая на вопрос, вместо того, чтобы просто говорить об ошибке в своем коде. +1 – Mic1780

+0

@ EOF, да, это тоже должно работать, если вы не ограничены требованием соблюдения C90. Я думаю, что это не проблема для большинства людей. –

0

Ваш код, вероятно, не делает то, что вы хотите. Скомпилируйте с Wall, и вы увидите некоторые предупреждения.

Вам необходимо изменить аргумент print, чтобы принять 2D-массив (теперь вы проходите int (*)[2], но функция ожидает int *), а затем вы можете напечатать значения правильно.

#include <stdio.h> 
void print (int ar[][2]); 

int main() { 
    int array[2][2] = { 
     {1,2}, 
     {3,4} 
    }; 
    print(array); 
    return 0; 
} 

void print (int ar[][2]) { 
    printf("%d\n", ar[0][0]); // 1 
    printf("%d\n", ar[1][0]); // 4 
} 
2

Если вы передаете двумерный массив функции:

int array[NROWS][NCOLUMNS]; 
print(array); 

описание функции должно соответствовать:

void print(int array[][NCOLUMNS]) 
{ ... } 

или

void print(int (*ap)[NCOLUMNS]) /* ap is a pointer to an array */ 
{ ... } 

2D- массивы, которые являются массивами распадов массивов указатель на массив, а не указатель на указатель.

0

Когда вы передаете массив функции, вы используете «pass-by-reference», что означает, что вы передаете адрес массива.

  • Я передаю адрес первого 1-D массива (массив [0]), или просто передаю адрес самой первой переменной (массив [0] [0]).

Нет. Способ передачи массива в настоящее время дает функцию 2-мерного массива.

  • И что касается функции печати, в этом случае я могу сказать, что, печатая ar [0], я печатаю массив [0] [0]?

Нет, вы по-прежнему необходимо указать номер, который вы хотите напечатать от ар [0]

  • Но почему это, что в случае печати * (ар + 1), я на самом деле print array [0] [1] вместо массива [1] [0]?

Это потому, что вы говорите программе, чтобы перейти к массиву в памяти и использовать арифметику указателя для перемещения по массиву. Например, если у вас есть переменная char * str, которая содержит символы abcde\0 и вы хотите получить символ в позиции 2, вы можете либо сделать str[2], либо *(str+2), что означает одно и то же, и оба дают знак 'c'.

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