Министерство образования и науки Российской Федерации. Федеральное государственное автономное




Министерство образования и науки Российской Федерации

Федеральное государственное автономное

Образовательное учреждение высшего образования

«Санкт-Петербургский политехнический университет

Петра Великого»

Университетский политехнический колледж

 

 

Методические указания и контрольные задания по дисциплине ПРИКЛАДНОЕ ПРОГРАММИРОВАНИЕ

Для студентов 2 и 3 курса заочной формы обучения

по специальности:

09.02.03. «Программирование в КС»

 

 

Санкт-Петербург

2018

Оглавление

ВВЕДЕНИЕ. 1

ЗАДАНИЯ И ВАРИАНТЫКОНТРОЛЬНОЙ РАБОТЫ.. 20

ПРИМЕРЫ24

ЭКЗАМЕНАЦИОННЫЕ ВОПРОСЫ.. 25

ЛИТЕРАТУРА ДЛЯ ИЗУЧЕНИЯ ДИСЦИПЛИНЫИ ВЫПОЛНЕНИЯ КОНТРОЛЬНОЙ РАБОТЫ: 26

Приложение 1. 29

 


ВВЕДЕНИЕ

Си (англ. C) — компилируемый статически типизированный язык программирования общего назначения, разработанный в 1969—1973 годах сотрудником Bell Labs Деннисом Ритчи как развитие языка Би. Первоначально был разработан для реализации операционной системы UNIX, но впоследствии был перенесён на множество других платформ. Язык программирования Си оказал существенное влияние на развитие индустрии программного обеспечения, а его синтаксис стал основой для таких языков программирования, как C++, C#, Java и Objective-C

Язык программирования Си отличается минимализмом. Авторы языка хотели, чтобы программы на нём легко компилировались с помощью однопроходного компилятора, чтобы каждой элементарной составляющей программы после компиляции соответствовало весьма небольшое число машинных команд, а использование базовых элементов языка не задействовало библиотеку времени выполнения. Однопроходный компилятор компилирует программу, не возвращаясь назад к уже обработанному тексту, поэтому использованию функций и переменных должно предшествовать их объявление. Код на Си можно легко писать на низком уровне абстракции, почти как на ассемблере. Иногда Си называют «универсальным ассемблером» или «ассемблером высокого уровня», что отражает различие языков ассемблера для разных платформ и единство стандарта Си, код которого может быть скомпилирован без изменений практически на любой модели компьютера. Си часто называют языком среднего уровня или даже низкого уровня, учитывая то, как близко он работает к реальным устройствам. Однако в строгой классификации он является языком высокого уровня.

В языке используются лексемы (являются допустимыми):

все символы латинского алфавита

A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z

a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z

цифры

0, 1, 2, 3, 4, 5, 6, 7, 8, 9

и специальные символы

, (запятая),;,. (точка), +, -, *, ^, & (амперсанд), =, ~ (тильда),!, /, <, >, (,), {, }, [, ], |, %,?, ' (апостроф), " (кавычки),: (двоеточие), _ (знак подчёркивания)

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

Также имеется символ #, который не может быть частью никакой лексемы, и используется в препроцессоре[⇨].

Идентификаторы

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

Идентификаторы — это те имена, которые даются программным объектам — (именованным) константам, переменным, типам и функциям.

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

Предопределённые константы

Для введения в программе на Си именованных констант используется директива препроцессора #define:

#define имя константы [значение].

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

#undef имя константы.

 

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

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

числовые (целочисленные или вещественные);

символьные (выделяются знаком апострофа);

текстовые строки (выделяются знаком двойных кавычек).

Ключевые слова[править | править вики-текст]

Ключевые слова — это лексемы (слова), которые зарезервированы компилятором для обозначения типов переменных, класса хранения, элементов операторов.

Стандартом предусмотрены следующие ключевые слова:

для указания операции получения размера объекта: sizeof;

для описания прототипа объекта: typedef;

для объявления переменных:

для обозначения класса хранения переменных: auto, register;

для обозначения того, что объект описывается в другом месте extern;

для обозначения того, что объект статический static;

для обозначения типа переменных char, short,int, long, signed, unsigned,float, double, void (для указания на произвольный родовой тип);

для обозначения специальных типов данных:

struct (структура), enum (перечисление), union;

для обозначения операторов и их элементов:

для обозначения операторов цикла: do, for, while;

для обозначения условного оператора: if, else;

для обозначения оператора выбора: switch, case, default;

для обозначения операторов перехода:

операторы прерывания исполнения кода: break, continue;

для обозначения оператора безусловного перехода: goto;

для обозначения оператора возврата из функции: return.

Позже добавлены следующие ключевые слова:

для обозначения того, что функция является встраиваемой: inline;

для обозначения типа переменной: _Bool, _Complex, _Imaginary;

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

Операция — это некоторая функция, которая выполняется над операндами и которая возвращает вычисленное значение — результат выполнения операции. Каждой операции в Си соответствует свой знак операции (см. выше).

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

унарные операции — операции вида

[знак операции] [операнд]

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

[операнд] [знак операции] [операнд]

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

Унарные операции — это операции, содержащие единственный операнд.

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

+ (унарный плюс), - (унарный минус), ~ (взятие обратного кода),! (логическое отрицание), & (взятие адреса), * (операция разыменовывания указателя), sizeof (операция определения занимаемого объектом объёма памяти).

Бинарные операции — это операции, содержащие два операнда, между которыми расположен знак операции.

К бинарным операциям в Си относятся следующие операции:

+ (сложение), - (вычитание), * (умножение), / (деление), % (взятие остатка от деления), & (поразрядное И), | (поразрядное ИЛИ), ^ (поразрядное исключающее ИЛИ), << (логический сдвиг влево), >> (логический сдвиг вправо), && (логическое И), || (логическое ИЛИ).

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

+= (добавление к левому операнду значения, представленного правым операндом);

-= (вычитание из левого операнда значения, представленного правым операндом);

*= (умножение левого операнда на значение, представленное правым операндом);

/= (деление левого операнда на значение, представленное правым операндом);

&= (поразрядное логическое И над левым и правым операндом);

|= (поразрядное логическое ИЛИ над левым и правым аргументом);

^= (поразрядное логическое исключающее ИЛИ над левым и правым аргументом);

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

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

Данные операции предполагают, что левый операнд представляет собою лево-допустимое выражение.

В Си имеется единственная тернарная операция — условная операция, которая имеет следующий вид:

[условие]? [выражение1]: [выражение2];

и которая имеет три операнда:

[условие] — логическое условие, которое проверяется на истинность,

[выражение1] — выражение, значение которого возвращается в качестве результата выполнения операции, если условие истинно;

[выражение2] — выражение, значение которого возвращается в качестве результата выполнения операции, если условие ложно.

Знаком операции здесь служит целое сочетание?:.

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

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

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

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

оператор if, содержащий проверку одного условия;

и оператор switch, содержащий проверку нескольких условий.

Оператор if работает следующим образом:

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

если условие, указанное в скобках, не выполнено, то сразу выполняется оператор, указанный после оператора if.

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

if((условие));

 

поскольку, фактически, выполняется пустой оператор. Более сложная форма оператора if содержит ключевое слово else:

if((условие)) (оператор)

else (альтернативный оператор)

(следующий оператор)

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

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

Цикл — это фрагмент программного кода, содержащий

условие выполнения цикла — условие, которое постоянно проверяется;

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

В соответствии с этим, различают два вида циклов:

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

цикл с постусловием, где сначала выполняется тело цикла, а уже потом проверяется условие выполнения цикла, и, если условие выполнено, то…;

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

В Си предусмотрен оператор цикла с предусловием:

while(условие) [тело цикла]

и оператор с постусловием do-while:

do [тело цикла] while(условие)

Также имеется оператор

for(блок инициализации;условие;оператор) [тело цикла],

который эквивалентен следующему блоку операторов:

[блок инициализации]

while(условие)

{

[тело цикла]

[оператор]

}

 

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

Операторы безусловного перехода

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

Оператор

goto [метка],

где [метка] — это некоторый (числовой) идентификатор, передаёт управление тому оператору, который помечен в программе указанной меткой:

[метка]: [оператор]

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

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

 

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

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

оператор continue прерывает выполнение тела цикла и передаёт управление в начало цикла, что инициирует проверку условия цикла.

Оператор continue может быть использован только внутри операторов do, while и for; оператор break также может использоваться внутри оператора switch.

Существует два особых случая применения операторов break и continue:

