Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






Сегментные регистры

Регистры даннях

В них можно хранить любые данные (числа, адреса и пр.).

В верхнем ряду Таблицы (AX (аккумулятор), BX (база), CX (счетчик), DX (регистр данных)) находятся шестнадцатиразрядные регистры, которые могут хранить числа от 0 до 65.535 (от 0h до FFFFh в шестнадцатеричной системе (вспоминаем прошлый выпуск)). Под ним идет ряд восьмиразрядных регистров (AH, AL, BH, BL, CH, CL, DH, DL), которые могут хранить максимальное число 255 (FFh). Это половинки (старшая или младшая) шестнадцатиразрядных регистров.

Регистры-указатели

Регистры SI (индекс источника) и DI (индекс приемника) используются в строковых операциях. Регистры BP и SP необходимы при работе со стеком.

Сегментные регистры

CS DS ES SS

Сегментные регистры необходимы для обращения к тому или иному сегменту памяти (например, видеобуферу).

3. В микропроцессорах i8086/88 сегментация памяти осуществляется простым способом. Все адресное пространство в 1 Мбайт разбивается на несколько (от 16 до 65536) смежных блоков памяти. Каждый такой блок может иметь размер от 16 байт до 64 Кбайт и выравнивается на шестнадцатибайтной границе. Блок памяти длиной в 16 байт и выравненный на 16-ти байтной границе называется параграфом. Для обращения к любому адресу в памяти необходимо знать его физический адрес, который в микропроцессорах i8086/88 и реальном режиме работы микропроцессоров x86 совпадает с его линейным адресом. Система команд в микропроцессорах x86 устроена так, что для образования эффективного адреса необходимо обязательное присутствие только одного его компонента. Таким образом любой компонент: база, индекс, смещение -- или даже оба из них могутбыть опущены.

Регистры сегментной адресации CS, DS, SS, ES используются для хранения начальных адресов полей памяти (сегментов), отведенных в программах для хранения:

команд программы (сегмент кода — CS);

данных (сегмент данных — DS);

стековой области памяти (сегмент стека — SS);

дополнительной области памяти данных при межсегментных пересылках (рас­ширенный сегмент — ES), поскольку размер сегмента в реальном режиме рабо­ты МП ограничен величиной 64 Кбайт.

4. Все регистры этой группы позволяют обращаться к своим «младшим» частям. Использовать для самостоятельной адресации можно только младшие 16– и 8-битные части этих регистров. Старшие 16 бит этих регистров как самостоятельные объекты недоступны.

Перечислим регистры, относящиеся к группе регистров общего назначения. Так как эти регистры физически находятся в микропроцессоре внутри арифметико-логического устройства (АЛУ), то их еще называют регистрами АЛУ:

1) eax/ax/ah/al (Accumulator register) – аккумулятор. Применяется для хранения промежуточных данных. В некоторых командах использование этого регистра обязательно;

2) ebx/bx/bh/bl (Base register) – базовый регистр. Применяется для хранения базового адреса некоторого объекта в памяти;

3) ecx/cx/ch/cl (Count register) – регистр-счетчик. Применяется в командах, производящих некоторые повторяющиеся действия. Его использование зачастую неявно и скрыто в алгоритме работы соответствующей команды.

4) edx/dx/dh/dl (Data register) – регистр данных.

Так же, как и регистр eax/ax/ah/al, он хранит промежуточные данные. В некоторых командах его использование обязательно; для некоторых команд это происходит неявно.

Следующие два регистра используются для поддержки так называемых цепочечных операций, т. е. операций, производящих последовательную обработку цепочек элементов, каждый из которых может иметь длину 32, 16 или 8 бит:

1) esi/si (Source Index register) – индекс источника.

Этот регистр в цепочечных операциях содержит текущий адрес элемента в цепочке-источнике;

2) edi/di (Destination Index register) – индекс приемника (получателя). Этот регистр в цепочечных операциях содержит текущий адрес в цепочке-приемнике.

В архитектуре микропроцессора на программно-аппаратном уровне поддерживается такая структура данных, как стек. Для работы со стеком в системе команд микропроцессора есть специальные команды, а в программной модели микропроцессора для этого существуют специальные регистры:

1) esp/sp (Stack Pointer register) – регистр указателя стека. Содержит указатель вершины стека в текущем сегменте стека.

2) ebp/bp (Base Pointer register) – регистр указателя базы кадра стека. Предназначен для организации произвольного доступа к данным внутри стека.

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

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

Для организации ветвлений в pic-контроллерах можно использовать 4 команды: две оперирующие с байтами (decfsz, incfsz) и две оперирующие с битами (btfsc, btfss). Работают эти команды следующим образом:

