Лекции по C++

PAGE 1

Лекции по C++.

Введение

В первом семестре рассматриваются основные конструкции языка Си и базовая технология программирования (структурное программирование).

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

  1. Алгоритм и программа

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

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

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

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

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

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

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

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

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

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

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

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

Языками высокого уровня являются:

  1. Фортран – первый компилируемый язык, созданный в 50-е годы 20 века. В нем были реализован ряд важнейших понятий программирования. Для этого языка было создано огромное количество библиотек, начиная от статистических комплексов и заканчивая управлением спутниками, поэтому он продолжает использоваться во многих организациях.
  2. Кобол – компилируемый язык для экономических расчетов и решения бизнес-задач, разработанный в начале 60-х годов. В Коболе были реализованы очень мощные средства работы с большими объемами данных, хранящихся на внешних носителях.
  3. Паскаль – создан в конце 70-х годов швейцарским математиком Никлаусом Виртом специально для обучению программированию. Он позволяет выработать алгоритмическое мышление, строить короткую, хорошо читаемую программу, демонстрировать основные приемы алгоритмизации, он также хорошо подходит для реализации крупных проектов.
  4. Бейсик – создавался в 60-х годах также для обучения программированию. Для него имеются и компиляторы и интерпретаторы, является одним из самых популярных языков программирования.
  5. Си – был создан в 70- е годы первоначально не рассматривался как массовый язык программирования. Он планировался для замены ассемблера, чтобы иметь возможность создавать такие же эффективные и короткие программы, но не зависеть от конкретного процессора. Он во многом похож на Паскаль и имеет дополнительные возможности для работы с памятью. На нем написано много прикладных и системных программ, а также операционная система Unix.
  6. Си++ - объектно-ориентированное расширение языка Си, созданное Бьярном Страуструпом в 1980г.
  7. Java – язык, который был создан компанией Sun в начале 90-х годов на основе Си++. Он призван упростить разработку приложений на СИ++ путем исключения из него низкоуровневых возможностей. Главная особенность языка – это то, что он компилируется не в машинный код, а в платформно-независимый байт-код (каждая команда занимает один байт). Этот код может выполняться с помощью интерпретатора – виртуальной Java-машины (JVM).

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

Программа на языке Си имеет следующую структуру:

#директивы препроцессора

. . . . . . . . .

#директивы препроцессора

функция а ( )

операторы

функция в ( )

операторы

void main ( ) //функция, с которой начинается выполнение программы

операторы

описания

присваивания

функция

пустой оператор

составной

выбора

циклов

перехода

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

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

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

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

#define ZERO 0.0

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

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

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

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

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

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

int y = 10 ; //именованная константа

float x ; //переменная

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

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

Пример программы на Си:

#include <stdio.h> //препроцессорная директива

void main() //функция

{ //начало

printf(“Hello! “); //печать

} //конец

Контрольные вопросы

  1. Из каких частей состоит программа на С++?
  2. Чем определение отличается от объявления?
  3. Перечислить этапы создания исполняемой программы на языке С++.
  4. Что такое препроцессор?
  5. Что такое директива препроцессора? Привести примеры директив препроцессора.
  6. Составить программу, которая печатает текст «Моя первая программа на С++»


2. Базовые средства языка СИ++

  1. Состав языка

В тексте на любом естественном языке можно выделить четыре основных элемента: символы, слова, словосочетания и предложения. Алгоритмический язык также содержит такие элементы, только слова называют лексемами (элементарными конструкциями ), словосочетания – выражениями, предложения – операторами. Лексемы образуются из символов, выражения из лексем и символов, операторы из символов выражений и лексем (Рис. 1.1)

Рис. 1.1. Состав алгоритмического языка

