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

книги / Проектирование программ и программирование на C++. Структурное программирование

.pdf
Скачиваний:
4
Добавлен:
12.11.2023
Размер:
3.86 Mб
Скачать

СИМВОЛЬНАЯ ИНФОРМАЦИЯ И СТРОКИ

16.1. Представление символьной информации

Для символьных данных в C++ введен тип c h a r. Для представ­ ления символьной информации используются символы, символьные

переменные и текстовые константы.

 

 

//с и м в о л зан и м ает один

б ай т , е го

зн ач ен и е не

//м е н я е т с я

 

 

 

 

c o n s t c h a r с = 'с '

 

 

/ * символьны е

переменны е

занимаю т

по одному

б ай ту , зн ач ен и я

м огут м е н я т ь с я * /

 

c h a r a ,b ;

 

 

 

 

//т е к с т о в а я

к о н ст а н т а

 

 

c o n s t c h a r

*з="П ример с т р о к и \п " ;

 

Строка в C++ -

это массив символов, заканчивающийся нуль-

символом - ' \ 0 '

(нуль-терминатором). По положению нуль-терми­

натора определяется фактическая длина строки. Количество элемен­ тов в таком массиве на 1 больше, чем изображение строки (рис. 11).

A

\0

A

 

’VV’

’A’

 

строка

символ

(2 байта)

(1 байт)

Рис. 11. Представление строки и символа

Присвоить значение строке с помощью оператора присваивания нельзя. Поместить строку в массив можно либо при вводе, либо с помощью инициализации.

void main()

{

char

si [ 1 0 ] = f,stringl,f;

int

k=sizeof(si);

c o u t « s l « M\tf,« k « e n d l ;

char

s2 []=f,string2";

k=sizeof(s2);

cout<<s2<<M\t"<<k<<endl;

char s3[]={ 's','t','r','i','n','g','3'} k=sizeof(s3);

cout«s3«"\t"«k«endl;

//у к а з а т е л ь

на с т р о к у ,

ее н е л ь з я

и зм ен и ть:

 

c h a r * s 4 = " s tr in g 4 " ;

 

 

 

k = s i z e o f (s 4 ) ;

 

 

 

 

c o u t « s 4 « " \ t " « k « e n d l ;

 

 

}

 

 

 

 

 

 

 

 

Результаты:

 

 

 

 

 

 

s t r i n g l

10

-

выделено 10 байтов, в том числе под \0;

 

s t r i n g 2

8

-

выделено 8 байтов (7+1 байт под \0);

 

s t r i n g 3

8

-

выделено 8 байтов (7+1байт под \0);

 

s t r i n g 4

4

-

размер указателя.

 

 

c h a r

* s = " S tr in g 5 " ;

//в ы д е л я е т с я

8 б ай то в

для

строки

 

 

 

 

 

 

 

 

c h a r*

s s ;

 

 

 

//о п и с а н у к а з а т е л ь

