Языки программирования для численных методов. Глушакова Т.Н - 64 стр.

UptoLike

64
будет эквивалентно *(*(m+i)+j), т.е. как будто бы в i-м элементе
массива хранится указатель на элементы другого массива, и j-й элемент
этого массива и есть нужный нам m[i][j].
Графически эта картина выглядит так :
Т .е. как будто бы m это массив указателей на массивы типа int. Но
двумерные массивы хранятся в памяти по строкам , значения одной строки
сразу следуют за другой. Никаких указателей там нет. Поэтому попытка
передачи двумерного массива, например int m[5][10], как параметра int
m[][], приведет к ошибке при выполнении программы.
Если же описать параметр как int m[][10], то компилятор будет знать ,
что m - это двумерный массив, который хранится по строкам , причем в
каждой строке 10 элементов. И операция m[i][j] будет трактоваться
компилятором как *(m+i*10+j).
Если все же необходимо использовать в качестве параметра
многомерные массивы , для которых на этапе компиляции неизвестно
большей одной размерности , необходимо явно в тексте программы
использовать доступ по этой схеме, т.е. писать *(m+i*N+j) вместо m[i][j]
для матрицы с N столбцами, где N передается как еще один параметр
функции.
Заметим , что запись int m[][] на самом деле и обозначает массив
указателей на int. Она эквивалентна записи int *m[], которая лучше
отражает то , что есть на самом деле. Массивы указателей используются
для создания динамических многомерных массивов. Это мы рассмотри
подробнее ниже.
Отметим еще раз , что в операциях адресной арифметики
прибавление/ уменьшение адреса, который содержит указатель,
выполняется с учетом его типа. Т .е. если мы имеем , например, указатель
int*, то прибавление к нему 1 сместит реальный адрес ячейки памяти на
m[0]
m[i]
m[i][0]
m[i][j]
m
                                      64
будет эквивалентно *(*(m+i)+j),          т.е. как будто бы в i-м элементе
массива хранится указатель на элементы другого массива, и j-й элемент
этого массива и есть нужный нам m[i][j].
      Графически эта картина выглядит так:

                               m[0]
                                         m[i][0]      m[i][j]
            m
                                m[i]




       Т.е. как будто бы m – это массив указателей на массивы типа int. Но
двумерные массивы хранятся в памяти по строкам, значения одной строки
сразу следуют за другой. Никаких указателей там нет. Поэтому попытка
передачи двумерного массива, например int m[5][10], как параметра int
m[][], приведет к ошибке при выполнении программы.
       Если же описать параметр как int m[][10], то компилятор будет знать,
что m - это двумерный массив, который хранится по строкам, причем в
каждой строке 10 элементов. И операция m[i][j] будет трактоваться
компилятором как *(m+i*10+j).
       Если все же необходимо использовать в качестве параметра
многомерные массивы, для которых на этапе компиляции неизвестно
большей одной размерности, необходимо явно в тексте программы
использовать доступ по этой схеме, т.е. писать *(m+i*N+j) вместо m[i][j]
для матрицы с N столбцами, где N передается как еще один параметр
функции.
       Заметим, что запись int m[][] на самом деле и обозначает массив
указателей на int. Она эквивалентна записи int *m[], которая лучше
отражает то, что есть на самом деле. Массивы указателей используются
для создания динамических многомерных массивов. Это мы рассмотри
подробнее ниже.
       Отметим еще раз, что в операциях адресной арифметики
прибавление/уменьшение      адреса,   который   содержит    указатель,
выполняется с учетом его типа. Т.е. если мы имеем, например, указатель
int*, то прибавление к нему 1 сместит реальный адрес ячейки памяти на