Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы си++.pdf
Скачиваний:
58
Добавлен:
09.04.2015
Размер:
455.01 Кб
Скачать

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

Структура текстового файла программы

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

В строгой интерпретации, в C/C++ физическим модулем является отдельный сегмент компиляции, т. е. объектный файл. Физическому модулю соответствует файл с исходным текстом C/C++, к которому подключены необходимые заголовочные файлы, образующие инт ерфейс между модулями. Поэтому часто (с некоторой долей условности) модулем называют также файл с исходным текстом. Язык С и первые реализации языка С++ не предоставляли других механизмов реализации модульности, поэтому физический модуль являлся одновременно и логическим модулем.

Пример структуры текстового файла программы, включающей функции main(), f1() и f2(): //имя файла

//директивы препроцессора

#include <стандартный файл> //подключение стандартных заголовочных файлов

#include ”файл пользователя” //подключение заголовочных файлов пользователя //определение глобальных переменных

//прототипы функций

 

void f1();

// прототип функции f1

int f2 (int, char);

//прототип функции f2

//определение функции main()

 

int main () {

//заголовок функции

 

//тело функции (операторы)

//операторы, содержащие вызов функций f1 и f2, например: f1();

//например: cout << f2(4, ‘a’) << endl; выведет то, что вернет вызов функции, т.е. выражение return 0; // завершает тело функции с заголовком int main ()

}

//определение функции f1()

 

void f1() {

//заголовок функции

 

//тело функции

return;

// завершает тело функции с заголовком void f1()

}

 

//определение функции f2()

 

int f2 (int k, char c) {

//заголовок функции

//тело функции f2

// завершает тело функции с заголовком int f1(int k, char c)!!!

return выражение;

}

 

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

17

 

Если функция main() получает аргументы, то она определяется так:

int main (int argc, char *argv[])

//или

int main(int argc, char **argv)

{

 

 

//тело функции

 

 

return 0;

 

 

}

где: int argc – число слов, переданное в программу при ее запуске, char *argv[ ] – массив из argc строк;

аргумент argv[0] является именем запускаемого на выполнение файла; argv[1] – первое переданное слово;

argv[2] – второе переданное слово ….. и т.д.

Стандарт языка С++ требует, чтобы функции были объявлены до первой ссылки на них: их прототипы размещаются в начале программы. Компилятор выполняет строгую проверку числа параметров и соответствия типов в прототипе, в вызове функции и в ее определении, а в ряде случаев выполняет и неявное преобразование типов.

Имена функций – это глобальные имена, видимые по умолчанию из всех файлов одного проекта. Однако прототип функции действует только в пределах одного файла. Из-за этого, в частности, приходиться помещать во все совместно компилируемые файлы директивы препроцессора, связанные с подключением .h-файлов, содержащих прототипы библиотечных функций. Как мы видели, прототипы функций помещаются в заголовочный файл, подключаемый директивой #include к тексту файла программы.

Структура программы из двух текстовых файлов

Рассмотрим модель программы из двух текстовых файлов (Рис.1.7). Линии 1-3 указывают область действия глобальных переменных (ниже точки определения): массива array, переменных ext_ch и ext_pp. В пределах области определения их можно использовать во всех функциях без дополнительного объявления как extern (линия 1 для массива array; линия 2 для переменной ext_ch; линия 3 для переменной ext_pp). Чтобы использовать переменные ext_ch и ext_pp в функции main(), т.е. выше точки определения, их надо объявить как extern (внешние) (например, линия 6 для переменной ext_pp).

Во всех функциях, за исключением function3() из файла File2.cpp , описана внутренняя переменная a, которой соответствует своя память, доступ к которой возможен только из пределов функции, но не из других функций.

Область определения глобальных переменных ограничена пределами одного файла (File1.cpp), и, следовательно, эти переменные невидимы в другом файле (File2.cpp). Для их использования требуется также объявление extern (например, линия 5 для массива array; линия 7 для переменной ext_ch; только функция function3() для переменной ext_pp).

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

