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

2 семестр / Литература / Язык программирования С++. Краткий курс. Страуструп

.pdf
Скачиваний:
9
Добавлен:
16.07.2023
Размер:
31.34 Mб
Скачать

20

Глава

1.

Основы

Префикс

s

td:

:

указывает,

что

имя

cou

t

находится

в

пространстве

имен

стандартной

библиотеки

(§3.4).

Как

правило,

при

обсуждении

стандартных

функций

я

оставляю

std::;

в

§3.4

показано,

как

сделать

имя

видимым

без

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

По сути, весь выполнимый код размещен

в

функциях

и

прямо

или

косвен­

но

вызывается

из

main

().Например:

#include <iostream> using namespace std;

/ /

Включение

("импорт") объявлений

//

библиотеки ввода-вывода

 

 

//Делаем видимыми имена из

пространства

//

имен std

без применения

std::

(§3.4)

douЫe

square(douЫe

{

 

 

return

х*х;

х)

// //

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

с

void {

print_square(douЫe cout << "Квадрат" <<

х) х

<<

"равен"<<

square(x) <<

"\n";

int

main

()

print_square(l.234);

//Вывод:

Квадрат

1.234

равен

1.52276

"Возвращаемый тип" void указывает,

го значения.

что

функция

не

возвращает

никако­

1.3.

Функции

Основной способ получить что-то в программе ответствующую функцию. Определение функции

на

-

С++ -

это

это способ

вызвать указать,

со­ как

должны

быть

выполнены

необходимые

действия.

Функция

не

может

быть

вы­

звана, если она не была объявлена ранее.

Объявление

функции

дает имя функции,

(если таковое

имеется),

а также количество

должны быть указаны в вызове. Например:

тип возвращаемого

значения

и типы аргументов,

которые

Elem*

next_elem();

void

exit(int);

douЫe

sqrt(douЬle);

11 // // //

Аргументов нет; возвращает

указатель

на

Elem

(Elem*)

Аргумент

типа

int;

не

возвращает

Аргумент типа

douЫe;

возвращает

ничего douЬle

В

объявлении

функции

возвращаемый

тип

указывается

перед

именем

функции,

а

типы

аргументов

-

после

имени,

заключенными

в

круглые

скобки.

22

Глава

1.

Основы

Если

определены

две

функции

с

одним

и

тем

же

именем,

но

с

разными

типами

аргументов,

компилятор

выберет

для

каждого

вызова

наиболее

подхо­

дящую

функцию.

Например:

void

print(int);

void

print(douЬle);

void

print(string);

void

user ()

{

 

 

print(42);

 

print(9.65);

 

print("Barcelona");

//Принимает

целочисленный аргумент

//Принимает

аргумент

с

плавающей

точкой

//Принимает

строковый

 

аргумент

 

//

Вызов

print (int)

11

Вызов

print (douЬle)

//

Вызов

print (string)

Если

могут

быть

вызваны

две альтернативные

функции,

но

ни

одна

из

них

не лучше другой, вызов считается

щение об ошибке. Например:

неоднозначным

и

компилятор

выдает

сооб­

void

print(int,douЬle);

void

print(douЫe ,int);

void

user2 ()

{

 

 

print(0,0); //Ошибка:

неоднозначность

Определение

нескольких

функций

с

одним

и

тем

же

именем

называется

перегрузкой функций и

является одной

граммирования (§7.2).

При перегрузке

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

тем

же

именем

должна

реализовывать одну

и

ту

же

семантику.

Примером

это­

го

являются

функции

print

()

-

каждая

функция

print

()

выводит

свой

ар­

гумент.

1.4. Типы, переменные и арифметика

 

Каждое имя и каждое выражение имеет тип, который

определяет,

операции могут быть над ним выполнены. Например, объявление

какие

int

inch;

гласит,

что

inch

имеет

тип

int,

т.е.

inch

представляет

собой

целочисленную

переменную. Объявление представляет собой инструкцию, которая вводит

сущность в программу. Оно определяет тип этой сущности.

объявляемую

Тип (для

определяет объекта).

множество

возможных

значений

и

множество

операций

1.5.

Область

видимости

и

время

жизни

27

находится объявление. Блок определяется парой

фигурных скобок

{ }.

Имена аргументов функции

рассматриваются как

локальные имена.

 

Область

видимости

класса:

имя называется

именем члена (или

именем

члена

класса), если оно определено в классе

(§2.2, §2.3, глава 4,

"Клас­

сы"),

вне

любой функции (§ 1.3), лямбда-выражения (§6.3.2) или

пере­

числения

enum class (§2.5). Его

область видимости простирается от

открывающей фигурной скобки {

охватывающего объявления до конца

этого

объявления.

 

 

 

 

 

 

 

 

 

Область

видимости

пространства имен: имя называется именем

члена

пространства имен,

если оно определено в

пространстве имен

(§3.4)

вне любой функции,

лямбда-выражения (§6.3.2),

класса (§2.2, §2.3,

гла­

ва 4,

"Классы") или

перечисления enum class

(§2.5). Его область

ви­

димости

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

конца его пространства

имен.

 

 

 

 

 

 

 

 

 

 

 

Имя,

объявленное

вне прочих конструкций,

называется

глобальным

именем

и

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

как

временные

объекты

и

объекты,

создаваемые

с

использованием

оператора

new (§4.2.2).

Например:

vector<int> vec;

//

vec

-

глобальное

имя

(глобальный

вектор

int)

struct

Record

 

string

name;

//

пате

 

11 ...

 

 

 

 

};

 

 

 

 

 

void

fct(int

arg)

//

fct

 

 

 

 

//

arg

является членом

Record (член-строка)

-

глобальное имя

(глобальная функция)

-

локальное имя

(аргумент функции)

string auto р

11 ...

motto = new

{"Who dares wins"}; Record{ "Hume"};

// // //

motto -

локальное имя

 

р указывает на

безымянный

объект

Record

(создан

new)

Объект

должны

быть

построен

(инициализирован),

прежде

чем

он

будет

использован,

а

при

выходе

из

области

видимости

-

уничтожен.

Для

объек­

та

пространства

имен

точкой

его

уничтожения

является

конец

программы.

Для

члена

точка

уничтожения

определяется

моментом

уничтожения

объекта,

членом

которого

он

является.

Объект,

созданный

с

использованием

опера­

тора

new,

"живет"

до

тех

пор,

пока

не

будет

уничтожен

оператором

delete

(§4.2.2).

1.7.

Указатели,

массивы

и

ссылки

29

Функция,

объявленная

как

constexpr,

может

применяться

к

неконстант­

ным

аргументам,

но

когда

это

происходит,

результат

не

является

констант­

ным

выражением.

Функция,

объявленная

как

constexpr,

может

вызываться

с

аргументами,

не являющимися

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

выражениями,

в

контекстах,

которые

не

требуют

константных

выражений.

Таким

образом,

нам

не

прихо­

дится

определять,

по

сути,

одну

и

ту

же

функцию

дважды:

один

раз

-

для

константных выражений и второй -

для переменных.

Чтобы быть объявленной как constexpr, функция

должна

быть

доста­

точно

простой,

не

должна

иметь

побочных

действий

и

может

использовать

только

информацию,

переданную

ей

в

качестве

аргументов.

В

частности,

она

не может изменять нелокальные переменные, но может содержать

использовать собственные локальные переменные. Например:

циклы

и

constexpr

douЫe

nth(douЫe х, int

n) //Предполагается, что

{

 

 

 

 

 

 

douЫe

res

=

1;

 

 

int

i

= О;

 

 

 

 

while

(i<n)

 

 

 

 

{

//Цикл

while:

выполняется,

пока истинно его условие

 

res*=x;

 

 

 

 

 

++i;

 

 

 

 

О

<=

п

(§1.7.1)

return

res;

В

ряде

мест константные

выражения

требуются

правилами

языка

(на­

пример,

для

границ

массивов

(§1.7),

в

метках

case

(§1.8), аргументах

-

значениях

шаблонов

(§6.2)

и

константах,

объявленных

с

использованием

constexpr).

В

других

случаях

вычисления

времени

компиляции

оказывают­

ся

важными

с

точки

зрения

производительности

программы.

Независимо

от

проблем

с

производительностью

понятие

неизменности

(объекта

с

неизмен­

ным

состоянием)

является

важной

концепцией

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

1.7.

Указатели,

массивы

и

ссыпки

Наиболее

фундаментальной

коллекцией

данных

является

смежно

располо­

женная

последовательность

элементов

одного

и

того

же

типа,

именуемая

мас­

сивом.

Фундаментально

это

именно

то,

что

может

предоставить

аппаратное

обеспечение.

Массив

элементов

типа

char

может

быть

объявлен

следующим

образом:

char

v[б];

//Массив

из

6

символов

Аналогично

указатель

может

быть

объявлен

следующим образом:

char*p;

//

Указатель

на

символ