Хрестоматия по программированию на Си в Unix



Массивы, строки, указатели. Хрестоматия по программированию на Си в Unix - стр. 8


Предположим, что у нас есть описание массива

static int mas[30][100];

  • выразите адрес mas[22][56] иначе
  • выразите адрес mas[22][0] двумя способами
  • выразите адрес mas[0][0] тремя способами
  • Составьте программу инициализации двумерного массива a[10][10], выборки элементов с a[5][5] до a[9][9] и их распечатки. Используйте доступ к элементам по указателю.

    Составьте функцию вычисления скалярного произведения двух векторов. Длина векторов задается в качестве одного из аргументов.

    Составьте функцию умножения двумерных матриц a[][] * b[][].

    Составьте функцию умножения трехмерных матриц a[][][] * b[][][].

    Для тех, кто программировал на языке Pascal: какая допущена ошибка?

    char a[10][20]; char c; int x,y; ... c = a[x,y];

    Ответ: многомерные массивы в Си надо индексировать так:

    c = a[x][y];

    В написанном же примере мы имеем в качестве индекса выражение x,y (оператор "запятая") со значением y, т.е.

    c = a[y];

    Синтаксической ошибки нет, но смысл совершенно изменился!

    Двумерные массивы в памяти представляются как одномерные. Например, если

    int a[N][M];

    то конструкция a[y][x] превращается при компиляции в одномерную конструкцию, подобную такой:

    int a[N * M]; /* массив развернут построчно */ #define a_yx(y, x) a[(x) + (y) * M]

    то есть

    a[y][x] есть *(&a[0][0] + y * M + x)

    Следствием этого является то, что компилятор для генерации индексации двумерных (и более) массовов должен знать M - размер массива по 2-ому измерению (а также 3-ему, 4-ому, и.т.д.). В частности, при передаче многомерного массива в функцию

    f(arr) int arr[N][M]; { ... } /* годится */ f(arr) int arr[] [M]; { ... } /* годится */ f(arr) int arr[] []; { ... } /* не годится */ f(arr) int (*arr)[M]; { ... } /* годится */ f(arr) int *arr [M]; { ... } /* не годится: это уже не двумерный массив, а одномерный массив указателей */

    А также при описании внешних массивов:

    extern int a[N][M]; /* годится */ extern int a[ ][M]; /* годится */ extern int a[ ][ ]; /* не годится: компилятор не сможет сгенерить операцию индексации */




    Содержание  Назад  Вперед