/* п ам ять

не

в ы д ел я ет ся ,

п оэтом у програм м а

мо­

жет за к о н ч и т ь с я

а в а р и й н о :* /

 

 

s s = /,S tr i n g 6 " ;

 

 

 

 

c h a r

*sss=new c h a r [ 1 0 ] ;

//вы д ел яем

динамическую

//п а м я т ь

s t r c p y ( s s s ," S t r i n g 7 " ) ; //ко п и р у ем строку в память Для ввода и вывода символьных данных в библиотеке языка С

определены следующие функции:

i n t g e tc h a r (v o id ) - осуществляет ввод одного символа из

входного потока, при этом она возвращает один байт информации (символ) в виде значения типа i n t . Это сделано для распознавания ситуации, когда при чтении будет достигнут конец файла.

i n t p u t c h a r ( i n t с ) - помещает в стандартный выходной поток символ с.

c h a r* g e ts (c h a r* s ) - считывает строку s из стандартного пото­

ка до появления символа ' \ п ', сам символ ' \ п ' в строку не заносится.

i n t p u ts ( c o n s t c h a r* s) записывает строку в стандарт­

ный поток, добавляя в конец строки символ ' \ п ' , в случае удачного завершения возвращает значение больше или равное 0 и отрицатель­

ное значение (EOF = -1) в случае ошибки,

 

c h a r s [2 0 ];

 

 

 

 

c in > > s ;

//в в о д

стр о к и

и з

с т а н д а р т н о г о

п отока

c o u t< < s ;

//в ы в о д

стр о к и

в

стан д ар тн ы й

п оток

JH вводе строки "123 456 789" чтение байтов осуществля­ ется до первого пробела, т.е. в строку s занесется только первое слово

строки " 1 2 3 \0 " , следовательно, выведется 123.

 

c h a r

s [ 2 0 ] ;

 

 

 

 

 

 

 

 

g e t s ( s ) ;

/ / в в о д

стр о к и

и з ст а н д а р т н о го

п о то ка

p u t s ( s ) ;

//в ы в о д

стр о к и

в

стандартн ы й

п оток

При вводе строки "123

456

789" чтение байтов осуществляется

до символа ' \ п ' , т.е. в s занесется строка "123

456 78 9 \п \0 " , при

выводе строки функция p u ts

возвращает еще один символ ' \ п ' , сле­

довательно, будет выведена строка "123

456

7 8 9 \ п \ п "

 

c h a r

s [ 2 0 ] ;

 

 

стр о к и и з

 

с т а н д а р т н о го

s c a n t ( " % s " , s ) ; / / в в о д

 

/ / п о т о к а

 

 

 

 

 

 

 

 

 

 

p r i n t f ( " % s " , s ) ; / / в ы в о д

стр о к и

в

стандартн ы й

/ / п о т о к

 

 

 

 

 

 

 

 

 

 

При вводе строки "123

456

 

789", чтение байтов осуществля­

ется до первого пробела, т.е. в строку s занесется только первое слово

строки

" 1 2 3 /0 " , следовательно,

выведется

123. Так

как

s - имя

массива, т.е. адрес его первого

элемента,

операция

& в

функции

s c a n t

не используется.

 

 

 

 

16.2. Библиотечные функции для работы со строками

Для работы со строками существуют специальные библиотечные функции, которые содержатся в заголовочном файле s t r i n g . h.

Некоторые библиотечные функции для работы со строками

Прототип функции

1

unsigned strlen(const char* s ) ;

i n t

s t r c m p (c o n s t

char*

s i ,

c o n s t

char*

s 2 ) ;

 

 

i n t

s t r c n m p (c o n s t

char*

s i ,

c o n s t

char*

s 2 ) ;

 

 

Краткое

описание

2 Вычисляет длину строки S

Сравнивает строки s i и s2

Сравнивает пер­ вые п символов строк s i и s2

Примечание

3

Если s l< s 2 , то результат отрицательный, если

sl= = s2 , то результат равен 0, если s 2 > s l - результат положительный Если s l< s 2 , то результат отрицательный, если

sl= = s2 , то результат равен 0, если s 2 > s l - результат положительный

 

 

1

 

 

char*

s tr c p y (c h a r *

s i ,

c o n s t

char*

s 2 );

 

 

 

char*

s tm c p y (c h a r *

s i ,

 

c o n s t

char*

s 2 , i n t

n ) ;

 

char*

s tr c a t ( c h a r *

s i ,

c o n s t

char*

s 2 ) ;

 

 

 

char*

s t m c a t ( c h a r *

s i ,

 

c o n s t

char*

s 2 ) ;

 

 

char*

s tr d u p (c o n s t

char* s ) ;

Окончание табл.

2 3

Копируетсимволы строкиs i в строкуs2

Копирует п сим­ волов строки s 1 в строку s2 Приписывает стро­ ку s2 к строке s i Приписывает

первые п символов строки s2 к стро­ ке s i

Выделяет память и переносит в нее копию строки S

Конец строки отбрасыва­ ется или дополняется пробелами

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

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

Задача 1. Дана строка символов, состоящая из слов, слова разделены между собой пробелами. Удалить из строки все слова, на­ чинающиеся с цифры.

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

#include <stdio.h> #include <string.h> void main()

{

//исходная

строка

char s[250],

w [25],

//слово

слов

mas[10][25];

//массив

puts("Хпвведите строку"); gets (s);

i n t k = 0 , t = 0 , i , l e n , j ; l e n = s t r l e n (s );

w h i l e (t < l e n )

f o r (j = 0 , i = t ; s [ i ] !=

' ; i + + , j + + )

w[_ s[i];

//формируем слово

до пробела

w[j]='/0'

//формируем конец

строки

strcpy(mas[k],w);

//копируем слово в массив

k++;

//увеличиваем счетчик слов

//переходим к следующему слову в исходной

//строке

 

 

 

t=i i-l;

 

 

 

}

 

 

строку

s t r c p y ( s , ;//очищаем исходную

for(t=0;t<k;t++)

i f ( m a s [ t ] [ 0 ] < ' 0 ' && m a s [t ] [ 0 ] > ' 9 ' )

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

{

streat(s,mas[t]);//копируем в строку слово strcat(s," ");//копируем в строку пробел

}

puts(s);//выводим результат

}

Задача № 2. Сформировать динамический массив строк. Уда­ лить из него строку с заданным номером.

В динамическом массиве строк каждая строка имеет свою длину, поэтому при формировании такого массива нужно выделять память под каждую строку отдельно.

#include <iostream.h> #include <string.h> void main()

{

int n; cout«"\nN=?";

cin»n;

//вспомогательная переменная для ввода строки char s [100];

char** mas=new char*[n]; for(int i=0;i<n;i++)

{

cout«"\nS=?";

cin>>s; //вводим строку /*выделяем столько памяти, сколько символов

в строке + один байт для '\0'*/

mas[i]=new char[strlen(s)+1]; //копируем строку в массив

strcpy(mas[i],s);

}

//вывод массива

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

{

cout«mas [i]; cout«"\n" ;

}

 

int k;

 

сои^<м\пК=?";

//ввести номер удаляемой

cin»k;

//строки

 

if(k>=n)

 

