на тему рефераты
 
Главная | Карта сайта
на тему рефераты
РАЗДЕЛЫ

на тему рефераты
ПАРТНЕРЫ

на тему рефераты
АЛФАВИТ
... А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я

на тему рефераты
ПОИСК
Введите фамилию автора:


Реферат: Лекции по C++


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

               Об"явление  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;

       }

Функции

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

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

   возвращаемыйТип имяФункции(<список параметров>)

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

   {

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

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

    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 << "Значение параметра меньше 18" << endl;

    return;

  }

  if ( ui.age < 21 )

    ui.age = 21;

}

/*

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

     возврТип имяФункции(<список параметров>);

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

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

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

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

int main()

{

  int value = 5;

  foo(value);

  cout << value << endl;

  return 0;

}

void foo(int &parm)  // - определение функции вызов параметра по ссылке

{

  ++parm;

}

/*  Результаты:

6

*/

void foo(int *); // пердача указателя

int main()

{

  int value = 5;

  foo(&value); // передается адрес

  cout << value << endl;

  getch();

  foo(&value);

  cout << value << endl;

  getch();

  return 0;

}

void foo(int* parm)

{

  ++*parm;  // параметр - указатель

}

/*  Результаты:

6

7

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

Программа LOCAL.CPP знакомит с понятием локальной переменной

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

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

Программа STATIC.CPP знакомит с понятием статической локальной переменной

- Макроопределения позволяют вам вводить компактные псевдо-функции, принимающие любые типы данных, поскольку компилятор не выполняет в этом случае проверку типов:

#define min(n1, n2) (((n1) < (n2)) ? (n1) : (n2))

#define max(n1, n2) (((n1) > (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 <iostream.h>

   void swap(int i, int j)

   {

    int temp = i;

    i = j;

    j = temp;

   }

   int main()

   {

    int a = 10, b = 3;

    swap (a, b);

    cout << "а = " << a << " and b = " << b;

    return 0;

   }

/*

2. Каков будет результат работы следующей программы? Что вы можете сказать по поводу еще одной функции swap?

*/

   #include <iostream.h>

   void swap(int &i, int &j)

   {

    int temp = i;

    i = j;

    j = temp;

   }

   int main()

   {

    int a = 10, b = 3;

    swap (a, b);

    cout << "а = " << a << " and b = " << b;

    return 0;

   }

/*

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

*/

   void inc(int &i)

   {

    i = i + 1;

   }

   void inc(int &i, int diff = 1)

   {

    i = + diff;

   }

/*

4. Найдите ошибку в функции.

/*

   double volume(double length, double width = 1, double height)

   {

    return length * width * height

   }

/*

5. Найдите ошибку в функции.

*/

   void inc (int &i, int diff = 1)

   {

    i = I + diff;

   }

/*

6. В этой программе есть ошибка. Что это за ошибка и как ее исправить?

*/

   # include<iostream.h>

   int main()

   {

    double x = 5.2;

    cout  << x << " ^ 2 = " << sqr(x);

    return 0;

   }

   double sqr( double х)

   { return x * x; }

/*

7. Попробуйте в функции вычисления факториала использовать операцию ?: .

Массивы

// Листинг 6.1. исходный текст программы AVERAGE1.CPP

// Программа иллюстрирует использование одномерных массивов

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

#include <iostream.h>

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

int main()

{

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

   int num_elem;

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

   do

      {

      cout << "Введите размер массива данных [2 ... "

           << MAX << "]: ";

      cin >> num_elem;

      cout << endl;

      } while (num_elem < 2 || num_elem > MAX);

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

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

      {

      cout << "массив[" << ix << "]: ";

      cin >> array[ix];

      }

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

   double sum = 0;

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

      sum += array[ix];

   cout << endl << "Среднее: " << sum / num_elem << endl;

   return 0;

/*

 - При объявлении одномерных массивов им можно присвоить начальные значения. Список ИНИЦИАЛИЗАЦИИ должен быть заключен в фигурные скобки, а элементы в нем должны быть разделены запятыми. Можно при инициализации задать данных МЕНЬШЕ, чем размер массива. В этом случае компилятор автоматически присвоит нулевые значения тем элементам, которые вы не инициализировали. И вдобавок, если вы не укажете размерность инициализируемого массива, она будет определена по количеству элементов в списке инициализации.

*/

// Листинг 6.2. исходный текст программы AVERAGE2.CPP

// Программа иллюстрирует использование одномерных массивов

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

// Данные задаются при инициализации массива.