18

 

File1.cpp

 

File2.cpp

 

 

 

Рис.1.7. Структура программы из двух файлов и область действия переменных в программе

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

19

 

Пример более сложной программы на С++ (сортировка строк)*1

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

Исходный текст программы представлен в текстовых файлах (main.cpp, bblsort.cpp) и в заголовочных файлах (Рис.1.8):

стандартном заголовочном файле stdafx.h

файле bblsort.h (подключаемом в начале каждого из текстовых файлов в рамках файла stdafx.h).

файл bblsort.h

#define MAXLINES 10

#define LINESIZE (12+1)

файл stdafx.h

#include <iostream>

#include <conio.h>

#include <cstring>

#include "bblsort.h"

int rdlines(void); void wrlines(int);

int lexcmp(int, int); void swap(int, int); void bblsort(int);

using namespace std;

файл main.cpp

#include "stdafx.h"

char Line[MAXLINES][LINESIZE]; int Revflg;

int main (int argc, char **argv)

{int numlines;

Revflg = (argc>1 && argv[1][0] =='-'); numlines = rdlines();

cout << "\n-----------------

\n" ;

bblsort(numlines);

 

wrlines(numlines);

\n" ;

cout << "\n-----------------

_getch();

 

return 0;

 

}

 

static int rdlines() {int i;

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

if (!cin.getline(Line[i], LINESIZE)) break;

}return i;

static void wrlines(int n) {unsigned i;

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

cout << Line[i] << endl;

} return;

файл bblsort.cpp

#include "stdafx.h"

extern char Line[ ][LINESIZE];

void bblsort( int n) {unsigned i, j;

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

for (j=n-1; j>=i; j--) if (lexcmp(j-1, j))

swap(j-1, j);

}return;

static int lexcmp (int i,int j) {extern int Revflg;

int lc;

lc= strcmp(Line[i], Line[j]); return ((lc<0 && Revflg) ||

(lc > 0 && !Revflg));

}

static void swap( int i, int j) {char temp [LINESIZE]; strcpy_s(temp, Line[j]); strcpy_s(Line[j], Line[i]); strcpy_s(Line[i], temp);

} return;

Рис.1.8. Структура программы сортировки строк

Программа с комментариями и подробное описание действий, выполняемых каждым фрагментом (А, B, C, D, …), представлены ниже.

//bblsort.h заголовочный файл

А#define MAXLINES 10

#define LINESIZE (12+1)

//stdafx.h стандартный заголовочный файл

B

#include <iostream>

//для ввода/вывода

#include <conio.h>

//для _getch()

 

#include <cstring>

//для strcmp(), strcpy_s()

1 *Программа не для всех

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

20

 

#include "bblsort.h"

//для MAXLINES, LINESIZE

int rdlines(void);

//прототипы функций, определенных в файле main.cpp

void wrlines(int);

 

int lexcmp(int, int);//прототипы функций,определенных в файле bblsort.cpp

void swap(int, int);

 

void bblsort(int);

 

using namespace std;

 

//main.cpp программный файл

C

#include "stdafx.h"

//подключение стандартного заголовочного файла

D

char

Line[MAXLINES] [LINESIZE];

//глобальные переменные

 

//буфер строк

 

int

Revflg;

 

//признак направления сортировки

E

 

 

//определение функции main()

 

int main (int argc, char **argv)

//аргументы вызова программы

// argc - число аргументов, argv – указатель на строки-аргументы

{

F

G

int numlines;

//локальная переменная функции main()

Revflg = (argc>1 && argv[1][0] =='-');

numlines = rdlines();

//вызов функции ввода строк

cout << "\n----------------------

\n" ;

bblsort(numlines);//вызов функции сортировки,аргумент – количество строк

wrlines(numlines);//вызов функции вывода строк,аргумент – количество строк

cout << "\n----------------------

\n" ;

_getch();

//функция _getch(); ожидает нажатия клавиши

return 0;

 

}

 

