Рефераты

Лекции по C++

переменной типа, специфицированного об"явлением, становится синонимом

имени типа. Об"явление typedef не создает типов. Оно создает синонимы для

существующих имен типов, которые были специфицированы другим способом.

Любой тип может быть об"явлен с typedef, включая типы указателя,

функции и массива. Имя с ключевым словом typedef для типов указателя,

структуры или совмещения может быть об"явлено прежде чем эти типы будут

определены, но в пределах видимости об"явления.

Примеры:

/******************** Example 1 ********************/

typedef int WHOLE;

/******************** Example 2 ********************/

typedef struct club {

char name[30];

int sise, year;

} GROUP;

/******************** Example 3 ********************/

typedef GROUP *PG;

/******************** Example 4 ********************/

typedef void DRAWE(int, int);

В первом примере об"является WHOLE как синоним для int .

Во втором примере об" является GROUP как структурный тип с тремя

элементами. Так как специфицирован также тег clab, то имя GROUP и тег club

могу быть использованы в об"явлениях.

В третьем примере используется предидущее имя typedef для об"явления

адресного типа. Тип PG об"является как указатель на тип GROUP, который в

свою очередь определен как структурный тип.

В последнем примере представлен тип DRAWE для функции не

возвращающей значения и требующей два аргумента типа int. Это означает,

например, что об"явление DRAWE box; эквивалентно об"явлению void box(int,

int);

Имена типов

Имя типа специфицирует особенности типа данных. Имена типов

используются в трех контекстах: в списках типов аргументов, при

об"явлении функций, в вычислениях cast (преобразованиях типов), и в sizeof

операциях. Списки типов аргументов рассматривались в

разделе 4.5. "Об"явления функций". Преобразования cast и операция sizeof

обсуждаются в разделах 5.7.2. и 5.3.4. соответственно.

Именами для основных, перечисляющих, структурных и совмещающих типов

являются спецификаторы типа для каждого из них. Имена для типов

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

Абстрактный декларатор - это декларатор без

идентификатора, состоящий из одного или более модификаторов указателей,

массивов и функций. Модификатор указателя (*) всегда появляется перед

идентификатором в деклараторе, в то время как модификатор массива ([]) или

функции ( () ) появляются после идентификатора. Таким образом, чтобы

правильно интерпретировать абстрактный декларатор, нужно начинать

интерпретацию с подразумеваемого идентификатора.

Абстрактные деклираторы могут быть составными. Скобки в составном

абстрактном деклараторе специфицируют порядок интерпретации, подобно тому

как это делается при интерпретации составных деклараторов об"явлений.

Абстрактный декларатор, состоящий из пустых круглых скобок () не

допускается, поскольку это двусмысленно. В этом случае невозможно

определить находится ли подразу-

меваемый идентификатор внутри скобок, и в таком случае- это

немодифицированный тип, или перед скобками, тогда- это тип функции.

Спецификаторы типа, установленные посредством об"явлений typedef, также

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

Примеры:

long * /* Example 1 */

int (*) [5] /* Example 2 */

int (*) (void) /* Example 3 */

В первом примере задано имя типа как указатель на тип long. Во втором

и третьем примерах показано каким образом скобки

модифицируют составные абстрактные деклараторы. В примере 2 задано имя

типа для указателя на массив иэ пяти злементов. В третьем примере именуется

указатель на функцию, не требующую аргументов и возвращающую значение типа

int.

КОНТРОЛЬНЫЕ ВОПРОСЫ:

1. Какие ошибки содержат следующие операторы?

enum State { on, off };

enum YesNo { yes, no};

enum DiskDriveStatus { on, off };

2. Верно или нет, что объявление следующего перечислимого типа неправильно?

enum YesNo { no = 0, No = 0, yes = 1, Yes = 1 };

3. Что не так в следующей программе?

#include

int main()

{

int *p = new int;

cout > *p;

cout )

// обязателен тип возвращаемого значения

{

< объявление данных >

< тело функции>

return возвращаемоеЗначение; // - если возвращаемыйТип не void

}

- Выход из функции осуществляется по оператору return. Void-функции

могут не возвращать значения.

Список параметров:

[const] тип1 параметр1, [const] тип2 параметр2, ...

- Ключевое слово const предохраняет передаваемые по ссылке аргументы от

случайного изменения.

