Компьютерные и информационные технологии
Создание работающего консольного приложения со средой C++ Builder, рассмотрение типов данных языка и операторов ввода-вывода. Ознакомление с операторами языка, использование операторов выбора и цикла. Описание работы с функциями и одномерными массивами.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | методичка |
Язык | русский |
Дата добавления | 26.02.2014 |
Размер файла | 1005,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
isgraph(c)
Возвращает 1, если с - печатаемый и видимый символ, и 0 - в противном случае; отличается от isprint() тем, что не включает в себя символ пробела
ispunct(c)
Возвращает 1, если с - символ пунктуации, и 0 - в противном случае
isspace(c)
Возвращает 1, если с - символ пробела, и 0 - в противном случае
tolower(c)
Переводит символ с из верхнего регистра в нижний
toupper(c)
Переводит символ с из нижнего регистра в верхний
Работа функций основана на анализе ASCII-кодов символов.
Задание
1. Запустите C++Builder.
2. Составьте программу, в которой с клавиатуры вводится и обрабатывается в соответствии с вариантом задания (таблица) некоторый символ. Используйте приведенные выше функции работы со символами.
3. Выполните компиляцию программы. При наличии ошибок внесите исправления.
4. Сдайте отчет преподавателю.
Варианты
№ |
Задача |
|
Для введенного пользователем символа определить, является ли этот символ буквой |
||
Перевести символ в нижний регистр, если он является буквой в вернем регистре |
||
Для введенного пользователем символа определить, является ли этот символ цифрой |
||
Для введенного пользователем символа определить, является ли этот символ знаком препинания |
||
Для введенного пользователем символа определить, является ли этот символ пробелом |
||
Для введенного пользователем символа определить, является ли этот символ управляющим |
||
Для введенного пользователем символа определить, является ли этот символ буквой нижнего регистра |
||
Для введенного пользователем символа определить, является ли этот символ печатаемым |
||
Для введенного пользователем символа определить, является ли этот символ шестнадцатеричной цифрой |
||
Для введенного пользователем символа определить, является ли этот символ буквой верхнего регистра |
||
Для введенного пользователем символа определить, является ли этот символ печатаемым и видимым |
||
Для введенного пользователем символа определить, является ли этот символ буквой или цифрой |
||
Перевести символ в верхний регистр, если он является буквой в нижнем регистре |
||
Умножить число на 10, если пользователь ввел цифру |
||
Вывести символ на экран, если он является печатаемым и видимым |
||
Если пара введенных символов - цифры, вывести на экран их сумму |
||
Для введенного пользователем символа определить, является ли этот символ пробелом |
||
Для введенного пользователем символа определить, является ли этот символ шестнадцатеричной цифрой |
||
Вывести символ на экран, если он является буквой или цифрой |
||
Перевести символ в нижний регистр, если он является буквой в вернем регистре |
||
Прибавить к числу 2, если пользователь ввел цифру |
||
Вывести символ на экран, если он является буквой |
||
Для введенного пользователем символа определить, является ли этот символ знаком препинания |
||
Для введенного пользователем символа определить, является ли этот символ пробелом |
||
Если пара введенных символов - цифры, вывести на экран их произведение |
Лабораторная работа 8
Строки, литералы. Передача строк в функции
Цель работы ? приобрести навыки работы со строками и литералами в языке С++, получить практические навыки при передаче строк в функции.
Теория
Строки и литералы
Для того чтобы работать с текстом, в языке Си++ не существует особого встроенного типа данных. Текст представляется в виде последовательности знаков (байтов), заканчивающейся нулевым байтом.
Строки представляются в виде массива байтов.
Пример
char string[20];
string[0] = 'H';
string[1] = 'e';
string[2] = 'l';
string[3] = 'l';
string[4] = 'o';
string[5] = 0;
В массиве string записана строка «Hello». При этом мы использовали только 6 из 20 элементов массива.
Для записи строковых констант в программе используются литералы. Литерал ? это последовательность знаков, заключенная в двойные кавычки.
Пример
«Это строка»
«0123456789»
«*»
Заметим, что символ, заключенный в двойные кавычки, отличается от символа, заключенного в апострофы. Литерал «*» обозначает два байта: первый байт содержит символ звездочки, второй байт содержит ноль. Константа '*' обозначает один байт, содержащий знак звездочки.
С помощью литералов можно инициализировать массивы.
Пример
char alldigits[] = «0123456789»;
Размер массива явно не задан, он определяется исходя из размера инициализирующего его литерала, в данном случае 11 (10 символов плюс нулевой байт).
При работе со строками особенно часто используется связь между массивами и указателями. Значение литерала ? это массив неизменяемых байтов нужного размера. Строковый литерал может быть присвоен указателю на char.
Пример
const char* message = «Сообщение программы»;
Значение литерала ? это адрес его первого байта, указатель на начало строки. В следующем примере функция CopyString копирует первую строку во вторую.
Пример
void CopyString(char* src, char* dst)
{
while (*dst++ = *src++)
*dst = 0;
}
int main()
{
char first[] = «Первая строка»;
char second[100];
CopyString(first, second);
return 1;
}
Указатель на байт (тип char*) указывает на начало строки. Предположим, нам нужно подсчитать количество цифр в строке, на которую показывает указатель str.
Пример
#include
int k=0;
while (*str!= 0) //признак конца строки ? ноль
{
if (isdigit(*str++)) //проверить байт, на который указывает
//str, и сдвинуть указатель на следующий
//байт
k++;
}
При выходе из цикла while переменная count содержит количество цифр в строке str, а сам указатель str указывает на конец строки ? нулевой байт. Чтобы проверить, является ли текущий символ цифрой, используется функция isdigit. Это одна из многих стандартных функций языка, предназначенных для работы с символами и строками.
Библиотечные функции для работы со строками
С помощью функций стандартной библиотеки языка, которые содержатся в заголовочном файле string.h, реализованы многие часто используемые операции над символьными строками. В большинстве своем в качестве строк они воспринимают указатели. Прежде чем использовать эти указатели в программе, нужно подключить их описания с помощью оператора #include.
Здесь мы будем иметь дело с двумя группами функций. Функции с именами, начинающимися с str, работают с С-строками, в которых нулевой байт означает конец строки. Функции же, начинающиеся с mem, работают с массивами символов, следовательно, позволяют работать и с нулевыми байтами.
Обратите внимание - функции вроде копирования и слияния строк (модифицирующие один из аргументов) изменяют первый аргумент, а не второй. Приведем ряд наиболее употребительных функций для работы со строками (таблица).
Прототип функции |
Краткое описание |
Примечание |
|
unsigned strlen(const char* s); |
Вычисляет длину строки s |
||
int strcmp(const char* s1, const char* s2); |
Сравнивает строки s1 и s2 |
Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 - результат положительный |
|
int strcnmp(const char* s1, const char* s2); |
Сравнивает первые n символов строк s1 и s2 |
Если s1<s2, то результат отрицательный, если s1==s2, то результат равен 0, если s2>s1 - результат положительный |
|
char* strcpy(char* s1, const char* s2); |
Копирует символы строки s1 в строку s2 |
||
char* strncpy(char* s1, const char* s2, int n); |
Копирует n символов строки s1 в строку s2 |
Конец строки отбрасывается или дополняется пробелами |
|
char* strcat(char* s1, const char* s2); |
Приписывает строку s2 к строке s1 |
||
char* strncat(char* s1, const char* s2); |
Приписывает первые n символов строки s2 к строке s1 |
||
char* strdup(const char* s); |
Выделяет память и переносит в нее копию строки s |
При выделении памяти используются функции |
|
char *strchr(char *s, int c) |
Возвращает указатель на первый встреченный в строке символ c. Если такого символа в строке не оказалось, возвращает NULL |
В следующем примере, использующем приведенные функции, в массиве result будет образована строка «1 января 1998 года, 12 часов».
Пример
char result[100];
char* date = «1 января 1998 года»;
char* time = «12 часов»;
strcpy(result, date);
strcat(result, «,»);
strcat(result, time);
Как видно из этого примера, литералы можно непосредственно использовать в выражениях.
Определить массив строк можно с помощью следующего объявления:
char* StrArray[5]={«one»,«two»,«three»,«four»,«five»};
Выделение памяти под строки
В следующем фрагменте программы динамически выделяем память под строку переменной длины и копируем туда исходную строку.
//стандартная функция strlen подсчитывает количество
//символов в строке
int length = strlen(src_str);
// выделить память и добавить один байт
// для завершающего нулевого байта
char* buffer = new char[length + 1];
strcpy(buffer, src_str); // копирование строки
Операция new возвращает адрес выделенной памяти.
Передача строк в качестве параметров функций
Строки при передаче в функции могут передаваться как одномерные массивы типа char или как указатели типа char*. В отличие от обычных массивов в функции не указывается длина строки, т. к. в конце строки есть признак конца строки /0.
Пример
//Функция поиска заданного символа в строке
int find(char *s,char c)
{
for (int I=0;I<strlen(s);I++)
if(s[I]==c) return I;
return -1;
}
Задание
1. Запустите C++Builder.
2. Составьте программу, в которой с клавиатуры вводится строка символов и обрабатывается в соответствии с вариантом задания (таблица), используя функции.
3. Выполните компиляцию программы. При наличии ошибок внесите исправления.
4. Сдайте отчет преподавателю.
Варианты
№ |
Задача |
|
Для встречающихся в заданном тексте пар рядом расположенных символов указать, сколько раз встречается каждое из таких двухбуквенных сочетаний |
||
Отредактировать предложение, удаляя из него лишние пробелы, оставляя только по одному пробелу между словами |
||
В заданном тексте удалить символ "," и подсчитать число удаленных символов |
||
Для каждого символа заданного текста указать, сколько раз он встречается в тексте. Сообщение об одном символе должно печататься не более одного раза |
||
Для каждого слова заданного предложения указать долю согласных. Определить слово, в котором доля согласных максимальна |
||
Удалить все гласные буквы из строки |
||
Отредактировать заданное предложение, заменяя многоточия точкой |
||
В заданном предложении найти самое короткое и самое длинное слово |
||
Подсчитать количество слов в строке |
||
Удалить из текста символы " " и подсчитать длину сформированного текста |
||
Удалить каждое четное слово из строки |
||
Перевернуть каждое четное слово в строке |
||
Удалить из строки все слова, заканчивающиеся на гласную букву |
||
Удалить из строки все слова, начинающиеся на гласную букву |
||
Перевернуть каждое четное слово в строке |
||
В заданном тексте удалить символ "," и подсчитать число удаленных символов |
||
В заданном предложении найти самое короткое и самое длинное слово |
||
Найти симметричные слова заданного предложения, например АЛЛА |
||
Удалить все согласные буквы из строки |
||
Проверить, имеется ли в заданном тексте баланс открывающих и закрывающих скобок |
||
Удалить из текста символы "," и подсчитать длину сформированного текста |
||
Для каждого слова заданного предложения указать долю гласных. Определить слово, в котором доля гласных минимальна |
||
Удалить каждое нечетное слово из строки |
||
Отредактировать заданное предложение, заменяя запятые пробелом |
||
Из текста выбрать числа и записать в массив N |
Лабораторная работа 9
Указатели и динамические массивы
Цель работы - получить практические навыки работы с указателями, овладеть навыками выделения, перераспределения и освобождение памяти при работе с динамическими массивами.
Теория
Язык Си++ отличается от других структурированных языков прежде всего широким использованием указателей. До некоторой степени именно наличие в языке Си++ указателей сделало его очень удобным для системного программирования.
Указатель - это некоторая переменная, которая в отличие от других переменных не содержит значения данного. Напротив, она указывает на переменную, которая содержит значение. То есть указатель содержит в себе не значение переменной, а ее адрес.
Нотация для указателей в языке Си++ следующая. Символ операции &, поставленный перед некоторой переменной, показывает, что нам нужен адрес этой переменной, а не ее текущее значение. Например, выражение &var1 означает адрес переменной var1, а не значение, которое эта переменная имеет.
означает «взять адрес переменной var1 и присвоить его значение переменной с именем ptr». Переменная ptr называется переменной-указателем. Зачем это делается? Так как переменная var1 содержит некоторое значение данных (пусть это будет значение x), после такой операции значение x становится доступно программе через переменную-указатель ptr, поскольку ptr теперь содержит адрес значения x. Операция & называется операцией получения адреса.
Операция * в языке Си++ отсылает к содержимому ячейки памяти, на которую указывает переменная, стоящая после символа *. Например, *ptr можно описать словами как «то, что содержится в ячейке с адресом, хранящимся в ptr». Операция * называется операцией доступа по указателю.
Пример
Два оператора присваивания
ptr=&var1;
var2=*ptr;
выполняют то же самое, что и один оператор
var2=var1;
Рассмотрим программу, демонстрирующую использование указателей. Эта программа печатает символ 'X'.
#include <iostream.h>
main()
{
char a, *b, c;
a='X';
b=&a;
c=*b;
cout<<c;
}
Результат: X.
Указателям могут присваиваться строки.
Пример
#include <iostream.h>
main()
{
char *ptr1="Привет", *ptr2;
ptr2=ptr1;
while(*ptr2!='\0')
{
++ptr2;
cout<<*ptr2;
}
}
Результат: Привет.
С помощью указателей осуществляется доступ к участкам динамической памяти, которые называются динамическими переменными. Динамические переменные создаются с помощью специальных функций и операций. Они существуют либо до конца работы программ, либо до тех пор, пока не будут уничтожены с помощью специальных функций или операций.
Для создания динамических переменных используют операцию new, определенную в C++:
указатель = new имя_типа[инициализатор];
Операция new позволяет выделить и сделать доступным участок динамической памяти, который соответствует заданному типу данных. Если задан инициализатор, то в этот участок будет занесено значение, указанное в инициализаторе.
Пример
int* x=new int(5);
Для удаления динамических переменных используется операция delete, определенная в C++:
delete указатель;
где указатель содержит адрес участка памяти, ранее выделенный с помощью операции new.
Пример
delete x;
Операция new при использовании с массивами имеет следующий формат:
new тип_массива
Такая операция выделяет для размещения массива участок динамической памяти соответствующего размера, но не позволяет инициализировать элементы массива. Операция new возвращает указатель, значением которого служит адрес первого элемента массива. При выделении динамической памяти размеры массива должны быть полностью определены.
Пример
//выделение динамической памяти 100*sizeof(int) байт
int* a = new int[100];
При формировании матрицы сначала выделяется память для массива указателей на одномерные массивы, а затем в цикле с параметром выделяется память под n одномерных массивов.
Пример
/*выделение динамической памяти под двумерный динамический массив*/
int** form_matr(int n,int m)
{
int **matr=new int*[n];//выделение памяти под
//массив указателей
for(int i=0;i<n;i++) //выделение памяти
//для массива значений
matr[i]=new int [m];
return matr;//возвращение указателя на массив указателей
}
Изменять значение указателя на динамический массив надо аккуратно, т. к. этот указатель затем используется при освобождении памяти с помощью операции delete.
Пример
/*освобождает память, выделенную под массив, если а адресует его начало*/
delete[] a;
Удаление из динамической памяти двумерного массива осуществляется в порядке обратном его созданию, т. е. сначала освобождается память, выделенная под одномерные массивы с данными, а затем память, выделенная под одномерный массив указателей.
Пример
int find(int **matr,int m,int I)
{
for(int i=0;i<m;i++)
if(matr[I][i]<0) return 1;
return 0;
}
При удалении из динамической матрицы строк или столбцов создается новая матрица нужного размера, в которую переписываются данные из старой матрицы. Затем старая матрица удаляется.
Пример
int **del(int **matr,int &n,int m)
{
//удаление четных строк
int k=0,t=0;
for(int i=0;i<n;i++)
if(i % 2!=0) k++; //количество нечетных строк
//выделяем память под новую матрицу
int **matr2=form_matr(k,m);
for(i=0;i<n;i++)
if(i % 2!=0)
{
//если строка нечетная, то переписываем ее в новую матрицу
for(int j=0;j<m;j++)
matr2[t][j]=matr[i][j];
t++;
}
n=t; //изменяем количество строк
//возвращаем указатель на новую матрицу как результат //функции
return matr2;
}
Задание
1. Запустите C++Builder.
2. Наберите программу, формирующую динамический массив, заполните его случайными числами и выведите на печать. Выполните указанное в варианте задание.
3. Для выделения памяти, заполнения массивов, удаления и добавления элементов (строк, столбцов) написать отдельные функции. В функции main() должны быть размещены только описания переменных и обращения к соответствующим функциям.
4. Выполните компиляцию программы. При наличии ошибок внесите исправления.
5. Сдайте отчет преподавателю.
Варианты
с |
Одномерный массив |
Двумерный массив |
|
1 |
Удалить первый четный элемент |
Добавить строку с заданным номером |
|
2 |
Удалить первый отрицательный элемент |
Добавить столбец с заданным номером |
|
3 |
Удалить элемент с заданным ключом (значением) |
Добавить строку в конец матрицы |
|
4 |
Удалить элемент равный среднему арифметическому элементов массива |
Добавить столбец в конец матрицы |
|
5 |
Удалить элемент с заданным номером |
Добавить строку в начало матрицы |
|
6 |
Удалить N элементов, начиная с номера K |
Добавить столбец в начало матрицы |
|
7 |
Удалить все четные элементы |
Добавить К строк в конец матрицы |
|
8 |
Удалить все элементы с четными индексами |
Добавить К столбцов в конец матрицы |
|
9 |
Удалить все нечетные элементы |
Добавить К строк в начало матрицы |
|
10 |
Удалить все элементы с нечетными индексами |
Добавить К столбцов в начало матрицы |
|
11 |
Добавить элемент в начало массива |
Удалить строку с номером К |
|
12 |
Добавить элемент в конец массива |
Удалить столбец с номером К |
|
13 |
Добавить К элементов в начало массива |
Удалить строки, начиная со строки К1 и до строки К2 |
|
14 |
Добавить К элементов в конец массива |
Удалить столбцы, начиная со столбца К1 и до столбца К2 |
|
15 |
Добавить К элементов, начиная с номера N |
Удалить все четные строки |
|
16 |
Добавить после каждого отрицательного элемента его модуль |
Удалить все четные столбцы |
|
17 |
Добавить после каждого четного элемента элемент со значением0 |
Удалить все строки, в которых есть хотя бы один нулевой элемент |
|
18 |
Добавить по К элементов в начало и в конец массива |
Удалить все столбцы, в которых есть хотя бы один нулевой элемент |
|
19 |
Добавить элемент с номером К |
Удалить строку, в которой находится наибольший элемент матрицы |
|
20 |
Удалить элемент с заданным номером |
Добавить строки после каждой четной строки матрицы |
|
21 |
Удалить N элементов, начиная с номера K |
Добавить столбцы после каждого четного столбца матрицы |
|
22 |
Удалить все четные элементы |
Добавить К строк, начиная со строки с номером N |
|
23 |
Удалить все элементы с четными индексами |
Добавить К столбцов, начиная со столбца с номером N |
|
24 |
Удалить все нечетные элементы |
Добавить строку после строки, содержащей наибольший элемент |
|
25 |
Удалить все элементы с нечетными индексами |
Добавить столбец после столбца, содержащего наибольший элемент |
Лабораторная работа 10
Динамические структуры данных
Цель работы - получить практические навыки работы с динамическими структурами данных.
Теория
Структуры
Структура - это объединенное в единое целое множество поименованных элементов данных. Элементы структуры (поля) могут быть различного типа, они все должны иметь различные имена.
Пример
struct Date //определение структуры
{
int day;
int month;
int year;
};
Date birthday; //переменная типа Date
Для переменных одного и того же структурного типа определена операция присваивания. При этом происходит поэлементное копирование.
Доступ к элементам структур обеспечивается с помощью уточненных имен:
имя_структуры.имя_элемента
Пример
//присваивание значений полям переменной birthday
birthday.day=11;
birthday.month=3;
birthday.year=1993;
Date Data;
//присваивание значения переменной birthday переменной Data
Data=birthday;
Из элементов структурного типа можно организовывать массивы также как из элементов стандартных типов.
Пример
Date mas[15]; //массив структур
//ввод значений массива
for (int i=0;i<15;i++)
{
cout<<”\nEnter day:”;cin>>mas[i].day;
cout<<”\nEnter month:”;cin>>mas[i].month;
cout<<”\nEnter year:”;cin>>mas[i].year;
}
Структуры и указатели
Указатели на структуры описываются точно так же, как и указатели на другие типы данных. Это необходимо для создания связных списков и других динамических структур данных, элементами которых являются структуры данных.
Фактически указатели на структуры так часто используются в Си++, что существует специальный символ для ссылки на элемент структуры, адресованной указателем.
Пример
#include <iostream.h>
#include <string.h>
typedef struct worker
{
char name[15];
char sonname[15];
char duty[15];
int sum;
};
main()
{
worker *p;
strcpy(p->name, "Василий);
strcpy(p->sonname, "Иванов");
strcpy(p->duty, "разнорабочий");
p->sum=10;
cout <<"имя фамилия должность зарплата\n";
cout<<p->name<<“ ”<<p->surname<<“ ”<<p->duty<<“ ”<<p->sum);
}
В этом варианте p объявляется как указатель типа worker, а не как переменная типа worker. Теперь, когда вы ссылаетесь на элементы p, используйте конструкцию: имя_указателя -> элемент_структуры Символ -> означает, что "элемент структуры направлен в ..."; это сокращенный вариант от точно такой же по смыслу конструкции (*имя_указателя).элемент_структуры, принятый в Си++.
Линейный однонаправленный список
Описание простейшего элемента такого списка выглядит следующим образом:
struct имя_типа
{
информационное поле;
адресное поле;
};
Информационное поле (данные) - это поле любого, ранее объявленного или стандартного, типа; адресное поле - это указатель на объект того же типа, что и определяемая структура, в него записывается адрес следующего элемента списка.
Пример
1. struct Node
{
int key;//информационное поле
Node*next;//адресное поле
};
2. struct point
{
char*name;//информационное поле
int age;//информационное поле
point*next;//адресное поле
};
Каждый элемент списка содержит ключ, который идентифицирует этот элемент. Ключ обычно бывает либо целым числом (1.), либо строкой (2.).
Задание
1. Запустите C++Builder 6.0.
2. Сформируйте и выведите на печать динамический массив из элементов структурного типа. Выполните поиск элементов в массиве, удовлетворяющих заданному в варианте условию (таблица) и сформируйте из них новый массив.
3. Для формирования, печати структур, выделения памяти, заполнения массивов, поиска заданных элементов напишите отдельные функции. В функции main() должны быть размещены только описания переменных и обращения к соответствующим функциям.
4. Выполните компиляцию программы. При наличии ошибок внесите исправления.
5. Сдайте отчет преподавателю.
Варианты
№ |
Структура |
Критерий для поиска в массиве структур |
|
1 |
struct person {char*name; char *adres; int age;}; |
Имена начинаются на букву `A' |
|
2 |
struct date {int day; char*month; int year;}; |
Даты с летними месяцами |
|
3 |
struct student {char*name; int kurs; float rating}; |
Студенты первого курса |
|
4 |
struct employee {char*name; float salary; int stage}; |
Сотрудники со стажем больше 10 лет |
|
5 |
struct pupil {char*name; int age; float rating;}; |
Ученики со средним баллом больше 4 |
|
6 |
struct person {char*name; int age;}; |
Возраст больше 25 лет |
|
7 |
struct date {int day; char*month; int year;}; |
Даты после 2000 года |
|
8 |
struct student {char*name; int kurs; float rating;}; |
Студенты, у которых рейтинг меньше 3 |
|
9 |
struct employee {char*name; float salary; int stage;}; |
Сотрудники, у которых имя начинается на букву `Л' |
|
10 |
struct pupil {char*name; int age; float rating;}; |
Ученики, у которых фамилия “Иванов” |
|
11 |
struct person {char*name; int age;}; |
Возраст меньше 18 |
|
12 |
struct date {int day; char*month; int year;}; |
Дата принадлежит первой декаде месяца |
|
13 |
struct student {char*name; int kurs; float rating;}; |
Студены пятого курса |
|
14 |
struct employee {char*name; float salary; int stage;}; |
Сотрудники со стажем меньше 3 лет |
|
15 |
struct pupil {char*name; int age; float rating;}; |
Ученики со средним баллом равным 4.5 |
|
16 |
struct person {char*name; int age;}; |
Имена начинаются на букву `A' |
|
17 |
struct date {int day; char*month; int year;}; |
Даты с зимними месяцами |
|
18 |
struct student {char*name; int kurs; float rating;}; |
Студенты первого курса, у которых рейтинг меньше 3 |
|
19 |
struct employee {char*name; float salary; int stage;}; |
Сотрудники со стажем больше 10 лет и заработной платой больше 15000 |
|
20 |
struct pupil {char*name; int age; float rating;}; |
Ученики 13 лет со средним баллом больше 4 |
|
21 |
struct person {char*name; int age;}; |
Возраст больше 25 лет и фамилия начинается на букву `C' |
|
22 |
struct date {int day; char*month; int year;}; |
Зимние даты после 2000 года |
|
23 |
struct student {char*name; int kurs; float rating;}; |
Студенты 1 и 2 курса, у которых рейтинг меньше 3 |
|
24 |
struct employee {char*name; float salary; int stage;}; |
Сотрудники, у которых имя начинается на букву `Л' и заработная плата меньше 6000 |
|
25 |
struct pupil {char*name; int age; float rating;}; |
Ученики, у которых фамилия “Иванов” и рейтинг больше 4 |
Лабораторная работа 11
Объектно-ориентированное программирование. Создание классов и объектов
Цель работы - научиться создавать и применять классы и объекты, изучить возможности объектно-ориентированного программирования
Теория
Объектно-ориентированное программирование - это способ написания программ. Парадигма объектно-ориентированного программирования состоит в следующем: определите, какие классы вам необходимы; предоставьте полный набор операций для каждого класса; общность классов выразите явно с помощью наследования.
Классы похожи на структуры языка С. Однако структура С определяет только данные, ассоциированные с этой структурой. Описание класса в языке С++ производится следующим образом:
class <имя класса>
{
private: <переменные-члены> // скрытая часть класса
public: <функции-члены> // общая часть класса
protected: <функции-члены> // защищенная часть класса
};
Ключевое слово class показывает компилятору, что все находящееся в фигурных скобках ({}) принадлежит объявлению класса. Не забывайте ставить точку с запятой в конце объявления класса. Имя класса можно выбрать произвольно, главное, чтобы в программе не было еще классов с таким же именем. Имя класса не должно содержать пробелов, не должно начинаться с цифры.
Класс - защищенная структура. В общем случае класс содержит 3 части: скрытую часть (private), общую часть (public) и защищенную часть (protected). Члены класса, описанные в скрытой части, доступны лишь членом этого же класса. Члены класса, описанные в общей части, доступны всем членам других классов. Члены класса, описанные в защищенной части, доступны только членам производных классов (т.е. “наследникам”).
В описании класса приводят лишь описание функций-членов (описывают только заголовки функций). Определения этих функций дается позже. Так как определение делается в глобальной области видимости, то для правильного указания на класс, необходим оператор разрешения области видимости: <имя класса>::<имя члена класса> .
Описание класса размещают в заголовочном файле. Этот файл называется также как и класс, и имеет расширение .h. Определение функций-членов класса размещают в файле с расширением .cpp.
Конструкторы и деструкторы
Перед использованием объекта класса необходимо его создать, а после использования уничтожить. Для создания объекта класса можно написать обычную функцию-член класса и вызывать ее перед использованием объекта класса. Но это неудобно, да и неправильно. А что, если пользователь забудет вызвать эту функцию? Тогда при использовании объекта возникнут ошибки. Неудобно после описания объекта каждый раз вызывать специальную функцию. Да и использование этой функции неправильно с точки зрения парадигмы программирования, ведь получается, что функция применяется к объекту, который еще не создан. Поэтому необходим механизм, позволяющий вызывать функцию для создания объекта при его описании. Это специальная функция-член класса, которая называется конструктор. Итак, конструктор - специальная функция-член класса, создающая объект. Имя конструктора совпадает с именем класса. Конструктор вызывается неявно при описании объекта класса. Например: У нас определен класс vector и определен конструктор без параметров vector();. Необходимо создать объект этого класса. Описываем объект как переменную: vector V1;. Такое описание возможно, если в классе есть конструктор без параметра. Такой конструктор называют еще конструктор по умолчанию. Если в классе есть только конструктор с параметрами, то их необходимо указать в описании: vector V2(10); Если в классе описаны несколько конструкторов, то вызывается тот, чей список параметров совпадает со списком параметров при описании объекта.
Особый вид конструктора - конструктор копирования. Этот конструктор предназначен для создания объекта как копии объекта этого же класса. Параметром такого конструктора всегда является ссылка на объект этого же класса. Например, для класса vector описание конструктора копирования может выглядеть так: vector(vector& v);. Вызывается конструктор копирования также неявно следующим образом: vector V1; … vector V2=V1;
Деструктор - это специальная функция-член класса, которая разрушает объект. Деструктор также вызывается неявно. Деструктор объекта вызывается, если завершен блок, в котором объект был создан, или если завершена работа программы (для глобальных объектов). Деструкторы не имеют параметров. Имя деструктора совпадает с именем класса, но впереди добавляется символ ~. Например, ~vector();.
Пример
Описание класса (файл vector.h):
class vector
{
double * vec;
int size;
public:
vector(int n=0); //конструктор по умолчанию и с
//параметром
vector(vector&); //конструктор копирования
~vector(); //деструктор
printVector(); //функция вывода вектора на экран
int getSize() //функция, возвращающая размер вектора
{ //эта функция является функцией с
return size; //inline-подстановкой
};
double operator [] (int); //операция индексации
//элементов вектора
};
Определение функций-членов класса (файл vector.cpp):
#include “vector.h”
vector::vector(int n)
{
vec=new double[n]; //выделение памяти под массив
//вещественных чисел
size=n; // определение размера
}
vector::vector(vector& v) //конструктор копирования
{
if(v.size>0)
{
vec=new double[v.size];//создание нового вектора
size=v.size; //настройка размера
for (int i=0;i<size;i++)
vec[i]=v.vec[i]; //копирование вектора v в
//текущий вектор
}
}
vector::~vector()
{
delete []vec; //освобождение памяти
size=-1; //размер указывает на то, что вектор разрушен
}
vector::printVector()// вывод содержимого вектора на экран
{
if(size!=-1)
{
for(int i=1;i<size;i++)
printf(“%lf ”,vec[i]);
}
}
double vector::operator [](int k) //операция индексации
{
if((k>-1)&&(k<size))
return vec[k]; //проверка индекса на правильность
else return 0;
}
Использование объектов
До использования объекта класса необходимо его создать (см. конструкторы). Применение функций-членов класса к объекту осуществляется через конструкцию . (точка), как и в случае со структурами.
Пример
#include “vector.cpp”
#include <stdio.h>
void main()
{
vector V1(20);
vector V2=V1;
for(int i=0;i<V1.getsize();i++)
printf(“%lf ”,V1[i]);
V1.printVector();
V2.printVector();
}
Динамические объекты
Если создание объекта в данный момент нежелательно, но необходимо его описать, то лучше создать динамический объект. Для этого надо описать указатель на объект. Например: vector *pV;. Позднее можно будет создать этот объект при помощи операции new, например: pV=new vector(20);. Только использовать этот объект можно будет лишь через указатель на него. Для применения функции-члена к динамическому объекту нужно воспользоваться конструкцией ->(стрелочка).
Пример
pV->printVector();
Задание
1. Запустите C++Builder 6.0.
2. Напишите программу, использующую класс (классы) для структуры данных по заданию в лабораторной работе № 10. Опишите конструктор по умолчанию, конструктор с параметром, конструктор копирования, деструктор, функции добавления элемента, удаления элемента, просмотра структуры, как функции-члены класса.
3. Выполните компиляцию программы. При наличии ошибок внесите исправления.
4. Сдайте отчет преподавателю.
Лабораторная работа 12
Знакомство со средой быстрой разработки приложений. Использование компонент библиотеки VCL
Цель работы - познакомиться со средой быстрой разработки программ RAD (от англ. rapid application development -- быстрая разработка приложений) C++ Builder и с наиболее часто используемыми компонентами библиотеки VCL (Visual Component Library - Визуальная библиотека Компонентов), изучить основные их свойства, создать работающее приложение для операционной системы Windows.
Теория
Формы являются основой приложений C++ Builder. Создание пользовательского интерфейса приложения заключается в добавлении в окно формы элементов объектов C++ Builder, называемых компонентами. Компоненты C++ Builder располагаются на палитре компонентов, выполненной в виде многостраничного блокнота. Важная особенность C++ Builder состоит в том, что он позволяет создавать собственные компоненты и настраивать палитру компонентов, а также создавать различные версии палитры компонентов для разных проектов.
Компоненты C++ Builder
Компоненты разделяются на видимые (визуальные) и невидимые (невизуальные). Визуальные компоненты появляются во время выполнения точно так же, как и во время проектирования. Примерами являются кнопки и редактируемые поля. Невизуальные компоненты появляются во время проектирования как пиктограммы на форме. Они никогда не видны во время выполнения, но обладают определенной функциональностью (например, обеспечивают доступ к данным, вызывают стандартные диалоги Windows и др.).
Для добавления компонента в форму можно выбрать мышью нужный компонент в палитре и щелкнуть левой клавишей мыши в нужном месте проектируемой формы. Компонент появится на форме, и далее его можно перемещать, менять размеры и другие характеристики.
Каждый компонент C++ Builder имеет три разновидности характеристик: свойства, события и методы.
Если выбрать компонент из палитры и добавить его к форме, инспектор объектов автоматически покажет свойства и события, которые могут быть использованы с этим компонентом. В верхней части инспектора объектов имеется выпадающий список, позволяющий выбирать нужный объект из имеющихся на форме.
Свойства компонентов
Свойства являются атрибутами компонента, определяющими его внешний вид и поведение. Многие свойства компонента в колонке свойств имеют значение, устанавливаемое по умолчанию (например, высота кнопок). Свойства компонента отображаются на странице свойств (Properties). Инспектор объектов отображает опубликованные (published) свойства компонентов. Помимо published-свойств, компоненты могут и чаще всего имеют общие (public), опубликованные свойства, которые доступны только во время выполнения приложения. Инспектор объектов используется для установки свойств во время проектирования. Список свойств располагается на странице свойств инспектора объектов. Можно определить свойства во время проектирования или написать код для видоизменения свойств компонента во время выполнения приложения.
При определении свойств компонента во время проектирования нужно выбрать компонент на форме, открыть страницу свойств в инспекторе объектов, выбрать определяемое свойство и изменить его с помощью редактора свойств (это может быть простое поле для ввода текста или числа, выпадающий список, раскрывающийся список, диалоговая панель и т.д.).
События
Страница событий (Events) инспектора объектов показывает список событий, распознаваемых компонентом (программирование для операционных систем с графическим пользовательским интерфейсом, в частности, для Windows 95 или Windows NT пре полагает описание реакции приложения на те или иные события, а сама операционная система занимается постоянным опросом компьютера с целью выявления наступления какого-либо события). Каждый компонент имеет свой собственный набор обработчиков событий. В C++ Builder следует писать функции, называемые обработчиками событий, и связывать события с этими функциями. Создавая обработчик того или иного события, вы поручаете программе выполнить написанную функцию, если это событие произойдет.
Для того чтобы добавить обработчик событий, нужно выбрать на форме с помощью мыши компонент, которому необходим обработчик событий, затем открыть страницу событий инспектора объектов и дважды щелкнуть левой клавишей мыши на колонке значений рядом с событием, чтобы заставить C++ Builder сгенерировать прототип обработчика событий и показать его в редакторе кода. При этом автоматически генерируется текст пустой функции, и редактор открывается в том месте, где следует вводить код. Курсор позиционируется внутри операторных скобок { ... }. Далее нужно ввести код, который должен выполняться при наступлении события. Обработчик событий может иметь параметры, которые указываются после имени функции в круглых скобках.
Методы
Метод является функцией, которая связана с компонентом, и которая объявляется как часть объекта. Создавая обработчики событий, можно вызывать методы, используя следующую нотацию: ->.
Пример
Edit1->Show();
Отметим, что при создании формы связанные с ней модуль и заголовочный файл с расширением *.h генерируются обязательно, тогда как при создании нового модуля он не обязан быть связан с формой (например, если в нем содержатся процедуры расчетов). Имена формы и модуля можно изменить, причем желательно сделать это сразу после создания, пока на них не появилось много ссылок в других формах и модулях.
Менеджер проектов
Файлы, образующие приложение - формы и модули - собраны в проект. Менеджер проектов показывает списки файлов и модулей приложения и позволяет осуществлять навигацию между ними. Можно вызвать менеджер проектов, выбрав пункт меню View/Project Manager. По умолчанию вновь созданный проект получает имя Project1.cpp.
По умолчанию проект первоначально содержит файлы для одной формы и исходного кода одного модуля. Однако большинство проектов содержат несколько форм и модулей. Чтобы добавить модуль или форму к проекту, нужно щелкнуть правой кнопкой мыши и выбрать пункт New Form из контекстного меню. Можно также добавлять существующие формы и модули к проекту, используя кнопку Add контекстного меню менеджера проектов и выбирая модуль или форму, которую нужно добавить. Формы и модули можно удалить в любой момент в течение разработки проекта. Однако, из-за того, что форма связаны всегда с модулем, нельзя удалить одно без удаления другого, за исключением случая, когда модуль не имеет связи с формой. Удалить модуль из проекта можно, используя кнопку Remove менеджера проектов.
Если выбрать кнопку Options в менеджере проектов, откроется диалоговая панель опций проекта, в которой можно выбрать главную форму приложения, определить, какие формы будут создаваться динамически, каковы параметры компиляции модулей (в том числе созданных в Delphi, так как C++ Builder может включать их в проекты) и компоновки.
Важным элементом среды разработки C++ Builder является контекстное меню, появляющееся при нажатии на правую клавишу мыши и предлагающее быстрый доступ к наиболее часто используемым командам.
Разумеется, C++ Builder обладает встроенной системой контекстно-зависимой помощи, доступной для любого элемента интерфейса и являющейся обширным источником справочной информации о C++ Builder.
Выбор компонентов для групповых операций
Для эффективной разработки пользовательских интерфейсов приложений C++ Builder нередко возникает необходимость в манипулировании компонентами на формах. Большинство операций для манипулирования компонентами находятся в меню Edit. К различным опциям этого меню следует обращаться после того, как на форме вы ран один или несколько компонентов, свойства которых требуется изменить.
Выбрать один компонент можно следующими способами:
1. Выбрав с помощью мыши компонент на форме
2. Выбрав имя компонента в селекторе объектов.
3. Переходом к компоненту на форме, нажимая клавишу Tab.
Выбрать несколько компонентов можно следующими способами:
1. Удерживая нажатой клавишу Shift, щелкнуть мышью на каждом компоненте.
2. Нажать левую клавишу мыши и окружить нужные компоненты прямоугольным контуром.
Установка разделяемых свойств компонентов
Большинство визуальных компонентов имеют общие свойства, (например, Visible, Width, Left). Для установки одинаковых значений общих свойств для нескольких компонентов необходимо выполнить следующие действия:
1. Выбрать несколько настраиваемых компонентов. При этом страница свойств объектов будет отображать только те свойства, которые имеются у всех выбранных компонентов.
2. Установить значения свойств, общих для выделенных компонентов.
Изменение размера компонентов
Изменение размера компонента можно проводить как при добавлении его на форму, так и после этого.
При добавлении компонента следует выбрать его на палитре компонентов. Далее нужно поместить курсор мыши на форму, нажать левую клавишу и перемещать мышь, в результате чего на форме появится прямоугольник, изображающий границы будущего компонента. Когда прямоугольник приобретет необходимые размеры, нужно отпустить кнопку мыши.
Если перевести курсор мыши на один из появившихся вокруг компонента маленьких черных квадратиков, курсор мыши изменяет форму. Перемещая этот курсор и вместе с ним границу компонента, можно изменять его размеры.
Для изменения размеров нескольких компонентов следует выбрать их одним из описанных выше способов. Далее нужно выбрать пункт меню Edit/Size. Появится диалоговое окно Size. Выберите опции размера. Для точной установки размера в пикселях можно ввести числа в поля Width и Height. Далее нужно нажать кнопку OK.
Можно добавить несколько копий компонента одного типа, выбирая компонент из палитры при нажатой клавише Shift. В этом случае вокруг компонента появляется прямоугольник, окружающий этот компонент. После этого каждый щелчок мышью на форме приводит к появлению на ней копии компонента. Закончив режим многократного копирования, следует щелкнуть мышью на инструменте выбора курсора (первая кнопка на палитре компонентов с изображением стрелки).
Выравнивание компонентов
Для выравнивания компонентов на форме можно использовать следующие комбинации клавиш (таблица).
Комбинация клавиш |
Действие |
|
Shift + стрелки |
Изменяет размер компонента на один пиксель в направлении выбранной стрелки |
|
Shift + Ctrl + стрелки |
Перемещает компонент на одну единицу сетки в направлении выбранной стрелки |
|
Ctrl + стрелки |
Перемещает компонент на один пиксель в направлении выбранной стрелки |
Можно также выровнять компоненты, используя пункт меню View/Alignment Palette. Для этого нужно:
1. Выбрать компоненты для выравнивания.
2. Выбрать пункт меню View/Alignment Palette.
3. Выбрать нужную кнопку.
Можно выровнять компоненты, используя пункт меню Edit/Align. Для этого нужно:
1. Выбрать компоненты для выравнивания.
2. Выбрать пункт меню Edit/Align. Появится диалоговое окно Alignment.
3. Выбрать нужную опцию и нажать на кнопку OK.
Можно изменить условия выравнивания компонент, используя пункт меню Options/Environment. Для этого нужно:
1. Выбрать пункт меню Options/Environment. Диалоговое окно Environment появится открытым на странице Preferences.
2. В группе Form designer можно выбрать следующие опции:
1) Display grid - сделать сетку из точек на форме видимой для выравниваемых компонентов;
2) Snap to grid - заставить левые и верхние стороны компонентов расположиться на линиях сетки.
3. Для того чтобы изменить расстояние между узлами сетки, нужно ввести новые значения вместо имеющихся. Значение по умолчанию -- 8 пикселей по оси X (по горизонтали) и по оси Y (по вертикали).
4. Нажать OK.
Создание приложений в C++ Builder
Первым шагом в разработке...
Подобные документы
Общие данные об основных операторах языка SQL. Интерактивный режим работы. Использование языка SQL для выбора информации из таблиц, для вставки, редактирования и удаления данных в них. Связь между операциями реляционной алгебры и операторами языка SQL.
реферат [146,5 K], добавлен 06.02.2015Анализ операторов ввода и вывода, а также характеристика форматов, используемых в этих операторах. Оформление законченной программы с применением этих операторов. Структура программы. Алфавит языка и типы данных. Ввод и вывод информации. Форматный вывод.
лабораторная работа [62,0 K], добавлен 15.07.2010Конструкции условных операторов if-else и простые типы языка Си. Общая схема работы компилятора. Алгоритм построения дерева разбора, строки вывода синтаксического разбора. Построение обратной польской записи как формы внутреннего представления программы.
курсовая работа [1,3 M], добавлен 01.06.2013Характеристика базовых конструкций языков программирования. Изучение истории их развития и классификации. Определение основных понятий языков программирования. Описание основных операторов, которые используются в языках программирования высокого уровня.
курсовая работа [400,6 K], добавлен 10.11.2016Строгая типизация и наличие средств структурного (процедурного) программирования императивного языка Pascal. Структура программы, выражения, строки. Правила и описание типов, процедур и функций, операторов ввода - вывода, модулей и подпрограмм.
курсовая работа [37,3 K], добавлен 28.06.2008Характеристика языка программирования С++. Описание классов и методов. Выполнение решения вычислительных процессов по заданным формулам. Создание диалогового приложения. Разработка инструкции пользователя. Операции над одномерными и двумерными массивами.
дипломная работа [2,0 M], добавлен 16.04.2017Принцип работы основных операторов языка программирования Turbo-Paskal: оператор присваивания, выбора Case, безусловного перехода, цикла, уловный, составной. Формальное описание и вызов функции и процедуры. Требования к списку фактических параметров.
реферат [261,8 K], добавлен 09.02.2011Особенности синтаксиса языка программирования С++. Создание панели меню, для получения информации о программе, сохранения результата и выхода из программы. Работа с файлами, двумерными и одномерными динамическими массивами, функциями, строками и циклами.
курсовая работа [782,3 K], добавлен 06.02.2016Внутренний язык СУБД для работы с данными. Результат компиляции DDL-операторов. Описание DML-языка, содержащего набор операторов для поддержки основных операций манипулирования содержащимися в базе данными. Организация данных и управление доступом в SQL.
лекция [131,0 K], добавлен 19.08.2013Изучение циклических операторов: оператора цикла, управляемого счетчиком, оператора цикла с предусловием и постусловием. Минимизированные функции, текст программы. Алгоритм работы приложения по нахождению функции с помощью операторов break и continue.
лабораторная работа [474,2 K], добавлен 23.11.2014Создание приложения, исполняющего трансляцию программы из языка Паскаль в язык Си: разработка алгоритма реализации задачи, описание необходимых констант, переменных, функций и операторов, представление листинга программы и распечатка результатов.
курсовая работа [305,9 K], добавлен 03.07.2011Встроенные типы данных, основные конструкции, структуры и применение языка Javа. Введение в интегрированную среду разработки Eclipse. Листинг программы, иллюстрирующей работу с одномерными массивами (создание массива). Спецификация класса Figure.
методичка [1,4 M], добавлен 30.06.2009Язык структурированных запросов SQL (Structured Query Language) и его место в сфере доступа к информации в реляционных базах данных. Структура и основные типы данных языка. Синтаксис и семантика главных операторов SQL, последние стандарты языка.
реферат [98,7 K], добавлен 29.03.2012Построение базовой линейной структуры и организация ввода с формы переменной. Определение значения функции и построение блок-схемы базовой структуры "ветвление". Использование цикла со счетчиком. Рассмотрение особенностей работы с одномерными массивами.
контрольная работа [1,4 M], добавлен 10.12.2021Ознакомление с понятием, особенностями объявления, инициализацией и принципами работы с одномерными и двумерными массивами. Изучение смысла тернарной операции вывода элементов матрицы. Рассмотрение сущности и способов использования указателей переменных.
лабораторная работа [22,1 K], добавлен 15.07.2010Изучение функций и возможностей среды разработки языка программирования Pascal. Рассмотрение работы с одномерными и двумерными массивами, со строками и числами. Математическая формулировка задач. Разработка алгоритмов, описание структуры программ.
курсовая работа [879,8 K], добавлен 11.02.2016Общая характеристика интерфейса языка программирования Delphi. Рассмотрение окна редактора кода, конструктора формы, инспектора объектов и расширения файлов. Ознакомление с основными этапами создания и сохранения простого приложения; проверка его работы.
презентация [184,3 K], добавлен 18.03.2014Понятие и характеристика операторов ввода и вывода информации, случаи их применяется в программах и основные виды: составной оператор Begin ... end, условный оператор If. Суть операторов безусловного перехода и циклических процессов, примеры применения.
реферат [27,9 K], добавлен 03.03.2010Введение в API-программирование. Структура API-программ. Организация ввода-вывода в консольном приложении Windows. Организация низкоуровнего консольного ввода-вывода. Расширенная поддержка клавиатуры в консоли. Поддержка работы с мышью в консоли.
курсовая работа [91,0 K], добавлен 10.02.2015Программирование линейных алгоритмов. Процедуры ввода READ и READLN и вывода WRITE и WRITELN. Примеры решения задач на языке Паскаль. Оператор присваивания и выражения. Основные способы формирования структурных операторов. Операторы вызова процедур.
курсовая работа [44,3 K], добавлен 18.03.2013