Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

chast1

.pdf
Скачиваний:
15
Добавлен:
10.06.2015
Размер:
499.82 Кб
Скачать

Основы С++ - структурное программирование

___________________________________________________________________________________

1.Концепция типов данных.Классификация типовязыка С++.Спецификаторы типов.

__________________________________________________________________________________

Концепция типов данных

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

Врамках алгоритмического языка данных - это значения, которые могут принимать различные програмные объекты (константы и переменные).

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

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

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

-операции и функции которые можно применять к величинам данного типа.

Программист выбирает тип каждой величины (константы или переменной) в соответствии с её назначением в алгоритме решения той задачи длякоторой разрабатывается программа.

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

Типы языка С++ делятся набазовые (основные, стандартные) и производные.

Классификация типов языка С++

Средибазовых выделяют: -int (целый)

-char (символьный)

-wchar_t (широкосимвольный) -bool (логический)

-float (вещественный)

-double (вещественный с двойной точностью) -void (отсутствие значения)

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

С помощью спецификаторов типов стандарт языкаС++ расширяет переченьбазовых типов. Базовые типы еще называют простыми.

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

Спецификаторы типов.

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

-short (короткий) -long (длинный) -signed (знаковый)

-unsigned (беззнаковый)

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

____________________________________________________________________________________

2.Диапазоны значений базовых типов.Проблемысовмещения типа переменной сприсваиваемым значением

__________________________________________________________________________________

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

Диапазоны значения базовых типов для 32х разрядных IBM PC в т.3.1

Некоторые важные с точки зрения практики программирования особенности использования вещественных и целых значений в программе.

Для вещественных типов в таблице указаны минимальные абсолютные значения неравные 0. Это означает что если в процессе вычислений переменная типа float приобретает значение по модулю меньше чем 3ю4*10^-38 то реально в памяти сохранится 0. Вторая особенность связи с тем что на хранение мантиссы числа отводится строго определенное для данного типа количество бит,следовательно если вещественное число в десятичной системе счисления то при записи мантиссы мы можем указать только определенное количество значащих десятичных цифр задающие максимальную возможную точность изображения вещественного числа в компьютере.

В 32х разрядных IBM PC количество значащих десятичных цифр отображаемых в значении float не может превышать 7-8 цифр. Типы double 15-16 цифр,long double 19-20 цифр.

Таким образом если мы хотим в вычислительном процессе использовать числа для записи которых может понадобится до 15 значащих десятичных цифр,например число 123456789.0, то соответствующая переменная должнабыть определена как double. Если эту переменную отнести к типу float то значение будет округлено и храниться будет 123456792.0

При работе с целыми значениями нужно учитыватьчто язык С++ не даст средств контроля ошибок типа "переполнение значения", т.е. ошибок выхода за допустимый диапазон значения. Пусть х типа short int x=90000, тогда переменная получит не значение 90000, а то которое будет получено из двоичного представления путем отсечения двух старшихбайтов. При этом система не сообщит об ошибки.

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

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

____________________________________________________________________________________

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

____________________________________________________________________________________

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

Отличительной особенность переменных как непрерывной области памяти является возможность связывать с её именем значения, поэтому переменную часто определяют как пару "имя_значение".

Каждой переменной присущ ряд атрибутов: -тип переменной.

-Область действия имени переменной -область видимости имени переменной

-класс памяти переменной (этот атрибут влияет надругие атрибуты: на область видимости и продолжительность существования)

-продолжительность существования переменной

Краткая характеристика атрибутов:

-Тип переменной - это главный атрибут определяющий:

1.пребуемый для переменной объем памяти выделяемый ей при определении 2.совокупность операций которые могут совершаться над переменной 3.алгоритм интнрпретации двоичного кода при обращении к переменной

4.правила контроля типов (вводится в язык с целью обнаружениянедопустимого присваивания)

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

Различают локальные и глобальные переменные.

Если переменная определена внутриблока (в теле функции чаще всего) - то она локальная. Область её действия от точки определения до конца блока.

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

____________________________________________________________________________________

4.Область видимости имени переменной.

____________________________________________________________________________________

Область видимости имени переменной - это та часть программы в которой допустим обычный доступ к области памяти данной переменной. Чаще всего область видимости данной переменной совпадает с её областью действия. Исключения из этого правила появляются если внутри какого либо блока объявлена переменная с именем каторое уже было использованно как имя глобальной переменной или имя другой локальной переменной, но в блоке объемлющим данный блок.

Поясним все сказанное на примере 4.1

int i=1;//(1)определена и инициализированна глобальная переменная целого типа. int main()//(2) начало объявления глобальной функции программы

