
- •Ответы по дисциплине «Основы алгоритмизации и программирования»
- •Запись алгоритма Евклида на языке с
- •Int main() {
- •Эвристический алгоритм «ближайшего соседа»
- •Эвристический алгоритм «ближайших пар»
- •«Правильный» алгоритм поиска маршрута
- •Эволюция языка с bcpl → b → c → k&r c → ansi c → c99 → c1x
- •#Define имя текст_для_подстановки
- •123, 67543, 037, 07777, 0Xabf7, 0xffff, …
- •123456789L, 0xful (это просто число 15).
- •Определение символических констант в limits.H
- •Int lower, upper, step;
- •Int main() {
- •Int main() {
- •Int main() {
- •Всего операций: 47
- •If (условие) оператор
- •If (условие) оператор1 else оператор2
- •Int main() {
- •Int main() {
- •Int main() {
- •Int main() {
- •If (found)
- •Адресация памяти
- •Адреса объектов программы
- •Int fact(int n) {
- •О размерах участков памяти, выделяемых объектам
- •Правила адресной арифметики
- •Никакие другие операции к адресам неприменимы, т.Е. Адреса нельзя умножать, делить, складывать между собой и пр.
- •Имя массива – это константный указатель на его начало.
- •T X[] эквивалентно t *X
- •Int main() {
- •Void *calloc(size_t n, size_t r)
- •Void free(void *p)
- •Int main() {
- •Void *p;
- •Void swaps(char** a, char** b) {
- •Int main(void) {
- •Int main() {
- •Правило «право-лево»
- •Int pt_in_rect(struct point p, struct rect r) {
- •Int main() {
- •Int main() {
- •Int ival;
- •Void init(Vector*);
- •Void resize(Vector*, int);
- •Void push_back(Vector*, double);
- •Void push_s(Stack *st, double d) {
- •Void init_q(Queue *q) {
- •Void enqueue(Queue *q, double d) {
- •Int dequeue(Queue *q, double *d) {
- •Typedef struct Heap {Vector V;} Heap;
- •Void init_h(Heap *hp) {
- •Int Heap_Maximum(Heap *hp, double *z) {
- •Void Max_Heap_Insert(Heap *hp, double X){
- •Void Max_Heapify(Heap *hp, int I) {
- •Int l, r, largest;
- •Int Heap_Extract_Max(Heap *hp, double *z) {
- •Void Build_Max_Heap(Heap *hp) {
- •Void Insert_head_l1(List1 *l, double z) {
- •Void Insert_back_l1(List1 *l, double z) {
- •Int Extract_head_l1(List1 *l, double *z) {
- •Int Extract_back_l1(List1 *l, double *z) {
- •Void reverse_l1(List1 *l) {
- •Исходный код функции sort_l1
- •Void sort_l1(List1 *l) {
- •Void visit(List1* l) {
- •Void traverse(List1* l) {
- •Void Print_l1(List1 *l) {
- •Void Insert_l2(List2 *l, double z, int direction) {
- •Прямой обход (сверху вниз), при котором мы посещаем узел, а затем левое и правое поддеревья
- •Поперечный обход (слева направо), при котором мы посещаем левое поддерево, затем узел, а затем правое поддерево
- •Обратный обход (снизу вверх), при котором мы посещаем левое и правое поддеревья, а затем узел.
- •Простой метод сортировки массива
- •Задача о взвешивании монет
- •1) Очевидно, что на последнем шаге процедуры взвешивания мы должны иметь дело максимум с 3 монетами, чтобы в при любом исходе взвешивания получить результат.
- •2) Задача предпоследнего шага – отобрать группу из 3-х монет. Это можно сделать, если в нашем распоряжении будет не более 9 монет (3 группы по 3 монеты).
- •3) Наконец, если у нас будет от 10 до 27 монет, мы сможем отобрать из них не более 9
- •Void mov(int n, char a, char c, char b) {
- •Int main() {
Int pt_in_rect(struct point p, struct rect r) {
if(p.x
< r.pt1.x || p.x > r.pt2.x) return 0;
if(p.y < r.pt1.y || p.y > r.pt2.y) return 0;
инициализация
структур
}
Int main() {
struct point z = {2, 2};
struct rect rc = {{1, 1}, {4, 5}};
printf("%s\n", pt_in_rect(z, rc) ? "inside" : "outside");
system("PAUSE");
return 0;
}
Как видно из предыдущей программы, структуры могут использоваться в качестве аргументов функций. Следующая программа демонстрирует, что структура может быть и возвращаемым из функции значением.
Найти прямоугольник, вмещающий два заданных прямоугольника.
...
struct point { int x, y;};
struct rect { struct point pt1, pt2; };
struct rect max_rect(struct rect r1, struct rect r2) {
struct rect rm = r1;
if(r2.pt1.x < rm.pt1.x) rm.pt1.x = r2.pt1.x;
if(r2.pt1.y < rm.pt1.y) rm.pt1.y = r2.pt1.y;
if(r2.pt2.x > rm.pt2.x) rm.pt2.x = r2.pt2.x;
if(r2.pt2.y > rm.pt2.y) rm.pt2.y = r2.pt2.y;
return
rm; }
Int main() {
struct rect rc1 = {{1, 1}, {4, 5}};
struct rect rc2 = {{2, 0}, {6, 6}};
struct rect rcm = max_rect(rc1, rc2);
printf("x1=%d, y1=%d, x2=%d, y2=%d\n",
rcm.pt1.x, rcm.pt1.y, rcm.pt2.x, rcm.pt2.y);
...}
Вопрос №69. Указатели на структуры и массивы структур. Доступ к членам структуры по указателю.
Структурные типы данных также как и обычные типы данных могут использоваться для конструирования указателей и массивов.
Пусть struct T – структурный тип данных, тогда:
struct T x – описывает переменную типа struct T, или просто структуру x,
struct T *p – описывает указатель на структуру типа struct T,
struct T m[5] – описывает массив из пяти структур типа struct T,
struct T *pm[] – описывает массив неопределенного размера из указателей на структуры типа struct T,
struct T (*pm)[] – описывает указатель на массив неопределенного размера из структур типа struct T и т.д.
Указатели на структуры особенно полезны при передаче аргументов-структур в функции, т.к. приводят к экономии памяти при передаче громоздких структур.
Даны описания:
(*pp).x
эквивалентно
pp->x
struct point pt, *pp = &pt;
(*pp).x = 3; (*pp).y = 5;
Скобки нужны потому, что приоритет операции . выше, чем у операции *
Вопрос №70. Определение новых типов с помощью typedef
Синтаксис определения новых типов в языке С достаточно громоздкий, что приводит к снижению «читабельности» (наглядности) исходного текста программы.
Этот недостаток устраняется с помощью специального оператора typedef, который позволяет вводить синонимы (упрощённую запись) для громоздких определений типов.
Например:
typedef unsigned char Uchar;
typedef int Boolean;
typedef char* String;
typedef struct point { int x, y; } Point;
typedef Point* Ppoint;
typedef struct rect {Point pt1, pt2;} Rect;
typedef int (*F) (int);
Вопрос №71. Битовые поля в структурах.
Как уже отмечалось ранее, членами одной структуры могут быть данные совершенно разных типов. В языке С есть возможность включать в состав структуры «нестандартные» элементы, размер которых исчисляется не в байтах, а в битах. В качестве имени типа для таких элементов обычно используется unsigned int, а размер в битах указывается после имени элемента через двоеточие:
struct {
unsigned int is_keyword : 1;
unsigned int is_extern : 1;
unsigned int is_static : 1;
} flags;
В этом примере определяется переменная flags, которая содержит три однобитовых поля. На отдельные поля ссылаются так же, как и на элементы обычных структур: flags. is_keyword, flags.is_extern и т. д. Поля "ведут себя" как малые целые и могут участвовать в арифметических выражениях точно так же, как и другие целые.
Замечание. Невозможно определить адрес битового поля структуры, поэтому операция &flags.is_keyword вызовет появление сообщения об ошибке при компиляции.
Вопрос №72. Объединения (union). Отличие объединений от структур.
Помимо структур в языке С имеется еще одна конструкция, позволяющая собрать под одним именем разнотипные элементы – объединения. Синтаксически объединения практически ничем не отличаются от структур, кроме использования ключевого слова union вместо ключевого слова struct.
Принципиальное отличие объединений от структур – все элементы объединения размещаются в памяти с одного адреса и перекрывают друг друга. Вследствие этого в каждый момент времени объединение может хранить только одно поле:
union u_tag {