Таким образом, элементами алгоритмического языка являются:

  1. Алфавит языка СИ++, который включает
  • прописные и строчные латинские буквы и знак подчеркивания;
  • арабские цифры от 0 до 9;
  • специальные знаки “{},| []()+-/%*.\’:;&?<>=!#^
  • пробельные символы (пробел, символ табуляции, символы перехода на новую строку).
  1. Из символов формируются лексемы языка:
  • Идентификаторы – имена объектов СИ-программ. В идентификаторе могут быть использованы латинские буквы, цифры и знак подчеркивания. Прописные и строчные буквы различаются, например, PROG1, prog1 и Prog1 – три различных идентификатора. Первым символом должна быть буква или знак подчеркивания (но не цифра). Пробелы в идентификаторах не допускаются.
  • Ключевые (зарезервированные) слова – это слова, которые имеют специальное значение для компилятора. Их нельзя использовать в качестве идентификаторов.
  • Знаки операций – это один или несколько символов, определяющих действие над операндами. Операции делятся на унарные, бинарные и тернарную по количеству участвующих в этой операции операндов.
  • Константы – это неизменяемые величины. Существуют целые, вещественные, символьные и строковые константы. Компилятор выделяет константу в качестве лексемы (элементарной конструкции) и относит ее к одному из типов по ее внешнему виду.
  • Разделители – скобки, точка, запятая пробельные символы.

  1. Константы в Си++

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

Константы делятся на 5 групп:

  • целые;
  • вещественные (с плавающей точкой);
  • перечислимые;
  • символьные;
  • строковые.

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

Целые константы могут быть десятичными, восьмеричными и шестнадцатеричными. Десятичная константа определяется как последовательность десятичных цифр, начинающаяся не с 0, если это число не 0 (примеры: 8, 0, 192345). Восьмеричная константа – это константа , которая всегда начинается с 0. За 0 следуют восьмеричные цифры (примеры: 016 – десятичное значение 14, 01). Шестнадцатеричные константы – последовательность шестнадцатеричных цифр, которым предшествуют символы 0х или 0Х (примеры: 0хА, 0Х00F).

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

Вещественные константы имеют другую форму внутреннего представления в памяти компьютера. Компилятор распознает такие константы по их виду. Вещественные константы могут иметь две формы представления: с фиксированной точкой и с плавающей точкой. Вид константы с фиксированной точкой:[цифры].[цифры] (примеры: 5.7, .0001, 41.).Вид константы с плавающей точкой: [цифры][.][цифры]E|e[+|-][цифры] (примеры:0.5е5, .11е-5, 5Е3). В записи вещественных констант может опускаться либо целая, либо дробная части, либо десятичная точка, либо признак экспоненты с показателем степени.

Перечислимые константы вводятся с помощью ключевого слова enum. Это обычные целые константы, которым приписаны уникальны и удобные для использования обозначения. Примеры: enum { one=1, two=2, three=3,four=4};

enum {zero,one,two,three} – если в определении перечислимых констант опустить знаки = и числовые значения, то значения будут приписываться по умолчанию. При этом самый левый идентификатор получит значение 0, а каждый последующий будет увеличиваться на 1.

enum { ten=10, three=3, four, five, six};

enum {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday} ;

Символьные константы – это один или два символа, заключенные в апострофы. Символьные константы, состоящие из одного символа, имеют тип char и занимают в памяти один байт, символьные константы, состоящие из двух символов, имеют тип int и занимают два байта. Последовательности, начинающиеся со знака \ , называются управляющими, они используются:

  • Для представления символов, не имеющих графического отображения, например:

\a – звуковой сигнал,

\b – возврат на один шаг,

\n – перевод строки,

\t – горизонтальная табуляция.

  • Для представления символов: \ , ’ , ? , ” ( \\, \’ ,\? ,\” ).
  • Для представления символов с помощью шестнадцатеричных или восьмеричных кодов (\073, \0хF5).

Строковая константа – это последовательность символов, заключенная в кавычки. Внутри строк также могут использоваться управляющие символы. Например: “\nНовая строка”,

“\n\”Алгоритмические языки программирования высокого уровня \”” .