decfsz f,d - вычесть 1 из регистра f, если результат =0, то пропустить следующую команду (d определяет, куда сохранять результат. Если d=0 - результат сохраняется в аккумуляторе W, если d=1 - результат сохраняется в регистре f)

incfsz f,d - добавить 1 к регистру f, если результат =0, то пропустить следующую команду

btfsc f,b - проверить бит b в регистре f, если он =0, то пропустить следующую команду

btfss f,b - проверить бит b в регистре f, если он =1, то пропустить следующую команду

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

6. Для организации цикла предназначена команда LOOP. У этой команды один операнд — имя метки, на которую осуществляется переход. В качестве счётчика цикла используется регистр CX. Команда LOOP выполняет декремент CX, а затем проверяет его значение. Если содержимое CX не равно нулю, то осуществляется переход на метку, иначе управление переходит к следующей после LOOP команде.

Содержимое CX интерпретируется командой как число без знака. В CX нужно помещать число, равное требуемому количеству повторений цикла. Понятно, что максимально может быть 65535 повторений. Ещё одно ограничение связано с дальность перехода. Метка должна находиться в диапазоне -127…+128 байт от команды LOOP (если это не так, FASM сообщит об ошибке).

7. Флаг – это бит, принимающий значение 1 («флаг установлен»), если выполнено некоторое условие, и значение 0 («флаг сброшен») в противном случае. Процессор имеет регистр флагов, содержащий набор флагов, отражающий текущее состояние процессора. Значение флагов CF, DF и IF можно изменять напрямую в регистре флагов с помощью специальных инструкций (например, CLD для сброса флага направления), но нет инструкций, которые позволяют обратиться к регистру флагов как к обычному регистру. Однако можно сохранять регистр флагов в стек или регистр AH и восстанавливать регистр флагов из них с помощью инструкций LAHF, SAHF, PUSHF, PUSHFD, POPF и POPFD.

Флаги состояния (биты 0, 2, 4, 6, 7 и 11) отражают результат выполнения арифметических инструкций, таких как ADD, SUB, MUL, DIV. Флаги состояния позволяют одной и той же арифметической инструкции выдавать результат трёх различных типов: беззнаковое, знаковое и двоично-десятичное (BCD) целое число. Если результат считать беззнаковым числом, то флаг CF показывает условие переполнения (перенос или заём), для знакового результата перенос или заём показывает флаг OF, а для BCD-результата перенос/заём показывает флаг AF. Флаг SF отражает знак знакового результата, флаг ZF отражает и беззнаковый, и знаковый нулевой результат.

Флаг направления DF (бит 10 в регистре флагов) управляет строковыми инструкциями (MOVS, CMPS, SCAS, LODS и STOS) – установка флага заставляет уменьшать адреса (обрабатывать строки от старших адресов к младшим), обнуление заставляет увеличивать адреса. Инструкции STD и CLD соответственно устанавливают и сбрасывают флаг DF. Системные флаги и поле IOPL управляют операционной средой и не предназначены для использования в прикладных программах.

8. Строка – упорядоченная последовательность символов. Количество символов в строке называется ее длиной. Длина строки может лежать в диапазоне от 0 до 255. Каждый символ строковой величины занимает 1 байт памяти и имеет числовой код в соответствии с таблицей кодов ASCII.

Var <имя_переменной>: string[<максимальная длина строки>] Например:

Var s1: string[10];

s2: string[20];

smax: string;

Для описания строковых переменных в Паскале существует предопределенный тип string.

Copy (S, poz, n) выделяет из строки S, начиная с позиции poz, подстроку из n символов. Здесь S – любое строковое выражение, poz, n – целочисленные выражения.

Concat (s1, s2,...,sn) выполняет слияние строк s1, s2,...,sn в одну строку.

Length(S) определяет текущую длину строкового выражения S. Результат – значение целого типа.

Pos(subS, S) определяет позицию первого вхождения подстроки subS в строку S. Результат – целое число, равное номеру позиции, где находится первый символ искомой подстроки.

Delete (S, poz, n) удаляет из строки S, начиная с позиции poz, подстроку из n символов.

Insert(subS, S, poz) вставляет в строку S, начиная с позиции poz, подстроку subS.

Str(x, S) преобразует число x в строковый формат.

Val(S, x, kod) преобразует строку символов S в число x.

В С++ существует 2 типа строк.

Первый из них - это массив переменных типа char. Переменная типа char хранит в себе 1 символ. Размер такой строки равняется размеру массива - 1, т.к. последний элемент содержит NULL (пустая переменная без значения), который обозначает символ конца строки. char name[50];

Второй из вариантов, более удобный - это специальный класс string

