Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
109
Добавлен:
17.05.2015
Размер:
519.68 Кб
Скачать

Логический тип (double)

Величины логического типа могут принимать только значения true и false, являющиеся зарезервированными словами. Внутренняя форма представления значения false – 0 (нуль). Любое другое значение интерпретируется как true. При преобразовании к целому типу true имеет значение 1.

Символьный тип (char)

Под величину символьного типа отводится количество байт, достаточное для размещения любого символа из набора символов для данного компьютера, что и обусловило название типа. Как правило, это 1 байт. Тип char, как и другие целые типы, может быть со знаком или без знака. В величинах со знаком можно хранить значения в диапазоне от -128 до 127. При использовании спецификатора unsigned значения могут находиться в пределах от 0 до 255. Величины типа char применяются также для хранения целых чисел, не превышающих границы указанных диапазонов.

Расширенный символьный тип (wchar_t)

Тип wchar_t предназначен для работы с набором символов, для кодировки которых недостаточно 1 байта. Размер этого типа зависит от реализации; как правило, он соответствует типу short. Строковые константы типа wchar_t записываются с префиксом L, например, L”Gates”.

Перечисления (enum)

При написании программ часто возникает потребность определить несколько именованных констант, при которых требуется, чтобы все они имели различные значения (при этом сами значения не столь важны). Для таких целей удобно воспользоваться перечисляемым типом данных enum, все возможные значения которого задаются списком целочисленных констант.Формат: enum [имя_типа] {список_констант};

Имя типа задается в том случае, если в программе требуется определять переменные этого типа.

Компилятор обеспечивает, чтобы эти переменные принимали значения только из списка константа

(компилятор – выделяет лексемы, а затем на основе грамматики языка распознает выражения и операторы, построенные из этих лексем. Компилятор выделяет синтаксические ошибки). Константы должны быть целочисленными и могут инициализироваться обычным образом. При отсутствии инициализатора первая константа обнуляется, а каждой следующей присваивается на единицу больше, чем предыдущей.

Пример 1:

enum Err{ERR_READ, ERR_WRITE, ERR_CONVERT};

Err error;

switch(error){

case ERR_READ:/*операторы */break;

case ERR_WRITE:/* операторы */break;

case ERR_CONVERT:/* операторы */break;

}

Константам ERR_READ, ERR_WRITE, ERR_CONVERT присваиваются значения 0, 1,2 соответственно.

Пример 2: enum {two=2, three, four, ten=10, eleven, fifty=ten+10};

Константам three, four присваиваются значения 3, 4, константе eleven-11.

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

Преимущество применения перечисления перед описанием именованных констант и директивой #define состоит в том, что связанные константы нагляднее; кроме того, компилятор при инициализации констант могут выполнять проверку типов.

Строки

Строка представляет собой массив символов, заканчивающийся нуль-символом.

Нуль-символ – это символ с кодом равным 0, который записывается в виде управляющей последовательности ‘\0’.

В независимости от того, какая размерность зарезервировано под строку, положение нуль-символа определяет фактическую ее длину. Строку можно инициализировать строковым литералом(по другому строковым константом).

Пример 1: char[10]= “Vasia” //выделяет под строку 10 элементов с номерами от 0 до 9.

//первые символы такой последовательности ‘v’ ‘a’ ‘s’ ‘i’ ‘a’.

В таком примере под строку выделяется 10 байтов, 5 из которых занято под символы строки, а 6 – под нуль-символ. Если строка при определении инициализируется, то ее размерность можно опустить (компилятор сам выделит количество байт).

Инициализировать строку можно при помощи указателя:

char str[ ]=”Vasia” //выполнено и заполнено 6 байт.

Оператор char *str=”Vasia” создает не строковую переменную, а указатель на строковую константу Vasia, изменить которую не возможно (к примеру, оператор str[1]=’0’-не допускается).

Знак равенства перед строковым литералом означает не присваивание, а инициализацию.

Операция присваивания одной строки другой не определена и может выполняться с помощью цикла или функций стандартной библиотеки – string.h.

string.h – из стандарной библиотеки Си;

string – из стандартной библиотеки С++;

cstring – для консольной версии.

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

Пример 2: Программа, которая запрашивает пароль не более трех раз.

#include<stdio.h>;

#include<string.h>

int main (){

char s[80],pass[]=’kuku’;

int i, k=0;

fro (i=0; ! k && i<3; i++){

printf (“\n Введите пароль :\n”);

gets(s); //функция ввода строки

if (str str (s,pass)) k=1; //функция сравнения строки

}

if (k) printf (“\n пароль принят”);

else printf (“\n пароль не принят”);

return 0;

}

Часто при инициализации строк используется указатель. Распространенные ошибки при работе со строками отсутствие нуль-символа и выход указателя при просмотре строки за ее границы.

