Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

алгоритмизация и программирование 3 глава




Комментарии в программе на С++ либо начинаются с двух символов «прямая косая черта» (//однострочный комментарий) и заканчивается символом перехода на новую строку, либо заключается между символами – скобками /*многострочный комментарий*/. Внутри комментария можно использовать любые допустимые на данном компьютере символы, а не только символы из алфавита языка С++, поскольку компилятор комментарии игнорирует. Вложенные комментарии – скобки стандартом не допускаются, хотя в некоторых компиляторах разрешены.

2.3. Данные и способы их организации

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

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

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

Тип данных однозначно определяет:

1. Формат представления данных в памяти компьютера.

2. Множество допустимых значений, принимаемое переменной или константой, принадлежащей к выбранному типу.

3. Множество допустимых действий применимых к этому типу (операции и функции).

Например, целые и вещественные числа, занимают одинаковый объем памяти (long int и float), но имеют разные диапазоны возможных значений.

Таблица 2 – Классификация типов данных C++

Базовые Определяемые программистом
Простые (скалярные) Логический (bool) Целые (short int, int, long int) Вещественные (float, double, long double) Символьные (char, wchar_t) Пустой тип (void) Простые Составные
Перечисления Указатели Ссылки Массивы Структуры Объединения Классы

Константы в языке Си++

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

Например:

const int k=1; // целая именованная константа

const float Pi = 3.1415926, Eps = 0.1e-5; // действительные константы

const char a = 'а'; // символьная константа

enum DAY {SUNDAY, MONDAY, TUESDAY, WEDNESDAY,

THURSDAY, FRIDAY, SATURDAY}; // перечисление

char *pc = nullptr; // нулевой указатель

Порядок объявления и инициализации переменных

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

имя_типа имя_переменной;

При описании можно присвоить переменной начальное значение, это называется инициализацией.

Например:

int d = 5; // Целочисленная переменная d проинициализирована значением 5

float b; // Объявлена вещественная переменная b

char s = '+'; /* Переменная s объявлена как символьная и проинициализирована значением '+'*/

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

int a, b, c; // Целые со знаком

char ch, sh; // Однобайтовые символьные

long l, m, k; // Длинные целые [-2147483648 – 2147483647]

float x, y, z; // Вещественные

long double u,v,w; // Длинные вещественные с двойной точностью

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

- имя;

- тип;

- значение (не обязательно);

- область видимости.

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

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

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

Область видимости. Переменные в языке Си классифицируются по области видимости и делятся на две категории: локальные и глобальные.

Локальная переменная – это такая переменная, которая объявлена внутри какого-либо блока (под блоком в языке Си понимается последовательность операторов, заключенная в фигурные скобки). Память под эту переменную выделяется в момент выполнения оператора ее объявления. По завершении работы блока эта переменная разрушается, а занимаемая ей память высвобождается. То есть, время жизни такой переменной ограничено тем блоком, в котором она объявлена.

Глобальная переменная – это такая переменная, которая объявлена вне любого блока. Следовательно, время ее жизни – время жизни самой программы.

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

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

- выбрать имя переменной (описать идентификатор);

- определить исходя из необходимого диапазона представления чисел тип переменной;

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

- обнулить или проинициализировать переменную начальным значением.

2.4. Стандартные простые типы данных

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

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

- int (целый);

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

- wchar_t (расширенный символьный);

- bool (логический);

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

- double (вещественный с двойной точностью).

Первые четыре типа называют целочисленными (целыми), последние два – типами с плавающей точкой. Код, который формирует компилятор для обработки целых величин, отличается от кода для величин с плавающей точкой.

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


- short (короткий);

- long (длинный);

- signed (знаковый);

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


По умолчанию все целочисленные типы считаются знаковыми, то есть спецификатор signed можно опускать.

Базовыми в системе типов языка С++ являются простые типы, представленные в следующей таблице:

Таблица 3 – Стандартные простые типы данных

Простые типы Тип Название Размер, байт Диапазон
Логический bool булевское (логическое)   false, true (0, 1)
Символьный signed char символ   -128 … 127
unsigned char беззнаковый символьный   набор допустимых символов с кодами 0 … 255
Целые short int короткое целое (short)   -32 768... 32 767 (-215.. 215 - 1)
unsigned short int беззнаковое короткое целое (слово)   0... 65 535 (0.. 216 - 1)
long int длинное целое (long)   -2 147 483 648 … 2 147 483 647
unsigned long int беззнаковое длинное целое   0 … 4294967295
Вещественные float вещественный   3.4e-38 … 3.4e+38
double двойной точности   1.7e-308 … 1.7e+308
long double расширенный   3.4e-4932 … 3.4e+4923

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

В стандарте ANSI диапазоны значений для основных типов не задаются, определяются только соотношения между их размерами, например:

sizeof (float) <=sizeof(double) <=sizeof(long double)

sizeof (char)<=sizeof(short) <=sizeof(int)<=sizeof(long)

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

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

1. Булевский (логический) тип обозначается стандартным идентификатором bool. В С++ имеются две константы булевской типа, которые обозначаются также посредством стандартных идентификаторов: true (истина) и false (ложь). Внутренняя форма представления значения false-0 (нуль). Любое другое значение интерпретируется как true. При преобразовании к целому типу true имеет значение 1. Над значениями булевского типа допустимы операции сравнения, причем, считается, что false < true. Кроме того, имеются четыре, стандартные логические операции, обозначаемые символами && (конъюнкция), || (дизъюнкция) и! (не – логическое отрицание). По приоритету эти операции имеют последовательность! - && - ||. Значения булевского типа занимают один байт памяти.

2. Символьный тип имеет стандартный идентификатор char. Значениями переменных этого типа являются символы из множества АSCII. Это множество состоит 256 различных символов, упорядоченных определенным образом, и содержит символы заглавных и строчных букв, цифр и различных других символов, включая специальные управляющие символы. Если символьное значение имеет графическое изображение, оно представляется соответствующим знаком, заключенным в апострофы, например: '*', '1', ';'. Тип char, как другие целые типы, может быть со знаком или без знака. Величины типа char применяются также для хранения целых чисел, не превышающих границы указанных диапазонов (см. табл. 3).

Расширенный символьный тип (wchar_t) предназначен для работы с набором символов, для кодировки которых недостаточно 1 байта, например, Unicode. Размер этого типа зависит от реализации; как правило, он соответствует типу short. Строковые константы типа wchar_t записываются с префиксом L, например, L”Gates”.

3. Целые типы – эта группа типов обозначает множества целых чисел в различных диапазонах. В С++ имеется пять целых типов, различающихся диапазоном значений и объемом занимаемой оперативной памяти. Целые типы обозначаются идентификаторами int, short int, long int, unsigned short int, unsigned long int: их характеристики приведены в таблице 3. Размер типа int не определяется стандартом, а зависит от компьютера, компилятора и операционной системы. Для 16-разрядного процессора под величины этого типа отводится 2 байта, для 32-разрядного – 4 байта. Поэтому при написании программ, переносимых на различные платформы, нельзя делать предположений о размере типа int. Для его получения необходимо пользоваться операцией sizeof, результатом которой является размер типа в байтах.

Число относится к целому типу тогда и только тогда, когда в его записи не содержится ни десятичной точки, ни признака порядка e.

Константам, встречающимся в программе, приписывается тот или иной тип в соответствии с их видом. Если этот тип по каким- либо причинам не устраивает программиста, он может явно указать требуемый тип с помощью суффиксов L, l (long) и U, u (unsigned). Например, константа 32L будет иметь тип long и занимать 4 байта. Можно использовать суффиксы L и U одновременно, например, 0х22UL или 05Lu.

Над целыми значениями допустимы четыре арифметических действия, имеющие привычный смысл и обозначаемые соответственно символами: + – сложение, - – вычитание, * – умножение, / – целая часть от деления. Кроме того, в С++ можно использовать еще унарные операции (++, --, унарный минус и плюс, …), операцию "типа деления": % – нахождение остатка от деления, операции присваивания (=, *=, /=,%=, +=, -=). Все приведенные операции при целых операндах дают целый результат. Также над целочисленными данными допустимо выполнять битовые, логические операции и операции сравнения.

4. Вещественные типы - эта группа типов обозначает множества вещественных значений в различных диапазонах. C++ поддерживает три вещественных типа, которые обозначаются стандартными идентификаторами float, double, long double (см. табл. 3). Вещественные числа могут изображаться в двух формах: в форме с фиксированной точкой (целая и дробная части отделяются друг от друга точкой, например, -19.324, 0.1281) и в форме с плавающей точкой (<мантисса>e<порядок>, например, 16.2e21, 2e-48).

Константы с плавающей точкой имеют по умолчанию тип double. Можно явно указать тип константы с помощью суффиксов F, f (float) и L, l (long). Например, константа 2Е+6L будет иметь тип long double, а константа 1.82f- тип float.

Над числами вещественных типов допустимы четыре арифметические операции: сложение, вычитание, умножение и деление; операции присваивания и сравнения.

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

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

2.5. Структура программы

Программа на языке С++ состоит из функций, описаний и директив препроцессора. Одна из функций должна иметь имя main. Выполнение программы начинается с первого оператора этой функции.

Формат простейшего определения функции:

тип_возвращаемого_значения имя_функции ([параметры]) // заголовок функции

{

// Блок тела функции:

// определения объектов;

// исполняемые операторы;

// return выражение; // если функция возвращает значение.

}

Как правило, функция используется для вычисления какого-либо значения, поэтому перед именем функции указывается его тип (тип возвращаемого результата). Если функция не должна возвращать значение, указывается тип void. Тело функции является блоком и, следовательно, заключается в фигурные скобки. Любая функция, кроме main, вызывается из другой функции. Примером функций являются библиотечные функции, например, sin (x), fabs (a).

Пример структуры простейшей программы Текст программы, состоящей из одной функции и содержащей компоненты, которые почти все могут отсутствовать
1. Препроцессорные директивы #include <iostream> /* подключение директивы (заголовочного файла) для организации ввода-вывода в С++ */
2. Описания using namespace std; // описание пространства имен std
3. Определение главной функции int main() // заголовок главной функции { // Блок тела функции // здесь находится программный код }

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

Текст программы на С++ обладает структурой. Общие принципы, позволяющие написать синтаксически правильную программу, таковы:

1. Каждый оператор заканчивается знаком «;». Обычная ошибка начинающего – это знак «;», завершающий заголовки функций или операторов цикла. В первом случае синтаксическая ошибка распознается как отсутствие тела функции, во втором случае телом цикла является пустой оператор, что синтаксической ошибкой не является, и программа выполняется.

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

3. Чтобы вызов функции мог быть выполнен, функция должна быть определена, т. е. описаны действия, которые она осуществляет.

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

- объявить и проинициализировать входные и выходные переменные;

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

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

Пример структуры программы, содержащей 2 функции: main и mysum.

  Зона комментариев // моя первая программа
  Зона директив препроцессора #include <iostream.h> #include <conio.h>
  Зона объявления прототипов пользовательских функций и глобальных переменных и структур данных int a = 10; int mysum(int x);
  ТОЧКА ВХОДА В ПРОГРАММУ Зона функции main() int main() { int b = 15, c; c = mysum(b); cout<<c; _getch(); }
  Зона определения пользовательских функций int mysum(int x) { int z = x + a; return z; }

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

§ подключение заголовочных файлов библиотек;

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

§ заголовок главной функции;

§ определение главной функции – блок, содержащий:

- объявление локальных переменных и констант и их инициализацию (присвоение начальных значений);

- ввод исходных данных (диалог с пользователем);

- обработка – обращение к функциям, вычисление выражений, выполнение операторов;

- вывод результата;

- возвращение кода завершения главной функции;

§ определения пользовательских вспомогательных функций и методов классов; для каждой функции после заголовка размещается блок, содержащий:

§ объявление локальных переменных и их инициализацию;

§ обработку формальных параметров с использованием локальных переменных;

§ возвращение результата.

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

Правила оформления текста программы, направленные на облегчение понимания смысла и повышение наглядности, таковы:

- разделять логические части программы пустыми строками;

- разделять операнды и операции пробелами;

- для каждой фигурной скобки отводить отдельную строку;

- в каждой строке должно быть, как правило, не более одного оператора;

- ограничивать длину строки 60-70 символами;

- отступами слева отражать вложенность операторов и блоков;

- длинные операторы располагать в нескольких строках;

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

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

Конечно, эти правила нужно использовать совместно с правилами именования элементов программы и комментирования текста программы:

- комментарии в тексте необходимы;

- имена объектов программы выбираются осмысленно. Каждое имя подчеркивает назначение и логику объекта, например, имена библиотечных функций sin, abs, printf и прочих говорят сами за себя. Имена объектов, введенные программистом, подчеркивают их абстрактный смысл, например, Count, Square, Point.x, Point.y и так далее.

2.6. Операторы

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

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

Среди исполняемых операторов можно выделить:

- простые операторы (оператор-выражение, операторы передачи управления);

- составные операторы (составной оператор, блок)

- структурированные операторы (условный, выбора, цикла).

Рассмотрим простые операторы

Оператор «выражение»

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

Примеры:

x ++; // выражение – оператор; выполняется операция инкремента

c = a * 1.5; // выражение с операцией присваивания

a *= b + c; // выполняется умножение с присваиванием: a = a * (b + c)

fun(i, k); // выполняется вызов функции

Оператора присваивания в языке С++ нет, его заменяет выражение, в составе которого есть операция присваивания.

Общий вид:

идентификатор = выражение;

Пример: x = y + 4; // выражение с операцией присваивания

Выполняется в два этапа:

а) вычисляется значение выражения, стоящего в правой части от знака присваивания;

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

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

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