Для его работы необходимо в начале программы подключить заголовочный файл string:

#include <string>

Для создания строки вам необходимо в начале программы написать using namespace std;

Теперь чтоб создать строку достаточно написать:

string s;

s.append(str) - добавляет в конец строки строку str. Можно писать как s.append(переменная), так и s.append("строка");

s.assign(str) - присваивает строке s значение строки str. Аналогично записи s=str;

int i=s.begin() - записывает в i индекс первого элемента строки

int i=s.end() - аналогично, но последнего

s.clear() - как следует из названия, отчищает строку. Т.е. удаляет все элементы в ней

s.compare(str) -сравнивает строку s со строкой str и возвращает 0 в случае совпадение (на самом деле сравнивает коды символов и возвращает из разность)

s.copy(куда, сколько, начиная с какого) - копирует из строки s в куда (там может быть как строка типа стринг, так и строка типа char). Последние 2 параметра не обязательные (можно использовать функцию с 1,2 или 3 параметрами)

bool b=s.empty() - если строка пуста, возвращает true, иначе false

s.erase(откуда, сколько) удаляет n элементов с заданной позиции

s.find(str,позиция) - ищет строку str начиная с заданной позиции

s.insert(позиция,str, начиная, beg, count) - вставляет в строку s начиная с заданной позиции часть строки str начиная с позиции beg и вставляя count символов

int len=s.length() - записывает в len длинну строки

s.push_back(symbol) - добавляет в конец строки символ

s.replace(index, n,str) - берет n первых символов из str и заменяет символы строки s на них, начиная с позиции index

str=s.substr(n,m) - возвращает m символов начиная с позиции n

s.swap(str) меняет содержимое s и str местами.

s.size() - возвращает число элементов в строке

9. Массив – это именованная группа однотипных данных, хранящихся в последовательных ячейках памяти.

Var

A: array [1..10] of integer;

I: byte; {переменная I вводится как индекс массива}

Begin

For i:=1 to 10 do

Readln (a[i]); { ввод i- го элемента производится с клавиатуры }

For i:=1 to 10 do

Write (a [ i ],’ ‘); {вывод массива осуществляется в строку, после каждого элемента печатается пробел}

 

#include "stdafx.h"

#include <iostream>

using namespace std;

int main ()

{

int X[10],N,i;

cout<<"\n N="; cin>>N; //ввод размера массива

for (i=0; i<N; i++)

{

cout<<"\n X["<<i<<"]="; //сообщение о вводе элемента

cin>>X[i]; //ввод элементов массива в цикле

cout<<"\t X["<<i<<"]="<<X[i]; //вывод массива

}

system("pause");

return 0;

}

10. Ввод-вывод данных в языке C++ осуществляется либо с помощью функций ввода-вывода в стили C, либо с использованием библиотеки классов C++. Преимущество объектов C++ в том, что они легче в использовании, поэтому предлагаю рассмотреть именно их. Описание объектов для управления вводом-выводом содержится в файле iostream.h. При подключении этого файла с помощью директивы #include <iostream.h> в программе автоматически создаются виртуальные каналы связи cin для ввода с клавиатуры и cout для вывода на экран, а также операции помещения в поток << и чтения из потока >>. С помощью объекта cin и операции >> можно присвоить значение любой переменной. Например, если переменная x описана как целочисленная, то команда cin>>x; означает, что в переменную x будет записано некое целое число, введенное с клавиатуры. Если необходимо ввести несколько переменных, то следует написать cin>>x>>y>>z;.

Объект cout и операция << позволяет вывести на экран значение любой переменной или текст. Текст необходимо заключать в двойные кавычки. Запись cout<<x; означает вывод на экран значения переменной x.

спользование флагов

Флаги позволяют включить или выключить один из параметров вывода на экран. Для установки флага вывода используется следующая конструкция языка C++:

cout.setf(ios::flag)

Для снятия флага конструкция:

cout.unsetf(ios::flag)

Здесь flag — имя конкретного флага.

Если при выводе необходимо установить несколько флагов, то можно воспользоваться арифметической операцией «или» (|). В этом случае конструкция языка C++ будет такой:

cout.setf(ios::flag1 | ios::flag2 | ios::flag3)

Манипуляторы встраиваются непосредственно в операторы ввода-вывода. Для корректного их использования необходимо подключить библиотеку iomanip с помощью оператора #include <iomanip>

11. Для того чтобы работать с файлами необходимо сначала их описать.

var

f,f1:text;

a:integer;

Далее необходимо ввести этот файл.

assign(f,'input.txt');

assign(f1,'output.txt');

Открываем файл для чтения.

reset(f);

