Основы C++

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

Рубрика Программирование, компьютеры и кибернетика
Вид лабораторная работа
Язык русский
Дата добавления 11.02.2015
Размер файла 189,9 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Размещено на http://www.allbest.ru/

61

ВВЕДЕНИЕ

Наиболее важными вехами последних 15-20 лет в создании программ на языках высокого уровня являются методологии структурного и объектно-ориентированного программирования. Параллельно с ними сравнительно давно используется метод «автоматного» программирования, позволяющий в основу проектирования программы заложить алгоритм - конечный автомат в виде диаграммы состояний или таблицы последовательных переходов и выходов. В отличие от традиционных алгоритмов, включающих два вида компонент: условие и действие, конечный автомат дополнительно включает такую компоненту, как состояние.

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

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

1. ОСНОВЫ АЛГОРИТМИЗАЦИИ

1.1 Алгоритм и программа

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

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

Сначала всегда разрабатывается алгоритм действий, а потом он записывается на одном из языков программирования. Текст программы обрабатывается специальными служебными программами - трансляторами. Языки программирования - это искусственные языки. От естественных языков они отличаются ограниченным числом «слов» и очень строгими правилами записи команд (операторов). Совокупность этих требований образует синтаксис языка программирования, а смысл каждой конструкции - его семантику.

1.2 Свойства алгоритма

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

2. Результативность: алгоритм должен приводить к получению результата за конкретное число шагов (при делении 1 на 3 получается периодическая дробь 0,3333(3), для достижения конечного результата надо оговорить точность получения этой дроби, например, до 4 знака после запятой).

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

4. Дискретность - процесс должен быть описан с помощью неделимых операций, выполняемых на каждом шаге (т. е. шаги нельзя разделить на более мелкие шаги).

Алгоритмы можно представить в следующих формах:

1) словесное описание алгоритма,

2) графическое описание алгоритма,

3) с помощью алгоритмического языка программирования.

1.3 Компиляторы и интерпретаторы

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

1.4 Языки программирования

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

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

2. ОСНОВНЫЕ ПОНЯТИЯ ЯЗЫКА СИ

2.1 Структура программы на Си

Директивы препроцессора управляют преобразованием текста программы до ее компиляции. Исходная программа, подготовленная на Си в виде текстового файла, проходит 3 этапа обработки:

1) препроцессорное преобразование текста;

2) компиляция;

3) компоновка (редактирование связей или сборка).

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

1) #define - указывает правила замены в тексте.

#define ZERO 0.0 - означает, что каждое использование в программе имени ZERO будет заменяться на 0.0.

2) #include <имя заголовочного файла> - предназначена для включения в текст программы заголовочных файлов, поставляемых вместе со стандартными библиотеками. Каждая библиотечная функция Си имеет соответствующее описание в одном из заголовочных файлов. Список стандартных заголовочных файлов определен стандартом языка. Употребление директивы include не подключает соответствующую стандартную библиотеку, а только позволяет вставить в текст программы описания из указанного заголовочного файла. Подключение кодов библиотеки осуществляется на этапе компоновки, т.е. после компиляции. Хотя в заголовочных файлах содержатся все описания стандартных функций, в код программы включаются только те функции, которые используются в программе.

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

Некоторые заголовочные файлы:

· ALLOC.H - функции для работы с памятью

· CONIO.H - функции консольного ввода-вывода

· DIR.H - работа с файлами и каталогами

· IO.H - функции для работы с файлами

· IOSTREAM.H - библиотека Си++ потоков ввода/вывода

· COMPLEX.H, MATH.H - математические функции

· STDIO.H - стандартная библиотека ввода-вывода

· STDLIB.H - библиотека стандартных функций

· STRING.H - функции для работы со строками

· TIME.H - функции для работы с датой и временем

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

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

тип <имя_функции> (список параметров);

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

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

Определения вводят объекты (объект - это именованная область памяти, частный случай объекта - переменная), необходимые для представления в программе обрабатываемых данных. Примерами являются:

float x; //объявление переменной

int y = 10; // объявление переменной и ее инициализация

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

Операторы определяют действия программы на каждом шаге ее исполнения.

Пример программы печати строки на Си:

#include <stdio.h>

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

void main(void)

{ //начало

printf (“Hello! “);

//вызов стандартной функции printf( ) из заголовочного файла stdio.h, //выводящей на экран информацию

} //конец

2.2 Типы данных

Типы данных характеризуют размер области памяти, которую будет занимать данное.

Тип данных

Определение

Размер, бит

char

символьный

8

int

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

