Смекни!
smekni.com

Основы алгоритмического языка С++ (стр. 10 из 21)

};

В примере nlist объявляется как массив структур, состоящий из двух строк и трех столбцов. Каждая структура состоит из трех элементов. Первая строка инициализации назначает величины первой строке массива nlist следующим образом:

1. Первая левая фигурная скобка Line 1 информирует компилятор о том, что это начало инициализации первой строки массива nlist(nlist[0]).

2. Вторая левая фигурная скобка означает то, что начинается инициализация первого элемента первой строки массива ( nlist[0] [0] ).

3. Первая правая фигурная скобка сообщает об окончании инициализации первого элемента- структуры nlist[0] [0]. Следующая левая фигурная скобка сообщает о начале инициализации второго элемента первой строки nlist[0] [1].

4. Процесс продолжается до конца Line 1 и заканчивается по последней правой фигурной скобке.

Аналогично, Line 2 назначает величины второй строке массива nlist.

Заметим, что внешние фигурные скобки инициализаторов Line 1 и Line 2 требуются. Следующая конструкция, в которой внешние фигурные скобки опущены будет неверной.

/* THIS CAUSES AN ERROR */

triplet nlist[2] [3] = {

{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, /* Line 1 */

{ 10,11,12}, { 13,14,15}, {16,17,18 } /* Line 2 */

};

В этом примере первая левая фигурная скобка в Line 1 стартует инициализацию nlist[0], которая является массивом из трех структур. Величины 1, 2, 3 назначаются трем элементам первой структуры. Когда встретится правая фигурная скобка (после величины 3), инициализация nlist[0] закончится и две оставшиеся структуры автоматически инициализируются нулем. Аналогично, { 4, 5, 6 } инициализирует первую структуру во второй строке nlist, а оставшиеся две структуры nlist[1] установятся в нуль. Когда компилятор встретит следующий список инициализации { 7, 8, 9 }, то это приведет к попытке инициализировать nlist[2]. Так как nlist содержит только две строки, то будет выдано сообщение об ошибке.

Примеры:

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

struct list {

int i, j, k;

float n[2] [3];

} x = {

1,

2,

3,

{4.0, 4.0, 4.0}

};

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

union {

char x[2] [3];

int i, j, k;

} y = {

{'1'},

{'4'}

};

В первом примере три элемента int структурной переменной x инициализированы 1, 2, и 3 соответственно. Три элемента первой строки массива m инициализированы как 4.0. Элементы второй строки инициализированы нулем по умолчанию.

Во втором примере инициализируется переменная y типа совмещения. Первым элементом совмещения является массив, для которого требуется составной инициализатор. Список инициализации {'1'} задает величины для первой строки массива. Поскольку в списке всего одна величина, то только первый элемент строки массива инициализируется символом 1 , а оставшиеся два элемента в строке инициализируются нулем (символом \0) по умолчанию. Аналогично, первый элемент второй строки массива x инициализируется символом 4, а оставшиеся два элемента в строке инициализируются нулем.

Строковые инициализаторы

Массив может быть инициализирован строчным литералом.

Например,

char code[ ] = "abc";

инициализирует code как массив символов из четырех элементов. Четвертым элементом является символ \0, который завершает все строковые литералы.

Если специфицируется размер массива, а строка больше чем

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

char code[3] = "abcd"

В примере только три первые символа инициализатора назначаются для массива code. Символ d и сивол нуль отбрасываются.

Если строка короче, чем специфицированный размер массива, то оставшиеся элементы массива инициализируются нулем (символом \0).

Объявления типов

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

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

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

Типы структур, совмещений и перечислений

Объявления типов структур, совмещений и перечислений имеют ту же самую общую синтаксическую форму, как и объявления переменных этих типов. В объявлении типа идентификатор переменной опущен, так как нет переменной которая объявляется. Именем структуры, совмещения или перечисления является тег.

В объявлении типа может появиться список объявлений элементов- <member-declaration-list> или список перечисления<enum-list>, определяющие тип.

Сокращенная форма объявления переменной, в котором tag ссылается на тип, определенный где-то еще, при объявлении типа не используется.

Примеры:

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

enum status {

loss = -1,

bye,

tie = 0,

win,

};

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

struct student {

char name[20];

int id, claas;

};

В первом примере объявляется тип перечисления, поименованный status. Имя типа может быть использовано в об'явлениях перменных типа перечисления. Идентификатор loss явно устанавливается в -1. Идентификаторы bye и tie ассоциируются со значением 0, а win принимает значение 1. Во втором примере объявляется структурный тип, поименованный student. Теперь можно использовать такое объявление, как struct student employee, чтобы объявить структурную переменную employee типа student.

Объявления typedef

Синтаксис:

typedef <type-spesifier><declarator>[,<declarator>...]; Объявления typedef являются аналогом объявления переменной, за исключением того, что ключевое слово typedef заменяет спецификатор класса памяти.

Объявление интерпретируется тем же самым путем, как объявления переменной или функции, но <declarator> вместо того, чтобы стать переменной типа, специфицированного объявлением, становится синонимом имени типа. Объявление 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. соответственно.

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

<type-specifier><abstract-declarator>

Абстрактный декларатор <abstract-declarator>- это декларатор без идентификатора, состоящий из одного или более модификаторов указателей, массивов и функций. Модификатор указателя (*) всегда появляется перед идентификатором в деклараторе, в то время как модификатор массива ([]) или функции ( () ) появляются после идентификатора. Таким образом, чтобы правильно интерпретировать абстрактный декларатор, нужно начинать интерпретацию с подразумеваемого идентификатора.

Абстрактные деклираторы могут быть составными. Скобки в составном абстрактном деклараторе специфицируют порядок интерпретации, подобно тому как это делается при интерпретации составных деклараторов объявлений. Абстрактный декларатор, состоящий из пустых круглых скобок () не допускается, поскольку это двусмысленно. В этом случае невозможно определить находится ли подразумеваемый идентификатор внутри скобок, и в таком случае- это немодифицированный тип, или перед скобками, тогда- это тип функции. Спецификаторы типа, установленные посредством объявлений 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 <iostream.h>

int main()

{

int *p = new int;

cout << "Enter а number";

cin >> *p;

cout << "The square of " << *p << " = " << (*p * *p);

return 0;

}

Функции

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

- Общая форма определения функции такова: