Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lek_1_slaydy.doc
Скачиваний:
1
Добавлен:
17.11.2019
Размер:
417.79 Кб
Скачать

1 ВВЕДЕНИЕ В С++

Сравнивая С и С++

  • С и С++ в основном используют один и тот же синтаксис, операторы, выражения, встроенные типы данных, структуры, массивы, объединения, циклы, функции и указатели.

  • С++ имеет несколько дополнительных ключевых слов, приведенных в табл. 1.1 вместе со словами (отмечены звездочкой), характерными для С++. В С++ также имеется несколько новых операторов, которые будут при­ведены позже.

Таблица 1.1. Ключевые слова С и С++

asm

default

friend*

protected*

switch

void

auto

delete*

goto

public*

template*

volatile*

break

do

if

register

this*

while

case

double

inline*

return

throw*

catch*

else

int

short

try*

char

enum

long

signed

typedef

class*

extern

new*

sizeof

union

const

float

operator*

static

unsigned

continue

for

private*

struct

virtual*

*Только для С++

  • С++ требует, чтобы прототипы всех функций были определены до их вызова.

В C определение прототипов желательно, но не обязательно.

  • В С++ осуществляется более строгая проверка типов в выражениях.

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

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

  • В С++ сильно ослаблена потребность в typedef-объявлениях. Вы можете объявить структуру типа

  • struct mystruct { … }; и затем объявлять переменные как mystruct x;. Чтобы проделать нечто подобное в C, вы должны на­писать struct mystruct x; или использовать typedef для структуры mystruct

  • В ANSI С символьные константы имеют тип int, и выражение sizeof('X') эквивалентно sizeof(int).

В С++ символьные константы имеют тип char, и выражение sizeof('X') соответствует sizeof(char).

Приведенный список не является полным сравнением С и С++.

Комментарии С+ +

В C комментарий

/* Это комментарий */ также может быть написан на С++ как

// Это комментарий

Комментарий в С++ распространяется до конца строки и никак не может быть вложенным внутри оператора

Смешение стилей комментария

В одной и той же программе одновременно могут употребляться комментарии С и С++. В листинге 1.2 приводится несколько таких примеров.

Листинг 1.2. COMMENTS.CPP (сравнение типов комментариев С и С++)

1: #include <iostream.h>

2:

3: //

4: // Автор : Том Сван

5: // Версия : v1.0

6: // Назначение : Демонстрация комментариев в С++

7; // -

8:

9: main()

10: {

11: cout « "A Brief С++ Commentary\n"; // Вывести заголовок

12: cout « "\n"; // Вывести пустую строку после заголовка 13:

14: /* Этот абзац демонстрирует, что комментарий на языке С может

15: занимать более одной строки.

16: Комментарий на С++ ограничен одной строкой. */ 17:

18: cout « "// This is not a comment.\n\n"; // Это комментарий

19:"cout « "/* This also is not comment.*/ \n\n";

20: cout /* Это комментарий. */ « "This text is displayed.\n";

21: return 0; \

22: }

В интегрированной среде при выделении синтаксиса цвет комментариев очень похож на цвет строчек текста, что делает COMMENTS.CPP трудным для чтения. Для изменения цветов выберите в Option | Environment разделах Syntax Highlighting | Cmtomize, затем Comment из списка Element и щелкните кнопкой мыши на альтернативном цвете переднего плана (FG). (Я использую темно-серый.)

В строках 3~7 используется комментарий С++ для небольшого информационного заголовка, описывающе­го программу. Многие программисты любят "помечать" свои исходные файлы своеобразно стилизованными заголовками, которые могут содержать информацию о программе, исправлениях, дате модификаций и т.п.

Строки 11-12 демонстрируют классический способ завершать операторы на С++ поясняющими коммента­риями. Строки 14-16 содержат многострочный комментарий на ANSI C. Для написания аналогичного коммен­тария на С++ каждую строку следовало бы начинать с / /.