16

float

с плавающей точкой одинарной точности

32

double

с плавающей точкой двойной точности

64

long double

с плавающей точкой максимальной точности

80

long

целый увеличенной длины

32

short int (short)

целый уменьшенной длины

16

signed int (signed)

знаковый, то есть целое со знаком

16

unsigned int (unsigned)

беззнаковый, то есть целое без знака

16

void

отсутствие значения

2.3 Переменные

Переменная - это именованная область памяти. Определение переменных: тип список_имен_переменных, где имена переменных - произвольно выбранная последовательность символов, разделенных запятыми, тип - тип данных (int, double, ...). Все переменные должны быть описаны до их использования.

Например:

char symbol, l;

int n9, number;

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

auto - автоматиче ская,

extern - внешняя,

static - статическая,

register - регистровая.

Например:

static int a;

register int b;

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

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

Автоматические переменные хранятся в оперативной памяти машины. Регистровые (register) переменные хранятся в регистрах процессора. Доступ к переменным, хранящимся в регистровой памяти, гораздо быстрее, чем к тем, которые хранятся в оперативной памяти. В остальном автоматические и регистровые переменные аналогичны. Регистровая память процессора невелика, и если доступных регистров нет, то переменная становится автоматической.

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

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

После того, как переменная объявлена, ей рано или поздно будет присвоено значение. Если явная инициализация (определение значений) отсутствует, то внешним и статическим переменным присваивается значение нуль; автоматические и регистровые переменные имеют в этом случае неопределенные значения.

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

2.4 Константы

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

Символьная константа

Символьная константа - это один символ, заключенный в одинарные кавычки: char 'x'. Некоторые символы могут быть представлены как символьные константы с помощью управляющих последовательностей.

'\n'

новая строка

'\t'

табуляция

'\0'

нулевой символ

'\\'

обратная косая черта

'\''

одинарная кавычка

'\r'

возврат каретки (курсора) к началу строки

'\a'

сигнал-звонок

'\"'

кавычка

'\b'

возврат на одну позицию

'\f'

перевод (прогон) страницы

'\v'

вертикальная табуляция

'\?'

знак вопроса

Целые и вещественные константы

Целые константы бывают: десятичные, восьмеричные (последовательность цифр не содержит цифр старше 7 и начинается с 0) и шестнадцатеричные (последовательность шестнадцатеричных цифр, перед которой записаны символы 0x или 0X).

Вещественные константы состоят из целой части, десятичной точки, дробной части и показателя десятичной степени "e" или "E". Целая или дробная части, показатель степени или десятичная точка могут опускаться. Например:

44. 3.14 44е0 .14 0.0

Константы перечислимого типа

Константы могут вводиться с помощью перечисления:

enum тип перечисления {список именованных констант}

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

имя константы = значение константы.

Константное выражение

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

#define maxline 1000

char line[maxline + 1];

или

seconds = 60 * 60 * hours;

Строковая константа

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

"i am a string"

Кавычки не являются частью строки, компилятор автоматически помещает в конец каждой строки нуль-символ '\0', следовательно для хранения строки требуется на одну ячейку памяти больше.

Именованные константы

Вводятся как

const тип имя константы = значение константы;

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

Например

const double E = 2.72;

const f = 7;

(по умолчанию присваивается тип int)

2.5 Операции

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

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

- вычитание и унарный минус;

+ сложение;

* умножение;

/ деление (при делении целых переменных остаток отбрасывается);

% деление по модулю (дает остаток от целочисленного деления);

++ увеличение на единицу (increment);

- - уменьшение на единицу (decrement).

Старшинство арифметических операций следующее:

++, - -

- (унарный минус)

*, /, %

+, -

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

Операции отношения и логические операции

Операциями отношения являются

=>, >, =<, <

Все они имеют одинаковое старшинство. Непосредственно за ними по уровню старшинства следуют операции равенства и неравенства:

==, !=,

которые тоже имеют одинаковое старшинство. Операции отношения по старшинству ниже арифметических операций, так что выражения типа i < lim-1 понимаются как i < (lim-1), как и предполагается.

Логические операции && (логическое умножение), || (логическое сложение) и ! (логическое отрицание) более интересны. Выражения, связанные такими операциями, вычисляются слева направо, причем их рассмотрение прекращается сразу же, как только становится ясно, будет ли результат истиной или ложью. Учет этих свойств очень существенен для написания правильно работающих программ. Рассмотрим, например, оператор цикла в считывающей строку функции getline.

for (i = 0; i < lim - 1 && (с = getchar()) != '\n' && c ! = EOF; ++i)