Открываем второй файл для записи, при этом всё что было в файле стирается.

rewrite(f1);

Также можно открыть второй файл для дозаписи (дозапись производится в конец файла).

append(f1);

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

read(f,a);

Запись осуществляется обычным оператором write с указанием файла в который производится запись.

write(f1,a);

После всех манипуляций все открытые файлы необходимо закрыть.

close(f);

close(f1);

Для работы с файлами используются специальные типы данных, называемые потоками. Поток ifstream служит для работы с файлами в режиме чтения, а ofstream в режиме записи. Для работы с файлами в режиме как записи, так и чтения служит поток fstream. В программах на C++ при работе с текстовыми файлами необходимо подключать библиотеки iostream и fstream.

Для того чтобы начать работать с текстовым файлом, необходимо описать переменную типа ofstream. Например, так: ofstream F;

 

Будет создана переменная F для записи информации в файл. На следующим этапе файл необходимо открыть для записи. В общем случае оператор открытия потока будет иметь вид:

F.open(«file», mode);

Файл может быть открыт в одном из следующих режимов:

ios::in — открыть файл в режиме чтения данных; режим является режимом по умолчанию для потоков ifstream;

ios::out — открыть файл в режиме записи данных (при этом информация о существующем файле уничтожается); режим является режимом по умолчанию для потоков ofstream;

ios::app — открыть файл в режиме записи данных в конец файла;

ios::ate — передвинуться в конец уже открытого файла;

ios::trunc — очистить файл, это же происходит в режиме ios::out;

ios::nocreate — не выполнять операцию открытия файла, если он не существует;

ios::noreplace — не открывать существующий файл.

Для того чтобы прочитать информацию из текстового файла, необходимо описать переменную типа ifstream. После этого нужно открыть файл для чтения с помощью оператора open.

ifstream F;

F.open(«file», mode);

12. if (условие) оператор_1; else оператор_2;

Здесь условие - это логическое выражение, переменная или константа.

Работает условный оператор следующем образом. Сначала вычисляется значения выражения, записанного в виде условия. Если оно имеет значение истина (true), выполняется оператор_1. В противном случае (значение ложное (false)) оператор_2.

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

if (условие) { оператор_1; оператор_2; … }

else { оператор_1; оператор_2; … }

Оператор варианта switch

Он необходим в тех случаях, когда в зависимости от значений переменной надо выполнить те или иные операторы:

switch (выражение)

{

case значение_1: операторы_1; break;

case значение_2: операторы_2; break;

case значение_3: операторы_3; break;

case значение_n: операторы_n; break;

}

Оператор работает следующем образом. Вычисляется значение выражения. Затем выполняются операторы, помеченные значением, совпадающим со значением выражения. То есть если, выражение принимает значение_1, то выполняются операторы_1 и т.д..

13. В языке программирования Паскаль существует три вида циклических конструкций.

Часто цикл for называют циклом со счетчиком. Этот цикл используется, когда число повторений не связано с тем, что происходит в теле цикла. Т.е. количество повторений может быть вычислено заранее.

for счетчик:=значение to конечное_значение do

тело_цикла;

for счетчик:=значение downto конечное_значение do

тело_цикла;

Цикл while является циклом с предусловием. В заголовке цикла находится логическое выражение. Если оно возвращает true, то тело цикла выполняется, если false – то нет.

Когда тело цикла было выполнено, то ход программы снова возвращается в заголовок цикла. Условие выполнения тела снова проверяется (находится значение логического выражения).

Цикл while может не выполниться ни разу, если логическое выражение в заголовке сразу вернуло false. Однако такая ситуация не всегда может быть приемлемой. Бывает, что тело цикла должно выполниться хотя бы один раз, не зависимо оттого, что вернет логическое выражение. В таком случае используется цикл repeat – цикл с постусловием.

В цикле repeat логическое выражение стоит после тела цикла. Причем, в отличие от цикла while, здесь всё наоборот: в случае true происходит выход из цикла, в случае false – его повторение.

Цикл с постусловием (do…while)(только с++)

Иногда возникает необходимость, чтобы тело цикла выполнилось хотя бы один раз, но условие не позволяет этому случится. Вот именно тут нам поможет цикл с постусловие do…while. Который реализован следующей конструкцией:

do оператор while (выражение);

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

Оператор break заканчивает выполнение ближайшего внешнего цикла или условного оператора, в котором он отображается. Управление передается оператору, который расположен после оператора, при его наличии.

14. Кроме стандартных типов данных Паскаль поддерживает скалярные типы, определенные самим пользователем. К ним относятся перечислимые типы (когда непосредственно, в разделе описания типов, заранее записываются все значения для переменных этого типа) и интервальные (когда задаются границы диапазона значений для данной переменной), указательные тип (кроме Pointer), структурированные типы и процедурные типы.