Программа USERINFO.CPP иллюстрирует использование модификатора

// const в списке параметров

*/

struct userInfo

{

int age;

char name[150];

};

void processUserInfo(/*const*/ userInfo &ui)

// при снятии комментария будет сообщение об ошибке,

// поскольку модификатор const запрещает изменение параметра

{

if ( ui.age < 18 ) {

cout );

При объявлении функции имена параметров могут быть опущены.

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

переданного аргумента и экономит память, так как при этом не создается

локальная копия аргумента:

[const] тип1& параметр1, [const] тип2& параметр2, ...

void foo(int &); // - объявление функции - это ее прототип

int main()

{

int value = 5;

foo(value);

cout (n2)) ? (n1) : (n2))

double num1 = 50, num2 = 5, rslt;

rslt = min(num1 / 2, num2 * 2);

- При объявлении функции с модификатором inline компилятор заменяет вызов

функции ее телом. В этом смысле эти функции похожи на макросы.

Отличие состоит в том, что встроенные функции выполняют проверку типов

данных.

Программа INLINE.CPP, иллюстрирующая применение встроенной функции

- Используя аргументы по умолчанию для некоторых параметров, при вызове

функции вы можете не задавать аргументы для этих параметров; тогда им

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

Программа DEFARGS.CPP, иллюстрирующая применение аргументов по умолчанию

- Рекурсивными называются функции, которые вызывают сами себя. Количество

рекурсивных вызовов должно быть ограничено, чтобы не столкнуться с

проблемой нехватки памяти. По этой причине каждая рекурсивная функция

должна выполнять проверку условия на окончание рекурсии.

Пример программы FACTOR.CPP, использующей рекурсивную функцию

- Перегрузка функций позволяет вам иметь несколько функций с одним именем,

