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

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

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

БИЛЕТ №13.

ТЕОРЕТИЧЕСКИЙ ВОПРОС: ОДНОМЕРНЫЕ ДИНАМИЧЕСКИЕ МАССИВЫ.

СИ

#include <stdio.h>

#include <stdlib.h> /// для работы с malloc, calloc, reallocconst int N = 2;

int sum(int *arr, int n){ int i, s = 0;

for (i = 0; i < n; i++) s += arr[i];

///ввод массива: scanf("%d", &arr[i]);

///вывод массива: printf("%d ", arr[i]); return s;

}

int main()

{

///Объявление одномерного массива из N элементов

///При помощи функции malloc()

int *A = (int *)malloc( N * sizeof(int) );

/// При помощи функции calloc()

int *B = (int *)calloc( N, sizeof(int) );

/// Работа с элементами массива одинакова

A[0] = 1; A[1] = 2; printf("%d\n", A[1]); /// 2 B[0] = 1; B[1] = 2; printf("%d\n", B[1]); /// 2

///Увеличиваем размер массива A на 1 функцией realloc()

A = (int *)realloc(A, (N + 1) * sizeof(int));

///Уменьшаем размер массива B на 1 функцией realloc()

B = (int *)realloc(B, (N - 1) * sizeof(int));

///Снова работаем

A[2] = 4;

printf("%d | %d\n", sum(A, N + 1), sum(B, N - 1)); /// 7 | 1

/// Обязательно освобождаем память free(A); free(B);

return 0;

}

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

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

СИ

#include <stdio.h>

///Функция, меняющая местами последнюю и предпоследнюю строки двумерного массива

///arr — массив, n — количество строк, m — количество столбцов

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

void bilet6(char *arr, int n, int m){ int i; char ch;

int wn1 = n - 1; int wn2 = n - 2; for (i = 0; i < m; i++){

ch = arr[m*wn1 + i];

arr[m*wn1 + i] = arr[m*wn2 + i]; arr[m*wn2 + i] = ch;

}

}

int main() {

int i, j; /// Счетчики циклов

/// Массив размером 4 x 6 (4 строки, 6 символов)

char arr[4][6] = {{"str_1"}, {"str_2"}, {"str_3"}, {"str_4"}};

///6 символ в каждой строке — \0 bilet6(&arr[0][0], 4, 6); /// Обработка for (i = 0; i < 4; i++) {

for (j = 0; j < 5; j++)

printf("%c", arr[i][j]); /// Вывод printf(" ");

}

printf("\n");

///Вывод: str_1 str_2 str_4 str_3

return 0;

}

 

 

БИЛЕТ №14.

 

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

Функция может возвращать:

 

Значение (C, C++): int Func(int a) {return a;}

 

Адрес (C, C++): int* Func(int n) {return (int *)malloc(n * sizeof(int));}

 

Ссылку (C++): int& Func(int *a, int i) {return a[i];}

 

 

 

 

 

 

Возврат указателя (СИ, C++)

 

 

 

#include <stdio.h>

 

 

 

#include <stdlib.h> /// для работы с malloc

 

 

 

/// Функция, возвращающая указатель на новый массив из N элементов

 

 

 

int * int_array(int N){

 

 

 

int *A = (int *) malloc(N * sizeof(int));

 

 

 

return A;

 

 

 

/// вместо 2-х строк: return (int *) malloc(N * sizeof(int));

 

 

 

}

 

 

 

int main()

 

 

 

{

 

 

 

int *arr = NULL; /// начальное значение NULL

 

 

 

arr = int_array(5); /// arr теперь "указывает на массив"

 

 

 

arr[0] = 5; arr[1] = 10; /// работаем как с массивом

 

 

 

printf("%d %d", arr[0], arr[1]); /// 5 10

 

 

 

free(arr); /// не забываем освобождать память

 

 

 

return 0;

 

 

 

}

 

Возврат ссылки (only C++)

#include <iostream> /// для работы с вводом-выводом #include <cstdlib> /// для работы с памятью

using namespace std; /// для удобной работы с cin, cout int & Func (int *a, int i) {

return a[i];

}

int main()

{

///Заводим указатель int *a = NULL;

a = new int[3]; /// Массив из 3-х элементов (язык C++)

///Первый параметр — массив, второй — индекс массива

Func(a, 0) = 4; Func(a, 1) = 5; Func(a, 2) = 6;

///Вывод значений: 4 5 6

cout << a[0] << ' ' << a[1] << ' ' << a[2] << endl;

/// Освобождение памяти delete [] a;

return 0;

}

Общий пример (C++)

#include <iostream> #include <cstdlib> using namespace std;

int Func1(int a) { /// Возврат значения return a;

}

int * Func2(int n) { /// Возврат адреса return new int[n];

/// или в СИ: return (int *) malloc(n * sizeof(int));

}

int & Func3(int *a, int i) { /// Возврат ссылки return a[i];

}

int main()

{

/// По значению

cout << Func1(5) << endl; /// 5

///По адресу int *a = NULL; a = Func2(1); a[0] = 4;

cout << a[0] << endl; /// 4

///По ссылке

Func3(a, 0) = 4;

/// Освобождаем память delete [] a;

return 0;

}

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

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

СИ

#include <stdio.h>

///Функция, меняющая местами последний и предпоследний столбец двумерного массива

///arr — массив, n — количество строк, m — количество столбцов

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

void bilet7(double *arr, int n, int m){ int i; double d;

int wm1 = m - 1; int wm2 = m - 2; for (i = 0; i < n; i++){

d = arr[i*m + wm1];

arr[i*m + wm1] = arr[i*m + wm2]; arr[i*m + wm2] = d;

}

}

int main()

{

int i, j; /// Счетчики циклов

double arr[3][4] = {{-1.5, 3.9, 4.2, 41.0}, {-5.4, -1.0, 56.6, 42.2}, {-3.8, 1.9, 6.2, 96.8}};

/// Массив размером 3 x 4 (3 строки, 4 столбца) bilet7(&arr[0][0], 3, 4); /// Обработка

for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++)

printf("%lf ", arr[i][j]); /// Вывод printf("\n");

}

return 0;

}

БИЛЕТ №15.

ТЕОРЕТИЧЕСКИЙ ВОПРОС: ПЕРЕГРУЗКА ФУНКЦИЙ.

Под перегрузкой функции понимается, определение нескольких функций (две или больше) с

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

Перегрузка функций имеется в C++, но в C данной возможности нет.

Пример перегрузки функций

#include <iostream> using namespace std;

int sum(int a, int b, int c){

cout << "(3 parameters) int sum" << endl; return a + b + c;

}

int sum(int a, int b){

cout << "(2 parameters) int sum" << endl; return a + b ;

}

float sum(float a, float b, float c){

cout << "(3 parameters) float sum" << endl; return a + b + c;

}

double sum(double a, double b, double c){

cout << "(3 parameters) double sum" << endl; return a + b + c;

}

int main()

{

int a1=1, b1=2, c1=3; float a2=2, b2=4, c2=7; double a3=3, b3=7, c3=14;

sum(a1, b1, c1); /// (3 parameters) int sum sum(a1, b1); /// (2 parameters) int sum sum(a2, b2, c2); /// (3 parameters) float sum sum(a3, b3, c3); /// (3 parameters) double sum return 0;

}

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

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

СИ

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

}