s[i] = c;

Перед считыванием очередного символа в массив s необходимо осуществить проверку трех условий: имеется ли еще место в массиве s, не является ли символ концом строки, не является ли символ концом файла. Наличие свободного места i < lim-1 должно проверяться первым, в случае невыполнения данного условия считывание следующего символа и проверка остальных условий производиться не будут.

Каждое условное выражение проверяется, истинно оно или ложно. В языке Си нет логического (boolean) типа. Поэтому результатом логического выражения является целочисленное арифметическое значение. В языке Си «истинно» - это не ненулевая величина, «ложно» - это нуль. Так, в приведенном примере при отсутствии места в массиве первое условное выражение будет равно нулю, следовательно логическое произведение трех условий также обратится в нуль независимо от выполнения остальных двух условий.

Операция условие ?:

Эта операция имеет вид:

выр1 ? выр2 : выр3

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

Если значение выр1 равно нулю, то вычисляется выр3 и его значение будет результатом операции. В любом случае вычисляется только одно из выражений: выр2 или выр3. Например, эту операцию удобно применять для нахождения наибольшего из двух чисел x и y:

max = (x > y) ? x : y ;

Преобразование типов

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

1. Все переменные типа char и short int преобразуются в int, все переменные типа float преобразуются в double.

2. Для любой пары операндов: если один из операндов long double, то и другой преобразуется в long double; если один из операндов double, то и другой преобразуется в double; если один из операндов long, то и другой преобразуется в long; если один из операндов unsigned, то и другой преобразуется в unsigned.

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

Тип результата вычисления выражения можно изменить, используя конструкцию «приведение», имеющую следующий вид:

(тип) выражение,

где «тип» - один из стандартных типов данных языка Си.

Например, если необходимо, чтобы результат деления переменной х типа int на 2 был типа float, записываем

(float) x/2;

2.6 Ввод и вывод данных

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

Для ввода/вывода данных в стиле Си используются функции, которые описываются в библиотечном файле stdio.h.

1) printf (форматная строка, список аргументов);

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

printf (“Значение числа Пи равно %f\n”, pi);

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

Каждому аргументу соответствует своя спецификация преобразования:

%d, %i - десятичное целое число;

%f - число с плавающей точкой;

%e, %E - число с плавающей точкой в экспоненциальной форме;

%u - десятичное число в беззнаковой форме;

%c - символ;

%s - строка.

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

\n - новая строка;

\t - табуляция;

\a - звуковой сигнал и др.

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

printf (“%05d”, 15)

даст результат 00015.

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

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

2) scanf (форматная строка, список аргументов);

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

Например:

scanf(“ %d%f ”, &x,&y);

При использовании библиотеки классов Си++ используется библиотечный файл iostream.h, в котором определены стандартные потоки ввода данных с клавиатуры cin и вывода данных на экран дисплея cout, а также соответствующие операции: << - операция записи данных в поток; >> - операция чтения данных из потока.

Например:

#include <iostream.h>;

. . . . . . . . .

cout << “\nВведите количество элементов: ”;

cin >> n;

3. ОСНОВНЫЕ ОПЕРАТОРЫ ЯЗЫКА СИ

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

3.1 Базовые конструкции структурного программирования

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

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

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

Цикл задает многократное выполнение оператора.

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

- составные операторы;

- операторы выбора;

- операторы циклов;

- операторы перехода.

3.2 Составные операторы

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

Примеры:

{

n++;

summa+=n;

} //это составной оператор

{

int n = 0;

n++;

summa+=n;

} //это блок

3.3 Операторы выбора

Операторы выбора - это условный оператор и переключатель.

1. Условный оператор имеет полную и сокращенную форму.

if (выражение-условие) оператор; //сокращенная форма

В качестве выражения-условия могут использоваться арифметическое выражение, отношение и логическое выражение. Если значение выражения-условия отлично от нуля (т. е. истинно), то выполняется оператор.

Например:

if (x<y&&x<z) min = x;

if ( выражение-условие) оператор1; //полная форма

else оператор2;

Если значение выражения-условия отлично от нуля, то выполняется оператор1, при нулевом значении выражения-условия выполняется оператор2.

Например:

if (d>=0)

{

x1 = (-b-sqrt(d))/(2*a);

x2 = (-b+sqrt(d))/(2*a);

cout<< “\nx1=”<<x1<<“x2=”<<x2;

}

else cout<<“\nРешения нет”;

2. Переключатель определяет множественный выбор. Его основная форма имеет следующий вид:

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