Строки 18-19 иллюстрируют важный принцип: комментарии любого стиля не должны оказаться в середи­не символьной строки. Строка 20 показывает, что только комментарий стиля ANSI C может быть вложен внутрь оператора — прием, приносящий скорее вред, чем пользу, и лучше его избегать.

Введение в потоки ввода-вывода

Поведение объекта потока ввода-вывода очень похоже на стандартный ввод-вывод потоков файлов.

Потоки cout (character out) и cin (character in) имеют множество разнообразных возможностей.

Чтобы отобразить символ с, вы можете написать

cout << с; или

cout.put(c);

Функция put() — член cout, это новое понятие, с которым вы будете часто встречаться в следующих раз­делах.

Для вызова функции-члена, отделите его точкой от cout, как в записи, используемой для доступа к члену структуры. Поток cout — пример класса, который может иметь относящиеся к нему функции, такие, как put(). Вы должны вызывать функ­цию-член только со ссылкой на объект, подобный cout. Без этого выражение

put(c); // ??? попытается вызвать независимую функцию put().

Оператор

cout.put(c); вызовет функцию put(), которая принадлежит cout.

Для того чтобы прочитать символ из стандартного ввода, следует использовать поток ввода cin, стоящий перед оператором » (взять из). Оператор

cin » с; читает один символ из стандартного ввода и присваивает его переменной с.

или:

cin.get(c);

Листинг 1.3. FILTER.CPP (простая программа-фильтр на С++)

1 : #include <iostream.h> 2:

3: main()

4: {

5: char с; 6:

7: while (cin.get(c))

8: cout.put(c);

9: return 0;

10: }

Строка 7 в FILTER.CPP вызывает cin.get(c) для ввода символа. Выражение cin.get(c) возвращает значение типа int или нуль при достижении конца источника ввода. Строка 8 передает все символы из источника в стандартный вывод.

Чтение данных встроенных типов

Самая привлекательная черта библиотеки потоков ввода-вывода С++ — чтение и запись данных самых различных типов. Листинг 1.4 демонстрирует чтение данных целых и вещественных типов с помощью операторов библиотеки потоков.

Попробуйте ввести ошибки (например, XXX вместо вещественного значения) для того, чтобы увидеть, как программа их обрабатывает.

Листинг 1.4. GETVAL.CPP (использование библиотеки потоков ввода-вывода для чтения данных встроенных типов)

1 : #include <iostream.h>

2: #include <stdlib.h>

3:

4: void test(void);

5:

6: main()

7: {

8: double fp; // Вещественное значение

9: long k; // Длинное целое 10:

11: cout « "Enter a floating-point value: ";

12: cin » fp;

// test проверяет результат вызова cin.good() //— функции-члена, которая возвращает //TRUE, если не было неисправимых ошибок //для указанного потока.

13: test();

14: cout « "Value entered is: " « fp << "\n";

15: cout << "Enter an integer value: ";

16: cin » k;

17: test();

18: cout « "Value entered is: " « k << '\n';

19: return 0;

20: } 21:

22: void test(void)

23: {

24: if (!cin.good()) {

25: cout << "Error detected";

26: exit(1);

27: }

28: }

Строка 11 запрашивает вещественное значение, читая его оператором потокового ввода в переменную fp типа double в строке 12. Аналогичный оператор ввода в строке 16 читает целое значение. В отличие от стандартного ввода-вывода, который требует точно задавать типы данных в функции scanf() или вызывать функции, которые могут читать и преобразовывать нестандартные типы, потоки ввода-вывода автоматически определяют тип переменных, используемых в операциях ввода-вывода. Поскольку не обязательно точно указывать типы данных, вы не сделаете ошибку в указании типа, как это могло бы быть при использовании стандартного ввода-вывода. В С++ очень сложно ввести в переменную данные неверного типа!

Строки 13 и 17 демонстрируют еще одно важное достоинство потоков ввода-вывода. Эти строки вызывают локальную функцию test(), приведенную в строках 22-28.

