Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование на языке Си. Учебно-методическое пособие

.pdf
Скачиваний:
1
Добавлен:
07.09.2026
Размер:
1 Мб
Скачать
☆
91
Контрольные вопросы
Какие виды деревьев вы знаете? Преимущества и недостатки деревьев. Как можно вставить элемент в дерево?
13. Создание проектов
При создании достаточно больших программ их следует разбивать на несколько файлов для улучшения функционатьности и удобства работы. Эти
файлы объединятся в проект.
Сначала создадим простейший проект в среде dev-cpp, в который будет входить всего один файл:
• выбрать пункт верхнего меню Файл – Создать – Проект;
• в появившемся окне выбрать тип проекта Empty Project (пустой проект), ввести имя проекта и щелкнуть по кнопке ОК:
• теперь в левой части окна нужно включить вкладку Проект, где появится название проекта (папка); если нажать на правую кнопку мыши, появляется контекстное меню, в котором можно Создать файл (новый), Добавить к
проекту, Удалить из проекта.
Файл main.cpp практически повторяет однофайловую программу, но не содержит подпрограмм.
Тем не менее, в начале программы нужно вставить объявления всех используемых процедур (заголовки с точкой с запятой в конце). Этим мы скажем транслятору, что такие процедуры есть (в других файлах или в библиотеках), и определим типы их параметров. Чаще эти объявления помещаются в отдельный файл с расширением .h и подключают с помощью директивы #include.
Для глобальных объектов – в одном модуле (там, где выделяется память
под глобальные переменные) они объявляются так же, как и обычно. Во всех остальных модулях, использующих глобальные переменные, перед их
объявлением ставится ключевое слово extern (от англ. external – внешний). Это означает, что они располагаются в каком-то другом модуле.
Например extern int X[]; размеры массивов указывать не нужно, потому
что память тут не выделяется. Начальные значения глобальных переменных
можно задавать только в том модуле, где они размещаются в памяти (то есть объявляются без ключевого слова extern).
Пример В проект добавляем prog.c и func.c
func.c
#include <iostream.h>
92
extern int N; void swap(int &x, int &y) { int t=x; x=y; y=t; } void sort(int *x) { int i, k; do { k=0; for(i=1; i<N; i++) if(x[i]<x[i-1]) { swap(x[i], x[i-1]); k=1;} } while(k); cout<<N<<endl; } void print (int *x) { for(int i=0; i<N; i++) cout<<x[i]<<" "; cout<<endl; }
func.h
void swap(int &, int &); void sort(int *); void print(int *);
prog.c
#include <iostream.h> #include "func.h" int m[10]={7,3,2,4,5,1,8,6,9,0}; int N=sizeof(m)/sizeof(int);
main(){ print(m); sort (m); print(m); }
Контрольные вопросы
Для чего используются проекты? Для чего используются заголовочные файлы?
93
14. Дополнительные возможности языка С++
Главное отличие языка С++ – это язык объектно-ориентированного
программирования. Но и в традиционном структурном программировании
бывает удобно использовать возможности С++.
Array и Vector
В стандартной библиотеке C++ есть std::array и std::vector, в которых добавлен функционал, упрощающий процесс управления массивами. Array – аналог статических массивов, vector – динамических. Основаны на ООП.
array
#include <iostream> #include <array> using namespace std; main(){ array<int, 4> a{ 1,4,9,16}; for(int i=0; i<a.size();i++) { cout << a[i]<<" "; cout<< a.at(i)<<endl; //a.at(i) - cс проверкой на диапазон, медленне но надежнее } }
vector
#include <iostream> #include <vector> using namespace std; void printarray (vector <int>a) { for(int i=0; i<a.size();i++) { cout << a[i] <<" "; // или cout<< a.at(i); } cout<<endl; } main(){ vector<int> a{1,4,9,16}; printarray(a); a={1,2,3}; printarray(a);
//изменение размера вектора a.resize(4);
94
printarray(a);
vector<int> b(5); printarray(b); b=a; //присваивание значений одного вектора другому // b[3]=4; printarray(a); printarray(b); //проверка на равенство двух векторов if(a==b) cout<<"a==b"<<endl;else cout<<"a!=b"<<endl; //добавление нового элемента к вектору. b.push_back(-5); printarray(b); }
Функции с начальными значениями параметров
В языке С++ можно задавать так называемые параметры функции по
умолчанию. Если в объявлении формального параметра задано выражение, то оно воспринимается как умолчание этого параметра. Все последующие параметры также должны иметь умолчания. Умолчания параметров подставляются в вызов функции при отсутствии в нём последних по списку
параметров.
Пример
int f(int m = 1, int n = 2){ printf("%d %d\n", m ,n); } f(5, 6); f(5); f();
Перегрузка функций
Позволяет создать несколько функций с одним именем, но разными
параметрами. Конкретный экземпляр функции выбирается по типу и количеству параметров.
Пример
int add(int a, int b) { return(a + b); } int add (int a, int b, int c) {
95
return(a + b + c); } float add (int a, double b) { return(b+a); } main(void) { cout << add(200, 101) << endl; cout << add(100, 201, 700) << endl; cout << add(700,1.01) << endl; }
Шаблоны функций
Шаблон позволяет создавать функции без указания точного типа(ов) некоторых или всех переменных. Конкретный тип определяется по типу фактических параметров при вызове функции.
Пример
template <typename T> void print(T * m, int n) { T a; for (int i = 0; i < n; i++) cout << m[i] << " "; cout << endl<<sizeof(a)<<endl; }
int main(){ int ia[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double da[] = {1.2345, 2.234, 3.57, 4.67876, 5.346, 6.1545, 7.7682}; char ca[] = {"1234"};
print(ia, 10); print(da, 7); print(ca, 4); }
96
Указатели на функции
Указатель на функцию содержит адрес в памяти, начиная с которого
располагается выполняемый код функции. Этот адрес можно сохранить, а затем использовать с помощью указателя соответствующего функции типа. Пример
#include <iostream.h> int xx (int a) { cout <<a<<"+"<<a<<endl; return a+a; } int yy ( int a) { cout <<a<<"*"<<a<<endl; return a*a; } int main () { int (*x)(int a); printf("%p",xx); - выведет адрес функции в памяти x = xx; cout<<x(3)<<'\n'; x = yy; cout<<x(4)<<'\n'; }
Передача функции в качестве параметра
Пример
#include <iostream.h> int xx (int a) { cout <<a<<"+"<<a<<endl; return a+a; } int yy ( int a) { cout <<a<<"*"<<a<<endl; return a*a; } int call (int a, int (*f) (int)) { cout << f(a) <<"\n"; }
int main () { call(3,xx); call(4,yy); }
97
Пример программы, использующей проекты, шаблоны, перегрузку
функций, передачу функций в качестве параметра.
Функция clock() возвращает время, пройденное с момента запуска программы, вызвавшей функцию clock(). Если часы недоступны, то
возвращается -1. Для преобразования возвращаемой величины в секунды надо разделить ее на CLOCKS_PER_SEC.
//main.cpp #include "lib.h" #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <time.h> const int n=30000; int A[n]; double B[n];
template <typename T> void FillRand (int n, T *A) { for(int i=0;i<n;i++) if(sizeof(T)==sizeof(int) ) A[i]=rand(); else A[i]=rand()/97; }
template <typename T> float timer(int n, T *a,void (*f) (int, T *)) { clock_t a1,a2; srand(1); FillRand(n,a); a1=clock(); f(n,a); a2=clock(); return (float)(a2-a1)/CLOCKS_PER_SEC; }
int main (){ printf("int SelectSort %.3f\n",timer(n,A,SelectSort)); printf("float SelectSort %.3f\n",timer(n,B,SelectSort));
printf("int InsertSort %.3f\n",timer(n,A,InsertSort)); printf("float InsertSort %.3f\n",timer(n,B,InsertSort));
printf("int BubbleSort %.3f\n",timer(n,A,BubbleSort)); printf("float BubbleSort %.3f\n",timer(n,B,BubbleSort));
98
}
//lib.h void SelectSort(int n, int A[]); void BubbleSort(int n, int A[]); void InsertSort(int n, int A[]); void SelectSort(int n, double A[]); void BubbleSort(int n, double A[]); void InsertSort(int n, double A[]);
//lib.cpp //lib.cpp #include <stdlib.h> #include <time.h>
void SelectSort(int n, int A[]) { int i,j,k,t; for (i=1;i<n;i++) { k=i; for (j=i+1;j<=n;j++) { if(A[k]>A[j]) k=j; } t=A[i]; A[i]=A[k]; A[k]=t; } }
void SelectSort(int n, double A[]) { int i,j,k; double t; for (i=1;i<n;i++) { k=i; for (j=i+1;j<=n;j++) { if(A[k]>A[j]) k=j; }
99
t=A[i]; A[i]=A[k]; A[k]=t; } }
void BubbleSort(int n, int A[]) { int i,j,t; for (i=0;i<n-1;i++) { for (j=n-1;j>i;j--) { if (A[j]<A[j-1]) { t=A[j]; A[j]=A[j-1]; A[j-1]=t; } } } }
void BubbleSort(int n, double A[]) { int i,j; double t; for (i=0;i<n-1;i++) { for (j=n-1;j>i;j--) { if (A[j]<A[j-1]) { t=A[j]; A[j]=A[j-1]; A[j-1]=t; } } } }
void InsertSort(int n, int A[]) { int i,j,t;
100
for (i=1;i<n;i++) { t=A[i]; j=i-1; while(j>=0 && t<A[j]) { A[j+1]=A[j]; j--; } A[j+1]=t; } }
void InsertSort(int n, double A[]) { int i,j; double t; for (i=1;i<n;i++) { t=A[i]; j=i-1; while(j>=0 && t<A[j]) { A[j+1]=A[j]; j--; } A[j+1]=t; } }
Функции с переменным числом параметров
В языке С++ существует возможность использовать функции с переменным числом параметров. Для объявления такой функции надо указать многоточие (,…) в конце списка параметров функции. Для вызова такой
функции не требуется никаких специальных действий, просто задается столько параметров, сколько нужно.
Во время интерпретации списка параметров такая функция пользуется информацией, не доступной компилятору. Поэтому он не в состоянии гарантировать, что ожидаемые параметры действительно присутствуют или что
они имеют правильные типы. Ясно, что, если параметр не был объявлен,
компилятор не имеет информации, необходимой для выполнения стандартной
проверки и преобразований типа.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]