Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование на языке Си. Билеты и ответы

.pdf
Скачиваний:
317
Добавлен:
10.09.2019
Размер:
761.78 Кб
Скачать

БИЛЕТ №16.

ТЕОРЕТИЧЕСКИЙ ВОПРОС: АРГУМЕНТЫ, ПЕРЕДАВАЕМЫЕ ФУНКЦИИ ПО УМОЛЧАНИЮ.

При обращении к функции, можно опускать некоторые её аргументы. Аргументы по умолчанию должны быть заданы в прототипе функции, если она идет после main(), иначе при описании.

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

Пример на языке СИ

///Программа, вычисляющая расстояние между двумя точками

///A(x0, y0) и B(xk, yk) плоскости XY

#include <iostream>

#include <cmath> using namespace std;

/// Описание (сигнатура/прототип) функции

float sum(float, float, float x0 = 0, float y0 = 0);

/// Определение функции (семантика функции)

float sum(float xk, float yk, float x0, float y0){

return sqrtf(powf((xk - x0), 2) + powf((yk - y0), 2));

}

int main()

{

int x1 = 3, y1 = 4;

cout << sum(x1, y1) << endl; /// 5 cout << sum(x1, y1, 3) << endl; /// 4

cout << sum(x1, y1, 4, 3) << endl; /// корень из 2 return 0;

}

ЗАДАЧА: НАПИСАТЬ ФУНКЦИЮ, ВОЗВРАЩАЮЩУЮ НОМЕР ПРЕДПОСЛЕДНЕГО ОТРИЦАТЕЛЬНОГО ЭЛЕМЕНТА ОДНОМЕРНОГО МАССИВА. ПРОДЕМОНСТРИРОВАТЬ ЕЁ ИСПОЛЬЗОВАНИЕ В ПРОГРАММЕ.

Ответ на практическое задание билета №2 такой же.

СИ

#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;

}

БИЛЕТ №17.

ТЕОРЕТИЧЕСКИЙ ВОПРОС: ПРОЕКТЫ.

Процесс создания программы из исходных файлов называется сборкой (building). Сборка включает в себя две стадии: компиляцию (compiling) и связывание (linking, другой перевод — компоновка).

Во время компиляции происходит создание объектных файлов (обычно с расширением .obj) из исходных (с расширением .cpp или .c) и заголовочных (с расширением .h).

После того как скомпилировались объектные файлы в дело вступает компоновщик и связывает объектные и библиотечные файлы (cо стандартным расширением .lib). В конце сборки, если ни компилятор, ни компоновщик не выдали ошибок, мы получим от компоновщика исполняемый файл (с расширением .exe).

NetBeans-проекты состоят из следующих типов файлов:

1.Исходные файлы (файлы .cpp, .c);

2.Файлы заголовков (файлы .h);

3.Файлы ресурсов (могут быть различные расширения);

4.Файлы тестов (файлы .cpp, .c).

5.Важные файлы (могут быть различные расширения).

Пример проекта

main.c

funcLib.h

funcLib.c

#include <stdio.h>

 

 

#include "funcLib.h"

/// #include "funcLib.c"

 

/// двойные кавычки, т. к. находится в папке проекта

/// ^ верхняя строчка не

float c; /// глобальная

extern float c; /// берем глобальную переменную

требуется

переменная

int main()

/// т. к. в проекте все

int sum_Int(int a, int b) {

{

нужные файлы уже лежат

return a + b;

int a = 12, b = 45;

/// IDE об этом знает

}

c = 1.1; /// используем её

int sum_Int(int a, int

 

float d = 1.3;

b);

float sum_Float(float a, float b)

printf("%d %f\n", sum_Int(a, b), sum_Float(c, d));

 

{

/// 57 2.4

float sum_Float(float a,

return a + b;

return 0;

float b);

}

}

 

 

ЗАДАЧА: НАПИСАТЬ ФУНКЦИЮ, ВОЗВРАЩАЮЩУЮ ЧИСЛО ЭЛЕМЕНТОВ ОДНОМЕРНОГО МАССИВА, КРАТНЫХ 2. ПРОДЕМОНСТРИРОВАТЬ ЕЁ ИСПОЛЬЗОВАНИЕ В ПРОГРАММЕ.

Ответ на практическое задание билета №3 такой же.

СИ

#include <stdio.h>

///Функция, возвращающая число элементов одномерного массива, кратных 2

///arr — массив, n — количество элементов в массиве

///Сложность алгоритма: T(n) = O(n)

int bilet3(int *arr, int n){ int i, k = 0;

for (i = 0; i < n; i++) /// От начала к концу

if ((arr[i] % 2) == 0) /// Если очередной элемент массива делится нацело на 2, то k++; /// Увеличиваем счетчик

return k; /// Возвращаем количество элементов, кратных 2

}

int main()

{

int arr[] = {-1, 3, 4, -5, -6}; /// Массив с 5-тью элементами

printf("%d\n", bilet3(arr, 5)); /// Вызов функции и вывод результата на экран: 2 return 0;

}

БИЛЕТ №18.

ТЕОРЕТИЧЕСКИЙ ВОПРОС: ПРЕПРОЦЕССОР.

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

Препроцессор С/С++ (англ. pre processor, предобработчик) — программа, подготавливающая код программы на языке C/C++ к компиляции.

Препроцессор СИ удаляет из кода комментарии, преобразует код в соответствии с макросами и выполняет иные директивы, начинающиеся с символа «#» (такие как #include, #define, разнообразные директивы типа #pragma).