{

case константа1:

операторы1;

break;

case константа2:

операторы2;

break;

. . .

default: операторы;

}

При выполнении оператора switch, вычисляется выражение, записанное после switch, оно должно быть целочисленным. Полученное значение последовательно сравнивается с константами, которые записаны следом за case. При первом же совпадении выполняются операторы, помеченные данной меткой. Если выполненные операторы не содержат оператора перехода, то далее выполняются операторы всех следующих вариантов, пока не появится оператор перехода или не закончится переключатель. Если значение выражения, записанного после switch, не совпало ни с одной константой, то выполняются операторы, которые следуют за меткой default. Метка default может отсутствовать.

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

Пример:

#include <iostream.h>

void main(void)

{

int i;

cout<<"\nEnter the number";

cin>>i;

switch(i)

{

case 1:cout<<"\nthe number is one";

case 2:cout<<"\n2*2 = "<<i*i;

case 3: cout<<"\n3*3 = "<<i*i; break;

case 4: cout<<"\n"<<i<<" is very beautiful!";

default: cout<<"\nThe end of work";

}

}

Результаты работы программы:

1. При вводе 1 будет выведено:

The number is one

2*2 = 1

3*3 = 1

2. При вводе 2 будет выведено:

2*2 = 4

3*3 = 4

3. При вводе 3 будет выведено:

3*3 = 9

4. При вводе 4 будет выведено:

4 is very beautiful!

The end of work

5. При вводе всех остальных чисел будет выведено:

The end of work

3.4 Операторы циклов

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

Группа действий, повторяющихся в цикле, называется его телом. Однократное выполнение цикла называется его шагом.

В языке Си известно три вида оператора цикла: while, do-while и for.

1. Цикл с предусловием:

while (условие)

{тело цикла;}

Тело цикла выполняется, пока условие истинно. Когда оно становится ложным, цикл завершается и выполняется следующий оператор программы.

Пример:

while (a!=0)

{

cin>>a;

s+=a;

}

2. Цикл с постусловием:

do

{тело цикла;}

while (условие);

Тело цикла выполняется, пока условие истинно.

Пример:

do

{

cin>>a;

s+=a;

}

while(a!=0);

3. Цикл с параметром.

В общем виде имеет следующий вид:

for (выражение1; выражение2; выражение3)

{тело цикла;}

Его основная форма:

for (инициализация; условие; изменение)

{тело цикла;}

В простейшей форме инициализация используется для присвоения начального значения параметру цикла. Условие определяет, когда цикл должен быть завершен. Как только оно становится ложным, начинает выполняться следующий за циклом for оператор. Изменение параметра обычно используется каждый раз при повторении цикла. Любое выражение может отсутствовать, но разделяющие их « ; » должны быть обязательно.

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

1) Уменьшение шага на 1:

for (n = 10; n>0; n--)

{тело цикла;}

2) Изменение шага на величину, отличную от 1:

for (n = 2; n>60; n+=13)

{тело цикла;}

3) Проверка сложного условия:

for (num = 1; num*num*num<216; num++)

{тело цикла;}

4) Изменение шага может осуществляться не только с помощью сложения или вычитания:

for (d = 100.0; d<150.0; d*=1.1)

{тело цикла;}

for (x=1; y<=75; y=5*(x++)+10)

{тело цикла;}

5) Можно использовать несколько инициализирующих или корректирующих выражений:

for (x=1, y=0; x<10; x++, y+=x)

{тело цикла;}

3.5 Операторы перехода

Операторы перехода выполняют безусловную передачу управления.

1) break - оператор прерывания блока, обычно используется для принудительного выхода из цикла.

{

< операторы>

if (<выражение_условие>) break;

<операторы>

}

Т.е. оператор break целесообразно использовать, когда условие продолжения итераций проверяется в середине цикла.

Пример:

// ищет сумму чисел, вводимых с клавиатуры, до тех пор, пока не

// будет введено 100 чисел или 0

for(s=0, i=1; i<100;i++)

{

cin>>x;

if( x==0) break; // если ввели 0, то суммирование заканчивается

s+=x;

}

2) continue - переход к следующей итерации цикла. Он используется, когда тело цикла содержит ветвления.

Пример:

// ищет количество и сумму положительных чисел

for( k=0, s=0, x=1; x!=0;)

{

cin>>x;

if (x<=0) continue;

k++; s+=x;

}

3) Оператор goto

Оператор goto имеет формат

goto метка;

В теле той же функции должна присутствовать конструкция

метка: оператор;

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

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