Явное преобразование типов выполняется при присваивании вида:

имя = (тип) выражение;

Например:

int a = 5, b = 2;

float c;

с = a/b;

Хочется думать, что значение с будет равно 2.5, ведь оно вещественное, но порядок операций таков, что деление старше присваивания, и оно выполняется с операндами целого типа, и его результат равен 2, то есть приведение типа будет выполнено только при присваивании.

Для явного преобразования типов используется известный прием:

c = (float) a/(float) b; // c = 2.5

Операция присваивания правоассоциативна, т.е. вычисления выполняются справа налево, поэтому допускается запись цепочек присваиваний, например:

x = y = z = 1; // Каждая переменная будет равна 1.

В сложных операциях присваивания (+=, *=, /= и т п.) при вычислении выражения, стоящего в правой части, используется и L-значение из левой части. Например, при сложении с присваиванием ко второму операнду прибавляется первый, и результат записывается в первый операнд, то есть выражение a += b является более компактной записью выражения a = a + b.

Еще один вид операторов, который можно отнести к операторам-выражениям, это оператор обращения к функции (вызов функции). Его операндам являются параметры функции.

Формат оператора:

имя функции ([список фактических параметров] – может отсутствовать);

Например:

scanf ("%d%f", &my_int, & my_float); // ввод данных