{//(3)

cout<<"Значение глобальной переменной i = "<<i<<endl;//(4)

int i=10;//(5) определение и инициализация локальной переменной. cout<<"Значение локальной переменной i ="<<i<<endl;//(6) {//(7)начало вложенного блока

int i=111;//(8)определена и инициализированна локальная переменная во вложенномблоке. cout<<"Значение вложенной локальной переменной i ="<<i<<endl;//(9)

cout<<"Значение глобальной переменной i ="<<::i<<endl;//(10) }//(11)окончание вложенного блока

cout<<"Значение глобальной переменной ::i ="<<endl;//(12) _getch();//(13)

return 0;//(14) }//(15) окончание main

Общие комментарии к программе:

1.В строке 1 определена глобальная переменная i область действия которой часть файла от точки определения до конца файла,в тоже время область видимости этой переменной это та же часть файла но за исключением частиблока (тело функции main) вкоторой область видимости глобальной переменной i отменена определенной локальной переменной i (5-15 строки), соответственно в строках 5-15 к глобольной переменной нельзя обратиться обычным способом, т.е. просто по её имени.

2.К глобальной переменной можно обратиться в той части программы которая входит в область действия но не видимости если воспользоваться операцией "указания области видимости" ::- эта операция позволяет получить из тела функции доступ к внешнему объекту (к глобальной переменной i (строка 10-12)

3.Область видимости локальной переменной так же может отличаться от её области действия. Например область действия локальной переменной i определенной в строке 5- это строки 5-15 но видна эта переменная не во всей области действия, исключение строки 8-11 в которых видимость этой локальной переменной отменяется действием другой локальной переменной с тем же именем i (8 строка). Таким образом область видимости вложена в область действия.

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

__________________________________________________________________________________

5.Класспамяти переменной.

___________________________________________________________________________________

-Следующий атрибут - класс памяти. Он определяетспособ размещения переменной в памяти компьютера и продолжительность её существования, кроме того класс памяти дополнительно регулирует область действия переменной.

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

Рассмотрим спецификаторы С++:

1.auto - используется явно или по умолчанию при определении локальной переменной, но не глобальной. Соответствующую переменную принято называть "автоматической". Под соответствующую переменную память выделяется в стэке при входе в блок,а инициализация переменной, если она задана в определении,проводится при выполнении оператора определения. Освобождение памяти выполняется при выходе из блока. Соответственно время жизни такой переменной от момента срабатывания оператора до момента выхода из блока.

Говорят что переменная определенная явно или неявно с auto имеет автоматическую память и локальную продолжительность существования.

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

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

3.staticможет использоваться только явно при определении локальной или глобальной переменной.Он задает внутренний тип компоновки и статическую продолжительность существования.

"Внутренний тип компоновки"- данные переменной связаны с тем файлом, в котором она определена,т.е. внутри файла. Если это глобальная переменная,то область её действия - только данный файл, её нельзя будет увидеть в другом файле. Если попытаться применить к ней спецификатор extern, то возникнет ошибка в периоде компиляции. Если переменная локальная, то её область действия будет как и без спецификатора static.

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

4.extern - может использоваться только явно и при объявлении глобальной переменной. Он задает внешний тип компоновки и статическую продолжительность существования.

"Внешний тип компоновки"- означает,что глобальная переменная определена в другом файле, либо в данном файле но далее по тексту файла.

Extern используется для расширения области действия глобальной переменной. Дополнительная область действия простирается от точки объявления до конца файла. Использование extern нельзя сочетать с инициализацией переменной. Если инициализацию задать то спецификатор extern будет игнорироваться. При объявлении переменной со спецификатором extern новая переменная не создается, соответственно область памяти под неё не выделяется. Этот спецификатор только разрешает доступ к уже созданной переменной определенной в другом месте программы.

Если глобальная переменная определена безспецификаторов то по умолчанию она имеет статическую продолжительность существования и внешний типкомпоновки, т.е. в другом файле доступ к ней можно получить с помощью extern.

Атрибут продолжительности существования переменной в С++ может иметь 3 значения: -статическое -локальное -динамическое

первые 2 рассмотрели выше.

___________________________________________________________________________________

6.Определение и объявление переменных.Модификатор const.Инициализация переменных.

__________________________________________________________________________________

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

Определение объекта,в том числе переменной - это оперптор который выделяет объекту память и устанавливает приуцщие объекта атрибуты. Любой объект программы должен иметь одно единственное определение.

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

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

Следует четко представлять, что понятие "объявление" в отличае от "определения" применимо только к глобальным переменным,т.е. глобальную переменную можно и определить и объявить, а локальную только определить.

Для глобальной переменной объявление формируется с помощью спецификатора extern.

Определение любого объекта в программе делается только 1 раз, а количество объявлений одного и того же объекта 0 или более раз, сколько выберет программист.

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

используется как собирательное для "определения" и "объявления". Мы можем вместо "определение" использовать "декларация".

Синтаксис определения переменной задается следующей формой: [S][m]<тип><имя1>[<инициализация1>]<имя2>[<инициализация2>] []-указывает на необязательность соответствующей части конструкции.

S-спецификатор класса памяти m-модификатор

В С++ допускается 2 модификатора: -const

-volatile

<тип>-тип переменной <имя>-идентификатор(имя переменной)

<инициализатор>-инициализатор определяющий на этапе компеляции начальное значение определяемой переменной.

Модификатор const - значение соответствующей переменнойнельзя менять. Такую переменную называют именованной константой. Если определение задаетконстанту,то в определении обязательно долженбыть инициализатор.

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

Const и volatile могут использоваться в одном определении одновременно. Это означает что значение переменной не может изменяться самой программой,но может быть подвержена внешним воздействиям.

Инициализатор может задаваться в двух формах:

-=<значение>

-(значение) функциональная

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

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

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

Примеры определения переменных:

-int m;//если это глобальная переменная, то она по умолчанию инициализируется 0,если локальная то инициализация не проводится

-int k=10;//инициализированная переменная

-const char e='d';//инициализированная именованная константа типа char -float x(45.76);//именованная вещественная переменная

<значение> в инициализаторе может задаваться нетолько константой но и выражением в котором используется константа и другие ранее инициализированные переменные

-int i=k*11;

Рассмотрим вопрос о краткости выполнения операции инициализации переменной в ходе работы программы.

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

Пример функции в теле которой определены две локальные переменные: int F1()

{

int v1=10 static int v2=20

...

}

Переменная v1 будет инициализирована при каждом вызове функции F1. Переменная v2 инициализированная числом 20 только 1 раз, во время первого вызовафункции F1 и она будет сохранять свое текущее значение которое сложилось к концу работы функции данного вызова, до следующего вызова функции.

___________________________________________________________________________________

7.Унарные операции.

______________________________________________________________________________

& - операция получения адреса операнда * - операция обращения по адресу, т.е. раскрытие адреса,иначе, это операция разыменования, т.е. доступа

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

+ - унарный плюс, введен для симметрии с унарным минусом.

~ - поразрядное инвертирование внутреннего двоичного кода целочисленного аргумента,побитовое отрицание ! - логическое отрицание (не) значения операнда. Поскольку в С++ логические значения обозначаются

целыми числами (0-false,не0-true),то при действииэтой операции на неравный 0 операнд операция возвращает 0, а при действии на 0 она возвращает 1.

Специфическими для С++ и С являются унарные операции инкремента и декремента.Существует 2 формы их записи:

-префиксная (знак операции перед операндом) -постфиксная (знак операции после операнда)

Эти операции имеют следующие свойства:

++ инкремент, т.е. увеличивает значение операнда на 1

Впрефиксной форме операция увеличивает значение операнда на 1 до его использования в выражении Например

i=1 k=10+ ++i;

тогда i=2, а k=12

Впостфиксной форме увеличивает значение операнда после использования аперанда в выражении. i=1

k=10+ i++; тогда i=2,a k=11

-- операция декремент уменьшает значение операнда на 1. Логика работы декремента аналогична логике работы инкремента.

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

sizeof - возможны 3 формы этой операции: -sizeof(<имя типа>) - имя типа всегда в круглых скобках

-sizeof(<имя переменной>) - здесь круглые скобки не обязательны -sizeof(<выражение>) - круглые скобки обязательны

Операция возвращает значение объема памяти необходимого для хранения соответственно значение данного типа, значение переменной или значениявыражения

cout<<sizeof(int)<<endl;

__//__ (double) __//__; __//__ (1.34) __//__;

____________________________________________________________________________________

8.Бинарные арифметическиеоперации.Операции сдвига ипоразрядные логические операции.

_______________________________________________________________________________

Арифметические операции

В С++ имеется стандартный набор арифметическихоперация. + (бинарный плюс) суммирует 2 арифметических оператора

- (бинарный минус) вычитает из первого арифметического операнда второй * (умножение) умножает первый на второй

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

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

Например для какого то компилятора возможно

11%2=1 (-11)%2=-1 11%(-2)=1 (-11)%(-2)=(-1)

int x; double y; x=+5+3;//x=8

y=7/3;//y=2.0 дробная часть отброшена,но результат вещественный y=7./3;//y=2.333...

y=-7/3;//y=-2.0вещественное

x=7/3;//x=2целое значение. В данном случае при передаче результата расчета в переменную х произойдет преобразование типов данных.

x=7%3;//x=1

y=7%3;//y=1.0

Операции сдвига и поразрядные логические операции

Операции сдвига определена для целочисленных операндов. Формат выражения с операцией сдвига: <левый операнд><знак операции><правый операнд>

В С++ определены следующие сдвиговые операции:

<< - сдвиг влево битового представления значения левого операнда на количество разрядов равное значению правого операнда

>> - сдвиг влево битового представления левого операнда -//-

i=1;

k=i<<1;//k=2 01 - 10 m=5;

q=m>>1;//q=2 10110

По определению сдвиговые операции обладают следующей особенностью: Сдвиг влево на n разрядов равносилен умножениючисла на 2^n.

Сдвиг вправо равносилен делению на 2^n с отбрасываниемдробнойчасти результата.

Поразрядные логические операции так же определены только для целочисленных операндов.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]