если оператор continue встретился в теле оператора for, то сначала происходит выполнение оператора, а уже затем происходит проверка условия цикла, таким образом оператор continue предназначен для немедленного перехода к следующей итерации выполнения цикла;

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

Оператор возврата из функции

В Си определён оператор return, который прерывает выполнение функции, где использован данный оператор. Если функция не должна возвращать значение, то используется вызов

return;

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

return[значение];

 

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

Функции

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

Для того, чтобы задать функцию в Си, необходимо её объявить:

сообщить имя (идентификатор) функции,

перечислить входные параметры (аргументы)

и указать тип возвращаемого значения,

Также необходимо привести определение функции, которое содержит блок операторов, реализующих поведение функции.

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

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

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

Объявление функции

Объявление функции имеет следующий формат:

[описатель] [имя] ([список])где

[описатель] — описатель типа возвращаемого функцией значения;

[имя] — имя функции (уникальный идентификатор функции);

[список] — список (формальных) параметров функции.

При необходимости в описателе могут присутствовать дополнительные элементы:

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

модификатор static задаёт статическую функцию;

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

Список параметров функции задаёт сигнатуру функции.

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

Определение функции имеет следующий формат:

[описатель] [имя] ([список]) [тело]

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

Тело функции имеет следующий вид:

{

[последовательность операторов]

return ([возвращаемое значение]);

}

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

сохранение точки вызова в стеке;

выделение памяти под переменные, соответствующие формальным параметрам функции;

инициализация переменных значениями переменных (фактических параметров функции), переданных в функцию при её вызове, а также инициализация тех переменных, для которых в объявлении функции указаны значения по умолчанию, но для которых при вызове не были указаны соответствующие им фактические параметры;

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

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

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

void example_func(int array[]); // array — указатель на первый элемент массива типа int

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

 

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

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

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

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

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

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

Размер целочисленных типов данных варьируется от не менее 8 до не менее 32 бит. Стандарт C99 увеличивает максимальный размер целого числа — не менее 64 бит. Целочисленные типы данных используются для хранения целых чисел (тип char также используется для хранения ASCII-символов). Все размеры диапазонов представленных ниже типов данных минимальны и на отдельно взятой платформе могут быть больше.[8]

 

Стандарт не требует, чтобы два разных типа имели разный размер: sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)[9]. Таким образом, даже типы char и long могут иметь одинаковый размер, но такие платформы очень редки. Стандарт гарантирует, что тип char всегда равен 1 байту.

Минимальный диапазон значений целых типов по стандарту определяется с -(2N-1) по 2N-1, где N — разрядность типа. Реализация компиляторов может расширять этот диапазон по своему усмотрению. На практике чаще используется диапазон с -2N по 2N-1. Минимальное и максимальное значения каждого типа указывается в файле limits.h в виде макросов.

Отдельное внимание стоит уделить типу char. Формально это отдельный тип, но фактически char эквивалентен либо signed char, либо unsigned char, в зависимости от компилятора.

Типы с приставками least- и fast- можно считать заменой типам int, short, long, с той лишь разницей, что первые дают программисту выбрать между скоростью и размером. Тип данных Размер Минимальный диапазон значений Первое появление

signed char минимум 8 бит от −127 (= -(28−1)) до 127

unsigned char минимум 8 бит от 0 до 255 (=28−1)

char минимум 8 бит от −127 до 127 или от 0 до 255 в зависимости от компилятора

short int минимум 16 бит от −32,767 (= -(215−1)) до 32,767 unsigned short int минимум 16 бит от 0 до 65,535 (= 216−1)

int минимум 16 бит от −32,767 до 32,767

unsigned int минимум 16 бит от 0 до 65,535 (= 216−1)

long int минимум 32 бита от −2,147,483,647 до 2,147,483,647 K&R C

unsigned long int минимум 32 бита от 0 до 4,294,967,295 (= 232−1) long long int минимум 64 бита от −9,223,372,036,854,775,807 до 9,223,372,036,854,775,807

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

В Си есть три разных способа выделения памяти (классы памяти) для объектов:

Статическое выделение памяти: пространство для объектов создаётся в сегменте данных программы в момент компиляции; время жизни таких объектов совпадает со временем жизни этого кода. Изменение таких объектов ведёт к так называемому в стандарте «неопределённому поведению» (англ. undefined behaviour). На практике эта операция приводит к ошибке во время выполнения.

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

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

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

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

В данном разделе рассмотрено представление в памяти программы в операционной системе GNU/Linux и архитектуре amd64. Порядок расположения кучи, стека и других областей может отличаться в других архитектурах и операционных системах.

При запуске программы из исполняемого файла в оперативную память импортируются инструкции процессора (машинный код) и инициализированные данные. В то же время в старшие адреса импортируются аргументы командной строки (доступные в функции main со следующей сигнатурой во втором аргументе int argc, char ** argv) и переменные окружения.

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

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

 

Память, выделенная динамически, предоставляется из кучи (heap). Для выделения памяти во время работы программы используется функция malloc из stdlib.h. Для освобождения функция free.

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

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

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

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

Простейшая программа на Си имеет следующий вид:

main() {}

По умолчанию предполагается, что основная функция программы (функция main()) возвращает целое число, поэтому такая программа должна компилироваться (возможно, с выдачей одного или нескольких предупреждений), если компилятор реализует стандарт ANSI C. Если, однако, компилятор следует стандарту C99, то такой код не будет компилироваться, и потребуется явное описание типа возвращаемого функцией main() значения. Допускается не писать оператор return у функции main(). В таком случае, согласно стандарту, функция main возвращает 0 (включая исполнение всех обработчиков, назначенных на exit()), подразумевая, что программа успешно завершилась[10].

ЗАДАНИЯ

1. Запустить программу, содержащую строку "Hello, world" и массив символьных данных с таким же содержанием выведенного на консоль текста.

 

2.Напишите описания следующих объектов: указателя на символ; массива из 10 целых; ссылки на массив из 10 целых; указателя на массив символьных строк; указателя на указатель на символ; целого-константы; указателя на целое-константу. Описания снабдить инициализацией.

 

Задание 3. Напишите программу, которая печатает размеры основных типов и типа указателя.

Используйте операцию sizeof.

 

4. Напишите программу, которая печатает буквы от 'a' до 'z' и цифры от '0' до '9' и их целые значения. Проделайте то же самое для других видимых символов. Проделайте это, используя шестнадцатеричную запись.

 

5. Напечатайте шестнадцатеричные представления переменных 4х разных типов данных.

 

6. Напишите функцию, печатающую числа с мантиссой разных размеров памяти.

 

7. Напишите функцию, которая меняет местами значения двух целых.

 

8. Каков размер массива str в следующем примере: char str[] = "a short string"; Какова длина строки"a short string"? Напишите код, выводящий на консоль это выражение.

 

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

название месяца и количество дней в нем.

 

10. С помощьюt typedef определите типы: unsigned char, константный unsigned char, указатель на целое, указатель на символ, указатель на массив символов.

 

11. Напишите цикл с for перепишите его с помощью оператора while.

 

12. Что произойдет при делении на нуль в вашей программе на С++?

 

13. Укажите порядок вычисления следующих выражений.

А)*p++

Б)*--p

Придумайте короткую программу с данными 2-мя значениями.

 

14. Напишите такие функции: подсчет длины строки, копирование строк Какими должны быть типы параметров и результатов функций? Сравните их со стандартными версиями, имеющимися в<string.h>.

 

15. Напишите функцию cat(), которая получает два параметра-строки и возвращает строку, являющуюся их конкатенацией. Для результирующей строки используйте память, отведенную с помощью new.

 

16. Напишите программу с применением в конструкции switch и case.

 

17. Составьте следующие описания: функция с параметрами типа указатель на символ; указатель на функцию; функция с параметром, имеющим тип такого указателя; функция, возвращающая такой указатель.

 

18. Напишите программу, подобную той, что выдает"Hello, world". Она получает имя(name) как параметр командной строки и выдает"Hello, name". Измените программу так, чтобы она получала произвольное число имен и всем им выдавала свое приветствие: "Hello,...".

 

19. Напишите программу, которая, беря из командной строки произвольное число имен файлов, все эти файлы переписывает один за другим в cout. Поскольку в программе происходит конкатенация файлов, вы можете назвать ее cat от слова concatenation - конкатенация).

 