Нельзя передавать управление внутрь операторов if, switch и циклов. Нельзя переходить внутрь блоков, содержащих инициализацию, на операторы, которые стоят после инициализации.

Пример:

int k;

goto m;

. . .

{

int a=3, b=4;

k=a+b;

m: int c=k+1;

. . .

}

В этом примере при переходе на метку m не будет выполняться инициализация переменных a, b и k.

4) Оператор return - оператор возврата из функции. Он всегда завершает выполнение функции и передает управление в точку ее вызова. Вид оператора:

return [выражение];

Лабораторная работа 1.

Условный оператор IF и операторы цикла

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

1. Шаг: 1. Диапазон [-20, 20]

2. Шаг: 5. Диапазон [-30, 30]

3. Шаг: 20. Диапазон [-40, 40]

4. Шаг: 1. Диапазон [-10, 10]

5. Шаг: 5. Диапазон [-20, 20]

6. Шаг: 6. Диапазон [-30, 30]

7. Шаг: 10. Диапазон [-40, 40]

8. Шаг: 8. Диапазон [-50, 20]

Пример

Шаг: 10. Диапазон [-20, 60]

Цикл FOR:

# include <iostream.h>

# include <conio.h>

void main(void)

{const a=-20, b=60, c=10;

float x, y;

clrscr();

for (x=a; x<=b; x+=c)

{

if (x<2) y=30+2*x;

else if (x>=50) y=x+6;

else y=6-2*x;

cout<<"x="<<x<<": y="<<y<<"\n";

}

getche();

}

Цикл WHILE:

# include <iostream.h>

# include <conio.h>

void main(void)

{const a=-20, b=60, c=10;

float x=a, y;

clrscr();

while (x<=b)

{

if (x<2) y=30+2*x;

else if (x>=50) y=x+6;

else y=6-2*x;

cout<<"x="<<x<<": y="<<y<<"\n";

x+=c;

}

getche();

}

Цикл DO-WHILE:

# include <iostream.h>

# include <conio.h>

void main(void)

{const a=-20, b=60, c=10;

float x=a, y;

clrscr();

do

{

if (x<2) y=30+2*x;

else if (x>=50) y=x+6;

else y=6-2*x;

cout<<"x="<<x<<": y="<<y<<"\n";

x+=c;

}

while (x<=b);

getche();

}

4. МАССИВЫ, СТРОКИ И УКАЗАТЕЛИ

В языках Си/Си++, кроме базовых типов, разрешено вводить и использовать производные типы, полученные на основе базовых. Массивы и указатели - наиболее простые и известные производные типы.

4.1 Одномерные массивы

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

int a[100]; // массив из 100 элементов целого типа

Операция sizeof(a) даст результат 400, т. е. 100 элементов по 4 байта.

Элементы массива всегда нумеруются с 0.

Чтобы обратиться к элементу массива, надо указать имя массива и номер элемента в массиве (индекс):

a[55] - индекс задается как константа,

a[I] - индекс задается как переменная,

a[2*I] - индекс задается как выражение.

Элементы массива можно задавать при его определении:

int a[10]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Операция sizeof(a) даст результат 40, т.е. 10 элементов по 4 байта.

Если количество значений меньше, чем объявленная длина массива, то эти значения получат только первые элементы, остальные будут содержать так называемый «мусор»:

int a[10]={1, 2, 3, 4, 5};

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

int a[ ]={1, 2, 3, 4, 5};

Здесь будет определен массив из 5 элементов.

4.2 Символьная информация и строки

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

Примеры:

const char c='c'; //символ - занимает один байт, его значение не меняется

char a, b; //символьные переменные, занимают по одному байту,

// значения меняются

const char *s=“Пример строки\n”; //текстовая константа

Строка в Си - это массив символов, заканчивающийся нуль-символом - `\0'(нуль-терминатором). По положению нуль-терминатора определяется фактическая длина строки. Количество элементов в таком массиве на 1 больше, чем изображение строки.

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

Пример:

void main()

{

char s1[10]="string1";

int k=sizeof(s1);

cout<<s1<<"\t"<<k<<endl;

char s2[ ]="string2";

k=sizeof(s2);

cout<<s2<<"\t"<<k<<endl;

char s3[ ]={`s','t','r','i','n','g','3'}

k=sizeof(s3);

cout<<s3<<"\t"<<k<<endl;

char *s4="string4";//указатель на строку, ее нельзя изменить

k=sizeof(s4);

cout<<s4<<"\t"<<k<<endl;

}

Результаты:

string1 10 - выделено 10 байтов, в том числе под \0