H

//определение функции rdlines() ввода строк с клавиатуры

I

static int rdlines()

//функция доступна только в данном файле main.cpp

{ int i;

//локальная переменная функции rdlines()

 

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

 

if (!cin.getline(Line[i], LINESIZE) )

 

} return i;

 

break;

 

 

//функция возвращает количество введенных строк

J

//определение функции wrlines() вывода n строк на экран

 

static void wrlines(int n) //функция доступна только в файле main.cpp

 

{

 

 

 

unsigned i;

//локальная переменная функции wrlines()

 

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

 

 

cout << Line[i] << endl;

}

return;

//функция выводит строки и ничего не возвращает

 

 

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

21

 

//bblsort.cpp программный файл

K#include "stdafx.h" //подключение стандартного заголовочного файла

Lextern char Line [][LINESIZE]; //объявление массива Line,

//определенного в файле main.cpp

M

 

//определение функции bblsort()сортировки строк

 

void bblsort( int n)

// n - число строк

 

{

unsigned i, j;

//локальные переменные функции bblsort()

 

 

 

 

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

 

 

for (j=n-1; j>=i; j--)

 

 

if (lexcmp(j-1, j)) swap(j-1, j);

 

}

return;

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

 

 

 

N

 

// определение функции lexcmp() сравнения строк

 

 

 

//аргументы i, j – номера строк для сравнения

 

static int lexcmp (int i, int j)

 

{

 

//функция доступна только в файле bblsort.cpp

 

extern int Revflg;

//объявление Revflg, определение в файле main.cpp

int lc;

lc= strcmp(Line[i], Line[j]); //библиотечная функция сравнения строк

return ((lc<0 && Revflg) || (lc > 0 && !Revflg));

}//функция lexcmp() возвращает 1 или 0 в зависимости от результата //сравнения строк lc и признака Revflg направления сортировки

O

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

 

// аргументы i, j – номера строк для обмена

static void swap( int i, int j) //функция доступна только в этом файле

{

 

 

char temp [LINESIZE];

//библиотечная функция копирования строк

strcpy_s(temp, Line[j]);

strcpy_s(Line[j], Line[i]);

 

strcpy_s(Line[i], temp);

 

return;

//функция swap() меняет строки и ничего не возвращает

}

 

 

А – заголовочный файл bblsort.h с препроцессорными константами MAXLINES и LINESIZE. Препроцессорные константы обычно помещаются в заголовочный файл, включаемый в другие файлы программы, по мере необходимости. При изменении значений констант изменения затронут только файл bblsort.h.

B – стандартный заголовочный

файл stdafx.h. Содержит директ ивы препроцессора для

подключения

стандартных заголовочных файлов с прототипами библиотечных функций (для

работы со строками и другими функциями, вызываемыми в файле); директ иву препроцессора для

подключения

пользовательского

заголовочного файла bblsort.h с препроцессорными

константами MAXLINES и

LINESIZE;

прототипы

функций rdlines(),

wrlines(),

определенных в файле main.cpp, и

lexcmp(), swap(), bblsort(),

определенных в файле

bblsort.cpp

программы, а также директиву using namespace std; определяющую для данной программы в качестве пространства, в котором распознаются ее имена, стандартное пространство имен std (за пределами его имена будут неизвестны).

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

22

 

Блоки от С до J включительно представляют содержание файла main.cpp с головной функцией main() и вызываемыми в ее теле функциями rdlines() и wrlines().

С – подключение к файлуmain.cpp стандартного заголовочного файла stdafx.h.

D – определение глобальных переменных, доступных во всех файлах программы при объявлении их в этих файлах как extern.

В блоках от E до G представлено определение головной функции main(), обязательной для программы на С++ и получающей управление первой после запуска программы на выполнение. Функции main() могут передаваться аргументы. Одна из возможных форм описания формальных