2.2. Типы данных в Си++

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

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

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

int (целый)

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

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

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

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

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

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

short (короткий)

long (длинный)

signed (знаковый)

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

2.2.1. Тип int

Значениями этого типа являются целые числа.

Размер типа int не определяется стандартом, а зависит от компьютера и компилятора. Для 16-разрядного процессора под него отводится 2 байта, для 32-разрядного – 4 байта.

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

short int - занимает 2 байта, следовательно, имеет диапазон –32768 ..+32767;

long int – занимает 4 байта, следовательно, имеет диапазон –2 147 483 648..+2 147 483 647

Тип int совпадает с типом short int на 16-разрядных ПК и с типом long int на 32-разрядных ПК.

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

unsigned short int - занимает 2 байта, следовательно, имеет диапазон 0 ..65536;

unsigned long int – занимает 4 байта, следовательно, имеет диапазон 0..+4 294 967 295.

2.2.2. Тип char

Значениями этого типа являются элементы конечного упорядоченного множества символов. Каждому символу ставится в соответствие число, которое называется кодом символа. Под величину символьного типа отводится 1 байт. Тип char может использоваться со спецификаторами signed и unsigned. В данных типа signed char можно хранить значения в диапазоне от –128 до 127. При использовании типа unsigned char значения могут находиться в диапазоне от 0 до 255. Для кодировки используется код ASCII(American Standard Code foe International Interchange). Символы с кодами от 0 до 31 относятся к служебным и имеют самостоятельное значение только в операторах ввода-вывода.

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

2.2.3. Тип wchar_t

Предназначен для работы с набором символов, для кодировки которых недостаточно 1 байта, например Unicode. Размер этого типа, как правило, соответствует типу short. Строковые константы такого типа записываются с префиксом L: L“String #1”.

2.2.4. Тип bool

Тип bool называется логическим. Его величины могут принимать значения true и false. Внутренняя форма представления false – 0, любое другое значение интерпретируется как true.

2.2.5. Типы с плавающей точкой.

Внутреннее представление вещественного числа состоит из 2 частей: мантиссы и порядка. В IBM-совместимых ПК величины типа float занимают 4 байта, из которых один разряд отводится под знак мантиссы, 8 разрядов под порядок и 24 – под мантиссу.

Величины типы double занимают 8 байтов, под порядок и мантиссу отводятся 11 и 52 разряда соответственно. Длина мантиссы определяет точность числа, а длина порядка его диапазон.

Если перед именем типа double стоит спецификатор long, то под величину отводится байтов.

2.2.6. Тип void

К основным типам также относится тип void Множество значений этого типа – пусто.

2.3. Переменные

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

int a; float x;

Общий вид оператора описания:

[класс памяти][const]тип имя [инициализатор];

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

Const – показывает, что эту переменную нельзя изменять (именованная константа).

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

Классы памяти:

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

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

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

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

Пример

int a; //глобальная переменная

void main(){

int b;//локальная переменная

extern int x;//переменная х определена в другом месте

static int c;//локальная статическая переменная

a=1;//присваивание глобальной переменной

int a;//локальная переменная а

a=2;//присваивание локальной переменной

::a=3;//присваивание глобальной переменной

}

int x=4;//определение и инициализация х

В примере переменная а определена вне всех блоков. Областью действия переменной а является вся программа, кроме тех строк, где используется локальная переменная а. Переменные b и с – локальные, область их видимости – блок. Время жизни различно: память под b выделяется при входе в блок (т. к. по умолчанию класс памяти auto), освобождается при выходе из него. Переменная с (static) существует, пока работает программа.

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

Имя переменной должно быть уникальным в своей области действия.

Описание переменной может быть выполнено или как объявление, или как определение. Объявление содержит информацию о классе памяти и типе переменной, определение вместе с этой информацией дает указание выделить память. В примере extern int x; - объявление, а остальные – определения.

  1. Знаки операций в Си++

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

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

&