{

cout<<"There is not such string\n"; return;

}

/*выделяем память для размещения нового масси­

ва строк (без строки с номером к)*/ char** temp=new char*[n-l];

int j=0;

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

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

if(i!=k)

{

//выделяем память под строку temp[j]=new char[strlen(mas[i])];

//копируем строку strcpy(temp[j],mas[i] );

j++;

}

n— ///уменьшаем размер массива for(i=0;i<n;i++) //вывод нового массива

{

c o u t < < t e m p [i ] ; c o u t < < " \ n " ;

}

. гу же задачу можно решить, не выделяя память под элементы

нового массива, а меняя указатели: tem p [j ] =mas [ i ];

/*выделяем память для размещения нового масси­ ва строк (без строки с номером к)*/

char** temp=new char*[n-l]; int j=0;

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

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

if(i!=k)

{

temp[j]=mas[i];// меняем указатели j++;

}

n— ; //уменьшаем размер массива delete []mas;//удаляем старый массив

mas=temp;//ставим указатель на измененный

//массив

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

{

cout<<mas[i]; //вывод массива cout<<"\n";

}

17.ФУНКЦИИ В C++

Сувеличением объема программы становится невозможно удерживать в памяти все детали. Чтобы уменьшить сложность про­ граммы, ее разбивают на части. В C++ задача может быть разделена на более простые подзадачи с помощью функций. Разделение задачи на функции также позволяет избежать избыточности кода, так как функцию записывают один раз, а вызывают многократно. Програм­ му, которая содержит функции, легче отлаживать.

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

17.1.Объявление и определение функций

Функция - это именованная последовательность описаний

и операторов, выполняющая законченное действие, например форми­ рование массива, печать массива и т.д.

Функция, во-первых, является одним из производных типов C++,

а во-вторых, минимальным исполняемым модулем программы (рис. 12).

Исходные данные

 

Результат (возвращаемое

(параметры, передаваемые

Функция

в функцию)

значение)

------------------------------ ^

 

 

Рис. 12. Функция как минимальный исполняемый модуль программы

Любая функция должна быть объявлена и определена.

Объявление функции (прототип, заголовок) задает имя функции,

тип возвращаемого значения и список передаваемых параметров. Определение функции содержит, кроме объявления, тело функ­

ции, которое представляет собой последовательность описаний и операторов,

тип

имя_функции([список_формальных параметров])

{

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

}

Тел _ дикции - это блок, или составной оператор. Внутри функции нельзя определить другую функцию.

В теле функции должен быть оператор, который возвращает по­ лученное значение функции в точку вызова. Он может иметь две формы:

1)return выражение;

2)return;

Первая форма используется для возврата результата, поэтому выражение должно иметь тот же тип, что и тип функции в определе­ нии. Вторая форма используется, если функция не возвращает значе­ ния, т.е. имеет тип void. Программист может не использовать этот оператор в теле функции явно, компилятор добавит его автоматиче­ ски в конец функции перед }.

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

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

Для того чтобы выполнялись операторы, записанные в теле функции, функцию необходимо вызвать. При вызове указываются: имя функции и фактические параметры. Фактические параметры за­ меняют формальные параметры при выполнении операторов тела функции. Фактические и формальные параметры должны совпадать по количеству и типу.

Объявление функции должно находиться в тексте раньше вызова функции, чтобы компилятор мог осуществить проверку правильности вызова. Если функция имеет тип не void, то ее вызов может быть операндом выражения.

/^Заданы координаты сторон треугольника, если такой треугольник существует, то найти его пло­ щадь*/

#include dost ream. h>

#include <math.h>

/^функция возвращает длину отрезка, заданного

координатами xl,yl и х2,у2*/

double line(double xl,double yl,double x2,double y2)

{

return sqrt(pow(xl-x2,2)+pow(yl y2,2));

}

/*функция возвращает площадь треугольника, за­ данного длинами сторон а,Ь,с*/

double square(double a, double b, double c)

{

s, p=(a+b+c)/2;

 

 

double

 

 

return

s=sqrt(p*(p-a)* (p-b)* (p-c));//формула

//Герона

 

 

 

}

 

треугольник существует

//возвращает true, если

bool triangle(double a,

double

b, double c)

{

 

return

true;

if(a+b>c&&a+c>b&&c+b>a)

else return false;

 

 

}

 

 

 

void main()

 

 

{

xl=l,yl,x2,y2,x3,y3;

 

double

 

double point1_2,point1_3,point2_3; do

{

cout«"\nEnter koordinats of triangle:"; cin>>xl»yl>>x2»y2»x3>>y3; pointl_2=line(xl,yl,x2,y2) ; pointl_3=line(xl,yl,x3,y3); point2_3=line(x2,y2,x3,y3);

if (triangle(point1_2,point1_3,point2_3)==true) cout«"S="«square (pointl_2,point2_3,point 1_3)

< < " \ n " ;

else cout<<"\nTriagle doesnt exist";

}

while(!(xl==0&&yl==0&&x2==0&&y2==0&&x3==0&&y3=

= 0 ) ) ;

}

Соседние файлы в папке книги