Функция проверяет результат вызова cin.good() — функции-члена, которая возвращает TRUE, если не было неисправимых ошибок для указанного потока. Можно использовать cout.good() точно так же и для выходного потока. В приведенном примере программы, если cin.good() возвращает FALSE, строки 25-26 выводят сообщение и завершают выполнение программы.

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

cin.clear();

Чтение символьных строк

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

char *s = "Данное";

//Оператор

cout << s;

отправит данную строку но назначению — в системный стандартный поток вывода, обычно на дисплей.

Для чтения строки

обратите процесс и используйте идентификатор потока ввода cin и оператор » (поместить в)

char buffer[128]; // Объявление буфера

строки

cin » buffer; // ???

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

Существует более безопасный способ ввести строку, как это показано в листинге 1.5.

Листинг 1.5. GETSTR.CPP (использование потоковой библиотеки для безопасного чтения строк)

1: #include <iostream.h>

2:

3: main()

4: {

5: char s[25];

6: char с;

7:

8: cout << "Enter a 24-char string safely: \n";

9: cin.get(s, 25, '\n');

10: cout « "You entered: " « s « “\n”;

11: if (cin.get(c) && с != '\n')

12: cout « "Maximum line length reached\n";

13: return 0;

14: } .

Функция-член cin.get() вызывается с тремя аргументами.

  • Адрес результирующего символьного массива. Строка-результат будет прочитана в этот массив и завершена нулевым символом.

  • Размер массива в байтах.

  • Символ, завершающий ввод. Если не указан, по умолчанию он равен '\n'.

До тех пор пока вы корректно задаете размер буфера результата, чтение ввода, приведенное в строке 9, безопасно. Одна проблема все же остается. Символ новой строки или другой символ, завершающий ввод, остается в потоке и должен быть прочитан еще одним оператором cin.get(), как это показано в строках 11-12. Если cin.get() не читает символ новой строки, ввод будет усечен. Этот факт необходимо учитывать при написании программ.

Проблему непрочитанного символа новой строки можно решить по-другому: с помощью вызова функции-члена cin.getline(). Для чтения 24-символьной строки в 25-байтовый буфер следует использовать операторы:

char buffer[25]; cin.getline(buffer, 25);

Запись данных

выражение

cout << v;

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

Форматный вывод с помощью потоков ввода-вывода

Библиотека потоков ввода-вывода понимает множество команд форматного вывода. Листинг 1.6 демонстрирует возможность использования трех идентификаторов выходного потокаdec, hex, и oct — для вывода целых значений в десятичном, шестнадцатеричном и восьмеричном форматах.

Листинг 1.6. CONVERT.CPP (использование форматного вывода в потоках ввода-вывода)

1 :#include <iostream.h>

2:#include <stdlib.h>

3:

4:#define SIZE 35

5:

6:main()

7:{

8: int value;

9: char s[SIZE];

10:

11: cout << "Value? ";

12: cin.get(s, SIZE, '\n');

13: value = atoi(s);

14: cout << "Decimal=" << dec << value

15: << "Hexadecimal=Ox" << hex << value

16: << "0ctal=0" << oct << value <<'\n';

17: return 0;

18: }

Строки 14-16 выводят в один и тот же поток различные данные. Одни из них — строки символов. Другие — целые числа. Идентификаторы dec, hex, и oct, выведенные в поток непосредственно перед выводом значения, изменяют текущий формат вывода выходного потока.

Кроме того, можно указать и ширину вывода с помощью вызова cout.width(n), где n — нужное число позиций.

Например, можно вывести значение в 15 позициях с выравниванием по правому краю, написав следующий участок кода:

int value = 1234; // Форматируемое значение cout.width(15); // Указать вывод в 15 позициях

cout « value; // Вывод значения в 15 позициях

Иногда бывает неудобно пользоваться форматным выводом библиотеки потоков. Ее сложные операторы могут быть трудными для чтения. Судя по обнародованным исходным текстам, программисты-эксперты в С++ предпочитают смесь методов форматирования вывода ANSI С и С++. Листинг 1.7 — типичный случай такого подхода, он полностью аналогичен CONVERT.CPP.