получение адреса операнда

*

Обращение по адресу (разыменование)

-

унарный минус, меняет знак арифметического операнда

~

поразрядное инвертирование внутреннего двоичного кода целочисленного операнда (побитовое отрицание)

!

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

++

Увеличение на единицу:

префиксная операция - увеличивает операнд до его использования,

постфиксная операция увеличивает операнд после его использования.

int m=1,n=2;

int a=(m++)+n; // a=4,m=2,n=2

int b=m+(++n);//a=3,m=1,n=3

- -

уменьшение на единицу:

префиксная операция - уменьшает операнд до его использования,

постфиксная операция уменьшает операнд после его использования.

sizeof

вычисление размера (в байтах) для объекта того типа, который имеет операнд

имеет две формы

sizeof выражение

sizeof (тип)

Примеры:

sizeof(float)//4

sizeof(1.0)//8, т. к. вещественные константы по умолчанию имеют тип double

Бинарные операции.

Аддитивные:

+

бинарный плюс (сложение арифметических операндов)

-

бинарный минус (вычитание арифметических операндов)

Мультипликативные:

*

умножение операндов арифметического типа

/

деление операндов арифметического типа (если операнды целочисленные, то выполняется целочисленное деление)

%

получение остатка от деления целочисленных операндов

Операции сдвига (определены только для целочисленных операндов).

Формат выражения с операцией сдвига:

операнд_левый операция_сдвига операнд_правый

<<

сдвиг влево битового представления значения левого целочисленного операнда на количество разрядов, равное значению правого операнда, освободившиеся разряды обнуляются

>>

сдвиг вправо битового представления значения правого целочисленного операнда на количество разрядов, равное значению правого операнда, освободившиеся разряды обнуляются, если операнд беззнакового типа и заполняются знаковым разрядом, если – знакового

Поразрядные операции:

&

поразрядная конъюнкция (И) битовых представлений значений целочисленных операндов (бит =1, если соответствующие биты обоих операндов=1)

|

поразрядная дизъюнкция (ИЛИ) битовых представлений значений целочисленных операндов (бит =1, если соответствующий бит одного из операндов=1)

^

поразрядное исключающее ИЛИ битовых представлений значений целочисленных операндов(бит =1, если соответствующий бит только одного из операндов=1)

Операции сравнения: результатом являются true( не 0) или false(0)

<

меньше, чем

>

больше, чем

<=

меньше или равно

>=

больше или равно

==

Равно

!=

не равно

Логические бинарные операции:

&&

конъюнкция (И) целочисленных операндов или отношений, целочисленный результат ложь(0) или истина(не 0)

||

дизъюнкция (ИЛИ) целочисленных операндов или отношений, целочисленный результат ложь(0) или истина(не 0)

Операции присваивания

=, +=, -=, += и т.д.

Формат операции простого присваивания:

операнд1=операнд2

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

Условная операция.

В отличие от унарных и бинарных операций в ней используется три операнда.

Выражение1 ? Выражение2 : Выражение3;

Первым вычисляется значение выражения1. Если оно истинно, то вычисляется значение выражения2, которое становится результатом. Если при вычислении выражения1 получится 0, то в качестве результата берется значение выражения3.

Например:

x<0 ? -x : x ; //вычисляется абсолютное значение x.

Операция явного (преобразования) приведения типа.

Существует две формы: каноническая и функциональная:

  1. (имя_типа) операнд
  2. имя_типа (операнд)

(int)a //каноническая форма

int(a) //функциональная форма

2.5. Выражения

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

Приоритеты операций в выражениях

Ранг

Операции

1

( ) [ ] -> .

2

! ~ - ++ -- & * (тип) sizeof тип( )

3

* / % (мультипликативные бинарные)

+ - (аддитивные бинарные)

5

<< >> (поразрядного сдвига)

6

< > <= >= (отношения)

7

== != (отношения)

8

& (поразрядная конъюнкция «И»)

9

^ (поразрядное исключающее «ИЛИ»)

10

| (поразрядная дизъюнкция «ИЛИ»)

11

&& (конъюнкция «И»)

12

|| (дизъюнкция «ИЛИ»)

13

?: (условная операция)

14

= *= /= %= -= &= ^= |= <<= >>= (операция присваивания)

15

, (операция запятая)

Контрольные вопросы

  1. Из каких элементов состоит естественный язык? Что является аналогами этих элементов в С++?
  2. Что такое лексема? Привести примеры лексем в языке С++.
  3. Что такое идентификатор? Правила записи идентификаторов.
  4. Что такое константа? Как константа обрабатывается компилятором?
  5. Какие типы констант существуют в С++. Привести примеры констант разных типов.
  6. К какому типу относятся константы 192345, 0х56, 0хСВ, 016, 0.7865, .0045, ‘c’, “x”, one, “one”, 5 , 5.?
  7. Что такое тип данных?
  8. Чем отличаются типы данных: float и double, char и wchar_t, int и short int?
  9. Чем отличаются типы данных int и unsigned int?
  10. Перечислить все типы данных, которые существуют в C++. Сколько места в памяти занимают данные каждого типа?
  11. На что влияет количество памяти, выделяемое для данных определенного типа?
  12. Что такое переменная? Чем объявление переменой отличается от ее определения? Привести примеры определений и объявлений.
  13. Что такое класс памяти? Какие классы памяти существуют в С++? Привести примеры объявлений и определений переменных разных классов памяти.
  14. Что такое выражение? Из чего состоит выражение?
  15. Что такое операнд?
  16. Какие операции можно применять к целочисленным данным? К вещественным данным? К символьным данным?
  17. Что такое отношение?
  18. В каком случае отношение считается ложным, а в каком – истинным?
  19. Какие операции называются унарными? Привести примеры.
  20. Какие операции называются бинарными? Привести примеры.
  21. Что такое тернарная операция? Привести пример.
  22. Какая разница между постфиксной и префиксной операцией инкремента (декремента)?
  23. Какие операции присваивания существуют в С++?
  24. Привести примеры выражений, содержащих операции присваивания, операции инкремента (декремента), аддитивные и мультипликативные операции. Пояснить, как они будут выполняться.
  25. Что такое леводопустимое значение? Привести пример.
  26. Чему будет равно значение выражений:

int z=x/y++; если int x=1, y=2;

int w=x%++y, если int x=1, y=2;

int a=++m+n++*sizeof(int); если int m=1, n=2;

float a=4*m/0.3*n; если float m=1.5; int n=5;

int ok=int(0.5*y)<short(x)++; если int x=10, y=3;


3. Ввод и вывод данных

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

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

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

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

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

Форматная строка может содержать

  1. символы печатаемые текстуально;
  2. спецификации преобразования;
  3. управляющие символы.

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

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

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

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

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

%c - символ;

%s - строка.

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

\n - управляющий символ новая строка;

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

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

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

%[-]m[.p]C, где

  1. - задает выравнивание по левому краю,

m – минимальная ширина поля,

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

С- спецификация формата вывода.

Пример