#include <iostream.h>

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 << "массив[" << ix << "]: " << array[ix] << endl;

      }

   cout << endl << "Среднее: " << sum / num_elem << endl;

   return 0;

}

 - Объявление одномерных массивов в качестве параметров функции возможно в двух формах: массив-параметр фиксированной размерности и массив-параметр неопределенной длины (открытый массив), При объявлении параметром массива фиксированной размерности указывается размер массива. В этом случае передаваемые функции аргументы должны соответствовать параметру по типу и размеру. Массив- араметр неопределенной длины объявляется с пустыми скобками, означающими, что аргумент может быть любого размера.

(Листинг 6.3а. исходный текст программы MINMAX.CPP)

(Листинг 6.3. исходный текст программы MINMAX.CPP)

СОРТИРОВКА массива - ПРИМЕР в файле list6_4cpp.

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

-      ПОИСК в массиве

означает нахождение в массиве элемента, совпадающего с заданным значением. Методы поиска делятся на две группы: для упорядоченных и неупорядоченных массивов. Метод линейного поиска применяется для неупорядоченных массивов, а метод двоичного поиска - для сортированных массивов. (Пример - list6_5.cpp)

 Рассмотрим понятия ПАРАМЕТРОВ-ФУНКЦИЙ и УКАЗАТЕЛИ НА ФУНКЦИИ:

(Листинг 6.5. исходный текст программы SEARCH.CPP)

БИБЛИОТЕЧНЫЕ ФУНКЦИИ ПОИСКА и СОРТИРОВКИ в непрерывных массивах:

*/

 void *bsearch(const void *key, const void *base, size_t nelem,

    size_t width, int (*fcmp)(const void*, const void*));

 // key - указатель на искомый элемент,

 //    возвращаемое значение - указатель на элемент (0 - не найден)

 // base - базовый адрес массива

 // num - число элементов в массиве

 // width - размер элемента

 // fcmp - указатель на функцию сравнения элементов массива

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

 //    Если элемент не обнаружен, возвращается 0.

 //     Для вычисления индекса можно использовать следующую формулу:

      index = (searchRslt - arrayBase) / sizeof(arrayBase[0]);

 void *lfind(const void *key, const void *base, size_t *num,

    size_t width, int (*fcmp)(const void *, const void*));

 void *lsearch(const void *key, void *base, size_t *num,

    size_t width, int (*fcmp)(const void *, const void *));

 // - если нет элемента, то он вставляется, поэтому возвращаемое значение

 //   всегда не ноль.

 void qsort(void *base, size_t nelem,

    size_t width, int (*fcmp)(const void *, const void *));

/*

 - При объявлении многомерных массивов вам нужно указать тип массива, его имя и размер (заключенный в свою пару скобок) по каждому измерению. Нижнее значение индекса для любого измерения равно 0. Верхнее значение индекса по любому измерению равно количеству элементов поэтому измерению минус единица.

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

   Пример работы с двумерным массивом:

(Листинг 6.6. Исходный текст программы MATRIX1.CPP)

- При объявлении многомерных массивов им можно присвоить начальные значения. Список ИНИЦИАЛИЗАЦИИ должен быть заключен в фигурные скобки, а элементы в нем должны быть разделены запятыми. Можно при инициализации задать данных меньше, чем размер массива, В этом случае компилятор автоматически присвоит нулевые значения тем элементам, для которых вы не указали начальные значения:

(Листинг 6.7. Исходный текст программы MATRIX2.CPP.)

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

(Листинг 6.8. Исходный текст программы MATRIX3.CPP)

Строки и управление вводом/выводом

Здесь подробнее рассматриваются операции консольного ввода/вы­вода. C++, как и его предок — язык С — не определяет операции ввода/вывода как часть языка, а выносит операции консольного ввода/вывода в библиотеки ввода/вывода. Такие библиотеки в основном предназначены для работы в MS-DOS. Рассмотрим небольшую выборку функций ввода/вывода, объявляемых в заголовочных файлах STDIO.H и IOSTREAM.H.

Сегодня мы рассмотрим следующие темы:

·     Форматированный потоковый вывод

·     Потоковый ввод

·     Функция printf

·     Строки в C++

·     Ввод строк

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11


на тему рефераты
НОВОСТИ на тему рефераты
на тему рефераты
ВХОД на тему рефераты
Логин:
Пароль:
регистрация
забыли пароль?

на тему рефераты    
на тему рефераты
ТЕГИ на тему рефераты

Рефераты бесплатно, реферат бесплатно, курсовые работы, реферат, доклады, рефераты, рефераты скачать, рефераты на тему, сочинения, курсовые, дипломы, научные работы и многое другое.


Copyright © 2012 г.
При использовании материалов - ссылка на сайт обязательна.