Этапы работы препроцессора СИ:

1.Лексический анализ кода C/C++ (синтаксический анализ не выполняется);

2.Обработка директив;

3.Выполнение подстановок.

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

#<keyword> <parameters>

Ключевое

Параметры

 

Пример

слово

Описание

 

(parameters)

 

(keyword)

 

 

 

 

 

 

 

 

Константа препроцессора:

 

 

Создание нового

#define A 5

 

 

Макрос препроцессора:

 

 

определения <name> со

 

<name> <value>

#define max( a, b ) ( (a) > (b) ? (a) : (b) )

#define

значением <value>.

or others

Вызов макроса: int z = max( x, y );

 

Играет роль константы или

 

 

Оператор #:

 

 

макроса препроцессора.

 

 

Оператор # перед параметром макроса обрамляет

 

 

 

 

 

 

его в двойные кавычки.

Пример:

#define make_str( bar ) # bar

printf( make_str( 42 ) );

Препроцессор преобразует в: printf( "42" );

Оператор ##:

Оператор ## в макросах объединяет две лексемы

Пример:

#define MakePosition( x ) x##X, x##Y, x##Width, x##Height

int MakePosition( Object );

Препроцессор преобразует в: int ObjectX, ObjectY, ObjectWidth,

ObjectHeight;

Пример:

#define cat( x, y ) х ## у

cat( cat( 1, 2 ), 3 );

Препроцессор обращает внимание на внешние скобки,

из-за чего получаем результат обработки: cat(1, 2)3

Ответ не обрадовал. Добавляем:

#define xcat( x, y ) cat( x, y )

Переделываем:

cat( cat( 1, 2 ), 3 ) меняем на xcat( xcat(

1, 2 ), 3 )

Теперь результат:

123

Константы define:

__LINE__ заменяется на номер текущей строки; номер текущей строки может быть переопределен директивой #line; используется для отладки;

__FILE__ заменяется на имя файла; имя файла тоже может быть переопределено с помощью директивы #line;

__DATE__ заменяется на текущую дату (на момент обработки кода препроцессором);

__TIME__ заменяется на текущее время (на момент обработки кода препроцессором);

__TIMESTAMP__ заменяется на текущие дату и время (на момент обработки кода препроцессором); __COUNTER__ заменяется на уникальное число,

начиная от 0; после каждой замены число увеличивается на единицу;

__STDC__ заменяется на 1, если компиляция происходит в соответствии со стандартом языка

C;

__STDC_HOSTED__ определена в C99 и выше; заменяется на 1, если выполнение происходит под управлением ОС.

Ими можно пользоваться (подставлять в вывод функции printf() и др.).

#undef

<name>

Препроцессор "забывает"

#undef A

определение <name>

 

 

 

 

 

Вставка файла.

 

 

 

"name"

 

 

 

Поиск файла выполняется в

 

 

 

текущей папке и папках,

 

 

 

указанных в командной

 

#include

<name>

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

#include <stdio.h>

"name"

<name>

#include "funcLib.h"

 

 

 

Поиск файла выполняется в

 

 

 

папках, содержащих файлы

 

 

 

стандартной библиотеки

 

 

 

(пути к этим папкам зависят

 

 

 

от реализации компилятора)

 

 

 

 

#define MAX 100

#if

<expression>

Начало условного блока

#if MAX == 100

<command>

#error MAX==100!!! /// YES

 

 

 

 

 

#endif

 

 

if defined

#ifdef A

 

<name>

Начало "условного блока

#ifdef

#error A объявлена!

<command>

проверки на

 

#endif

 

 

существование"

 

 

 

 

<name>

if not defined

#ifndef A

#ifndef

Начало "условного блока

#error Ошибка! A не объявлена!

<command>

 

проверки на отсутствие"

#endif

 

 

 

 

 

#if MAX==101

 

 

 

#error MAX=100!!!

#else

<command>

Блок "иначе"

#else

 

 

 

#define X 200

 

 

 

#endif

 

 

 

#define MAX 102

 

 

 

#if MAX==101

#elif

<expression>

else if

#error MAX=100!!!

<command>

Блок "иначе если"

#elif MAX==102

 

 

 

 

#define X 202

 

 

 

#endif

#endif

Конец условного блока

См. предыдущие примеры

 

 

 

#include <iostream>

 

 

 

using namespace std;

 

 

 

#line 200 /// Устанавливаем счетчик строк

 

 

Изменяет содержимое

равным 200

 

<number>

псевдопеременных

int main() /// Эта строка сейчас имеет номер

#line

__LINE__ и __FILE__

200

<filename>

 

<filename> —

{ /// Номер этой строки равен 201

 

 

 

 

необязательный параметр

cout << __LINE__; /// Здесь выводится

 

 

 

номер 202

 

 

 

return 0;

 

 

 

}

 

 

Информационное

 

 

 

сообщение об ошибке.

 

#error

<message>

Дает указание компилятору

См. предыдущие примеры

остановить компиляцию.

 

 

 

 

 

Она используется в

 

 

 

основном для отладки.

 

 

 

Информационное

#define A 100

#warning

<message>

предупреждающее

#ifdef A

сообщение.

#warning A существует

 

 

 

 

Используется для отладки.

#endif

 

 

Работа

 

#pragma

<name>

директивы #pragma зависит

 

 

от конкретной реализации