Перечислимый тип

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

Var Season: (winter,spring,summer,autum);

Temp: (23,24,25,26);

 

Интервальный тип

Интервальный тип позволяет задавать две константы,определяющие границы диапазона значений для каждой переменной.Обе константы должны принадлежать одному и тому же стандартному типу (кроме real). Например,

Var S:1..30;

Сh:'a'..'f';

 

Указательный тип

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

Type PtStack=^Stack;

Stack=array[1..40] of real;

 

Процедурный тип

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

Type Tproc1=procedure (var x,y:real);

Tproc2=function (x:real):real;

С++

Переименование типов (typedef)

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

typedef тип новое_имя [ размерность ];

В данном случае квадратные скобки являются элементом синтаксиса. Размерность может отсутствовать.

Перечисления (enum)

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

enum [ имя_типа ] { список_констант };

Структуры (struct)

В отличие от массива, все элементы которого однотипны, структура может содержать элементы разных типов. В языке C++ структура является видом класса и обладает всеми его свойствами, но во многих случаях достаточно использовать структуры так, как они определены в языке С:

struct [ имя_типа ] {

тип_1 элемент_1:

тип_2 элемент_2;

тип_n элемент_n;

} [ список_описателей ];

Битовые поля

Битовые поля — это особый вид полей структуры. Они используются для плотной упаковки данных, например, флажков типа «да/нет». Минимальная адресуемая ячейка памяти — 1 байт, а для хранения флажка достаточно одного бита. При описании битового поля после имени через двоеточие указывается длина поля в битах (целая положительная константа):

struct Options{

bool centerX:1;

bool centerY:1;

unsigned int shadow:2;

unsigned int palette:4;

};

15. Файл — именованная область данных на носителе информации. В различных операционных и/или файловых системах могут быть реализованы различные типы файлов; кроме того, реализация различных типов может различаться.

«Обыкновенный файл» — файл, позволяющий операции чтения, записи, перемещения внутри файла

Каталог (англ. directory — алфавитный справочник) или директория — файл, содержащий записи о входящих в него файлах. Каталоги могут содержать записи о других каталогах, образуя древовидную структуру.

Жёсткая ссылка (англ. hardlink, часто используется калька «хардлинк») — в общем случае, одна и та же область информации может иметь несколько имён. Такие имена называют жёсткими ссылками (хардлинками). После создания хардлинка сказать где «настоящий» файл, а где хардлинк невозможно, так как имена равноправны. Сама область данных существует до тех пор, пока существует хотя бы одно из имён. Хардлинки возможны только на одном физическом носителе.

Символьная ссылка (симлинк, софтлинк) — файл, содержащий в себе ссылку на другой файл или директорию. Может ссылаться на любой элемент файловой системы, в том числе, и расположенный на другом физическом носителе.

Создание файла и запись данных в него

Процедура assign обеспечивает связь файловой переменной программы с реальным файлом на диске. Первым аргументом указывается переменная, вторым – адресное имя файла.

Процедура rewrite открывает файл в режиме записи, т.е. мы можем вводить данные в файл с помощью процедуры вывода из программы write. Если указанный файл отсутствует на диске, то он будет создан. Если файл существует и содержит данные, то все они будут удалены и заменены в дальнейшем новыми (перезаписаны).

Запись данных в файл – результат выполнения процедуры write (f, c), где f – файловая переменная, а с – выводимый из программы, но вводимый в файл символ.

В конце требуется закрыть файл и «освободить» переменную f. Это делается с помощью процедуры close.

Чтение данных из файла

Процедура reset открывает файл для чтения. Т.е. мы можем в дальнейшем в программе извлекать данные из файла с помощью процедуры read.

Данные извлекаются «порциями» базового типа. В данном примере – это char (символы).

Чтение данных из файла продолжается до тех пор, пока не будет достигнут конец файла. Функция eof проверяет достигнут ли конец файла, переданного ей в качестве аргумента и, если достигнут, возвращает true. Выражение not eof (f) проверяет обратное – то, что конец файла еще не достигнут.

16. Функция - это часть программы, которая вычисляет и возвращает значение.

Заголовок функции определяет идентификатор функции, формальные параметры (если есть), и тип результата функции. Допустимы порядковые, вещественные, строковые и указательные типы результата. Функция вызывается при оценке выражения, использующего данную функцию.

Заголовок функции сопровождается:

Разделом описаний, в котором объявляются локальные объекты

Операторной частью, в которой находятся операторы, которые будут выполнены при вызове функции

 

Операторная часть должна содержать по крайней мере один оператор, который назначает присваивает значение идентификатору функции. Результатом функции будет последнее присвоенное значение.

Function UpCaseStr(S: String): String;

Var I: Integer;

Begin

For I:=1 To Length(S) Do

If (S[I]>='a') And (S[I]<='Z') Then Dec(S[I], 32);

UpCaseStr:=S;

End;

Процедура - это часть программы, в которой выполняется специфическое действие, обычно основанное на наборе параметров.

Procedure WrStr (X, Y: Integer; S: String);

Var SaveX, SaveY: Integer;

Begin

SaveX:=WhereX;

SaveY:=WhereY;

GotoXY(X, Y);

Write(S);

GotoXY(SaveX, SaveY);

End;

Формальные и фактические параметры.

Формальные параметры подпрограммы указывают, с какими параметрами следует обращаться к этой программе (количество примеров, их последовательность, типы). Они задаются в заголовке подпрограммы в виде списка формальных параметров, разбитого на группу формальных параметров включаются однотипные параметры одной категории.

Вызов по ссылке и по значению

Список параметров, задаваемый в заголовке процедуры и функции, обеспечивает связь подпрограммы с вызывающей программой. Через него в подпрограмму передаются исходные данные и возвращается результат. При этом предусмотрено два принципиально отличающихся механизма передачи параметров - по значению и по ссылке. Синтаксически эти два способа отличаются употреблением слова Var перед соответствующей переменной в заголовке подпрограммы. Если это слово имеется, то переменная передается по ссылке, а если нет - по значению.

Параметры–значения

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

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

Локальные и глобальные переменные и подпрограммы.

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

17. Абстрагирование — это способ выделить набор значимых характеристик объекта, исключая из рассмотрения незначимые. Соответственно, абстракция — это набор всех таких характеристик.

Инкапсуляция — это свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе, и скрыть детали реализации от пользователя.

Наследование — это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс — потомком, наследником, дочерним или производным классом.

Полиморфизм — это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта. При использовании термина «полиморфизм» в сообществе ООП подразумевается полиморфизм подтипов; а использование параметрического полиморфизма называют обобщённым программированием.

Класс является описываемой на языке терминологии исходного кода моделью ещё не существующей сущности (объекта). Фактически он описывает устройство объекта, являясь своего рода чертежом. Говорят, что объект — это экземпляр класса. При этом в некоторых исполняющих системах класс также может представляться некоторым объектом при выполнении программы посредством динамической идентификации типа данных. Обычно классы разрабатывают таким образом, чтобы их объекты соответствовали объектам предметной области.

Сущность в адресном пространстве вычислительной системы, появляющаяся при создании экземпляра класса или копирования прототипа (например, после запуска результатов компиляции и связывания исходного кода на выполнение).

Прототип — это объект-образец, по образу и подобию которого создаются другие объекты. Объекты-копии могут сохранять связь с родительским объектом, автоматически наследуя изменения в прототипе; эта особенность определяется в рамках конкретного языка.

18. Указатель — это переменная, значением которой является адрес памяти, по которому хранится объект определенного типа (другая переменная).

Указатели широко используются в C++. В чем то, именно их наличие сделало этот язык более удобным для системного программирования. Но стоит отметить, что это одна из наиболее сложных для освоения возможностей C++.

Как правило, при обработке оператора объявления переменной тип имя_переменной; компилятор автоматически выделяет память под переменную имя_переменной в соответствии с указаннымтипом: char C='$'; //Будет выделена под символьную переменную С

int *p

Звездочка в описании указателя относится непосредственно к имени, поэтому, чтобы объявить несколько указателей, ее ставят перед именем каждого из них: float *x, y, *z;

Операция получения адреса обозначается знаком &, а операция разадресации *. Первая возвращает адрес своего операнда. Операция разадресации * возвращает значение переменной, хранящееся в по заданному адресу, то есть выполняет действие, обратное операции &. Значение одного указателя можно присвоить другому. Если указатели одного типа, то для этого применяют обычную операцию присваивания. Если указатели ссылаются на различные типы, то при присваивании значения одного указателя другому, необходимо использовать преобразование типов.

19. Динамическое выделение памяти необходимо для эффективного использования памяти компьютера. В С++ операции new и delete предназначены для динамического распределения памяти компьютера. Операция new выделяет память из области свободной памяти, а операция delete высвобождает выделенную память. Выделяемая память, после её использования должна высвобождаться, поэтому операции new и delete используются парами. Даже если не высвобождать память явно, то она освободится ресурсами ОС по завершению работы программы. Рекомендую все-таки не забывать про операцию delete.

// пример использования операции new

int *ptrvalue = new int;