string2 8 - выделено 8 байтов (7 + 1 байт под \0)

string3 8 - выделено 8 байтов (7 + 1 байт под \0)

string4 4 - размер указателя

Примеры:

char *s=”String5”; //выделяется 8 байтов для строки

char*ss; //описан указатель

ss=”String6”; //память не выделяется, поэтому программа может //закончиться аварийно.

char *sss=new char[10]; //выделяем динамическую память

strcpy(sss,”String7”); //копируем строку в память

Для ввода и вывода символьных данных в библиотеке языка Си определены следующие функции:

int getchar(void) - осуществляет ввод одного символа их входного потока, при этом она возвращает один байт информации (символ) в виде значения типа int. Это сделано для распознавания ситуации, когда при чтении будет достигнут конец файла.

int putchar (int c) - помещает в стандартный выходной поток символ c.

char* gets(char*s) - считывает строку s из стандартного потока до появления символа `\n', сам символ `\n' в строку не заносится.

int puts(const char* s) записывает строку в стандартный поток, добавляя в конец строки символ `\n', в случае удачного завершения возвращает значение больше или равное 0 и отрицательное значение (EOF=-1) в случае ошибки.

Примеры:

char s[20];

cin>>s; //ввод строки из стандартного потока

cout<<s; //вывод строки в стандартный поток

Результат работы программы:

При вводе строки “123 456 789”, чтение байтов осуществляется до первого пробела, т. е. в строку s занесется только первое слово строки “123/0”, следовательно, выведется: 123.

char s[20];

gets(s); //ввод строки из стандартного потока

puts(s); //вывод строки в стандартный поток

Результат работы программы:

При вводе строки “123 456 789”, чтение байтов осуществляется до символа `\n', т.е. в s занесется строка”123 456 789\n\0”, при выводе строки функция puts возвращает еще один символ `\n', следовательно, будет выведена строка “123 456 789\n\n”.

char s[20];

scanf(“%s”, s); //ввод строки из стандартного потока

printf(“%s”, s); //вывод строки в стандартный поток

При вводе строки “123 456 789”, чтение байтов осуществляется до первого пробела, т. е. в строку s занесется только первое слово строки “123/0”, следовательно, выведется 123. Так как s - имя массива, т.е. адрес его первого элемента, операция & в функции scanf не используется.

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

unsigned strlen(const char*s); Вычисляет длину строки s.

int strcmp(const char*s1, const char *s2); Сравнивает строки s1 и s2. Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 - результат положительный.

int strncmp(const char*s1, const char *s2); Сравнивает первые n символов строк s1 и s2. Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 - результат положительный.

char *strcpy(char*s1, const char*s2); Копирует символы строки s1 в строку s2.

char *strncpy(char*s1, const char*s2, int n); Копирует n символов строки s1 в строку s2. Конец строки отбрасывается или дополняется пробелами.

char *strcat(char*s1, const char*s2); Приписывает строку s2 к строке s1.

char *strncat(char*s1, const char*s2); Приписывает первые n символов строки s2 к строке s1.

Пример:

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

#include <stdio.h>

#include <string.h>

void main()

{

char s[250], //исходная строка

w[25], //слово

mas[10][25]; //массив слов

puts(“\nвведите строку”);

gets(s);

int k=0, t=0, i, len, j;

len=strlen(s);

while(t<len)

{

for (j=0, i=t; s[i]!=' `; i++, j++) w[j]=s[i];//формируем слово до пробела

w[j]='/0'; //формируем конец строки

strcpy(mas[k],w); //копируем слово в массив

k++; //увеличиваем счетчик слов

t=i+1; //переходим к следующему слову в исходной строке

}

strcpy(s,””); //очищаем исходную строку

for(t=0; t<k; t++)

if(mas[t][0]<'0'&&mas[t][0]>'9') //если первый символ не цифра

{

strcat(s, mas[t]); //копируем в строку слово

strcat(s, ” “); //копируем в строку пробел

}

puts(s); //выводим результат

}

4.3 Указатели

Указатели являются специальными объектами и предназначены для хранения адресов памяти. Когда компилятор обрабатывает оператор определения переменной, например, int i=10;, то в памяти выделяется участок памяти в соответствии с типом переменной (int = 4 байта для 32-х разрядных ЭВМ) и записывает в этот участок указанное значение. Все обращения к этой переменной компилятор заменит на адрес области памяти, в которой хранится эта переменная.

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

Указатели делятся на две категории: указатели на объекты и указатели на функции.

Рассмотрим указатели на объекты, которые хранят адрес области памяти, содержащей данные определенного типа.

В простейшем случае объявление указателя имеет вид: тип *имя;

Тип может быть любым, кроме ссылки.

Примеры:

int *i;

double *f, *ff;

char *c;

Размер указателя зависит от модели памяти. Можно определить указатель на указатель: int**a;

Указатель может быть константой или переменной, а также указывать на константу или переменную.

Примеры:

int i; //целая переменная

const int ci=1; //целая константа

int *pi; //указатель на целую переменную

const int *pci; //указатель на целую константу

Указатель можно сразу проинициализировать:

int *pi=&i; //указатель на целую переменную

const int *pci=&ci; //указатель на целую константу

int*const cpi=&i; //указатель-константа на целую переменную

const int* const cpc=&ci; //указатель-константа на целую константу

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

Для инициализации указателя существуют следующие способы:

1) с помощью операции получения адреса

