скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыРеферат: Лекции по C++

за исключением того, что ключевое слово 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;

}

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

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.