printf("\nСпецификации формата:\n%10.5d - целое,\n%10.5f - с плавающей точкой\

\n%10.5e – в экспоненциальной форме\n%10s - строка",10,10.0,10.0,"10");

Будет выведено:

Спецификации формата:

00010 – целое

10.00000 – с плавающей точкой

1.00000е+001 - в экспоненциальной форме

10 – строка.

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

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

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

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

  1. << - операция записи данных в поток;
  2. >> - операция чтения данных из потока.

Например:

#include <iostream.h>;

. . . . . . . . .

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

cin >> n;

Контрольные вопросы

  1. Что такое форматная строка? Что содержит форматная строка функции printf? Что содержит форматная строка функции scanf?
  2. Что такое спецификация преобразования? Привести примеры спецификаций преобразования для различных типов данных.
  3. Что будет выведено функцией
    printf("\nСреднее арифметическое последовательности чисел равно: %10.5f \nКоличество четных элементов последовательности равно%10.5d ",S/n,k);
  4. Как записать вывод результатов из вопроса 3 с помощью операции << ?
  5. Как выполнить ввод переменных х и у, где x типа long int, а у типа double с помощью функции scanf? С помощью операции >> ?


4. Основные операторы языка Си++»

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

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

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

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

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

Следование

Ветвление

Цикл

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

Операторы управления работой программы называют управляющими конструкциями программы. К ним относят:

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

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

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

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

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

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

Примеры:

i++;

a+=2;

x=a+b;

4.3. Составные операторы

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

{

n++; это составной оператор

summa+=n;

}

{

int n=0;

n++; это блок

summa+=n;

}

4.4. Операторы выбора

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

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 ;

case константа2 : оператор2 ;

. . . . . . . . . . .

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

}

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

Пример:

#include <iostream.h>

void main()

{

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

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

2*2=4

3*3=4

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

3*3=9

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

4 is very beautiful!

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

The end of work

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

Различают:

  1. итерационные циклы;
    1. арифметические циклы.

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

В итерационных циклах известно условие выполнения цикла.

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

while (выражение-условие)

оператор;

В качестве <выражения-условия> чаще всего используется отношение или логическое выражение. Если оно истинно, т. е. не равно 0, то тело цикла выполняется до тех пор, пока выражение-условие не станет ложным.

Пример

while (a!=0)

{

cin>>a;

s+=a;

}

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

do

оператор

while (выражение-условие);

Тело цикла выполняется до тех пор, пока выражение-условие истинно.

Пример:

do

{

cin>>a;

s+=a;

}

while(a!=0);

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

for ( выражение_1;выражение-условие;выражение_3)

оператор;

выражение_1 и выражение_3 могут состоять из нескольких выражений, разделенных запятыми. Выражение_1 - задает начальные условия для цикла (инициализация). Выражение-условие> определяет условие выполнения цикла, если оно не равно 0, цикл выполняется, а затем вычисляется значение выражения_3. Выражение_3 - задает изменение параметра цикла или других переменных (коррекция). Цикл продолжается до тех пор, пока выражение-условие не станет равно 0. Любое выражение может отсутствовать, но разделяющие их « ; » должны быть обязательно.

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

  1. Уменьшение параметра:

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

{ оператор};

  1. Изменение шага корректировки:

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

{ оператор };

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

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

{ оператор };

  1. Коррекция может осуществляться не только с помощью сложения или вычитания:

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

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

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

{ оператор };

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

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

  1. Операторы перехода

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

  1. break - оператор прерывания цикла.

{

< операторы>

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

<операторы>

}

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

Пример:

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

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

{

cin>>x;

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

s+=x;

}

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

Пример:

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

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

{

cin>>x;

if (x<=0) continue;

k++;s+=x;

}

  1. Оператор 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.

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

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


5. Примеры решения задач с использованием основных операторов Си++

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

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

Решение задач по программированию предполагает ряд этапов:

  1. Разработка математической модели. На этом этапе определяются исходные данные и результаты решения задачи, а также математические формулы, с помощью которых можно перейти от исходных данных к конечному результату.
  2. Разработка алгоритма. Определяются действия, выполняя которые можно будет от исходных данных придти к требуемому результату.
  3. Запись программы на некотором языке программирования. На этом этапе каждому шагу алгоритма ставится в соответствие конструкция выбранного алгоритмического языка.
  4. Выполнение программы (исходный модуль ->компилятор ->объектный модуль -> компоновщик -> исполняемый модуль)
  5. Тестирование и отладка программы. При выполнении программы могут возникнуть ошибки 3 типов:
    1. синтаксические – исправляются на этапе компиляции;
    2. ошибки исполнения программы (деление на 0, логарифм от отрицательного числа и т. п.) – исправляются при выполнении программы;
    3. семантические (логические) ошибки – появляются из-за неправильно понятой задачи, неправильно составленного алгоритма.

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

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

  1. тестирование классов входных данных, т. е. набор тестов должен содержать по одному представителю каждого класса данных:

X

0

1

0

1

-1

1

-1

Y

0

1

1

0

1

-1

-1

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

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

  1. Тестирование команд. Набор тестов должен обеспечивать прохождение каждой команды не менее одного раза.
  2. Тестирование ветвей. Набор тестов в совокупности должен обеспечивать прохождение каждой ветви не менее одного раза. Это самый распространенный критерий в практике программирования.

5.1. Программирование ветвлений

Задача №1. Определить, попадет ли точка с координатами (х, у ) в заштрихованную область.

Исходные данные: х,у

Результат: да или нет

Математическая модель:

Ok=I || II || III || VI, где I, II, III, IV – условия попадания точки в заштрихованную область для каждого квадранта.

Квадрант I: Область формируется прямыми 0Х и 0У, прямой, проходящей через точки (0,1)и(1,0) и прямой, проходящей через точки (0,3) и (2,0).

Необходимо определить уравнения прямых у=ax+b. Решаем две системы уравнений:

  1. 1=a*0+b;

0=a*1+b;

  1. 2=a*0+b;

0=a*3+b;

Из этих систем получаем следующие уравнения прямых:

y=-1x+1;

y=-2/3x+1;

Тогда условие попадания точки в I квадрант будет выглядеть следующим образом:

y>=-x+1&&y<=-2/3x+2&&y>=0&&x>=0.

Квадранты II и III: Область формируется прямыми 0Х и 0У и двумя окружностями, описываемыми формулами x2+y2=1, x2+y2=9.

Тогда условие попадания точки во II и III квадранты будет выглядеть следующим образом:

x2+y2>=1&& x2+y2<=9&&&&x<=0.

Квадрант IV:

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

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

(x>=0&&x<=1&&y<=-1&&y>=-3)|| (x>=1&&x<=3&&y<=0&&y>=-3) .

Программа:

#include <iostream.h>

#include <math.h>

void main()

{

float x,y;

cout<<"\nEnter x,y";

cin>>x>>y;

bool Ok=(y>=-x+1&&y<=2/3*x+2&&x>=0&&y>=0)||

(pow(x,2)+pow(y,2)>=1&&pow(x,2)+pow(y,2)<=9&&x<=0)||

(x>=0&&x<=1&&y<=-1&&y>=-3)||(x>=1&&x<=2&&y<=0&&y>=-3);

cout<<"\n"<<Ok;

}

Тесты:

Квадрант

Исходные данные (X,Y)

Результат (Ok)

I

0.2,0.2

0

I

0.7,0.5

1

II

-0.5, 0.5

0

II

-2,0

1

III

-0.5,-0,5

0

III

-2,-1

1

IV

0,5,-0.5

0

IV

1.5, -1

1

Центр системы координат

0,0

0

5.2. Программирование арифметических циклов.

Для арифметического цикла заранее известно сколько раз выполняется тело цикла.

Задача №2

Дана последовательность целых чисел из n элементов. Найти среднее арифметическое этой последовательности.

#include <iostream.h>

#include <math.h>

void main()

{

int a,n,i,k=0;

double s=0;

cout<<"\nEnter n";

cin>>n;

for(i=1;i<=n;i++)

{

cout<<"\nEnter a";

cin>>a;

s+=a;k++;

}

s=s/k;

cout<<"\nSr. arifm="<<s<<"\n";

}

Тесты

N

5

A

1,2,3,4,5,3

S

3

Задача №3

S=1+2+3+4+. . . +N

#include <iostream.h>

#include <math.h>

void main()

{

int n,i,s=0;

cout<<"\nEnter n";

cin>>n;

if(n<=0) {cout<<”\nN<=0”;return;}

for(i=1;i<=n;i++)s+=i;

cout<<"\nS="<<s<<"\n";

}

Тесты

n

S

n=-1

N<=0

n=0

N<=0

n=5

S=15

Задача №4

S=15-17+19-21+ . . ., всего n слагаемых.

#include <iostream.h>

#include <math.h>

void main()

{

int n,i,s=0,a=15;

cout<<"\nEnter n";

cin>>n;

if(n<=0) {cout<<”\nN<=0”;return;}

for(i=1;i<=n;i++)

{

if(i%2==1)s+=a;

else s-=a;

a+=2;

}

cout<<"\nS="<<s<<"\n";

}

Тесты

n

S

n=-1

N<=0

n=0

N<=0

n=3

S=17

5.3. Итерационные циклы

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

Задача №5

Дана последовательность целых чисел, за которой следует 0. Найти минимальный элемент этой последовательности.

#include <iostream.h>

#include <math.h>

void main()

{

int a,min;

cout<<"\nEnter a";

cin>>a;

min=a;

while(a!=0)//for(;a!=0;)

{

cout<<"\nEnter a";

cin>>a;

if (a!=0&&a<min)min=a;

}

cout<<"\nmin="<<min<<"\n";

}

Тесты:

a

2

55

-3

-10

0

min

-10

a

12

55

4

27

0

min

4

a

-6

-43

-15

-10

0

min

-10

Задача №6 : Найти сумму чисел Фибоначчи, меньших заданного числа Q.

#include<iostream.h>

void main()

{

int a=1,b=1,s=2,Q,c;

cout<<"\nEnter Q";

cin>>Q;

if(Q<=0)cout<<"Error in Q";

else

if(Q==1)cout<<"\nS=1";

else

{

c=a+b;

while(c<Q) //for(;c!=0;)

{

s+=c;

a=b;

b=c;

c=a+b;

}

cout<<"\nS="<<s<<"\n";

}

}

Тесты:

Q

S

-1

Error in Q

0

Error in Q

1

1

2

2

10

20

Тесты:

Q

-1

Error in Q

0

Error in Q

1

2

2

2 3

10

2 3 5 7 11

5.4. Вложенные циклы

Задача №7: Напечатать N простых чисел.

#include<iostream.h>

void main()

{

int a=1,n,d;

cout<<"\nEnter N";

cin>>n;

for(int i=0;i<n;)//внешний цикл

{

a++;d=1;

do //внутренний цикл

{

d++;

}

while(a%d!=0);//конец внутреннего цикла

if(a==d){

cout<<a<<" ";

i++;}

}//конец внешнего цикла

}


6. Массивы

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

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

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

6.1. Определение массива в Си/Си++

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

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

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

0

1

2

…..

99

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

a[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};

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

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

Операция sizeof(a) даст результат 20, т. е.5 элементов по 4 байта. Длин массива вычисляется компилятором по количеству значений, перечисленных при инициализации.

6.2. Обработка одномерных массивов

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

Перебор элементов массива характеризуется:

  • направлением перебора;
  • количеством одновременно обрабатываемых элементов;
  • характером изменения индексов.

По направлению перебора массивы обрабатывают :

  • слева направо (от начала массива к его концу);
  • справа налево (от конца массива к началу);
  • от обоих концов к середине.

Индексы могут меняться

  • линейно (с постоянным шагом);
  • нелинейно (с переменным шагом).

6.2.1. Перебор массива по одному элементу

Элементы можно перебирать:

  1. Слева направо с шагом 1, используя цикл с параметром

for(int I=0;I<n;I++){обработка a[I];}

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

for (int I=0;I<n;I+=step){обработка a[I];}

  1. Справа налево с шагом 1, используя цикл с параметром

for(int I=n-1;I>=0;I--){обработка a[I];}

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

for (int I=n-1;I>=0;I-=step){обработка a[I];}

6.2.2 Формирование псевдодинамических массивов