int a=5;

int *p=&a; или int p(&a);

2) с помощью проинициализированного указателя

int *r=p;

3) адрес присваивается в явном виде

char*cp=(char*)0х В800 0000;

где 0х В800 0000 - шестнадцатеричная константа, (char*) - операция приведения типа.

4) присваивание пустого значения:

int*N=NULL;

int *R=0;

4.4 Динамическое выделение памяти

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

В языке Си для динамического выделения памяти под переменную и освобождения памяти из-под ненужной переменной служат соответственно функции malloc( ) и free( ).

В языке Си++ предусмотрены две операции - new и delete, которые мы и рассмотрим.

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

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

Иллюстрация работы с динамически выделенной памятью под массив:

# include <iostream.h>

# include <conio.h>

void main(void)

{int *p, i, size;

clrscr();

cout<<”Введите размер массива: ”;

cin>>size;

p=new int[size]; //Выделяем память под массив целых чисел

if (!p) cout<<"Недостаточно памяти";

else

{

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

{p[i]=i;

cout<<p[i];}

delete(p); //Освобождаем память

}

getche();

}

4.5 Одномерные массивы и указатели на массивы

При определении массива ему выделяется память. После этого имя массива воспринимается как константный указатель того типа, к которому относятся элементы массива. Исключением является использование операции sizeof (имя_массива) и операции &имя_массива.

Примеры:

int a[100];

int k=sizeof(a); //результатом будет 4*100=400 (байтов).

int n=sizeof(a)/sizeof(a[0]); //количество элементов массива

Результатом операции & является адрес нулевого элемента массива:

имя_массива==&имя_массива==&имя_массива[0]

Имя массива является указателем-константой, значением которой служит адрес первого элемента массива, следовательно, к нему применимы все правила адресной арифметики, связанной с указателями. Запись имя_массива[индекс] это выражение с двумя операндами: имя массива и индекс. Имя_массива - это указатель константа, а индекс определяет смещение от начала массива. Используя указатели, обращение по индексу можно записать следующим образом: *(имя_массива+индекс).

Пример:

for(int i=0; i<n; i++) //печать массива

cout<<*(a+i)<<" "; //к адресу массива добавляется константа i

// и полученное значение разыменовывается

Так как имя массива является константным указателем, то его невозможно изменить, следовательно, запись *(а++) будет ошибочной, а *(а+1) - нет.

Указатели можно использовать и при определении массивов:

int a[100]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int *na=a; //поставили указатель на уже определенный массив

int *b=new int[100]; //выделили в памяти место под массив

...

Подобные документы

  • Базовый синтаксис языка программирования С#. Объявление переменных и присваивание им значений. Управление порядком выполнения программы. Выполнение преобразований с помощью команд преобразования. Определение классов, конструктора, работа с файлами.

    курс лекций [692,5 K], добавлен 23.11.2009

  • Возможности языков программирования С и С++. Разработка и реализация информационно-поискового справочника "Блок питания", листинг программы. Функции и структура данных в программе. Динамическое распределение памяти, работа с файлами, несложные сортировки.

    курсовая работа [38,7 K], добавлен 10.01.2011

  • История развития языка программирования Pascal, его основные концепции. Вычисления в математических задачах. Изменение порядка выполнения инструкций программы. Выполнение оператора цикла. Логические выражения, линейные алгоритмы, условные операторы.

    методичка [847,6 K], добавлен 10.01.2013

  • Строгая типизация и наличие средств структурного (процедурного) программирования императивного языка Pascal. Структура программы, выражения, строки. Правила и описание типов, процедур и функций, операторов ввода - вывода, модулей и подпрограмм.

    курсовая работа [37,3 K], добавлен 28.06.2008

  • Цели и задачи дисциплины "Технология программирования". Программные средства ПК. Состав системы программирования и элементы языка. Введение в систему программирования и операторы языка Си. Организация работы с файлами. Особенности программирования на С++.

    методичка [126,3 K], добавлен 07.12.2011

  • Структура, функции и организация деятельности Интерпола. Основные этапы проектирования базы данных картотеки. Назначение и виды запросов. Структура базы данных Интерпола по дисциплине "Основы алгоритмизации и программирования". Главная кнопочная форма.

    дипломная работа [2,6 M], добавлен 10.07.2015

  • Изучение общей структуры языка программирования Delphi: главные и дополнительные составные части среды программирования. Синтаксис и семантика языка программирования Delphi: алфавит языка, элементарные конструкции, переменные, константы и операторы.

    курсовая работа [738,1 K], добавлен 17.05.2010

  • Основы языка программирвоания C++. Элементы управления в Microsoft Visual C++. Алгоритмические конструкции языка программирования Visual C++ и базовые элементы управления. Глобальные константы и переменные. Управление программой с помощью клавиатуры.

    курсовая работа [1,7 M], добавлен 08.04.2015

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

    презентация [1,8 M], добавлен 05.11.2016

  • Этапы подготовки и решения реальных задач. Словесно-формульное, графическое описание, псевдокоды. Программа нахождения квадрата числа на языке Бейсик. Разветвляющийся и циклический алгоритм. Общие положения программирования. Базовые конструкции.

    презентация [308,3 K], добавлен 31.10.2016

  • Понятие базового и прикладного программного обеспечения. Информация, ее свойства и виды. Интерфейс ОС Windows. Программа управления файлами "Проводник". Windows-редакторы Paint и MS Word. MS Excel: расчет амортизации. Программа Internet Explorer.

    практическая работа [1,1 M], добавлен 16.01.2011

  • Понятие алгоритма. Цикл программы. Структурная схема алгоритма. Элементы языка Тurbo Рascal. Алфавит. Идентификаторы. Комментарии. Лексика языка С++. ESC-последовательности. Операции. Ключевые слова. Комментарии.

    контрольная работа [43,0 K], добавлен 24.04.2006

  • Классификация систем программирования. Специализированные редакторы, программы-компиляторы и исполнимый код. Разновидности Visual Basic. Версии Паскаля и его использование. Приложения на языке Java. Разработка программы для вычисления предельной ошибки.

    курсовая работа [34,0 K], добавлен 28.12.2009

  • История создания языка Java. Основные принципы объектно-ориентированного программирования. Структура, особенности синтаксиса и примеры прикладных возможностей использования языка Java, его преимущества. Перспективы работы программистом на языке Java.

    курсовая работа [795,9 K], добавлен 14.12.2012

  • Проектирование программного модуля в среде программирования Borland Delphi 7.0. Схемы алгоритмов решения задач по темам "Символьные переменные и строки", "Массивы", "Работа с файлами", "Создание анимации". Реализация программного модуля, код программы.

    отчет по практике [961,6 K], добавлен 21.04.2012

  • Базовые основы программы Prolog - языка и системы логического программирования. Работа с текстами и предложениями. Электронный казахско-русско-английский словарь. Дистанционный комплекс обучения государственному языку специалистов технического профиля.

    реферат [45,6 K], добавлен 15.09.2014

  • Характеристика структурированного языка программирования С, его основных структурных компонентов, области памяти, библиотеки. Методы поиска в массивах данных. Описание программы, функции сортировки и меню выбора, последовательного и бинарного поиска.

    курсовая работа [1,7 M], добавлен 19.05.2014

  • Рассмотрение особенностей среды программирования Delphi. Разработка программы для пересчета длины из фунтов в килограммы с использованием следующих объектов: Edit, Label, Button. Значения свойств поля ввода-редактирования и командной кнопки Перерасчет.

    практическая работа [177,2 K], добавлен 18.10.2012

  • Освоение технологии структурного программирования и применения стандартных методов работы с одномерными массивами при разработке и создании программы на языке Турбо Паскаль. Разработка программы методом пошаговой детализации с помощью псевдокода.

    реферат [276,9 K], добавлен 27.02.2008

  • Международный стандарт на язык программирования Паскаль. Приемы объектно-ориентированного программирования в Турбо Паскале. Символы языка, его алфавит. Этапы разработки программы. Понятие алгоритмов и алгоритмизации. Структура программ на Паскале.

    курсовая работа [29,8 K], добавлен 28.02.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.