
- •Оглавление
- •Билет 1: Понятия о структурном программировании
- •Билет 2: Моделирование стандартных управляющих структур
- •Билет 3: структура программы
- •Билет 4: организация (структура) модуля
- •Билет 5: Переменные
- •Билет 6: Система типов языка
- •Билет 7: Арифметические типы языка c
- •Билет 8: Константы
- •Билет 9: КонстантныеобъектывязыкеСи.
- •Билет 10: Константные объекты
- •Билет 11. Переменные, понятие об объекте, lvalue и rvalue выражения.
- •Билет 12. Время жизни переменных.
- •Билет 15. Операторы. Приоритет и ассоциативность операторов.
- •Билет 19: Побочные эффекты в языке Си.
- •Билет 20: Организация функций. Определение функций
- •Билет 25: Инструкция If…else. Программирование разветвлений.
- •Билет 26: Инструкция switch и организация разветвленных алгоритмов.
- •Билет 27: Циклические алгоритмы, классификация, функциональная схема
- •Билет 28: Циклические инструкции.
- •Билет 29: инструкция for и арифметические циклы
- •Билет 30: Инструкция while и do...While, интерационные циклы
- •Билет 31: Циклы с выходом. Бесконечные циклы
- •Билет 32. Организация вложенных циклов
- •Билет 33: Массивы. Определение и инициализация одномерных массивов
- •Билет 34. Массивы. Определение и инициализация двумерных массивов
- •Билет 35. Связь указателей и массивов
- •Билет 40. Указатели. Определение типизированных и нетипизированых указателей. Модель, используемая при работе с указателями. Операции с указателями.
- •Билет 41: Операции с указателями
- •Билет 42. Использование указателей для возврата из функции через параметры
- •Билет 43. Указатели на функцию. Определение. Операции. Использование в параметрах функции
- •Билет 44. Типичные ошибки при работе с массивами
- •Билет 45. Массив указателей, динамическая матрица
- •Билет 46. Понятие некорректного указателя.
- •Билет 47. Организация строк. Общие сведения
- •Билет 48. Ввод/вывод строк
- •Void funk(“Kozin”); - при этом ничего не возвращается. Данная запись используется довольно редко.
- •Билет 52. Организация динамического одномерного массива
- •Билет 53. Структуры. Определение типа структур. Определение переменных в структуре и инициализация. Операции со структурой
- •Билет 54. Обращение к полям структуры. Массивы структур
- •Билет 55. Использование структур при работе с функциями. Указатели на структуры
- •Билет 58: Файловый ввод-вывод. Символьный ввод-вывод в языке Си.
- •Синтаксис преобразования вывода
- •Билет 60: Файловый ввод-вывод. Строковый ввод-вывод в языке Си.
- •Билет 61: Файловый ввод-вывод. Блоковый ввод-вывод в языке Си.
- •Int fseek(file *f, long int колич_байт, int начало_отсчета);
Какую работу нужно написать?
Билет 34. Массивы. Определение и инициализация двумерных массивов
!!!Теория по массивам представлена в предыдущем вопросе(34). При ответе использовать её!
Двумерный массив - это одномерный массив, элементами которого являются одномерные массивы. Наглядно двумерный массив удобно представлять в виде таблицы, в которой n строк и m столбцов, а под ячейкой таблицы, стоящей в i-й строке и j-м столбце понимают некоторый элемент массива a[i][j].
Определение двумерного массива аналогично одномерному, отличия: 1 – две пары индексных скобок вместо одной: int mt1[MAXROW] [MAXCOL] (где MAXROW и MAXCOL определены до этой записи);, 2 – в первых скобках обязательно должно стоять число (это связано с тем, что С необходимо знать, сколько строк выделять в памяти, см. определение двумерного массива); чтобы не ставить этот размер, в С99 их заменяют на звездочку перед именем, т.е.: double *ars[];
Инициализация аналогична одномерным массивам, отличия в записи:
int mt1[2] [3]={{1,3,5},{2,4,6}};
mt2[r][c]=c;
В случае н-мерных массивов появляется н пар индексных скобок при определении. Притом элементами такого массива являются массивы измерения н-1. В памяти они представлены как набор строк, находящихся в одной области.
Билет 35. Связь указателей и массивов
В языке Си массивы и указатели тесно связаны. Во-первых, имя каждого массива может рассматриваться как указатель на первый элемент массива. А во-вторых, с указателем можно работать как с массивом (пример: строка объявляется как указатель, а отдельный символ можно посмотреть, как элемент одномерного массива).
Элемент массива a[i] есть элемент массива, на который указывает значение a+i, т.е. *(a+i), где значение а является адресом первого элемента массива а, а именно a[0]. Выражение a+i является примером арифметических действий с указателями - целое значение i складывается со значением указателя, адресом первого элемента массива а. Значение этого выражения есть а плюс объем памяти, занимаемый i элементами массива a. Предположим, что x - двумерный массив. Тогда ссылка на подмассив x[i] является ссылкой на i-ю строку массива x. x[i] дает адрес первого элемента этой строки, т.е. *(x+i). Элементы каждой строки занимают непрерывную область памяти, так как массивы хранятся записанными по строкам, т.е. при записи элементов массива в память быстрее всех изменяется последний индекс.
Аналогично, ссылка на y[i], где y - n-мерный (n>1) массив, является ссылкой на (n-1)-мерный подмассив с элементами y[i, j2,j3,_jn], где значения jk соответствуют определению массива y. y[i] дает адрес первого элемента этого подмассива, т.е. *(y+i). Все элементы этого (n-1)-мерного подмассива занимают непрерывную область памяти.
Разница между именем массива и указателем в том, что имя массива – константный указатель, т.е. ему нельзя присвоить другой адрес (в связи с этим не работают и выражения вроде а++, т.к. они изменяют значение указателя).
Плюсы и минусы: легкий доступ к элементам массива, но можно массив спутать с указателем и попытаться его имя инкрементировать, после чего компилятор будет долго ругаться.
Билет 36. Использование указателей в качестве итераторов. Идиома *р++
Итератор – это объект, выполняющий роль «бегунка», средство доступа и обхода контейнеров.
Контейнер – объект, предназначенный для хранения других объектов.
Т.е. через него можно получить доступ напрямую к значению элемента, минуя систему имен. В С в качестве итераторов применяют указатели.
Рассмотрим такую задачу: допустим, у нас есть структура, в которой есть массив чисел. В массив, начиная с пятого элемента и во все нечетные, необходимо записать число 5. Данную задачу проще и быстрее решить с помощью итератора. Просто создаем указатель it на пятый элемент массива, а затем в цикле производим операцию: *it=5; it+=2;
Идиома –устоявшееся выражение, которое приобрело особый смысл.
Теперь по поводу идиомы *р++ (это выражение изначально говорит, что р является итератором). Унарные операции * и ++ имеют один и тот же приоритет, но выполняются слева направо (т.е. сначала указатель будет разыменован, а потом прибавление единички). Чтобы понять, к чему относится оператор, необходимо посмотреть в обратном направлении, справа налево (т.е. +1 идет к адресу, а не к содержанию ячейки памяти). Данная идиома используется в массивах, где надо обработать текущий элемент и перейти к следующему (напоминаю, что операция р++ эквивалентна р=р+1).
Билет 37. Обработка одномерных массивов (ввод\вывод и т.п.)
Массивы в С, как одномерные, так и двумерные, обрабатываются поэлементно и только поэлементно (исключение составляют строки, которые в данном билете не рассматриваются). В принципе, вот и весь ответ на данный вопрос. Чтобы сказать что-то более-менее объемное, надо написать Козину пример обработки, функцию ввода одномерного массива с клавиатуры, к примеру. Также желательно показать работу этой функции на модели одномерного массива:
Ar 0 1 2 … n
Т.е по шагам, как изменяется массив.
В принципе, все.
Билет 38. Обработка двумерных массивов (ввод\вывод и т.п.)
См. билет № 38. Отличия двумерного массива: при обработке используются вложенные циклы, обрабатывать можно по столбцам или построчно (если по столбцам, то во внешнем цикле стоит счетчик по столбцам, а во внутреннем – по строкам, если построчно, то наоборот).
Модель двумерного массива – таблица, притом имя массива является указателем на нулевой элемент нулевой строки. В памяти массив располагается в непрерывном блоке памяти (т.е. все его строки собраны в одном месте).
Билет 39. Массивы с переменными размерами в стандарте С99
В С99 в функциях можно объявлять массивы с переменными размерами. В отличие от динамических массивов, при работе с ними не нужны функции работы с памятью.
Пример: В программе игры крестики-нолики пользователь сам задает размеры поля. Эти размеры передаются в функцию игры, которая создает необходимый двумерный массив, а после игры возвращает победителя. Вкратце эта функция будет выглядеть так:
int game(int r, int c)
{
int pole[r][c];
/* game */
return winner;
}
Если в программе есть массив, размеры которого постоянно меняются, а нужен он только для одной функции, то наверно лучше воспользоваться этим способом, т.к. выделение и очищение памяти для динамического массива требует кучу времени. С другой стороны, другие языки вполне обходятся и без этого (к примеру, в С++ вместо переменных массивов применяются контейнер-векторы).