//new – операция выделения свободной памяти под создаваемый объект.

Операция new создает объект заданного типа, выделяет ему память и возвращает указатель правильного типа на данный участок памяти. Если память невозможно выделить, например, в случае отсутствия свободных участков, то возвращается нулевой указатель, то есть указатель вернет значение 0. Выделение памяти возможно под любой тип данных: int, float,double, char и т. д.

// пример использования операции delete:

delete ptrvalue;

// где ptrvalue – указатель на выделенный участок памяти типа int

// delete – операция высвобождения памяти

20. Весь реальный мир состоит из объектов. Города состоят из районов, в каждом районе есть свои названия улиц, на каждой улице находятся жилые дома, которые также состоят из объектов. Практически любой материальный предмет можно представить в виде совокупности объектов, из которых он состоит. Допустим, что нам нужно написать программу для учета успеваемости студентов. Можно представить группу студентов, как класс языка C++.

class Students {

// Имя студента

std::string name;

// Фамилия

std::string last_name;

// Пять промежуточных оценок студента

int scores[5];

// Итоговая оценка за семестр

float average_ball;

};

Классы в программировании состоят из свойств и методов. Свойства — это любые данные, которыми можно характеризовать объект класса. Методы — это функции, которые могут выполнять какие-либо действия над данными (свойствами) класса.

Методы класса — это его функции.

Свойства класса — его переменные.

Для того, чтобы разрешить доступ к данным класса извне, используют модификатор доступа public. Все функции и переменные, которые находятся после модификатора public, становятся доступными из всех частей программы.

 

Закрытые данные класса размещаются после модификатора доступа private. Если отсутствует модификатор public, то все функции и переменные, по умолчанию являются закрытыми (как в первом примере).

21. Используя public наследование мы передаем потомкам всё что есть в основном классе в таком виде, как и записано в основном классе. Получаем клон основного класса. Разница в том что элементы основного класса к элементам своего клона отношения не имеют.

Используя private наследование можно создать первого потомка от которого дальнейшее наследование будет бессмысленно. Если первый потомок получает возможность работы с некоторыми элементами, переданными по механизму наследования, то потомки первого потомка таких возможностей не получают. Кроме того, потомки первого потомка даже лишены возможности узнавать кто их первый родитель. Предполагается, что потомки класса B не должны даже знать о существовании класса A (либо потомков класса B вообще не должно быть).

Используя protected наследование, программист предполагает, что внутри всех потомков и потомков потомков и потомков потомков потомков будут использоваться только такие элементы, передаваемые механизмом наследования, которые будут защищены от внешнего воздействия извне своих классов.

22. Оо

23. Наследование — это способ повторного использования программного обеспечения, при котором новые производные классы (наследники) создаются на базе уже существующих базовых классов (родителей). При создании новый класс является наследников членов и методов ранее определенного базового класса. Создаваемый путем наследования класс является производным (derived class), который в свою очередь может выступать в качестве базового класса (based class) для создаваемых классов. При использовании наследования члены и методы кроме свойств public и private могут иметь свойство protected. Для одиночного класса описатели protected и private равносильны. Разница между protected и private проявляется при наследовании. Закрытые члены и методы, объявленные в базовом классе как protected, в производном могут использоваться как открытые (public). Защищенные (protected) члены и методы являются промежуточным вариантом между public и private.

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

class name_derived_class:

type_inheritance base_class

{

//закрытые методы и члены класса

...

public:

//открытые методы и члены класса

...

protected:

//защищенные методы и члены класса

...

};

Здесь name_derived_class — имя создаваемого производного класса, type_inheritance — способ наследования, возможны следующие способы наследования: public, private и protected; base_class — имя базового типа.

24. Функция friend — это функция, которая не является членом класса, но имеет доступ к закрытым и защищенным членам класса. Дружественные функции не считаются членами класса; это обычные внешние функции с особыми правами доступа. Дружественные функции не расположены в области класса и не вызываются с помощью операторов выбора члена (. и –>), если они не являются членами другого класса. Функция friend объявляется с помощью класса, который предоставляет доступ. Объявление friend можно поместить в любом месте объявления класса. На него не влияют ключевые слова управления доступом.

25. В C++ существует возможность перегрузить не только функции, но и операции внутри класса, например, можно добиться того, чтобы операция * при работе с матрицами осуществляла умножение матриц, а при работе с комплексными числами — умножение комплексных чисел.

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

нельзя поменять приоритет операций;

нельзя изменить тип операции (из унарной операции нельзя сделать бинарную или наоборот);

перегруженная операция является членом класса и может использоваться только в выражениях с объектами своего класса;

нельзя создавать новые операции;