параметров функции main() представлена в блоке E.

E – заголовок функции main(): int argc – число строк-аргументов переданное в программу; char** argv – указатель на строки-аргументы; аргумент argv[0] является именем запускаемого на выполнение файла; argv[1] – это первый аргумент-строка; argv[2] – это второй аргумент-строка и т.д. Количество строк-аргументов равно argc.

Если при выполнении программы задать в качестве аргумента символ +, то строки будут упорядочены по возрастанию (от a к z). Если при выполнении программы задать в качестве

аргумента символ -, то строки будут упорядочены по убыванию.

Задание аргумента при выполнении программы в среде Microsoft Visual C++ 2005 осуществляется в поле Command arguments подкоманды Debugging команды Project

имя_проекта Properties…( Projectимя_проекта Properties…окно имя_проекта Property Pages Configuration Properties Debugging поле Command arguments).

F – определение локальной целой переменной numlines.

G – перед обращением к argv[1][0] проверяется число аргументов argc, т.к. при отсутствии второго аргумента выражение argv[1][0] не имеет смысла.

Блок содержит последовательные вызовы функций ввода – rdlines(), сортировки – bblsort() и вывода – wrlines() строк. При этом функции rdlines() и wrlines() определены в файле main.cpp, а функция bblsort() – в файле bblsort.cpp.

В блоках H и I представлено определение функции rdlines(), возвращающей целое число прочитанных строк. Спецификатор static указывает, что функция используется только в данном файле.

Переменная i определена как локальная в блоке. Если вводится нормальная строка (вызов функции cin.getline(Line[i],LINESIZE) возвращает значение отличное от 0), то функция rdlines() возвращает номер строки; в противном случае (например, при нажатии клавиш Ctrl+Z) , ввод строк завершается.

J – определение функции wrlines(). Функция не возвращает значения, поэтому определена как имеющая тип void.

Блоки от K до O включительно представляют содержание файла bblsort.cpp с функцией сортировки bblsort() и вызываемыми в ее теле функциями сравнения – lexcmp() и обмена – swap() строк.

K – подключение к файлуbblsort.cpp стандартного заголовочного файла stdafx.h.

L – описание глобального массива строк Line, спецификатор extern указывает на то, что определение массива сделано в другом месте (в данном случае в файле main.cpp).

M – определение функции bblsort(). Функция вызывает функции сравнения – lexcmp() и обмена – swap() строк. Функция не описывается как static, потому что она вызывается функцией main(), которая определена в другом файле.

N – определение функции lexcmp(). Возвращаются значения Истина (1) или Ложь (0),

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

23

 

кодируемые целыми значениями. Поэтому функция определена как имеющая тип int. Глобальная переменная Revflg описана как внешняя, так как она определена в другом файле. Прототип функция стандартной strcmp() содержится в заголовочном файле string.h.

O – определение функции swap(). Функция определена как имеющая тип void. Прототип стандартной функция strcpy() содержится в заголовочном файле string.h. Локальная переменная стокового типа temp предназначена для временного хранения строки при выполнении обмена.

Результат выполнения программы в среде Microsoft Visual С++ 2005 в режиме консольных приложений:

При аргументе +

При аргументе -:

qwertyui

qwertyui

wertyuio

wertyuio

ertyuio

ertyuio

rtyuiop

rtyuiop

rtyu

rtyu

tyui

tyui

asdfghjk

asdfghjk

sdfghjkl

sdfghjkl

dfgh

dfgh

fghj

fghj

----------------------

----------------------

asdfghjk

wertyuio

dfgh

tyui

ertyuio

sdfghjkl

fghj

rtyuiop

qwertyui

rtyu

rtyu

qwertyui

rtyuiop

fghj

sdfghjkl

ertyuio

tyui

dfgh

wertyuio

asdfghjk

Программирование – лекция 1 (лекции Стрикелевой Л.В.)

24