Скачать презентацию Методы программирования Хуторова Ольга Германовна Лекция 5 Скачать презентацию Методы программирования Хуторова Ольга Германовна Лекция 5

MP_L5.ppt

  • Количество слайдов: 35

Методы программирования Хуторова Ольга Германовна Лекция 5 Методы программирования Хуторова Ольга Германовна Лекция 5

Темы лекции n С++ q q Типы данных Массивы Темы лекции n С++ q q Типы данных Массивы

Базовые типы: n n n логический тип (bool) символьный тип (char) целые типы (int, Базовые типы: n n n логический тип (bool) символьный тип (char) целые типы (int, short int, unsigned int, long int. . . ) типы с плавающей запятой (float, double, long double) тип void массивы

Типы, определенные пользователем: n n перечислимые типы (enum) указатели ссылки структуры и классы Типы, определенные пользователем: n n перечислимые типы (enum) указатели ссылки структуры и классы

Логические типы n В числовом еквиваленте false соответствует нулевому значению переменной, true - любому Логические типы n В числовом еквиваленте false соответствует нулевому значению переменной, true - любому ненулевому. int v = true; int v 1 = false; n n //v содержит 1 //v 1 содержит 0 Размер bool-переменной на большинстве машин равен 1 байту. при необходимости использовать размер переменных, следует применять оператор sizeof. int sz = sizeof(bool); //sz содержит размер типа bool n размеры одинаковых типов на разных машинах могут отличаться.

Символьные типы При использовании символьных типов как числовых возникает проблема неправильной интерпретации: какой диапазон Символьные типы При использовании символьных типов как числовых возникает проблема неправильной интерпретации: какой диапазон числа, - от 0 до 255 или от -128 до 127? Поэтому для исключения подобной неоднозначности следует использовать явное определение типов signed char(-128. . 127) unsigned char(0. . 255).

Символы #include<iostream> using namespace std; int main() { unsigned char c='A'; cout<< c << Символы #include using namespace std; int main() { unsigned char c='A'; cout<< c << " "<< (int)c<

последовательное посимвольное считывание #include<iostream> using namespace std; int main() { unsigned char c; while(cin>>c) последовательное посимвольное считывание #include using namespace std; int main() { unsigned char c; while(cin>>c) // Цикл пока считывание успешно { // Делаем необходимые действия } return 0; } n n Для того, чтобы сообщить программе о завершении файла при вводе с клавиатуры необходимо нажать клавиши Ctrl-d в системе Linux и Ctrl-z в системе Windows. Эта программа при считывании данных будет игнорировать символы–разделители: пробелы, символы новой строки и табуляции. Если нужно, чтобы в переменную c считывались все символы, в том числе и разделители, то необходимо для потока ввода cin установить манипулятор noskipws при помощи инструкции cin>>noskipws; .

форматирванный ввод-вывод: n n n новая строка горизонтальная табуляция забой вертикальная табуляция возврат каретки форматирванный ввод-вывод: n n n новая строка горизонтальная табуляция забой вертикальная табуляция возврат каретки прогон листа звонок обратная косая черта Вопрос одиночная кавычка двойная кавычка n t b v r f a \ ? ' "

Целые типы q q signed и unsigned. short, long, l ong long. На х86 Целые типы q q signed и unsigned. short, long, l ong long. На х86 как правило определены такие величины: n n n short int -32768. . 32767 int, long int -2147483648. . 2147483647 unsigned short int 0. . 65535 unsigned int, unsigned long int 0. . 4294967295 unsigned long int 0. . 18446744073709551615 long int -9223372036854775808. . 9223372036854775807

Перечисления n Перечисление - это тип переменной, у которого заранее определен набор данных enum Перечисления n Перечисление - это тип переменной, у которого заранее определен набор данных enum e. Names{ ered, eblack, egreen }; e. Names val; val = ered; if(val != eblack){. . . } n По умолчанию данные нумеруются с нуля, но можно установить номер и самостоятельно: enum e. Names{ ered=10, eblack, egreen }; //eblack 11, egreen-12 n Допускается преобразование в int.

Типы с плавающей запятой n n n float double long double q q компиляторозависимый Типы с плавающей запятой n n n float double long double q q компиляторозависимый тип, для Intel 7. 1, к примеру, определен тип long float, который соответствует double. для целочисленных вычислений nипы с плавающей запятой использовать не рекомендуется, т. к. скорость работы с ними намного ниже чем с int.

Массивы Массив - это набор однотипных елементов, расположенных в памяти последовательно. Нумерация массивов производится Массивы Массив - это набор однотипных елементов, расположенных в памяти последовательно. Нумерация массивов производится от 0. Размер массива должен определятся константой n Массив в языке C++ задается следующим образом: тип_элементов идентификатор[размер]; n где тип_элементов — произвольный тип данных языка C++, который будут иметь элементы массива, например, int, double и т. д. ; n идентификатор — имя массива, n размер — число элементов в нем. n

/* автоматический локальный массив. содержит непредсказуемые значения */ double ad[3]; . . . ; /* автоматический локальный массив. содержит непредсказуемые значения */ double ad[3]; . . . ; n Если же вы добавите ключевое слово static, то массив будет вести себя точно так же, как статическая локальная переменная - проинициализируется при первом входе в блок, а затем будет сохранять свои значения: /* статический локальный массив. Инициализируется нулями при первом входе в блок, после этого сохраняет значения элементов */ static double ad[3]; . . . ;

Массив на этапе конструирования можно инициализировать определенными значениями char buf[] = Массив на этапе конструирования можно инициализировать определенными значениями char buf[] = "aaa"; int size = sizeof(buf); //size равен 4 //Учитывается символ // окончания строки char cbuf[] = {'a', 'a'}; //теперь размер массива 3 char cbuf[10] = {'a', 'a'}; /*размер 10, проинициализированы первые три елемента, остальные содержат случайные значения */

Инициализация n /* Одномерный массив из трех элементов типа double */ /* инициализируется тремя Инициализация n /* Одномерный массив из трех элементов типа double */ /* инициализируется тремя вещественными числами */ double ad[3] = { 0. 0, 10. 0, -1. 0 }; n Список значений для инициализации может быть короче массива, при этом вашими значениями будут инициализированы только первые элементы: /* Инициализируем только два первых элемента. */ double ad[3] = { 1. 5, 2. 0 }; n если мы пользуемся явной инициализацией, то можем не указывать размерность массива, а поставить просто пустые квадратные скобки. Например, запись, приведенная ниже, создаст массив из 5 элементов - по количеству чисел для инициализации: /* Массив, размерность которого задана списком инициализации */ int x[] = { 1, 2, 3, 4, 5 };

Программы создает массив, заданного пользователем размера, считывает с клавиатуры его элементы, прибавляет к каждому Программы создает массив, заданного пользователем размера, считывает с клавиатуры его элементы, прибавляет к каждому элементу массива число 1, выводит результат на экран: #include using namespace std; void main() {const int n=10; int i; int arr[n]; // Размер массива // Счетчик в циклах // Объявление массива // Считываем массив cout<<"Введите "<>arr[i]; // Прибавляем по 1 к каждому элементу for(i=0; i

Многомерные массивы int buf[2][3] = {0, 1, 2, 3, 4, 5}; float a[2][3][4][5] n Многомерные массивы int buf[2][3] = {0, 1, 2, 3, 4, 5}; float a[2][3][4][5] n Читаются многомерные массивы слева направо, т. е. (для вышеприведенного примера): массив из двух елементов, каждый из которых является массивом из трех елементов.

Инициализация n Массив также можно явно инициализировать при создании, double m[2][4] = { { Инициализация n Массив также можно явно инициализировать при создании, double m[2][4] = { { 1, 2, 3, 4 }, {-1, 1, 0, 0 } }; n Как и в случае одномерных массивов, вы можете задавать не все значения, а только часть. double m[2][4] = { { 1, 2 } }; инициализируя одномерные массивы, можно не указывать размерность - она определится автоматически по количеству заданных значений. С многомерными массивами дело обстоит несколько иначе - не указывать можно только первую размерность. Вторая размерность (и прочие, если их больше двух) должна быть указана. Например, такая запись double m[][4] = { { 1, 2, 3, 4 }, {-1, 1, 0, 0 } }; n приведет к созданию массива той же размерности 2 x 4.

Объявление, вывод двумерного массива n вывести на экран двумерный массив в виде таблицы, разделяя Объявление, вывод двумерного массива n вывести на экран двумерный массив в виде таблицы, разделяя элементы в строке одним пробелом: const int n=2; const int m=4; int A[n][m]; for(int i=0; i

Форматирование чисел при выводе n Для того, чтобы выводимое число или строка имело ровно Форматирование чисел при выводе n Для того, чтобы выводимое число или строка имело ровно заданную ширину, необходимо перед выводом его на экран для потока cout вызвать метод width с параметром 3. Данный метод устанавливает ширину поля для выводимого значения. for(int i=0; i

Объявление, ввод двумерного массива n считать двумерный массив с клавиатуры можно: for(i=0; i<n; ++i) Объявление, ввод двумерного массива n считать двумерный массив с клавиатуры можно: for(i=0; i>A[i][j];

Передача массива в качестве параметра n n n размер создаваемого массива может быть неопределен Передача массива в качестве параметра n n n размер создаваемого массива может быть неопределен на момент компиляции программы, поэтому функция не может знать размер полученного массива. Поэтому при объявлении функции необходимо задавать два параметра: массив передаваемых элемента (без указания размера массива) и размер массива. Например, функция поиска наименьшего значения в массиве int A[n] может быть объявлена так: double Min (int A[], int n) Соответственно, внутри функции main мы объявляем массив int A[n] и вызываем функцию Min, передав в качестве параметров массив A и его размер n: Min (A, n);

Передача массива в качестве параметра Размер (количество елементов) массива можно узнать оператором sizeof. При Передача массива в качестве параметра Размер (количество елементов) массива можно узнать оператором sizeof. При передаче в функцию массива в качестве параметра, передается указатель на первый елемент, поэтому sizeof из функции вернет размер указателя на первый елемент: void check. Array(int *val, int len) { cout << sizeof(val) << 'n'; //sizeof вернет размер указателя for(int i=0; i

динамические массивы int *p = new int[10]; //выделили память на 10 елементов delete [] динамические массивы int *p = new int[10]; //выделили память на 10 елементов delete [] p; //освободили память

изменить размер массива const int SIZE = 10; float *p = new float[SIZE]; { изменить размер массива const int SIZE = 10; float *p = new float[SIZE]; { float *p 1= new float[SIZE+20]; for(int i=0; i

динамические массивы n n для создания массива можно использовать и функцию malloc, для освобождения динамические массивы n n для создания массива можно использовать и функцию malloc, для освобождения памяти в этом случае используют free. при создании через malloc(free) никаких конструкторов(дес трукторов) не вызывается, - происходит просто выделение сырой памяти. const int SIZE = 10; double *p = (double*) malloc(SIZE*sizeof(double)); . . . free(p); //освободим память

Несколько ошибок n n 1. 2. Смешивание разных операторов создания-удаления Нельзя смешивать разные операторы Несколько ошибок n n 1. 2. Смешивание разных операторов создания-удаления Нельзя смешивать разные операторы выделения и освобождения памяти, т. е. создать елемент через new, а удалять через free и наоборот, создать с помощью malloc, а удалять вызовом delete, - поведение в данном случае неопределено, т. е. может быть все что угодно от вылета программы до, образно говоря, форматирования жесткого диска. Очень опасная и труднонаходимая ошибка. Вызов оператора delete вместо оператора delete [] Происходит удаление только первого елемента, - в лучшем случае приводит к потерям памяти: Повторный вызов delete или free для уже удаленных объектов Как правило, на практике происходит немедленное аварийное завершение программы, но по стандарту поведение не определено, поэтому возможна труднонаходимая блуждающая ошибка. Отсутствие операторов удаления delete (free) Если логика программы не нуждается в вызове деструкторов, то приводит только к потерям памяти.

Пример создания массива массивов: const int SIZE = 10; int **pbuf = new (int*)[SIZE]; Пример создания массива массивов: const int SIZE = 10; int **pbuf = new (int*)[SIZE]; for(int i=0; i

массивы и указатели n В одномерном случае мы вместо массива могли ставить указатель на массивы и указатели n В одномерном случае мы вместо массива могли ставить указатель на тип его элемента. double arr[2][4]; double *p; p=arr; // у указателя неправильный тип

массивы и указатели n Выходит, у нашего двумерного массива тип элемента не double, а массивы и указатели n Выходит, у нашего двумерного массива тип элемента не double, а какой-то другой? Так и есть. И именно поэтому новые размерности указываются в новых наборах квадратных скобочек. Наш массив arr как бы остался одномерным. Просто его элементы вместо объектов типа doublе тоже являются массивами. И мы, если возникнет такая потребность, можем их даже использовать как самостоятельные массивы: double arr[2][4]; double *p; p = arr[0]; /* указатель на нулевую строку */ n А раз так, то оказывается, что тип элемента arr - вовсе не double, а массив из 4 double. То есть double (*parr)[4]; Обратите внимание - круглые скобки здесь необходимы. Если вы их уберете, вы вместо указателя на массив получите массив четырех указателей. n

#include <stdlib. h> #include <stdio. h> void print_text(char *text[]) { int i; for (i=0; #include #include void print_text(char *text[]) { int i; for (i=0; text[i] != NULL; i++) printf("%s", text[i]); } main() { char *s[] = { "Hello, " , "worldn", NULL }; print_text(s); return 0; }

n /* Такая функция может работать только с массивами 2 x 4 */ double n /* Такая функция может работать только с массивами 2 x 4 */ double sum 2 x 4(double arr[2][4]) { int i, j; double s; for (i=0, s=0; i<2; i++) for (j=0; j<4; j++) s+=arr[i][j]; return s; } /* A у такой первый размер может быть любым */ double sum(int dim, double arr[][4]) { int i, j; double s; for (i=0, s=0; i

n n А иногда бывает удобно использовать даже не массив указателей, а указатель на n n А иногда бывает удобно использовать даже не массив указателей, а указатель на указатель. Например, если в программе надо предусмотреть случай, когда у нас не то что ни одной строки нет, а даже нет массива для хранения этих строк: #include #include void print_text(char **text) { int i; if (text == NULL) printf("No text at alln"); else { for (i=0; text[i] != NULL; i++) printf("%s", text[i]); } } main() { char *s[] = { "Hello, " , "worldn", NULL }; char **p = NULL; print_text(s); print_text(p); return 0; } n Такая программа, если ей по ошибке передадут NULL вместо массива строк, не сломается, а напечатает "No text at all".

Список литературы n n Х. Дейтел, П. Дейтел Как программировать на С++ Бьярн Страустрап, Список литературы n n Х. Дейтел, П. Дейтел Как программировать на С++ Бьярн Страустрап, Введение в язык С++