Программирование на языке Си. Билеты и ответы
.pdfЯвляясь одним из самых популярных языков программирования, C++ широко используется для разработки программного обеспечения. Область его применения включает создание операционных систем, разнообразных прикладных программ, драйверов устройств, приложений для встраиваемых систем, высокопроизводительных серверов, а также развлекательных приложений (например, видеоигры). Существует несколько реализаций языка C++ — как бесплатных, так и коммерческих. Их производят Проект GNU, Microsoft, Intel и Embarcadero (Borland). C++
оказал огромное влияние на другие языки программирования, в первую очередь на Java и C#.
При создании C++ Бьёрн Страуструп стремился сохранить совместимость с языком C. Множество программ, которые могут одинаково успешно транслироваться как компиляторами C, так и компиляторами C++, довольно велико
— отчасти благодаря тому, что синтаксис C++ был основан на синтаксисе C.
"HELLO, WORLD!" НА СИ И C++. |
||
СИ |
C++ |
|
//*********main.c********* |
//*********main.cpp********* |
|
#include <iostream> |
||
#include <stdio.h> |
||
using namespace std; |
||
int main() |
||
int main() |
||
{ |
||
{ |
||
printf("Hello world!\n"); |
||
cout << "Hello world!" << endl; |
||
return 0; |
||
return 0; |
||
} |
||
} |
||
|
ЗАДАЧА: НАПИСАТЬ ФУНКЦИЮ, ВОЗВРАЩАЮЩУЮ НОМЕР ВТОРОГО ОТРИЦАТЕЛЬНОГО ЭЛЕМЕНТА ОДНОМЕРНОГО МАССИВА. ПРОДЕМОНСТРИРОВАТЬ ЕЁ ИСПОЛЬЗОВАНИЕ В ПРОГРАММЕ.
СИ
#include <stdio.h> /// stdio.h для работы с вводом-выводом
///Функция, возвращающая номер (индекс) второго отрицательного элемента одномерного массива
///Если такого элемента в массиве нет, то возвращается значение -1
///arr — массив, n — количество элементов в массиве
///Сложность алгоритма: T(n) = O(n)
int bilet1(double *arr, int n){
int i, j = 0, k = -1; /// k — позиция искомого элемента for (i = 0; i < n; i++) /// Двигаемся от начала к концу
if (arr[i] < 0) { /// Если значение очередного элемента < 0, то
if (j == 0) /// Если первого отрицательного элемента ещё не было найдено, то j = 1; /// Мы нашли первый отрицательный элемент
else if (j == 1) { /// Если первый отрицательный был найден ранее, то
k = i; /// Мы нашли второй отрицательный элемент, который является искомым break; /// Смысла продолжать поиск нет, поэтому выход из цикла
}
}
return k; /// Возвращаем найденную позицию (индекс) элемента
}
int main()
{
double arr[] = {-1.5, 3.9, 4.2, -5.0, 6.7}; /// Массив с 5-тью элементами printf("%d\n", bilet1(arr, 5)); /// Вызов функции и вывод результата на экран: 3 return 0;
}
БИЛЕТ №2.
ТЕОРЕТИЧЕСКИЙ ВОПРОС: СТРУКТУРА ПРОГРАММЫ, ПРИМЕРЫ ЛИНЕЙНЫХ ПРОГРАММ В СТИЛЕ СИ И С++.
Файлы .h — заголовочные файлы. Файлы .c (.cpp) — файлы реализации.
ОБЩАЯ СТРУКТУРА ПРОГРАММЫ.
/// Подключение библиотек (заголовочных файлов)
///Они имеют расширение .h
#include <stdio.h>
///stdio.h для работы с вводом-выводом
#include <stdlib.h>
///stdlib.h для выделения памяти, контроля процесса выполнения программы, преобразований типов…
///Все названия стандартных библиотек выделяются угловыми скобками < >
#include "myFuncLib.h"
///myFuncLib.h — нестандартная библиотека, расположенная в папке проекта
///Выделяется двойными кавычками " "
///Объявление главной функции main
///Основная функция main служит отправной точкой для выполнения программы int main() /// В круглых скобках указываются параметры функции
{ /// начало блока инструкций
int a = 5, b = 6, c; /// Объявление переменных
printf("Hello world!\n"); /// Вызов функции printf (параметр — строка) return 0; /// Возврат значения (должно совпадать с типом функции)
} /// конец блока инструкций
ПРИМЕРЫ ЛИНЕЙНЫХ ПРОГРАММ В СТИЛЕ СИ И C++.
Линейная программа — программа, все операторы которой выполняются последовательно, в том порядке, в котором они записаны. Это самый простой вид программ (<объявление>, <присваивание>, if – else if – else, switch – case, etc.).
Циклическая программа — программа, в которой реализованы команды цикла (for, while, do-while).
Пример линейной программы в стиле СИ |
Пример линейной программы в стиле C++ |
|
|
//*********main.c********* |
//*********main.cpp********* |
#include <stdio.h> |
#include <iostream> |
#include <stdlib.h> |
using namespace std; |
int main() |
int main() |
{ |
{ |
float a, b, c; |
float a, b, c; |
printf("Input a: "); |
cout << "Input a: "; |
scanf("%f", &a); |
cin >> a; |
printf("Input b: "); |
cout << "Input b: "; |
scanf("%f", &b); |
cin >> b; |
c = a / b; |
c = a / b; |
printf("c (a / b) = %f\n", c); |
cout << "c (a / b) = " << c << endl; |
return 0; |
return 0; |
} |
} |
ЗАДАЧА: НАПИСАТЬ ФУНКЦИЮ, ВОЗВРАЩАЮЩУЮ НОМЕР ПРЕДПОСЛЕДНЕГО ОТРИЦАТЕЛЬНОГО ЭЛЕМЕНТА ОДНОМЕРНОГО МАССИВА. ПРОДЕМОНСТРИРОВАТЬ ЕЁ ИСПОЛЬЗОВАНИЕ В ПРОГРАММЕ.
СИ
#include <stdio.h>
/// Функция, возвращающая номер (индекс) предпоследнего отрицательного элемента одномерного массива
///Если такого элемента в массиве нет, то возвращается значение -1
///arr — массив, n — количество элементов в массиве
///Сложность алгоритма: T(n) = O(n)
int bilet2(double *arr, int n){
int i, j = 0, k = -1; /// k — позиция искомого элемента
for (i = n - 1; i >= 0; i--) /// Двигаемся от конца к началу
if (arr[i] < 0) { /// Если значение очередного элемента < 0, то
if (j == 0) /// Если первого отрицательного элемента ещё не было найдено, то j = 1; /// Мы нашли первый отрицательный элемент
else if (j == 1) { /// Если первый отрицательный был найден ранее, то
k = i; /// Мы нашли второй отрицательный элемент, который является искомым break; /// Смысла продолжать поиск нет, поэтому выход из цикла
}
}
return k; /// Возвращаем найденную позицию (индекс) элемента
}
int main()
{
double arr[] = {1.5, 3.9, 4.2, 5.0, -6.7}; /// Массив с 5-тью элементами printf("%d\n", bilet2(arr, 5)); /// Вызов функции и вывод результата на экран: –1 return 0;
}
БИЛЕТ №3.
ТЕОРЕТИЧЕСКИЙ ВОПРОС: ТИПЫ ДАННЫХ ЯЗЫКА СИ (СТАНДАРТНЫЕ И ПОЛЬЗОВАТЕЛЬСКИЕ).
Тип данных — характеристика набора данных, которая определяет:
Диапазон возможных значений данных из набора;
Допустимые операции, которые можно выполнять над этими значениями;
Способ хранения этих значений в памяти.
Различают:
Простые типы данных: целые, действительные числа и др.;
Составные типы данных: массивы, структуры и др.
СТАНДАРТНЫЕ ТИПЫ ДАННЫХ ЯЗЫКА СИ
Базовые стандартные типы данных языка СИ
Тип |
Пояснение |
Размер |
Диапазон значений |
Основной |
|
спецификатор формата |
|||||
|
|
|
|
||
|
|
|
|
|
|
char |
Один символ |
1 байт |
–128…+127 |
%c |
|
(кол-во значений: 28) |
|||||
|
|
|
|
||
char [] |
Массив символов (строка) |
— |
— |
%s |
|
|
|
|
|
|
|
|
|
|
–32768…32767 |
|
|
|
Короткое целое число со |
2 байта* |
(кол-во значений: 216) |
|
|
short |
или |
или |
%hi |
||
знаком |
|||||
|
1 байт** |
–128…+127 |
|
||
|
|
|
|||
|
|
|
(кол-во значений: 28) |
|
|
|
|
|
0…+65535 |
|
|
unsigned |
Короткое целое число без |
2 байта* |
(кол-во значений: 216) |
|
|
или |
или |
%hu |
|||
short |
знака |
||||
1 байт** |
0…+255 |
|
|||
|
|
|
|||
|
|
|
(кол-во значений: 28) |
|
int |
Целое число со знаком |
2 байта |
–32768…32767 |
%i или %d |
|
(кол-во значений: 216) |
|||||
|
|
|
|
||
unsigned int |
Целое число без знака |
2 байта |
0…+65535 |
%u |
|
(кол-во значений: 216) |
|||||
|
|
|
|
||
|
Длинное целое число со |
|
−2 147 483 648…+2 147 |
|
|
long |
4 байта |
483 647 |
%li или %ld |
||
знаком |
|||||
|
|
(кол-во значений: 232) |
|
||
|
|
|
|
||
unsigned |
Длинное целое число без |
4 байта |
0…+4 294 967 295 |
%lu |
|
long |
знака |
(кол-во значений: 232) |
|||
|
|
||||
|
|
|
10-38…1038 |
%f |
|
|
Вещественное число |
|
(%g — наиболее короткий |
||
float |
4 байта |
(указана точность) |
из: %e, %f) |
||
одинарной точности |
|||||
|
|
(кол-во значений: 232) |
(%e — экспоненциальная |
||
|
|
|
|||
|
|
|
|
запись) |
|
|
|
|
10-308…10308 |
%lf |
|
|
Вещественное число двойной |
|
(%g — наиболее короткий |
||
double |
8 байт |
(указана точность) |
из: %e, %f) |
||
точности |
|||||
|
|
(кол-во значений: 264) |
(%e — экспоненциальная |
||
|
|
|
|||
|
|
|
|
запись) |
*— указано значение по стандарту.
**— указано значение из следующего источника: «СИ лекции 2017.pptx» от преподавателя по программированию.
Реальный размер целочисленных типов зависит от реализации.
Стандарт лишь оговаривает отношения в размерах между типами и минимальные рамки для каждого типа:
Так long long не должен быть меньше long, который в свою очередь не должен быть меньше int, который в
свою очередь не должен быть меньше short (но может быть равен ему). Так как char — наименьший из возможных адресуемых типов, другие типы не могут иметь размер меньше него.
Минимальный размер для char — 1 байт, для short и int — 2 байта, для long — 4 байта, для long long — 5 байт.
ФАЙЛЫ.
Файл – именованная область внешней памяти, выделенная для хранения массива данных.
При открытии файла с ним связывается поток ввода-вывода. Выводимая информация записывается в поток, вводимая информация считывается из потока.
Когда поток открывается для ввода-вывода, он связывается со стандартной структурой типа FILE, которая определена в stdio.h. Структура FILE содержит необходимую информацию о файле.
Объявление: FILE *f1, *f2;
Функция открытия файла: FILE * fopen (const char* filename, const char* mode); <filename> — имя открываемого файла (включая путь).
<mode> — способ доступа к файлу:
Type |
Описание |
"r" |
Чтение (файл должен существовать) |
"w" |
Запись (если файл существует, то его содержимое очищается) |
"a" |
Запись в конец (добавление) (файл создается, если он не существует) |
"r+" |
Чтение и запись (файл должен существовать) |
"w+" |
Чтение и запись (если файл существует, то его содержимое теряется) |
"a+" |
Чтение и дополнение (если файл не существует, то он создаётся) |
Пример: myFile = fopen("file.txt", "r");
Функция очистки буфера в файл: int fflush (FILE* stream);
Если данные выходного буфера не были записаны в файл (задача ожидает своей очереди), то они записываются туда (задача становится активной, после — завершается). Поток остается открытым.
Пример: fflush(myfile);
Функция закрытия файла: int fclose(FILE* stream);
Пример: fclose(myfile);
ГЕНЕРАЦИЯ ПСЕВДОСЛУЧАЙНЫХ ЧИСЕЛ. Заголовочный файл <stdlib.h>.
Функция int rand(); возвращает псевдослучайное целочисленное значение в диапазоне от 0 до RAND_MAX
(включая 0 и RAND_MAX).
RAND_MAX в 32-bit системах может быть равен 32767.
Функция void srand(unsigned seed); предопределяет последовательность случайных чисел целым числом seed. Таким образом, при каждом запуске программы функция rand() будет выдавать одни и те же значения в одной и той же последовательности. Подробнее в таблице.
Запуск программы |
Перед rand() вызывается |
Не вызывается srand() |
|
srand(5) |
|||
|
|
||
№1, вызов rand() |
1242 |
533 |
|
№2, вызов rand() |
1242 |
27522 |
|
№3, вызов rand() |
1242 |
15115 |
|
— |
Предопределённое число |
Случайное число |
Функция random_Int, возвращающая число типа integer. Отрезок [A, B]
#include <math.h>
#include <stdlib.h>
int random_Int(int a, int b) {
return floor(((rand() * 1.0) / RAND_MAX) * (b - a + 1.0)) + a;
}
Функция random_Float, возвращающая число типа float. Отрезок [0, 1]
#include <stdlib.h>
float random_Float() { /// float можно заменить на double return rand() * 1.0 / RAND_MAX;
}
ЛОГИЧЕСКИЙ ТИП ДАННЫХ (C99).
Заголовочный файл <stdbool.h>.
В C99 был добавлен логический тип _Bool (с подчеркиванием). Также, дополнительный заголовочный файл <stdbool.h> определяет для него псевдоним bool, а также макросы true (истина) и false (ложь). _Bool ведёт себя также как и обычный встроенный тип, за одним исключением: любое ненулевое (не ложное) присваивание _Bool хранится как единица. Такое поведение защищает от переполнения.
Логический тип данных BOOL (C99)
#include <stdio.h>
#include <stdbool.h> /// Для работы с логическим типом данных int main()
{
bool h1 = false; /// bool то же, что и _Bool printf("%d\n", h1); /// 0
printf("%f\n", h1); /// 0.000000
_Bool h2 = true; /// _Bool то же, что и bool printf("%d\n", h2); /// 1
printf("%f\n", h2); /// 0.000000 return 0;
}