Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ВОПРОСЫ.docx
Скачиваний:
14
Добавлен:
08.05.2019
Размер:
2.84 Mб
Скачать

35. Кривая Безье, ее построение и редактирование.

Кривая Безье строится по опорным точкам, и разделенная на сегменты между этими точками. Опорные точки и сегменты можно редактировать: смещать, изменять форму, удалять – изменяя тем самым форму линии. Если строить кривую простыми кликами мышки, то получится ломаная линия. Если вместо клика проводить линию, опорные точки получаются сглаженными; от каждой опорной точки будут отходить две направляющие линии, изменяя положение и длину которых можно изменять форму кривой Безье. Такой кривой можно описать любой контур. Редактируется кривая Безье опорными точками, их направляющими, удалением и добавлением новых опорных точек, удалением сегментов.

36.Линии и блоки как простейшие элементы оформления текстовой и графической документации.

Такие элементы могут быть использованы как элементы соединения, разделения, выявления или штриховки. Из них собираются блок-схемы, которые также используются в оформлении текстовой и графической документации

37. Массивы, структуры, классы языка С++.

(ВЕРСИЯ ЮЛИ)

Массивы представляют из себя множество переменных с определенным типом данных (int,char,float и т.д.) и состоит из двух частей: имени массива и индекса элемента.

Для создания массива надо написать тип (аналогичен типам переменных) затем имя массива и в квадратных  скобках количество элементов:

int numbers[1000]; // массив на 1000 числовых элементов.

float test[10] // массив на 10 вещественных чисел

А для доступа к n-ому элементу необходимо написать имя массива[номер элемента] и работать с ним как с обычной переменной.

Пример:

numbers[200]=201; //записать в 200 элемент число 201

test[1]=0,5; // в 1 элемент записать 0,5

test[9]=10;  // в 9 элемент записать число 10

int a=5;

numbers[test[9]]=111; /*записать в элемент массива numbers с номером, равным содержимому test[9], число 111*/

test[a]=2; // записать в элемент массива с номером, равным a, число 2

Внимание!!! Нумерация элементов начинается с 0, а не с 1. То есть,  массив

int test[3]

состоит из

test[0];

test[1];

test[2]

Структура  в  C++  — почти что полноценный класс. Со  структурой  можно делать все, что можно делать с классом. Например,  структуры  могут участвовать в наследовании; в них можно объявлять секции public, private, protected и даже виртуальные функции. Тем не менее, для  структур  действуют несколько иные правила: по умолчанию все члены считаются открытыми (public), чтобы готовые программы на С не приходилось переписывать заново под каноны  C++ . Теория — вещь хорошая, но давайте вернемся на землю. Стоит ли демонстрировать свою «крутизну» и объявлять  структуру  с множественным наследованием и виртуальными функциями? На практике  структуры  используются вместо классов лишь при соблюдении следующих условий:

 Структура  не содержит виртуальных функций.

 -Структура  не является производной от чего-либо, кроме разве что другой  структуры .

 -Структура  не является базовой для чего-либо, кроме разве что другой  структуры . Нормальные программисты  C++  обычно используют  структуры  лишь для маленьких удобных наборов данных с тривиальными функциями. В частности,  структуры  часто используются в ситуациях, когда объект  C++  должен быть совместим на битовом уровне с внешней  структурой  данных (особенно со структурами С). При этом можно запросто объявлять конструкторы и невиртуальные функции (особенно тривиальные встроенные), поскольку для них не создается v-таблица, которая могла бы нарушить битовую совместимость.

Механизм классов в C++ позволяет пользователям определять собственные типы данных. По этой причине их часто называют пользовательскими типами. Класс может наделять дополнительной функциональностью уже существующий тип.

Определение класса состоит из двух частей: заголовка, включающего ключевое слово class, за которым следует имя класса, и тела, заключенного в фигурные скобки. После такого определения должны стоять точка с запятой или список объявлений:

class Screen { /* ... */ };

class Screen { /* ... */ } myScreen, yourScreen;

Внутри тела объявляются данные-члены и функции-члены и указываются уровни доступа к ним. Таким образом, тело класса определяет список его членов.

Каждое определение вводит новый тип данных. Даже если два класса имеют одинаковые списки членов, они все равно считаются разными типами:

class First {

int memi;

double memd;

};

class Second {

int memi;

double memd;

};

class First obj1;

Second obj2 = obj1; // ошибка: obj1 и obj2 имеют разные типы

Тело класса определяет отдельную область видимости. Объявление членов внутри тела помещает их имена в область видимости класса. Наличие в двух разных классах членов с одинаковыми именами – не ошибка, эти имена относятся к разным объектам. (Подробнее об областях видимости классов мы поговорим в разделе 13.9.)

После того как тип класса определен, на него можно ссылаться двумя способами:

  • написать ключевое слово class, а после него – имя класса. В предыдущем примере объект obj1 класса First объявлен именно таким образом;

  • указать только имя класса. Так объявлен объект obj2 класса Second из приведенного примера.

Оба способа сослаться на тип класса эквивалентны. Первый заимствован из языка C и остается корректным методом задания типа класса; второй способ введен в C++ для упрощения объявлений.

(ВЕРСИЯ МАШИ)

Массив – это набор данных одного типа, например массив целых чисел или массив строк. Мы рассмотрим недостатки, присущие встроенному массиву, и напишем для его представления свой класс Array, где попытаемся избавиться от этих недостатков. Затем мы построим целую иерархию подклассов, основываясь на нашем базовом классе Array. В конце концов мы сравним наш класс Array с классом vector из стандартной библиотеки С++, реализующим аналогичную функциональность. В процессе создания этих классов мы коснемся таких свойств С++, как шаблоны, пространства имен и обработка ошибок. К числовым типам данных могут применяться встроенные арифметические и логические операции: объекты числового типа можно складывать, вычитать, умножать, делить и т.д.

int ival2 = ival1 + 4096; // сложение

int ival3 = ival2 - ival; // вычитание dval = fval * ival; // умножение

ival = ival3 / 2; // деление

bool result = ival2 == ival3; // сравнение на равенство

result = ival2 + ival != ival3; // сравнение на неравенство

result = fval + ival2 < dval; // сравнение на меньше

result = ival > ival2; // сравнение на больше

В дополнение к встроенным типам стандартная библиотека С++ предоставляет поддержку для расширенного набора типов, таких, как строка и комплексное число. (Мы отложим рассмотрение класса vector из стандартной библиотеки до раздела 2.7.) Промежуточное положение между встроенными типами данных и типами данных из стандартной библиотеки занимают составные типы – массивы и указатели. (Указатели рассмотрены в разделе 2.2.) Массив – это упорядоченный набор элементов одного типа. Например, последовательность

0 1 1 2 3 5 8 13 21

представляет собой первые 9 элементов последовательности Фибоначчи. (Выбрав начальные два числа, вычисляем каждый из следующих элементов как сумму двух предыдущих.) Для того чтобы объявить массив и проинициализировать его данными элементами, мы должны написать следующую инструкцию С++:

int fibon[9] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 };

Здесь fibon – это имя массива. Элементы массива имеют тип int, размер (длина) массива равна 9. Значение первого элемента – 0, последнего – 21. Для работы с массивом мы индексируем (нумеруем) его элементы, а доступ к ним осуществляется с помощью операции взятия индекса. Казалось бы, для обращения к первому элементу массива естественно написать:

int first_elem = fibon[1];

Однако это не совсем правильно: в С++ (как и в С) индексация массивов начинается с 0, поэтому элемент с индексом 1 на самом деле является вторым элементом массива, а индекс первого равен 0.Таким образом, чтобы обратиться к последнему элементу массива, мы должны вычесть единицу из размера массива:

fibon[0]; // первый элемент

fibon[1]; // второй элемент

...

fibon[8]; // последний элемент

fibon[9]; // ... ошибка

Девять элементов массива fibon имеют индексы от 0 до 8. Употребление вместо этого индексов 1-9 является одной из самых распространенных ошибок начинающих программистов на С++. Для перебора элементов массива обычно употребляют инструкцию цикла. Вот пример программы, которая инициализирует массив из десяти элементов числами от 0 до 9 и затем печатает их в обратном порядке:

int main()

{

int ia[10];

int index;

for (index=0; index<10; ++index) // ia[0] = 0, ia[1] = 1 и т.д.

ia[index] = index;

for (index=9; index>=0; --index)

cout << ia[index] << " ";

cout << endl; }

Оба цикла выполняются по 10 раз. Все управление циклом for осуществляется инструкциями в круглых скобках за ключевым словом for. Первая присваивает начальное значение переменной index. Это производится один раз перед началом цикла:

index = 0;

Вторая инструкция:

index < 10;

представляет собой условие окончания цикла. Оно проверяется в самом начале каждой итерации цикла. Если результатом этой инструкции является true, то выполнение цикла продолжается; если же результатом является false, цикл заканчивается. В нашем примере цикл продолжается до тех пор, пока значение переменной index меньше 10. На каждой итерации цикла выполняется некоторая инструкция или группа инструкций, составляющих тело цикла. В нашем случае это инструкция

ia[index] = index;

Третья управляющая инструкция цикла

++index

выполняется в конце каждой итерации, по завершении тела цикла. В нашем примере это увеличение переменной index на единицу. Мы могли бы записать то же действие как

index = index + 1

но С++ дает возможность использовать более короткую (и более наглядную) форму записи. Этой инструкцией завершается итерация цикла. Описанные действия повторяются до тех пор, пока условие цикла не станет ложным. Вторая инструкция for в нашем примере печатает элементы массива. Она отличается от первой только тем, что в ней переменная index уменьшается от 9 до 0. Несмотря на то, что в С++ встроена поддержка для типа данных “массив”, она весьма ограничена. Фактически мы имеем лишь возможность доступа к отдельным элементам массива. С++ не поддерживает абстракцию массива, не существует операций над массивами в целом, таких, например, как присвоение одного массива другому или сравнение двух массивов на равенство, и даже такой простой, на первый взгляд, операции, как получение размера массива. Мы не можем скопировать один массив в другой, используя простой оператор присваивания:

int array0[10]; array1[10];

...

array0 = array1; // ошибка

Вместо этого мы должны программировать такую операцию с помощью цикла:

for (int index=0; index<10; ++index)

array0[index] = array1[index];

Массив “не знает” собственный размер. Поэтому мы должны сами следить за тем, чтобы случайно не обратиться к несуществующему элементу массива. Это становится особенно утомительным в таких ситуациях, как передача массива функции в качестве параметра. Можно сказать, что этот встроенный тип достался языку С++ в наследство от С и процедурно-ориентированной парадигмы программирования

Структура программ С++ это разметка рабочей области (области кода) с целью чёткого определения основных блоков программ и синтаксиса. Структура программ несколько отличается в зависимости от среды программирования. Мы ориентируемся на MVS2010, и по этому примеры программ будут показаны именно для MVS2010. Нет ничего сложного в том, чтобы портировать код из MVS2010 в другие среды разработки и вы поймете со временем, как это сделать.  

Структура программ С++ для Microsoft Visual Studio.

?

1

2

3

4

5

6

// struct_program.cpp: определяет точку входа для консольного приложения.

#include "stdafx.h"

//здесь подключаем все необходимые препроцессорные директивы

void main() { // начало главной функции с именем main

//здесь будет находится ваш программный код

}

В строке 1 говорится о точке входа для консольного приложения, это значит, что данную программу можно запустить через командную строку Windows указав имя программы, к примеру, такое struct_program.cppСтрока 1 является однострочным комментарием, так как начинается с символов "//", подробнее о комментариях будет рассказано в следующей статье. Встроке 2 подключен заголовочный файл "stdafx.h". Данный файл похож на контейнер, так как в нем подключены основные препроцессорные директивы(те, что подключил компилятор, при создании консольного приложения), тут же могут быть подключены и вспомогательные(подключенные программистом).

include - директива препроцессора, т. е. сообщение препроцессору. Строки, начинающиеся с символа "#" обрабатываются препроцессором до компиляции программы.

Препроцессорные директивы также можно подключать и в строках, начиная после записи #include "stdafx.h" до начала главной функции. Причём такой способ подключения библиотек является основным, а использование "stdafx.h" - это дополнительная возможность подключения заголовочных файлов. С 4-й по 6-ю строки объявлена функция main. Строка 4 – это заголовок функции, который состоит из типа возвращаемых данных (в данном случае void), этой функцией, и имени функции, а также круглых скобочках, в которых объявляются параметры функции.

void - тип данных не имеющий значения, т.е он не может хранить никакой информации.

Между фигурными скобочками  размещается  основной программный код, называемый еще телом функции. Это самая простая структура программы. Данная структура написана в Microsoft Visual Studio 2010(MVS2010). Все выше сказанное остается справедливым и для других компиляторов,  кроме строки 2. Контейнера "stdafx.h" нигде кроме MVS нет.

Структура программы для  C++ Builder.

При создании консольного приложения мастер создания проектов создает автоматически следующий код:

?

1

2

3

4

5

6

//препроцессорная директива, автоматически подключённая мастером создания  проектов

#include <vcl.h>

int main()

{

return 0;

}

Мы видим, что у функции поменялся тип данных, место void написано int. Это говорит о том что по завершении работы функция вернет какое-то целочисленное значение, в нашем случае 0. Целочисленное потому, что int – это тип данных для целых чисел, таких как  4,  5,  6,  456, 233 и т. д.

Главное помнить, что если тип возвращаемых данных у функции main - int или любой другой, кроме void, то следует писать строку типа этой: return  возвращаемое значение;

В строке 2 подключена библиотека vcl.h  – её генерит мастер создания приложений автоматически, поэтому удалять её не следует, иначе проект не будет рабочим.

В общем говоря, мастер создает автоматически структуру программы, немного отличающуюся от тех, что мы рассмотрели, но суть остается та же.

Например:

?

1

2

3

4

int main(int argc, char* argv[])

{

return 0;

}

Такой пример структуры генерится мастером в MVS2010. Данный main немного отличается. Подробнее рассмотрим позже, но скажу, что данный main имеет такой вид, так как изначально рассчитан на поддержку юникода. Юникод - стандарт кодирования символов, позволяющий представить знаки практически всех письменных языков. Подробнее о юникоде поговорим позже.

Существуют разные версии main, но в этом нет ничего страшного, так как main  была главной функцией так она ей и остается, поэтому все выше сказанное остается актуальным.

Пример структуры программы MVS2010 с подключенными библиотеками.

?

1

2

3

4

5

6

#include "stdafx.h"

#include <iostream>

using namespace std;

void main()

{

}

Имя подключаемых библиотек пишется внутри знаков больше, меньше:  <имя заголовочных файлов>.

Заголовочные файлы и имя подключаемых библиотек – одно и то же.

Синтаксис подключения заголовочных файлов:

#include <имя заголовочного файла>

Более старые заголовочные файлы подключаются так (этот стиль подключения библиотек унаследован у языка программирования C):

#include <имя заголовочного файла.h>

Различие состоит в том, что после имени ставится расширение  ".h".

Язык программирования С++ является регистрозависимым. Например: Return 0; – не правильно, будет ошибка компиляции. return 0; – правильно!!!

Механизм классов в C++ позволяет пользователям определять собственные типы данных. По этой причине их часто называют пользовательскими типами. Класс может наделять дополнительной функциональностью уже существующий тип. Так, например, IntArray, введенный в главе 2, предоставляет больше возможностей, чем тип "массив int". С помощью классов можно создавать абсолютно новые типы, например Screen (экран) или Account (расчетный счет). Как правило, классы используются для абстракций, не отражаемых встроенными типами адекватно.