Листинг 1.7. CONVERT2.CPP (альтернативный вариант форматного вывода)

1: #include <iostream.h>

2: #include <stdio.h>

3: #include <stdlib.h>

4:

5: #define SIZE 35

6:

7: main()

8:{

9 int value;

10: char s[SIZE];

11: char buffer[80];

12:

13: cout « "Value? ";

14: cin.get(s, SIZE, '\n');

15: value = atoi(s);

16: sprintf(buffer,"Decimal=%d Hexadecimal=%#x Octal=%#o\n", 17: value, value, value); 18: cout « buffer; 19: return 0;

20: }

Сложный оператор вывода библиотеки потоков из CONVERT.CPP заменен вызовом sprintf() в строках 16-17. Функция sprintf(), описанная в STDLIB.H, готовит символьную строку согласно тем же правилам, которые используются в printf() и других подобных функциях. Строка 16 указывает форматы %d (десятичный), %#x (шестнадцатеричный), %#o (восьмеричный) для вставки данных в символьный буфер в соответствующем порядке. Простой оператор вывода в строке 18 выводит готовую строку в системный стандартный вывод.

Область видимости и объявление переменных

Например, если существует глобальная переменная int count, функция может объявить локальную переменную с тем же именем, не вызвав при этом сообщения компилятора об ошибке:

Int count; // Глобальная переменная

Void AnyFunction()

{int count;

// Локальная переменная

}

Область видимости локальной переменной count действует в пределах объявленной функции. В этой функ­ций локальная переменная count делает невозможным доступ к глобальной переменной с тем же именем. Для решения этой проблемы в С++ можно использовать

оператор разрешения области видимости ::.

Перепишем приведенную выше функцию следующим образом:

int count; //Глобальная переменная

Void AnyFunction(){

int count; //Локальная переменная

count = 1234; // Присвоить значение локальной переменной

::count = 4321; // Присвоить значение глобальной переменной count

}

Теперь она присваивает значение 1234 локальной переменной count и 4321 — глобальной. Выражение ::count указывает С++, что используется внешняя переменная count, а не локальная (рис. 1.1).

Рис. 1.1. Оператор разрешения области видимости может открыть доступ к скрытой глобальной переменной

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

Листинг 1.8. SCOPE.CPP (использование оператора разрешения видимости)

  1. #include <iostream.h>

  2. int k = 100; // Глобальная переменная

  3. main()

  4. {

  5. int i = 200; // Локальная переменная

  6. cout << "Global k == " << k << \n";

  7. cout << "Local i == " << i << '\n';

  8. {

  9. int к = 300;

  10. cout <<Local к *= " << k << '\n';

  11. cout « "Global k == " << ::k << '\n';

  12. }

  13. return 0;

  14. }

В строке 3 объявляется и инициализируется значением 100 глобальная переменная k; а в строке 7 объявля­ется переменная i, локальная в функции main(). Строки 9-10 выводят значения k и i.

Нет необходимости ис­пользовать оператор разрешения видимости в строке 9, так как была объявлена только одна переменная k.

Строки 11-15 содержат новый блок-оператор, заключенный внутри функции main(). Хотя это и необычно для практики программирования, блок может быть размещен в другом блоке (строки 11 и 15). Конечно, на практике подобные вложенные блоки принадлежат операторам if, while и им подобным. Внутри вложенного блока в строке 12 объявляется новая переменная с именем k, инициализированная значением 300.

В отличие от С, С++ позволяет объявлять и инициализировать переменные в любом месте блока-оператора.

Теперь мы имеем две переменных k: глобальную, объявленную в строке 3, и локальную, объявленную в строке 12. Поскольку новая локальная k скрывает глобальную переменную с тем же именем, в строке 13 отображается значение локальной переменной. Чтобы получить доступ к глобальной переменной, используется оператор разрешения области видимости, как показано в строке 14.

Переменные, объявленные внутри блока-оператора, существуют только в пределах этого блока. Область их видимости ограничена местом их объявления.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]