Массивы

При использовании простых переменных каждой области памяти для хранения данных соответствует свое имя. Если с группой величин одинакового типа требуется выполнять однообразные действия, то их целесообразно упорядочить по порядковому номеру и присвоить одно общее на все имя. Такая именованная последовательность однотипных величин называется массивом.

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

Если элементов в массиве больше, чем инициализаторов, то элементы для которых не указаны, обнуляются.

Пример 1:

Int b[5]={3,2,1};

b[0]=3;

b[1]=2;

b[2]=1;

b[3], b[4]=0

Массивы делятся на одномерные(пример, int A[5] //одномерный массив из 5 элементов) и многомерные, также на статические (заданные размерности) и динамические (размерности изменяются).

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

Пример 2: Подчитывается сумма элементов

#include<iostream.h>;

int main ( ){

const int n=10;

int i, sum;

int marks [n]={3,4,5,4,4,};

for (i=0, sum=0, i<n, i++) sum+=marks[i];

cout <<”Сума элементов:” <<sum;

return0;

}

Размерность массивов предпочтительнее задавать с помощью именованных констант, как это сделано в примере, поскольку при таком подходе для ее изменения достаточно скорректировать значение константы всего лишь в одном месте программы. При обращении к элементам массива, автоматический контроль выхода индекса за границу массива не производится, что может привести к ошибкам.

Пример 3: Сортировка целочисленного массива методом выбора

#include <iostream.h>;

int main ( ) {

const int n=20; //задает кол-во элементов массива

int b[n]; //описание массива

int i;

for (i=0, i<n; i++) cin>> b[i]; //ввод массива

for (i=0, i<n-1; i++){ //n-1 раз ищем наим. знач.

int imin=i; //принимаем на наим. элемент первый из рассматриваемых элементов

for (int j=i+1, j<n, j++); //поиск элемента неупоряд.

if (b[j]<b[imin], imin=j); //если нашли наим. элемент заполняем его номер

int a=b[i]; //идет обмен элементами с номерами i и imin

b[i]=b[imin];

b[imin]=a;

}

for (i=0, i<n, i++)cout << b[i]<<’ ‘;

return0; //вывод упоряд. массива

}

Процесс обмена элементов массива с номерами i и imin через буферную переменную a на i-том проходе цикла будет выглядеть след. образом:

i imin

Цифры около стрелок обозначает порядок децствия.

В предыдущем примере к i-му элементу массива можно обратиться, используя указатель на объект *(b+i). Присвоить адрес этого указателя можно при помощи следующей операции: &b[0].

Многомерные массивы – задаются указанием каждого измерения в квадратных скобках, например, оператор int matr [6] [8] задает описание двумерного массива из 6 строк и 8 столбцов.

В памяти такой массив располагается в последовательных ячейках построчно.

Многомерные массивы размещаются так, что при переходе к следующему элементу быстрее всего изменяется последний индекс. Для доступа к элементу многомерного массива указываются все его индексы, например, matr [i][j], или более экзотическим способом *(matr [i]+j). Это возможно, поскольку matr[i] является адресом начала i-й строки массива. При инициализации многомерного массива он представляется либо как массив из массивов, при этом каждый массив заключается в свои фигурные скобки (в таком случае, при описании массива левый его элемент можно не указывать), либо задается общий список элементов в том порядке в котором элементы располагаются в памяти:

  1. int mass2[ ][2]={{1,1}, {0,2}, {1,0}};

  2. int mass2[3][2]={1,1,0,2,1,0}

Динамические массивы создаются при помощи операции – new, при этом обязательно указывается тип и размерность, например, int n=10;

float *p=new float [n];

В этой строке создается переменная – указатель на float, а в динамической памяти отводится непрерывная область, достаточная для размещения 100 элементов вещественного типа, и адрес ее начала записывается в указатель p.

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

Преимущество динамических массивов состоит в том, что их размерность может быть переменной, т.е. объем памяти, выделяемой под массив, определяется на этапе программы. Доступ к элементам динамического массива осуществляется точно так же, как к статическим, например, к элементу номер 5 можно обратиться как p[5] или *(p+5).

Альтернативный способ создания динамического массива – это функции malloc библиотеки С.

int i=10;

float *q=(float*) malloc (n*sizeof (float));

Операция преобразования типа, записанная перед функций malloc, требуется потому, что функция возвращает значение указателя типа void*, а инициализируется указатель на float.

Память зарезервированная под динамический массив с помощью операций new [ ], освобождается при помощи оператора delete, а память, зарезервированная при помощи malloc, освобождается при помощи free, например: delete [ ] p;

free[q];

При несоответствии способов выделения и освобождения памяти результат не определен. В операторе delete [ ], в [ ] размерность не указывается, но скобки обязательно.

Соседние файлы в папке шпоры