20. Переведите небольшую программу с языка С на С++. Измените заголовочные файлы так, чтобы они содержали описание всех вызываемых функций и описание типов всех параметров. По возможности все команды #define замените конструкциями enum, const. Удалите из файлов.c все описания внешних, а определения функций приведите к виду, соответствующему С++. Вызовы malloc() и free() замените операциями new и delete. Удалите ненужные операции приведения.

 

21. Напишите функцию sort(), использующую более эффективный алгоритм сортировки.

 

22. Посмотрите в учебном пособии на определение структуры tnode Напишите функцию, заносящую новые слова в дерево узлов tnode. Напишите функцию для вывода узлов дерева tnode. Напишите функцию, которая производит такой вывод в алфавитном порядке. Измените структуру tnode так, чтобы в ней содержался только указатель на слово произвольной длины, которое размещается с помощью new в свободной памяти. Измените функцию так, чтобы она работала с новой структурой tnode.

 

23. Напишите шифрующую программу, которая читает символы из cin и пишет их в cout в зашифрованном виде. Можно использовать следующий простой метод шифрации: для символа s зашифрованное представление получается в результате операцииs s^key[i], где key – массив символов, передаваемый в командной строке. Символы из массива key используются в циклическом порядке, пока не будет прочитан весь входной поток. Первоначальный текст получается повторным применением той же операции с теми же элементами key. Если массив key не задан (или задана пустая строка), шифрация не происходит.

 

24. Напишите макропроцессор с простыми возможностями, как у препроцессора С. Текст читайте из cin, а результат записывайте в cout. Вначале реализуйте макроопределения без параметров. Подсказка: в программе калькулятора есть таблица имен и синтаксический анализатор, которыми можно воспользоваться.

 

25. Определите класс histogram (гистограмма), в котором ведется подсчет чисел в определенных интервалах, задаваемых в виде параметров конструктору этого класса. Определите функцию выдачи гистограммы. Сделайте обработку значений, выходящих за интервал. Для решения обратитесь к <task.h>.

 

26. Напишите функцию, которая будет переворачивать двумерный массив. (Первый элемент массива станет последним).

 

Таблица 1

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

Вариант 1, 6,8,13 А),24 Вариант 8, 14,21,9,10 Вариант 11,24,4,13Г),1
  2,11,23,8,13А)   11,15,8,23,20   8,25,5,13В),1
  3,8,23,22,5   8,13 Д),7,18,21   1,8,14,6,13Б)
  4,13 Б),20,6,19   16,8,6,17,22   2,8,16,7,13А)
  5,14,23,19,7   11,17,5,16,13А)   3,21,8,12,20
  6,13 В),18,9,14   13 Е),16,4,23,5   4,14,9,10,11
  7,14,16, 17,3   18,14,3,13Г),1    
  8,11, 21,16,5   8,19,2,13В),1    
  9,13 Г),15,6,26   8,20,1,13Б),22    
  10,14, 16,12,7   11,21,1,13А),23    
  11,23, 11,8,21   11,22,2,9,18    
  12,23, 10,9,21   8,23,3,4,12    

 

 

ПРИМЕРЫПРОГРАММ

1.ПРИМЕР

#include "stdafx.h"

#include <iostream>

using namespace std;

 

int main(int argc, char* argv[])

{

cout << "My first program!" << endl;

system("pause");

return 0;

}

2. ПРИМЕР

#include <stdio.h>

int main (void)

{

int a, b = 5, c;

float x, y = -.5, z;

printf("a=");

scanf("%d", &a);

x = c = a;

printf("a=%d, c=%d, x=%f\n",a,c,x);

a += b;

printf("a=%d\n", a);

return 0;

}

ЭКЗАМЕНАЦИОННЫЕ ВОПРОСЫ

 

1.Классификация языков программирования (компилируемые, исполняемые на виртуальных машинах и интерпретируемые ЯП). Язык программирования C++. Стандарт языка. Стандартная библиотека.

2.Структура простейшей программы на C++. Процесс компиляции.

3.Базовые типы C++. Переменные, константы и литералы. Приведение типов.

4.Хранение целых и вещественных чисел в памяти компьютера.

5.Оператор присваивания. Арифметические операторы. Операторы сравнения и логические операторы. Порядок действий (приоритет операторов).

6.Использование библиотечных функций на примере заголовочного файла 7.Ветвления в программе. Условный оператор и оператор множественного выбора.

8.Операторы для организации



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2018-12-21 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: