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

Программирование

.pdf
Скачиваний:
18
Добавлен:
29.02.2016
Размер:
1.3 Mб
Скачать

31

}

/* Вывод матрицы по строкам */ void out_matr(float *matr, int n, int m)

{

int i, j;

for (i = 0; i < n; i++)

{

for (j = 0; j < m; j++) cout<<matr[i*m + j]<<" ";

cout<<endl;

}

cout<<endl;

}

/* Сложение двух матриц */

void add_matr(float *matr1, float *matr2,float *matr3, int n, int m)

{

int i,j;

for (i = 0; i < n; i++) for (j = 0; j < m; j++)

*(matr3+i*m+j)=*(matr1+i*m+j) +*(matr2+i*m+j); // или matr3[i*m+j]=matr1[i*m+j] + matr2[i*m+j];

}

char* RUS(const char* text)

{

CharToOem(text, buf); return buf;

}

7 Структуры

Cтруктура - это составной объект, в который входят элементы любых типов, за исключением функций. В отличие от массива, все элементы которого однотипны, структура может содержать элементы разных типов:

struct [ имя_типа ] { тип_1 элемент_1; тип_2 элемент_2;

тип_n элемент_n;

} [ список_описателей ];

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

struct

{

int year;

char month[10]; int day;

} date, date2;

32

Если список отсутствует, описание структуры определяет новый тип, имя которого можно использовать в дальнейшем наряду со стандартными типами, например:

struct student{ // описание нового типа с именем student char fio[30];

long int num_zac; double sr_bal;

}; // описание заканчивается точкой с запятой

// определение массива типа student и переменной типа student. student gr[30], p:

Для переменных одного и того же структурного типа определена операция присваивания, при этом происходит поэлементное копирование. Структуру можно передавать в функцию и возвращать в качестве значения функции.

Доступ к полям структуры выполняется с помощью операций выбора

. (точка) при обращении к полю через имя структуры и -> при обращении через указатель, например:

student stud1, gr[30]; strcpy(stud1.fio, "Страусенко"); gr[8] .sr_bal=5;

Если элементом структуры является другая структура, то доступ к ее элементам выполняется через две операции выбора:

struct A {int a, double х;}; struct В {A a, double х;} х[2]; х[0] .а. а = 1; х[1]. х = 0.1;

Как видно из примера, поля разных структур могут иметь одинаковые имена, поскольку у них разная область видимости.

Пример. Описать структуру с именем NOTE, содержащую следующие

поля:

NAME – фамилия, имя;

TEL – номер телефона;

BDAY – день рождения (массив из трех чисел). Написать программу, выполняющую следующие действия:

ввод с клавиатуры данных в массив BLOCKNOTE, состоящий их восьми элементов типа NOTE; записи должны быть упорядочены по трем первым цифрам номера телефона;

вывод на экран информации о человеке, чья фамилия введена с кла-

виатуры;

если такого нет, выдать на дисплей соответствующее сообщение.

Текст программы:

#include <iostream.h>

#include <windows.h>

#include <string.h>

33

char buf[256];

char *Rus(char *text) {CharToOem(text,buf); return buf;}

//объявление нового типа struct note

{

char name[30]; char tel[10]; int bday[3];

}; //объявление функций

void out_str (note * a, int n); void in_str (note * a, int n); void sort (note * a, int n); void poisk (note * a, int n); int main ()

{

int n;

cout<<Rus("Ведите количество записей: "); cin>>n;

//динамическое выделение памяти // под массив структур

note *bloknote=new note[n]; //вызов функций in_str(bloknote,n); sort(bloknote,n); out_str(bloknote,n); poisk(bloknote,n);

return 0;

}

//определение функций void out_str(note *a, int n)

{

int i,j;

for (i=0;i<n;i++)

{

cout<<a[i].name<<"\t"<<a[i].tel<"\t"; for (j=0;j<3;j++)

cout<<a[i].bday[j]<<".";

cout<<endl;

}

}

void in_str(note *a, int n)

{

int i,j;

for (i=0;i<n;i++)

{

cout<<Rus("Введите имя: "); do

{

cin.getline(a[i].name,30);

}

while (strlen (a[i].name)==0); cout<<Rus("Введите телефон: "); do

34

{

cin.getline(a[i].tel,10);

}

while (strlen (a[i].tel)==0);

cout<<Rus("Введите дату рождения(dd mm yyyy): "); for (j=0;j<3;j++)

cin>>a[i].bday[j];

}}

void sort(note *a, int n)

{

int i,k; note temp;

for(k=1;k<n;k++) for (i=0;i<n-k;i++)

//сравнение трех первых символов телефона if (strncmp(a[i].tel,a[i+1].tel,3)>0)

{

temp=a[i];

a[i]=a[i+1];

a[i+1]=temp;

}

}

void poisk(note *a, int n)

{

int i,j;

bool f=false; char st[30];

cout<<Rus("Введите имя для поиска: "); do

{

cin.getline(st,30);

}

while (strlen (st)==0); for (i=0;i<n;i++)

//сравнение строк

if (strcmp(a[i].name,st)==0)

{

out_str(&a[i],1); f=true;

}

if (f==false)

cout<<Rus("Нет в списке.")<<endl;

}

8 Потоки и файлы

Указатель на файл – это указатель на информацию, определяющую различные параметры файла, включая его имя, состояние и текущую позицию. В принципе, указатель на файл идентифицирует конкретный дисковый файл и используется потоком для выполнения операций ввода-вывода. Указатель на файл – это переменная-указатель типа FILE (тип, определенный в файле stdio.h). Чтобы прочитать или записать файлы, программе надо ис-

35

пользовать указатели на файлы. Для создания файловой переменнойуказателя используется оператор типа: FILE *fp;

Открытие файла

Функция fopen() открывает для использования поток, связывает файл с данным потоком и затем возвращает указатель типа FILE на данный поток. Функция fopen() имеет прототип:

FILE *fopen (const char *filename, const char *mode); ,

где filename указывает на строку, содержащую имя файла, а mode указывает на строку, содержащую желаемый режим открытия файла (таблица

8.1).

Функция fopen() возвращает указатель базового типа FILE. Данный указатель идентифицирует файл и используется большинством функций файловой системы. Его никогда не следует изменять самостоятельно. Функция fopen() возвращает нулевой указатель (NULL), если файл не может быть открыт.

Таблица 8.1

Режим

З н а ч е н и е

«w» (write)

Новый текстовый файл открывается для записи. Если файл уже

существовал, то его содержимое стирается и он создастся заново

 

«r» (read)

Открывается только для чтения существующий текстовый файл

«a» (append)

Текстовый файл открывается или создается для добавления в ко-

нец файла новой порции информации

 

 

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

«w+»

модификации. Если файл уже существует, то его содержание

стирается. После открытия файла чтение и запись допустимы в

 

 

любом месте, в том числе разрешена запись в конец файла

 

Существующий текстовый файл открывается как для чтения, так

«r+»

и для записи в любом месте файла; однако запись в конец, при-

 

водящая к увеличению размера файла недопустима

 

Текстовый файл открывается или создается с возможностью по-

«a+»

следующей модификации. В отличие от режима «w+» можно от-

крыть существующий файл без уничтожения его содержимого; в

 

 

отличие от режима «r+» можно записывать в конец файла, уве-

 

личивая его размеры

Примечания

1 При использовании «r» или «r+» поток должен существовать

2 По умолчанию файлы открываются в текстовом режиме. Для открытия файла в двоичном режиме, необходимо к режиму добавить символ b rb», «wb», «a+b»)

Если необходимо открыть файл с именем «a:\file1.dat» на запись, следует записать:

FILE *fp;

. . .

fp = fopen(“a:\\file1.dat”, “w”);

или лучше

FILE *fp;

. . .

36

if ((fp = fopen(“a:\\file1.dat”, “w”) = = NULL)

{

perror(RUS(“Не могу открыть файл”)); return 0;

}

else cout<<RUS(“Файл открыт для записи”)<<endl;

Данный способ позволяет обнаружить ошибки при открытии файла, например, наличие защиты от записи на дискете или отсутствие свободного места.

По завершению работы с файлом его рекомендуется закрыть при помощи функции

int fclose(FILE *fp);

Ввод/вывод в поток

Ввод/вывод в поток можно осуществлять различными способами: в виде последовательности байтов, в виде символов и строк или с использованием форматных преобразований. Для каждого вида операций определен свой набор функций.

Операции ввода/вывода выполняются, начиная с текущей позиции потока, определяемой положением указателя потока. Указатель устанавливается при открытии на начало или конец файла (в соответствии с режимом открытия) и изменяется автоматически после каждой операции ввода/вывода. Текущее положение указателя можно получить с помощью функций ftell и fgetpos и задать явным образом с помощью функций fseek и fsetpos.

Ниже перечислены функции ввода/вывода потока (таблица 8.2).

Таблица 8.2

Функция

 

Описание

1

 

2

 

Посимвольный

обмен

Чтение символа из потока

 

Функция возвращает очередной символ в

int getc(FILE *f);

 

форме int из потока f. Если символ не

int fgetc(FILE *f);

 

может быть прочитан, то возвращается

 

 

значение EOF

Запись символа в поток

 

Функция записывает символ с в поток f.

int putc(int c, FILE *f);

 

При ошибке возвращает значение EOF,

int fputc(int c, FILE *f);

 

иначе — записанный символ

 

Строковый

обмен

Чтение строки из потока

 

Функция fgets читает из определяемого

char*fgets(char*s,int n,FILE*f);

 

указателем f файла не более (n - 1) сим-

 

 

волов и записывает их в строку s. Функ-

 

 

ция прекращает чтение, как только про-

 

 

чтет (n - 1) символов или встретит символ

 

 

новой строки '\n', который переносится в

 

 

строку s. При ошибках или при достиже-

 

 

нии конца файла, при условии, что из

 

 

файла не прочитан ни один символ,

 

 

функция возвращает значение NULL

37

 

Окончание таблицы 8.2

 

 

 

1

2

Запись строки в поток

Функция fputs записывает строку s в

int fputs(char *s, FILE *f);

файл, заданный указателем f на поток, и

 

возвращает неотрицательное целое. При

 

ошибках функция возвращает значение

 

EOF

Форматированный

обмен

Вывод из файла форматированных данных

Функция вводит строку параметров par1,

int fscanf(FILE*f, const char *fmt [,par1, par2…]);

раг2 и т. д. в формате, определенном

 

строкой fmt, из файла f. Возвращает чис-

 

ло переменных, которым присвоено зна-

 

чение

Запись данных в поток

Функция записывает в поток f перемен-

Int fprintf(FILE *f, const char *fmt, …);

ные, список которых обозначен многото-

 

чием (…), в формате, указанном строкой

 

fmt. Возвращает число записанных сим-

 

волов

Порционный (поблочный) обмен

Чтение данных из потока

Функция fread() считывает из файла, оп-

size_t fread(void *p, size_t size, size_t n, FILE *f );

ределяемого указателем потока f, в об-

 

ласть памяти p n элементов размером по

 

size байтов каждый. Функция возвращает

 

число действительно прочитанных эле-

 

ментов. Если число элементов меньше

 

заказанного n, то это свидетельствует ли-

 

бо о достижении конца файла, либо об

 

ошибке чтения

Запись данных из заданного буфера в поток

Функция записывает n элементов длиной

size_t fwrite(void *p, size_t size, size_t n. FILE *f);

size байт из буфера, заданного указателем

 

р, в поток f. Возвращает число записан-

 

ных элементов

Позиционирование

в потоке

Текущая позиция в потоке

Функция возвращает текущую позицию в

long int ftell(FILE *f);

файле, связанном с потоком f как длин-

 

ное целое

Изменение текущей позиции в потоке

Функция перемещает текущую позицию

int fseek(FILE *f, long off, int org);

в файле, связанном с потоком f, на по-

 

зицию off, отсчитываемую от значения

 

org, которое должно быть равно одной из

 

трех констант, определенных в <stdio.h>:

 

SEEK_CUR — от текущей позиции ука-

 

зателя;

 

SEEK_END — от конца файла;

 

SEEKSET - от начала файла

Пример. С помощью текстового редактора (DOS) создать файл, содержащий текст, длина которого не превышает 1000 символов (длина строки текста не должна превышать 70 символов).

Файл должен иметь расширение DAT.

38

Написать программу, которая:

-выводит текст на экран дисплея;

-определяет количество символов в самом длинном слове. Текст программы:

#include <stdio.h> #include <iostream.h> #include <string.h> #include <windows.h> char buf[256];

char *Rus(char *text) {CharToOem(text,buf); return buf;}

int main()

{

FILE *fp;

char str[70],*p; int n,max_sl;

if ((fp=fopen("blocnote.dat","r"))==NULL) //открытие файла

{

perror(Rus(”Ошибка открытия файла для чтения”)); return 1;

}

max_sl=0;

while(fgets(str,70,fp)) //чтение строки из файла

{

cout<<Rus(str);

//выделение слов в строке и подсчет их

p=strtok(str," ,.;!?\n");//выделение первого слова в строке do

{

if (strlen(p)> max_sl) //если длина слова > максимальной max_sl= strlen(p);

}

while(p=strtok(NULL," ,.;!?\n"));

}

cout<<endl;

cout<<Rus("Символов в самом длинном слове: ")<<max_sl<<endl; return 0;

}

Список литературы

1Ишкова, Э. А. С++. Начала программирования / Э. А.Ишкова. – М.: «Бином», 2000. –304 с.

2Культин, Н. Б. С/С++ в задачах и примерах / Н. Б. Культин. – СПб.: БХВ-Петербург, 2002. – 592 с.

3Павловская, Т. А. С/С++. Программирование на языке высокого уровня: учебник / Т. А.Павловская. – СПб.: Питер, 2006. – 461 с.

39

4Павловская, Т.А. С/С++. Структурное программирование: практикум / Т.А. Павловская, Ю.А. Щупак – СПб.: Питер, 2003. – 240 с.

5Подбельский, В.В. Язык С++:учеб. пособие / В.В. Подбельский - М.: Финансы и статистика, 2005. – 560с.

6Шелест, В. Д. Программирование / В. Д. Шелест - СПб: БХВ - Пе-

тербург, 2002. – 288 с.

7Шилдт, Г. Программирование на BORLAND C++ для профессионалов: пер. с англ./ Г. Шилдт – Минск.: Попурри, 1998. – 800 с.

8Шилдт, Г. Теория и практика С++: пер. с англ. / Г. Шилдт. - СПб.: БХВ-Петербург, 2001. – 416 с.

40

Приложение А

(рекомендуемое)

ГОСУДАРСТВЕННОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ

«БЕЛОРУССКО-РОССИЙСКИЙ УНИВЕРСИТЕТ»

Кафедра «Автоматизированные системы управления»

Контрольная работа № 1

по дисциплине «Основы алгоритмизации и программирования»

Выполнил: студент гр. АСОИЗ–_

_________________Иванов И. И.

Номер зач. книжки ХХХХХХ

Проверил: ст. преподаватель кафедры АСУ

_________________Петров П. П.

Могилев 200_

Рисунок А.1 – Пример оформления титульного листа