но с разными списками аргументов (список аргументов еще называется

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

сигнатуры.

Программа OVERLOAD.CPP, иллюстрирующая перегрузку функции

ТИПОВЫЕ ВОПРОСЫ С ОТВЕТАМИ

Можно ли в С++ объявлять вложенные функции?

Нет, так как это приводит к большим накладным расходам во время

выполнения программы.

В каких случаях нужно использовать статические глобальные переменные?

Можете использовать их, где хотите. Когда вы объявляете статической

глобальную переменную (которые я вам не советую использовать вообще), вы

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

файлов. Такая переменная недоступна из других файлов вашего проекта.

Как расходуется память при обслуживании вызовов рекурсивной функции?

Исполняющая система использует стек для хранения временных данных, в том

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

другие ресурсы, стек ограничен в своем размере. В результате при длинной

цепочке вызовов рекурсивной функции стек может переполниться, что приведет

к остановке программы из-за ошибок выполнения или переполнения стека.

ПРАКТИКУМ

Контрольные вопросы

1. Каков будет результат работы следующей программы? Что вы можете сказать

по поводу функции swap?

*/

# include

void swap(int i, int j)

{

int temp = i;

i = j;

j = temp;

}

int main()

{

int a = 10, b = 3;

swap (a, b);

cout

void swap(int &i, int &j)

{

int temp = i;

i = j;

j = temp;

}

int main()

{

int a = 10, b = 3;

swap (a, b);

cout

int main()

{

double x = 5.2;

cout

const int MAX = 0x1FFF; //64K/8 - максимальный размер массива типа double

***

int main()

{

double array[MAX]; // объявление одномерного массива

***

int num_elem;

// Ввод количества обрабатываемых данных

do

{

cout > num_elem;

cout MAX);

// Ввод данных

for (int ix = 0; ix < num_elem; ix++)

{

cout > array[ix];

}

// Расчет среднего значения

double sum = 0;

for (ix = 0; ix < num_elem; ++ix)

sum += array[ix];

cout

const int MAX = 10; //50

int main()

{

double array[MAX] = { 12.2, 45.4, 67.2, 12.2, 34.6, 87.4,

83.6, 12.3, 14.8/*, 55.5*/ };

int num_elem = MAX;

//double array[] = { 12.2, 45.4, 67.2, 12.2, 34.6, 87.4,

// 83.6, 12.3, 14.8, 55.5 };

//int num_elem = sizeof(array) / sizeof(array[0]);

double sum = 0;

for (int ix = 0; ix < num_elem; ++ix)

{

sum += array[ix];

cout |

|04 | |

|05 |int main() |

|06 |14 |

Пример программной сессии:

Введите три числа через пробел: 123

Сумма чисел = 6

Среднее этих чисел = 2

Введите три символа: ABC

Вы ввели символы 'A', 'B', 'C'

Введите число, символ, и число: 12A34.4

Вы ввели 12 A 34.4

Введите символ, число и символ: A3.14Z

Вы ввели A 3.14 Z

В программе из листинга 2 объявляется четыре переменных типа double и три

переменных типа char. Оператор вывода в строке 10 предлагает вам ввести три

числа. Оператор ввода в строке 11 помещает введенные вами числа в

переменные х, у и z. He забывайте, что при вводе чисел их нужно разделять

пробелами. Либо вводите каждое число с новой строки. Первое введенное вами

число будет помещено в переменную х, второе — в у, а третье окажется в

переменной z. Данные в переменные заносятся в том порядке, в котором

переменные перечислены в операторе ввода в строке 11. Оператор в строке 12

вычисляет сумму значений переменных х, у и z. Оператор вывода в строках 13

и 14 выводит сумму и среднее значение введенных вами величин.

Оператор вывода в строке 15 предлагает вам ввести три символа. Оператор

(ввода в строке 16 последовательно размещает введенные символы в переменных

с1, с2, с3. Использовать пробел для разделения вводимых символов не

обязательно. Например, вы можете ввести данные и таким образом: 1А2, Bob и

1 D d. Оператор вывода в строках 17—19 выводит введенные вами символы,

разделенные пробелами и заключенные в одинарные кавычки.

Оператор вывода в строке 20 предлагает вам ввести число, символ и число.

Оператор ввода в строке 21 помещает ваши данные в переменные х, с1 и у.

Пробел-разделитель здесь нужен только в том случае, если символ может быть

интерпретирован как часть числа. Например, если вам нужно ввести число 12,

символ «точка» и число 55, вам нужно набрать на клавиатуре 12 . 55.

Вводимый символ «точка» лучше «заключить» в пробелы, чтобы быть уверенным,

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

числе целую и дробную части. Оператор вывода в строке 22 выводит введенные

вами данные разделенные пробелами.

Оператор вывода в строке 23 предлагает вам ввести символ, число и символ.

Оператор ввода в строке 24 последовательно размещает введенные значения в

переменных с1, х, с2. Пробел-разделитель здесь нужно использовать только в

том случае, если символ может быть интерпретирован как часть числа.

Например, если вам нужно ввести символ «-», число 12 и цифру 0, вам нужно

набрать на клавиатуре 12 0. Оператор вывода в строке 25 выводит введенные

вами данные, разделяя их пробелами.

Функция printf

Просматривая программы, написанные разными людьми, вы часто можете

встретить функцию printf. Этот стандартный оператор вывода пришел из языка

С. Так как C++ является расширением С, эта функция поддерживается и в этом

языке. Многие программисты до сих пор предпочитают использовать старую

функцию printf, а не потоки ввода/вывода C++. Вот почему вам эта функция

наверняка уже знакома. Но, помимо этого, эта функция имеет несколько очень

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

потоков. Прототип функций можно найти в заголовочном файле STDIO.H.

Функция printf

Общая форма объявления функции printf:

int printf(const char *format[, argument,... ]);

Параметр format является символьным массивом, содержащим выводимый текст.

Кроме этого обязательного параметра, могут быть необязательные аргументы.

Массив format может содержать специальные форматирующие символы, которые

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

Функция printf является очень мощной функцией с богатыми возможностями

форматирования вывода. В качестве первого шага в освоении ее возможностей

рассмотрим Esc-последовательности, позволяющие представлять специальные

символы. Esc-последовательность начинается с символа «\» — «обратная косая

черта». Esc-коды представлены в таблице 1.

Таблица 1. Еsс - последовательности

|Последовательн|Десятичное |Шестнадцатеричное |Название |

|ость |значение |значение | |

|\а |7 |0х07 |Звонок |

|\b |8 |0х08 |Возврат назад |

|\f |12 |0х0С |Перевод страницы |

|\n |10 |0х0А |Новая строка |

|\г |13 |0x0D |Возврат каретки |

|\t |9 |0х09 |Табуляция |

|\v |11 |0х0В |Вертикальная табуляция|

|\\ |92 |0х5С |Обратная черта |

|\' |44 |0х2С |Апостроф |

|\" |34 |0х22 |Кавычка |

|\? |63 |0х3 F |Знак вопроса |

|\0 | | |Восьмеричное число, от|

| | | |1 до 3 цифр |

|\XHHH и \xhhh | |0xhhh |Шестнадцатеричное |

| | | |число |

Функция printf имеет специальные форматирующие спецификации (символы) для

вывода переменных. Общий вид этих спецификаций таков:

% [flags] [width] [.precision] [F | N | h | l | L ]

Опции flags могут определять выравнивание, отображение знака числа при

выводе, вывод десятичной точки и символов заполнения. Кроме того, эти флаги

определяют префиксы для восьмеричных и шестнадцатеричных чисел. Возможные

значения флагов приведены в таблице 2.

Таблица 7.2. Значения флагов строки формата функции printf

|Символ |Назначение |

|- |Выравнивать вывод по левому краю поля |

|+ |Всегда выводить знак числа |

|Пробел |Выводить пробел перед положительным числом и знак |

| |минус — перед отрицательным |

|# |Не влияет на вывод десятичных целых, для |

| |шестнадцатеричных чисел выводит префикс 0х или 0Х, |

| |перед восьмеричными целыми выводит ноль, десятичную |

| |точку для вещественных чисел. |

Спецификация width определяет минимальное количество выводимых символов.

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

значение для width начинается с нуля, printf использует в качестве

заполнителей нули, а не пробелы. Если в качестве значения для width

используется универсальный символ *, а не число, то printf подставляет на

место этого символа значение, которое должно содержаться в списке

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

значению. Ниже приведен пример вывода числа 2, занимающего три позиции,

согласно значению второго аргумента printf:

printf("%*d", 3, 2);

Спецификатор precision определяет максимальное количество выводимых цифр. В

случае целого числа он определяет минимальное количество выводимых

символов. Для precision также можно применить символ *, вместо которого

будет подставлено значение из списка аргументов. Это значение точности

представления должно предшествовать выводимому значению. Ниже приведен

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

символов, как это задано вторым аргументом printf:

printf("%7.*f", 10, 3.3244);

Символы F, N, h, l и L являются символами размера, переопределяющими размер

по умолчанию. Символы F и N применяются с указателями, far и near

соответственно. Символы h, l, и L используются для указания соответственно

типов short int, long или long double.

Символам типа данных должен предшествовать форматирующий символ %. В

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

printf. Символы типов данных перечислены в таблице 7.3.

Таблица 3. Символы типов данных строки формата функции printf

|Тип данных|символ|результат |

| |типа | |

|Символ |c |Один символ |

| |d |Десятичное целое со знаком |

| |i |Десятичное целое со знаком |

| |O |Восьмеричное целое без знака |

| |N |Десятичное целое без знака |

| |X |Шестнадцатеричное целое без знака; набор цифр - |

| | |0123456789abcdef |

| |X |Шестнадцатеричное целое без знака; набор цифр - |

| | |0123456789ABCDEF |

|Указатель |P |Для указателей near выводит только смещение в виде: |

| | |0000. Указатели far отображаются в виде: SSSS:0000 |

|Указатель |N | |

|на целое | | |

|Вещественн|F |Выводит величину со знаком в формате [-]dddd.dddd |

|ое | | |

| |E |Выводит вещественную величину со знаком в |

| | |экспоненциальном формате [-]d.dddde[+|-]ddd |

| |Е |Выводит вещественную величину со знаком в |

| | |экспоненциальном формате [-]d.ddddE[+|-]ddd |

| |G |Выводит вещественную величину со знаком в формате f или |

| | |е в зависимости от ее значения и заданной точности |

| |G |Выводит вещественную величину со знаком в формате F или |

| | |Е в зависимости от ее значения и заданной точности |

|Указатель |S |Выводит строку символов, пока не встретит |

| | |нуль-терминатор строки |

Разберем небольшой пример. Программа OUT2.CPP, исходный код которой

приведен в листинге 3, создана на основе программы OUT1.CPP. В этой

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

printf. Программа выводит те же числа, что и OUT1.CPP, используя три

различных набора спецификаций преобразования.

Листинг 3. Исходный текст программы OUT2.CPP в файле List7-3.CPP

|01 |// Программа, использующая printf для форматирования вывода |

|02 | |

|03 |#include |

|04 | |

|05 |int main() |

|06 | Printf(" %6.4f / %10.4lf = %7.5lf\n", |

Пример вывода программы из листинга 3:

128 + 67 = 195

Вывод использует спецификации преобразования %lf :

355.0000 / 113.0000 = 3.14159

Вывод использует спецификации преобразования %le :

3.5500e+02 / 1.1300e+02 = 3.14159e+00

Вывод использует спецификации преобразования %lg :

355 / 113 = 3.1416

Символьная переменная aChar: @

ASCII-код @: 64

В программе из листинга 3 объявляется целый набор переменных различных

типов. Оператор вывода в строках 13 и 14 выводит целые, используя

спецификацию формата %d. В таблице 4 приведены результаты действия

спецификаций преобразования из строки 13. Обратите внимание на то, что

первая переменная была преобразована из типа unsigned char в тип integer.

Таблица 4. Результат действия спецификаций форматирования в функции printf

из строки 13

|Спецификация формата|Переменная |Тип данных |Тип после |

| | | |преобразования |

|%3d |aByte |unsigned |Int |

| | |char | |

|%2d |anInt |int |Int |

|%3d |aByte + |int |Int |

| |anInt | | |

Оператор вывода в строке 17 выводит переменные aSingle, aDouble и выражение

aSingle / aDouble, используя спецификации преобразования %6.4f, %6.41f и %

7.51f. Точность представления задается ими равной 4, 4 и 5 цифрам, а

минимальная ширина поля 6, 6 и 7 цифрам соответственно. Две последних

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

Оператор вывода в строке 21 подобен оператору из строки 17. Отличие состоит

в том, что используется е-формат вместо f-формата. Соответственно три

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

Оператор из строки 25 также похож на оператор из строки 17. Основное

отличие состоит в том, что вместо f-формата используется g-формат. В

результате первые два числа выводятся без дробной части, поскольку они

являются целыми величинами.

Оператор вывода в строке 28 выводит содержимое переменной aChar по формату

%с. Оператор вывода в строке 29 выводит ту же переменную aChar дважды,

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

выводится ASCII-код символа). Для этого используются спецификации

преобразования %с и %d соответственно.

Массивы символов в C++

В C++ имеется специальный класс для работы со строками, которого, конечно,

не было в языке С. В С строки вводились как массивы символов, ограниченные

нуль-символом (ASCII-код которого равен нулю), поэтому большое количество

программ, написанных на С, используют символьные массивы. Более того, и в

C++, несмотря на то, что он имеет класс для работы со строками, находится

применение массивам символов. Поэтому термин «строка» имеет два значения:

строка в смысле C++ и строка как массив символов. Весь этот раздел будет

посвящен тому, как нужно и не нужно использовать символьные массивы.

Символ '\0' также называют нуль-терминатором. Строки, оканчивающиеся нуль-

терминатором, называют еще ASCIIZ-строками, где символ Z обозначает ноль —

ASCII-код нуль-терминатора. Еще этот символ называют NUL-символом,

поскольку этот термин является его именем в ASCII.

Все строки обязательно должны оканчиваться нуль-терминатором, и при

объявлении размера массива необходимо это учитывать. Когда вы объявляете

строковую переменную как массив символов, увеличьте размер массива на один

символ для нуль-терминатора. Использование строк с конечным нулем также

имеет то преимущество, что здесь отсутствуют ограничения, накладываемые

реализацией C++. Кроме того, структура ASCIIZ-строк очень проста.

Ввод строк

В программах, которые мы рассматривали, операторы потокового вывода

выводили строковые константы; C++ поддерживает потоковый вывод для строк

как специального не-предопределенного типа данных. (Можно сказать, что это

было сделано по требованию масс.) Операции и синтаксис для вывода строковых

переменных остаются прежними. При вводе строк операция извлечения из потока

» не всегда будет работать так, как вы ожидаете, поскольку строки часто

содержат пробелы, которые игнорируются оператором ввода; поэтому вместо

оператора ввода вам нужно использовать функцию getline. Эта функция вводит

заданное количество символов.

Функция getline

Перегруженная функция getline объявляется следующим образом:

istreams getline( signed char *buffer,

int size,

char delimiter = '\n') ;

istreams getline( unsigned char *buffer,

int size,

char delimiter = '\n') ;

istream& getline( char *buffer,

int size,

char delimiter = '\n') ;

Параметр buffer является указателем на строку, в которую помещаются

вводимые символы. Параметр size задает максимальное количество вводимых

символов. Параметр delimeter определяет символ-ограничитель, при появлении

которого ввод символов прекращается прежде, чем будут введены все size

символов. Параметр delimeter имеет аргумент по умолчанию, равный '\n'. В

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

при нажатии клавиши

Пример

#include //см. файл Ex01.cpp

int main()

{

char name[80] ;

cout « "Enter your name: ";

cin.getline(name, sizeof(name) - 1);

cout « "Hello " « name « ", how are you?";

return 0;

}

Функции, объявленные в STRING. H

Стандартная библиотека для работы со строками содержит много полезных

функций (объявляемых в STRING.H), разработанных коллективными усилиями

многих программистов на С. В файлах заголовка STDIO.H и IOS-TREAM.H также

имеются прототипы строковых функций. Комитетом ANSI/ISO C++ предложен класс

для работы со строками. Строки этого класса больше похожи на строки в

языках Pascal и BASIC. (Мы познакомимся с классами в День 8, а со строковым

классом в День 11.) Этот раздел будет посвящен рассмотрению некоторых (ни в

коей мере не всех) функций, объявленных в STRING.H.

Некоторые функции из STRING.H имеют несколько версий. Дополнительные версии

этих функций, имеющих в имени префиксы _f, f или _ работают с указателями

типа far. Этих версий вы не встретите в плоской, 32-битной модели памяти

компилятора Borland.

Присвоение значений строкам

C++ поддерживает два способа присвоения значений строкам. Вы можете

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

при объявлении строки. Этот метод прост: требуется операция присваивания и

строковая константа.

Инициализация строки

Общий метод инициализации строки:

char stringVar[stringSize] = stringLiteral;

Пример

char a3tring[81] = "Borland C++ 5 in 21 days";

char Named = "Rene Kinner";

Второй способ присвоить значение строке — это вызвать функцию, которая

копирует содержимое одной строки в другую, — не забывая при этом и нуль-

символ. Эта функция называется strcpy. Она предполагает, что копируемая

строка оканчивается символом NUL и прекращает копирование, как только

встретит этот символ.

Функция strcpy

Прототип функции strcpy таков:

char* strcpy(char *target, const char *source);

Функция копирует строку source в строку target. Функция предполагает, что

целевая строка имеет размер, достаточный для того, чтобы вместить

содержимое строки-источника.

Пример

char name[41] ;

strcpy(name, "Borland C++ 5");

Переменная name содержит строку "Borland C++ 5".

Функция strdup

Функция strdup копирует одну строку в другую, при этом отводит необходимое

количество памяти для целевой строки.

Прототип функции strdup таков:

char* strdup(const char *source);

Функция копирует строку source и возвращает указатель на строку-копию.

Пример

char *string1 = "Монархия в Испании";

char *string2;

string2 = strdup(string1);

После того, как будет отведено необходимое количество памяти для строки

string2, строка string1будет скопирована в строку string2.

Функция strncpy

Библиотека строковых функций предлагает также функцию strncpy, копирующую

заданное количество символов из одной строки в другую.

Прототип функции strncpy таков:

char * strncpy(char *target, const char *source, size_t num);

Функция копирует num символов из строки source в строку target. Функция не

выполняет ни усечение, ни заполнение строки.

Пример

char str1[] = "Pascal";

char str2[] = "Hello there";

strcnpy(strl, str2, 5);

Переменная strl содержит строку "Hellol". Заметьте, что символ ‘l’ строки-

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

Определение длины строки

При работе со строками часто бывает нужно знать длину строки.

Функция strlen

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

включается нуль-терминатор.

Прототип функции strncpy таков:

size_t strlen (const char *string) ,

Функция strlen возвращает длину строки string. size_t — это имя,

приписанное типу unsigned int оператором typedef.

Пример

char str[] = "1234567890";

size_t i;

i = strlen(str),

Переменной i будет присвоено значение 10.

Конкатенация строк

Операция конкатенации используется достаточно часто, когда новая строка

получается объединением двух или более строк.

Присоединить одну строку к другой можно функцией strcat.

Функция strcat

Конкатенация строк означает их последовательное присоединение друг к другу.

Прототип функции strcat таков:

char *strcat(char *target, const char *source) ;

Функция добавляет к содержимому целевой строки содержимое строки-источника

и возвращает указатель на целевую строку. Функция предполагает, что целевая

строка может вместить содержимое объединенной строки.

Пример

char string[81] ;

strcpy(string, "Turbo");

strcat (string, " C++");

Переменная string содержит строку "Turbo C++".

Функция strncat

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

символов из строки-источника.

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

char *strncat(char *target, const char *source, size_t num);

Функция добавляет к содержимому целевой строки num символов из строки-

источника и возвращает указатель на целевую строку.

char strl[81] = "Hello I am ";

char str2[41] = "Keith Thompson";

strncat(strl, str2, 5);

Переменная strl теперь содержит строку "Hello I am Keith".

Пример использования функций getline, strlen и strcat в файле List7_4.cpp

(исходный код программы STRING.CPP). Программа выполняет следующие задачи:

. Предлагает вам ввести строку; ввод не должен превышать 40 символов

. Предлагает вам ввести вторую строку; ввод не должен превышать 40 символов

. Выводит число символов, содержащихся в каждой строке

. Присоединяет вторую строку к первой

. Выводит результат конкатенации

. Выводит длину объединенной строки

. Предлагает вам ввести символ для поиска

. Предлагает вам ввести символ для замены

. Выводит содержимое объединенной строки после замены символа

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

Поскольку строки являются массивами символов, вы не можете применить

операцию сравнения для проверки равенства двух строк. Библиотека функций

STRING.H предлагает набор функций для сравнения строк. Эти функции

сравнивают символы двух строк, используя для этого ASCII-коды символов. Это

функции strcmp, stricmp, strncmp и strnicmp.

Вообще говоря, все функции сравнения работают одинаково: возвращают 0, если

две строки совпали, отрицательную величину, если вторая строка больше по

величине, и положительное значение, если большей оказалась первая строка.

Функция strcmp

Функция strcmp выполняет сравнение двух строк с учетом регистра символов.

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

int strcmp(const char *strl, const char *str2);

Функция сравнивает строки strl и str2. Возвращает в качестве результата

сравнения целую величину:

< 0 когда strl меньше, чем str2;

= 0 когда strl равна str2;

> 0 когда strl больше, чем str2.

Пример

char stringl[] = "Borland C++";

char string2[] = "BORLAND C++";

i = strcmp(string1, string2);

В последнем операторе переменной i присваивается положительное значение,

так как string1 больше string2 (ASCII-коды символов в нижнем регистре

больше ASCII-кодов символов в верхнем.)

Функция stricmp

Функция stricmp выполняет сравнение двух строк, не учитывая регистра

символов.

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

int stricmp(const char *strl, const char *str2);

Функция сравнивает строки strl и str2, не делая различия между символами в

нижнем и верхнем регистре. Возвращает в качестве результата сравнения целую

величину:

< 0 когда strl меньше, чем str24

= 0 когда strl равна str24

> 0 когда strl больше, чем str2.

Пример

char string1[] = "Borland C++";

char string2[] = "BORLAND C++";

int i = strcmp(string1, string2);

В последнем операторе переменной i присваивается значение 0, так как

string1 и string2 отличаются друг от друга только регистром символов.

Функция strncmp выполняет сравнение заданного количества символов двух

строк с учетом регистра символов.

Функция strncmp

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

int strncmp(const char *strl, const char *str2, size_t num);

Функция сравнивает первые num символов строк strl и str2. Возвращает в

качестве результата сравнения целую величину:

< 0 когда strl меньше, чем str2;

= 0 когда strl равна str2;

> 0 когда strl больше, чем str2.

Пример

char string1[] = "Borland C++";

char string2[] = "Borland Pascal";

i = stricmp(string1, string2, 9);

В последнем операторе переменной i присваивается отрицательное значение,

так как значение "Borland С" меньше, чем "Borland Р".

Функция strnicmp

Функция strnicmp выполняет сравнение заданного количества символов двух

строк без учета регистра символов.

Страницы: 1, 2, 3, 4, 5


© 2010 Современные рефераты