printf ("Целое = %d, Вещественное = %f\n", my_int, my_float) // вывод

Пробелы в строке текста являются значащими, то есть, если ввести целое 5 и дробное 9.9, то строка вывода будет иметь вид:

Целое = 5, Вещественное = 9.900000

Операторы передачи управления рассмотрим позже (п. 3.6, п. 4.1)

2.7. Организация ввода/вывода данных

Ввести данное – означает присвоить произвольное значение переменной во время выполнения программы. Вывести данное – означает напечатать на экране значение переменной при выполнении программы.

В С++ нет встроенных средств ввода/вывода – он осуществляется с помощью функций, типов и объектов, содержащихся в стандартных библиотеках. Используется два способа: функции, унаследованные из языка С, и объекты С++.


Организация ввода/вывода в стиле С

Простейший из способов ввода и вывода (обмена) данных – это форматированный, с определением правил размещения данных во входном – выходном потоке. Для реализации такого обмена необходима библиотека stdio.h (standart input output library), которая подключается к программе директивой #include <stdio.h>

Для ввода значения данного с клавиатуры (с эхоповтором на экране) используется функция scanf, синтаксис которой:

scanf ("форматная строка", список_ввода);

Здесь «список ввода» – имена переменных, значения которых будут введены с клавиатуры при выполнении функции scanf. Имена переменных предваряются символом &, который является признаком адресной операции, и означает, что введенное значение пересылается по адресу, определенному именем переменной. При вводе данные отделяются пробелами, или Enter’ом.

Для вывода значения данного на экран используется функция printf, синтаксис которой:

printf ("форматная строка", список_вывода);

Здесь «список вывода» – список имен переменных и выражений (в том числе констант), значения которых появятся на экране при выполнении функции printf.

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

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...