запрещено перегружать операции:. (доступ к членам класса), унарную операцию * (значение по адресу указателя),:: (расширение области видимости),?: (операция if);

допустима перегрузка следующих операций: +, -, *, /, %, =, <, >, +=, -=, *=, /=, &&, ||, ++, —, (), [], new, delete.

type operator symbols(type1 parametr)

{

операторы;

}

Здесь type — тип возвращаемого операцией значения, operator — служебное слово, symbols — перегруженная операция, type1 — тип второго операнда, первым операндом является экземпляр текущего класса, parametr — имя переменной второго операнда.

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

тип имя_функции (список_переменных)

{

тело_функции

}

Заголовок функции содержит:

тип возвращаемого функцией значения, он может быть любым; если функция не возвращает значения, указывают тип void;

имя_функции, с которым она будет вызываться;

список_переменных — перечень передаваемых в функцию аргументов, которые отделяются друг от друга запятыми; для каждой переменной из списка указывается тип и имя;

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

имя_функции (список_переменных);

27. Перегрузка функций в C++ используется, когда нужно сделать одно и то же действие с разными типами данных. Для примера, создадим простую функцию max, которая будет определять максимальное из двух целых чисел.

/* Функция max для целых чисел */

int max(int num1, int num2)

{

if (num1 > num2)

return num1;

return num2;

}

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

/* Функция max для чисел с плавающей запятой */

double max(double num1, double num2)

{

if (num1 > num2)

return num1;

return num2;

}

Теперь, когда мы будет вызывать функцию max с целыми параметрами, то вызовется первая функция. А если с дробными — то вторая. Например:

// Здесь будет использоваться первый вариант функции max

int imax = max(1, 10);

// А здесь - второй

double dmax = max(1.0, 20.0);

28. Для динамических данных память выделяется и освобождается в процессе выполнения программы, а не в момент ее запуска. Так, например, если в программе объявлен массив из 100 элементов, то при запуске программы резервируется память для всех ста элементов, даже если в процессе работы программы всего будут использованы первые 10 элементов массива. С другой стороны, при использовании в программе динамических типов память под них заранее не выделяется. Лишь когда поступают новые данные, вызывается специальная функция, которая выделяет память, куда эти данные записываются.

Тут появляется проблема. Для динамических типов данных не объявляются переменные, иначе память бы выделялась под переменные. Как тогда обращаться к данным, записанным неизвестно где в памяти? Можно ввести переменные-указатели и при выделении памяти записывать адрес этой памяти в указатели. Но мы же не знаем, сколько памяти потребуется в процессе выполнения. Сколько вводить указателей? Проблема решается путем использования структур. Допустим, мы пишем программу, позволяющую вводить данные на сотрудников организации. Количество сотрудников неизвестно. Можно было бы создать массив записей с запасом. Однако, если данных о каждом сотруднике много, то каждая запись занимает много памяти; получается, что мы будем расходовать много памяти в пустую, если сотрудников мало. Чтобы извлечь данные из такого агломерата данных, надо пройтись по ссылкам начиная с переменной-указателя. Т.е. первой мы извлечем последнюю записанную структуру. Потом предпоследнюю и постепенно будем двигаться к структуре, которая была создана первой во времени. Такой динамический тип данных называется стеком. Объекты извлекаются из стека таким образом, что первым выбирается тот, который был помещен последним. Стек — это не единственный способ организации динамических данных, но наиболее простой.

Если динамические данные больше не нужны, следует не забыть освободить память.

В языке программирования C выделение памяти в процессе выполнения программы можно организовать с помощью функций malloc() и calloc(), освобождение памяти с помощью free(). Объявление этих функций находится в заголовочных файлах stdlib.h и malloc.h. К исходному коду можно подключить любой из них.

Функция malloc() принимает в качестве параметра число, обозначающее объем памяти, который требуется выделить. Если свободная память есть, и malloc() удается ее "захватить", то функция возвращает указатель на нее. Этот указатель не имеет типа, поэтому программист самостоятельно должен привести его к требуемому в программе типу данных.

Функция free() принимает указатель, и освобождает память по адресу, который он содержит.

Преимущество этой программы в том, что память выделяется только под то количество структур, которое необходимо. Количество структур определяется в процессе выполнения программы. Однако приходится тратить память на указатели. Если структура содержит лишь одно значащее поле, как в примере выше, то такие затраты могут быть неоправданны. Проще было бы объявить массив с запасом. Но если структура сложная, содержит много полей, то организация динамических типов данных приносит существенный плюс.

 

<== предыдущая лекция | следующая лекция ==>
Виртуальные функции используются для ... | Предмет, метод конституционного права России, его место в системе национального права


Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных