Пользовательские типы данных.



Команда cin.get() - это еще один вызов функции, которая считывает данные из входного потока данных и ожидает нажатия клавиши ENTER.

cin.get();

А cin.getline() позволяет вводит строку вместе с пробелами.

                                                                                                                              

Файловый ввод/вывод.

1. fstream – класс для чтения и записи.

2.

  1. создать объект класса ofstream;
  2. связать объект класса с файлом, в который будет производиться запись;
  3. записать строку в файл;
  4. закрыть файл.

3.

  1. создать объект класса ifstream и связать его с файлом, из которого будет производиться считывание;
  2. прочитать файл;
  3. закрыть файл.

4. Классы IOStream имеют 4 функции для оценки состояние потока: good(), bad(), fail(), а также eof(), Исключая good()каждая функция проверяет один бит в состоянии основного потока и возвращает, включен ли этот бит (есть ошибки?). good() в частности проверяет, если все биты выключены (поток действителен?). Вот для чего они:

§ good(): Поток не обнаружил ошибку.

§ bad(): Поток столкнулся с ошибкой, которая влияет на целостность потока (то есть ошибка выделения памяти, отсутствие буфера и т. Д.)

§ fail(): Обычно исправимая ошибка (ошибка форматирования / разбора).

§ eof(): Конец файла (EOF) персонаж был достигнут.

При выполнении операций ввода-вывода необходимо проверять наличие ошибок в потоке при обработке ввода. Что новички, как правило, не знают, что только Функция, которая должна была использоваться для проверки правильности ввода fail(), Все остальные функции полезны в других случаях, но не для кондиционирования ввода.

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

Потоки имеют логический оператор, который возвращает !fail(), это позволяет элегантно проверять поток после выполнение ввода, как это:

while (myFile >> myInt) {

// ...

}

Это лучший способ выполнить ввод. Само извлечение должно присутствовать в условном контексте, чтобы тело, в котором оно используется, выполнялось, только если извлечение прошло успешно.

5. Также как и ввод, вывод в файл может быть различным.

  • Форматированный вывод. Функция fprintf (файловый_указатель, строка_формата, переменные).
  • Посточный вывод. Функция fputs (строка, файловый_указатель).
  • Посимвольный вывод. Функция fputc() или putc(символ, файловый_указатель).

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

Запись в каждую строку файла полей одной структуры:

#include <stdio.h>

 

int main () {

FILE *file;

struct food {

   char name[20];

   unsigned qty;

   float price;

};

struct food shop[10];

char i=0;

 

file = fopen("fprintf.txt", "w");

 

while (scanf("%s%u%f", shop[i].name,

      &(shop[i].qty),

      &(shop[i].price)) != EOF) {

 

   fprintf(file, "%s %u %.2f\n",

           shop[i].name, shop[i].qty,

           shop[i].price);

   i++;

}

fclose(file);

}

Построчный вывод в файл (fputs(), в отличие от puts() сама не помещает в конце строки '\n'):

while (gets(arr) != NULL) {

fputs(arr, file);

fputs("\n", file);

}

Пример посимвольного вывода:

while ((i = getchar()) != EOF)

putc(i, file);

5. На самом деле, файловый ввод-вывод ничем не отличается от консольного. За единственным исключением – если данные читаются из файла, то в любой момент можно вернуться к началу файла и считать все заново.

Алгоритмы

1.

2.В файле гост

3.

4. К составным операторам относят собственно составные операторы и блоки. В обоих случаях это последовательность операторов, заключенная в фигурные скобки. Блок отличается от составного оператора наличием определений в теле блока. Например:

{

n++;                                    это составной оператор

summa+=n;

}

{

int n=0;

n++;                                    это блок

summa+=n;

}

5.

6. Условный (тернарный) оператор (обозначается как ?:) является единственным тернарным оператором в языке С++, который работает с 3-мя операндами. Из-за этого его часто называют просто «тернарный оператор». Оператор ?: предоставляет сокращенный способ (альтернативу) ветвления if/else.

Стейтменты if/else:

if (условие)
   выражение;
else
   другое_выражение;

Можно записать как:

(условие) ? выражение : другое_выражение;

Обратите внимание, операнды условного оператора должны быть выражениями (а не стейтментами).

7. 8.

9.

10.

 

11.
12 и 13. #include <iostream>

#include <cmath>

#include <iomanip>

using namespace std;

int main()

{

  setlocale(LC_ALL, "Rus");

  // Произведение функций и аргумент

  float MulF, X;

  // Параметр цикла и количество сомножителей

  int I, N;

  cout << "Задайте аргумент и число сомножителей: ";

  cin >> X >> N;

  // Произведение значений библиотечной функции

  MulF = 1;

  for (I = 1; I <= N; I++) {

        cout << "\nI=" << I << " 1.0/I*X=" << 1.0 / I * X;

        MulF = MulF * atanh(1.0 / I * X);

  }

  cout << "\nПроизведение atanh(1/i*x)=" << MulF;

  // Вычисление произведения arth по бесконечному ряду

  // Для ряда: сумма, слагаемое, аргумент, погрешность

  float SumR, AddR, X_R, Eps;

  // Номер слагаемого ряда

  int N_R;

  cout << "\n\nВведите погрешность: ";

  cin >> Eps;

  MulF = 1;

  for (I = 1; I < N + 1; I++) {

        // Из выражения arth(X_R)=arth(1/I*X) аргумент ряда =

        X_R = X / I;

        // Вычисление arth для конкретного значения X_R

        // Начальные значения переменных

        SumR = 0; AddR = X_R; N_R = 1;

        // Повторять до получения требуемой точности

        do {

               SumR = SumR + AddR; // Частичная сумма

               N_R = N_R + 1; // Номер следующего слагаемого

               // Следующее слагаемое, выраженное через предыдущее

               AddR = AddR * pow(X_R, 2) / (2 * N_R + 1);

        } while (abs(AddR / SumR) >= Eps);

        cout << "\nЧисло слагаемых=" << N_R << " для аргумента X_R=" << X_R;

        // Накапливаем произведение arth

        MulF = MulF * SumR;

  }

  cout << "\nПроизведение atanh(x/i) через бесконечный ряд = " << MulF;

  cin.get();

  return 0;

}

15.

5.Основные понятия языка С++

Алфавит

Множество символов языка C включает:

  • прописные буквы латинского алфавита;
  • строчные буквы латинского алфавита;
  • арабские цифры;
  • разделители: , . ; : ? ! ' " | / \ ~ _ ^ ( ) { } [ ] < > # % & - = + *

Остальные символы могут быть использованы только в символьных строках, символьных константах и комментариях. Язык C++ различает большие и маленькие буквы, таким образом, name и Nameразные идентификаторы.

2.Лексемы:

  1. Ключевые слова (keywords).
  2. Идентификаторы (identifiers).
  3. Литералы (literals) или константы (constants).
  4. Операторы (operators).
  5. Знаки пунктуации (punctuators).

Особым элементом языка является создание комментариев (т.е. той части текста программы, которая будет игнорироваться компилятором). В языке С++ возможны два вида комментариев:

 

 


/* многострочный
комментарий */

с++; // однострочный комментарий до конца строки

Ключевые слова -- определенные зарезервированные слова, имеющие конкретное значение. Можно выделить следующие группы ключевых слов:

  1. ключевые слова для объявления типов;
  2. ключевые слова для создания языковых конструкций;
  3. остальные слова (для создания гетерогенных типов данных, для реализации принципов ООП и др.)

Ключевые слова в языке С++ всегда записываются прописными буквами. Например, if -- это ключевое слово для создания условной конструкции, а IF, If, iF может быть идентификаторами или константами и никогда не будут восприниматься компилятором как оператор.

Идентификаторы -- это последовательности латинских букв, цифр и символов подчеркивания ( _ ), обозначающае имена переменных. Прописные и строчные символы различаются. Например, x и X -- это разные переменые. Длина идентификатора могут быть произвольной, но лучше давать идентификаторам короткие имена, отражающие смысл значения, которое они описывают:

 

 

i // обычно целая переменная цикла
count // количество
buff_size // составное (из 2 слов) имя с символом _
g374 // непонятно
_foo // плохо
if // не может быть идентификатором, т.к. это ключевое слово
374q // не может начинаться с цифры

Литералы -- это постоянные значения (константы):

5 // целая константа
05 // целая константа в восьмеричной системе счисления
0х5 // целая константа в шестнадцатеричной системе счисления
5.0 // вещественная константа с двойной точностью
5.f // вещественная константа
'5' // символьная константа
"hello" // строковая константа

Знаки пунктуации используются для логического разделения текста программы. Например,
;  -- заканчивает арифметическое выражение или оператор;
,  -- используется для разделения в перечислениях переменных, констант, аргументов и т.п.;
{} -- ограничивает группу выражений или операторов;
() -- используется для описания аргументов функций.

3. В языке C++ есть встроенная поддержка определенных типов данных. Их называют основными типами данных (или «фундаментальные/базовые/встроенные типы данных»).

Вот список основных типов данных в языке C++:

Категория Тип Значение Пример
Логический тип данных bool true или false true
Символьный тип данных char, wchar_t, char16_t, char32_t Один из ASCII-символов ‘c’
Тип данных с плавающей запятой float, double, long double Десятичная дробь 3.14159
Целочисленный тип данных short, int, long, long long Целое число 64
Пустота void Пустота  

4.Идентификатор — это имя переменной, функции, класса или другого объекта в языке C++. Мы можем определять идентификаторы любыми словами/именами. Тем не менее, есть несколько общих правил, которые необходимо соблюдать:

Идентификатор не может быть ключевым словом. Ключевые слова зарезервированы.

Идентификатор может состоять только из букв (нижнего и верхнего регистра) латинского алфавита, цифр и символов подчёркивания. Это означает, что все другие символы и пробелы — запрещены.

Идентификатор должен начинаться с буквы (нижнего или верхнего регистра). Он не может начинаться с цифры.

Язык C++ различает нижний регистр от верхнего. nvalue отличается от nValue и отличается от NVALUE.

Константы

Как следует из названия, константа — это переменная, значение которой не меняется за время ее существования. Предваряя переменную ключевым словом const при ее объявлении и инициализации, вы объявляете ее как константу:
const int N_max =100;
Идентификатор константы записывается по общим правилам написания идентификаторов (см. подсказку выше).
Ниже перечислены основные характеристики констант:
1. Они должны инициализироваться при объявлении, и однажды присвоенные им значения никогда не могут быть изменены.
2. Константа не может быть объявлена непосредственно в пространстве имен, но может быть объявлена либо в классе, либо в функции.
3. Значение константы должно быть вычислено во время компиляции.

Таким образом, инициализировать константу значением, взятым из другой переменной, нельзя. Если все-таки нужно это сделать, используйте поля только для чтения.
Константы всегда неявно статические. Нет необходимости включать модификатор static в объявление константы.
Использование констант в программах обеспечивает, по крайней мере, три преимущества:
1. Константы облегчают чтение программ, заменяя «магические» числа и строки читаемыми именами, назначение которых легко понять. Например, через константу N_max может задать максимальное количество элементов в массиве объектов, при необходимости это число может быть изменено всего лишь в одном операторе объявления константы.
2. Константы облегчают модификацию программ. Например, предположим, что в программе C# имеется константа IncomeTax (подоходный налог), которой присвоено значение 13 процентов. Если налог когда-нибудь изменится, вы можете модифицировать все вычисления налога, просто присвоив новое значение этой константе, и не понадобится просматривать код в поисках значений и изменять каждое из них, надеясь, что оно нигде не будет пропущено.
3. Константы позволяют избежать ошибок в программах. Если попытаться присвоить новое значение константе где-то в другом месте программы, а не там, где она объявлена, компилятор выдаст сообщение об ошибке.

6. Стандартные ключевые слова C++

alignas alignof andб and_eqб asmобъект auto bitandб bitorб bool break case catch char char8_tc char16_t char32_t class complб conceptc const const_cast constevalc constexpr   constinitc continue co_awaitc co_returnc co_yieldc decltype default delete do double dynamic_cast else enum explicit exportc extern
false float for friend goto if inline int long mutable namespace new noexcept notб not_eqб nullptr operator orб or_eqб private protected public register reinterpret_cast requiresc return short signed sizeof static static_assert   static_cast struct switch template this thread_local throw true try typedef typeid typename union unsigned using п  
7,8,9,10    

6.Вычисления в языке С++

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

2. Выражение – это последовательность операторов и их операндов, задающих вычисления. Выражения состоят из операторов, констант, функций и переменных. В языке С/C + + выражением считается любая допустимая комбинация этих элементов. Поскольку большинство выражений в языке C /C + + напоминают алгебраические, часто их таковыми и считают. Но есть и специфические особенности. Однако главное то, что в процессе вычислений формируется результат (например, результатом вычисления 2+2 является число 4)

3.

Оператор (operator) Назначеие (meaning) Тип оператора (type) Порядок выполнения (associativity)
:: область видимости (scope resolution) unary
[ ] доступ к элементам массива (array subscript) unary слева направо
( ) вызов функции (function call) multiple слева направо
type( ) оператор преобразования типов, конструирования значения (conversion, constructor) unary
-> операторы доступа к членам гетерогенных типов данных (member selection) unary слева направо
++ -- постфиксный инкремент/декремент (postfix increment/decrement) unary
new Динамическое размещение в памяти переменных и массивов (allocate) binary  
delete delete [] удаление из памяти переменной/массива, размещенного динамически (deallocate) binary
++ -- префиксный инкремент/декремент (prefix increment/decrement) unary
* получение значения по указателю (dereference) unary  
& получения указателя на переменную (address-of) unary  
+ унарный плюс (unary plus) unary  
- арифметическое отрицание (arithmetic negation) unary  
! отрицание/логическое НЕ (logical NOT) unary  
~ побитовое дополнение (bitwise complement) unary  
sizeof определение размера переменной (size of object) unary  
typedef определение имени типа (type name) unary  
(type) приведение типов (type cast) unary справа налево  
const_cast dynamic_cast reinterpret_cast static_cast приведение типов (type cast) unary  
.* ->* получение указателя на член класса (pointer to class member) unary слева направо
* / умножение/деление (multiplication/division) binary слева направо
% остаток от деления (remainder) binary слева направо  
+ - сложение/вычитание (addition/subtraction) binary слева направо
<< >> побитовый левый/правый сдвиг (left/right shift) unary слева направо
< > <= >= сравнение (comparison) binary слева направо
== != равенство/неравенство (equality/inequality) binary слева направо    
& побитовое И (bitwise AND) binary слева направо      
^ побитовое исключающее ИЛИ (bitwise exclusive OR) binary слева направо      
| побитовое ИЛИ (bitwise OR) binary слева направо      
&& || логическое И/ ИЛИ (logical AND/OR) binary слева направо    
? : арифметическая условная конструкция (ariftnetic if) ternary справа налево      
= присваивание (assignment) binary справа налево      
*= /= умножение/деление с присваиванием (multiplication/division assignment) binary справа налево    
%= остаток от деления с присваиванием (modulus assignment) binary справа налево      
+= -= сложение/вычитание с присваиванием (addition/subtraction assignment) binary справа налево    
<<= >>= побитовый левый/правый сдвиг с присваиванием (left/right shift assignment) binary справа налево    
&= побитовое И с присваиванием (bitwise AND assignment) binary справа налево      
|= побитовое ИЛИ с присваиванием (bitwise inclusive OR assignment) binary справа налево      
^= побитовое исключающее ИЛИ с присваиванием (bitwise exclusive OR assignment) binary справа налево      
throw генерация исключения unary      
, разделитель (comma) unary слева направо      
             

4.

5. Арифметические преобразования приводят оба операнда бинарного арифметического выражения к одному типу, который и будет типом результата выражения. Два общих правила таковы:

  • типы всегда приводятся к тому из типов, который способен обеспечить наибольший диапазон значений при наибольшей точности. Это помогает уменьшить потери точности при преобразовании;
  • любое арифметическое выражение, включающее в себя целые операнды типов, меньших чем int, перед вычислением всегда преобразует их в int.
  • Мы рассмотрим иерархию правил преобразований, начиная с наибольшего типа long double.

Если один из операндов имеет тип long double, второй приводится к этому же типу в любом случае. Например, в следующем выражении символьная константа 'a' трансформируется в long double (значение 97 для представления ASCII) и затем прибавляется к литералу того же типа:

3.14159L + 'a'.

Если в выражении нет операндов long double, но есть операнд double, все преобразуется к этому типу. Например:

int ival;

float fval;

double dval;

 

// fval и ival преобразуются к double перед сложением
dval + fval + ival;

В том случае, если нет операндов типа double и long double, но есть операнд float, тип остальных операндов меняется на float:

char cvat;

int ival;

float fval;

 

// iva1 и cval преобразуются к float перед сложением
cvat + fval + ival;

Если у нас нет вещественных операндов , значит, все они представляют собой целые типы. Прежде чем определить тип результата, производится преобразование, называемое приведением к целому: все операнды с типом меньше, чем int, заменяются на int.
При приведении к целому типы char, signed char, unsigned char и short int преобразуются в int. Тип unsigned short int трансформируется в int, если этот тип достаточен для представления всего диапазона значений unsigned short int (обычно это происходит в системах, отводящих полслова под short и целое слово под int), в противном случае unsigned short int заменяется на unsigned int.
Тип wchar_t и перечисления приводятся к наименьшему целому типу, способному представить все их значения. Например, в перечислении

enum status { bad, ok };

значения элементов равны 0 и 1. Оба эти значения могут быть представлены типом char, значит char и станет типом внутреннего представления данного перечисления. Приведение к целому преобразует char в int.
В следующем выражении

char cval;

bool found;

enum mumble { ml, m2, m3 } mval;

unsigned long ulong;

cval + ulong; ulong + found; mval + ulong;

перед определением типа результата cval, found и mval преобразуются в int.
После приведения к целому сравниваются получившиеся типы операндов. Если один из них имеет тип unsigned long, то остальные будут того же типа. В нашем примере все три объекта, прибавляемые к ulong, приводятся к типу unsigned long.
Если в выражении нет объектов unsigned long, но есть объекты типа long, тип остальных операндов меняется на long. Например:

char cval;

long lval;

// cval и 1024 преобразуются в long перед сложением
cval + 1024 + lval;

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

6.

7.

8.

9. Оператор «запятая»

Оператор «запятая» используется для связки нескольких выражений. Левая сторона оператора «запятая» всегда вычисляется как void (то есть не выдающее значения). Это означает, что значение выражения, находящегося с правой стороны, станет значением разделенного запятыми выражения. Например: х = (у = 3, у + 1);

Сначала присваивается 3 переменной у, а затем 4. переменной х. Скобки необходимы, поскольку оператор «запятая» имеет более низкий приоритет по сравнению с оператором присваивания.

Оператор «запятая» вызывает выполнение последовательности действий. Когда он используется с правой стороны оператора присваивания, то присваиваться будет значение последнего выражения, стоящего в разделенном запятыми списке. Ниже приведен еще один пример: у = 10;

х = (у = у - 5, 25 / у);

После выполнения х получит значение 5, поскольку исходным значением у было 10, а затем оно уменьшилось на 5. Затем 25 поделили на полученное 5 и получили результат.

Об операторе «запятая» следует думать как об обычном слове «и» в нормальном русском языке, когда оно используется в выражении «сделай это, и это, и это».

10. Префиксная и постфиксная формы. Инкремент. Операция, которую мы сейчас рассмотрим, является более специфичной, нежели предыдущие. При программировании нам часто приходится иметь дело с увеличением какой-либо величины на единицу. Это можно сделать «в лоб», используя оператор а = а+1;//увеличение переменной а на 1 или с помощью сложения с присваиванием: а += 1; //увеличение переменной а на 1 Но есть еще один, более сжатый, чем предыдущие, способ: ++а; //увеличение переменной а на 1. Операция ++ инкрементирует, или увеличивает на 1, свой операнд.

Знак операции инкремента может быть записан двояко: в префиксной форме, когда он расположен перед своим операндом, и в постфиксной форме, когда операнд записан перед знаком ++. В чем разница? Часто инкрементирование переменной производится совместно с другими операциями над ней: в = с*++а;

Возникает вопрос — что выполняется раньше: инкрементирование или умножение? В данном случае первым выполняется инкрементирование. Каким образом это определить? Префиксная форма записи и означает то, что инкремент будет выполнен первым. Если бы использовалась постфиксная форма, то сначала бы выполнилось умножение, а затем переменная «а» была бы увеличена на 1.Операция декремента, обозначаемая --, в отличие от операции инкремента, уменьшает,а не увеличивает, на единицу свой операнд. Декремент также допускает префиксную и постфиксную формы записи.

Простые типы данных.

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

Любая константа, переменная, выражение или функция относятся к некоторому типу. Тип данных определяет диапазон допустимых значений и операций, которые могут быть применены к этим значениям. Кроме того, тип данных задает формат представления объектов в памяти компьютера, ведь в конце концов любые данные будут представлены в виде последовательности двоичных цифр (нулей и единиц). Тип данных указывает, каким образом следует интерпретировать эту информацию. Тип любой величины может быть установлен при ее описании, а в некоторых языках может выводиться компилятором по ее виду (Fortran, Basic).

2. Классификация типов данных

Любые данные могут быть отнесены к одному из двух типов: простому (основному), форма представления которого определяется архитектурой ЭВМ, или сложному, конструируемому пользователем для решения конкретных задач. Данные простого типа — это символы, числа и т.п. элементы, дальнейшее дробление которых не имеет смысла. Из таких элементарных данных формируются структуры (сложные типы) данных.

Принято различать следующие типы данных:· Простые.• Числовые типы.§ Целочисленные.§ Вещественные.• Символьный тип.• Логический тип.• Перечислимый тип.◊ Множество.◊ Указатель.· Составные.◊ Массив.• Строковый тип.◊ Запись.◊ Последовательность.

3 и 4. Простые типы

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

Целочисленные типы данных делятся, в свою очередь, на знаковые и беззнаковые. Целочисленные со знаком могут принимать как положительные, так и отрицательные значения, а беззнаковые — только неотрицательные значения. Диапазон значений при этом определяется количеством разрядов, отводимых на представление конкретного типа в памяти компьютера (см. “Представление чисел”).

Вещественные типы бывают: с фиксированной точкой, то есть хранятся знак и цифры целой и дробной частей (в настоящее время в языках программирования реализуются редко), и с плавающей точкой, то есть число приводится к виду m х 2e, где m — мантисса, а e — порядок числа, причем 1/2 m 1, e — целое число. В данном случае хранятся знак, число e и двоичные цифры дробной части числа m, которые умещаются в отведенную для этого память. Говорят, что вещественные числа представимы с некоторой точностью.

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

Логический тип. Данные этого типа имеют два значения: истина (true) и ложь (false). К ним могут применяться логические операции. Используется в условных выражениях, операторах ветвления и циклах. В некоторых языках, например С, является подтипом числового типа, при этом ложь = 0, истина = 1 (или истинным считается любое значение, отличное от нуля).

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

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

Указатель (тип данных). Если описанные выше типы данных представляли какие-либо объекты реального мира, то указатели представляют объекты компьютерного мира, то есть являются исключительно компьютерными терминами. Переменная-указатель хранит адрес в памяти компьютера, указывающий на какую-либо информацию, как правило — на другую переменную.

Составные типы

Составные типы формируются на основе комбинаций простых типов.

Массив является индексированным набором элементов одного типа, простого или составного (см. “Операции с массивами”). Одномерный массив предназначен для компьютерной реализации такой структуры, как вектор, двухмерный массив — таблицы.

Строковый тип. Хранит строку символов. Вообще говоря, может рассматриваться как массив символов, но иногда рассматривается в качестве простого типа. Часто используется для хранения фамилий людей, названий предметов и т.п. К элементам этого типа может применяться операция конкатенации (сложения) строк. Обычно реализованы также операции сравнения над строками, в том числе операции “<” и “>”, которые интерпретируются как сравнение строк согласно алфавитному порядку (алфавитом здесь является набор символов соответствующей кодовой таблицы). Во многих языках реализованы и специальные операции над строками: поиск заданного символа (подстроки), вставка символа, удаление символа, замена символа.

Запись. Наиболее общий метод получения составных типов из простых заключается в объединении элементов произвольных типов. Причем сами эти элементы могут быть, в свою очередь, составными. Так, человек описывается с помощью нескольких различных характеристик, таких, как имя, фамилия, дата рождения, пол, и т.д. Записью (в языке С — структурой) называется набор различных элементов (полей записи), хранимый как единое целое. При этом возможен доступ к отдельным полям записи. К полю записи применимы те же операции, что и к базовому типу, к которому это поле относится (тип каждого поля указывается при описании записи).

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

5 . На данном уроке мы поговорим о преобразовании типов данных в процессе работы программы из одного типа в другой.

Конечно, в идеальном случае, желательно, чтобы программа была построена таким образом чтобы лишний раз избегать всякого рода преобразований и использовать везде данные нужного типа. Но не всегда так получается и преобразование типа в ряде случаев просто необходимо. Например, мы складываем значения двух переменных типа unsigned short и, по идее у нас результат тоже должен присваиваться переменной типа unsigned short. Но мы не уверены в том, что этот результат уместится в такой тип, например, мы захотим сложить числа 65535 и 65534. Поэтому здесь без преобразования не обойтись. И таких ситуаций огромное множество, поэтому мы должны знать как происходит преобразование типов автоматически, а также как мы можем этим процессом управлять. Думаю, данный урок даст хоть и не полную картину преобразований типов, но, тем не менее, внесёт некоторую ясность в данную тему.

Для начала давайте начнём с автоматического преобразования типов, или, если это правильно назвать, с неявного приведения типов. В данном случае преобразованием типов будет управлять компилятор и мы никаких специальных операций для данного преобразования не применяем.

Если операнды некоторой операции принадлежат различным типам, то они автоматически приводятся к определённому общему типу. А к какому именно, существует ряд правил.

Также надо учесть, что автоматические преобразования типов имеют место лишь в тех случаях, когда они не влекут потери данных и при этом превращают операнды с меньшим диапазоном значений в операнды с большим диапазоном. Например, если мы складываем операнд целого типа с операндом с плавающей точкой, то первый автоматически приведётся к типу с плавающей точкой. Или, если мы складываем операнд типа int с оператором типа short, то второй автоматически превратится в число типа int, так как у него больший диапазон значений. Тем самым достигается принцип целостности информации. Если же результат наших операций мы попытаемся присвоить переменной такого типа, у которого меньший диапазон значений, то мы рискуем потерять часть информации, хотя при этом код все равно соберётся и мы получим лишь предупреждение.

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

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

 

· long double

· double;

· float;

· unsigned long long;

· long long;

· unsigned long;

· long;

· unsigned int;

· int

 

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

В операциях присваивания также может происходить неявное преобразование типов данных.

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

Может быть и наоборот, если мы хотим значение 4-байтового типа присвоить переменной 8-байтового типа. Также произойдёт неявное преобразование и, наоборот, 4 старших байта добавятся и заполнятся нулями. Это будет уже безопасное приведение типа и при этом целостность информации не страдает.

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

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

Явное преобразование типов происходит тогда, когда мы применяем специальные механизмы для приведения одного типа к строго определённому другому типу. В языке C в для явного приведения типа перед переменной или выражением, значения которых мы преобразуем к другому типу, ставится в круглых скобках тип, к которому мы данное значение преобразуем, например

 

int i;

char c = 45;

i = (int)c;

 

В данном случае значение переменной c явно преобразовывается к типу данных int, а затем уже в преобразованном виде присваивается переменной i.

Оператор sizeof

Оператор sizeof возвращает размер в байтах объекта или типа данных. Синтаксис его таков:

sizeof ( type name );

sizeof ( object );

sizeof object;

Результат имеет специальный тип size_t, который определен как typedef в заголовочном файле cstddef. Вот пример использования обеих форм оператора sizeof:

#include cstddef

int ia[] = { 0, 1, 2 };

// sizeof возвращает размер всего массива

size_t array_size = sizeof ia;

// sizeof возвращает размер типа int

size_t element_size = array_size / sizeof( int );

Применение sizeof к массиву дает количество байтов, занимаемых массивом, а не количество его элементов и не размер в байтах каждого из них. Так, например, в системах, где int хранится в 4 байтах, значением array_size будет 12. Применение sizeof к указателю дает размер самого указателя, а не объекта, на который он указывает:

int *pi = new int[ 3 ];

size_t pointer_size = sizeof ( pi );

Здесь значением pointer_size будет память под указатель в байтах (4 в 32-битных системах), а не массива ia.

Вот пример программы, использующей оператор sizeof:

#include string

#include iostream

#include cstddef

int main() {

size_t ia;

ia = sizeof( ia ); // правильно

ia = sizeof ia; // правильно

// ia = sizeof int; // ошибка

ia = sizeof( int ); // правильно

int *pi = new int[ 12 ];

cout "pi: " sizeof( pi )

" *pi: " sizeof( pi )

endl;

// sizeof строки не зависит от

// ее реальной длины

string stl( "foobar" );

string st2( "a mighty oak" );

string *ps = stl;

cout " st1: " sizeof( st1 )

" st2: " sizeof( st2 )

" ps: sizeof( ps )

" *ps: " sizeof( *ps )

endl;

cout "short : " sizeof(short) endl;

cout "shorf" : " sizeof(short*) endl;

cout "short : " sizeof(short) endl;

cout "short[3] : " sizeof(short[3]) endl;

}

Результатом работы программы будет:

pi: 4 *pi: 4

st1: 12 st2: 12 ps: 4 *ps:12

short : 2

short* : 4

short : 2

short[3] : 6

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

Гарантируется, что в любой реализации С++ размер типа char равен 1.

// char_size == 1

size_t char_size = sizeof( char );

Значение оператора sizeof вычисляется во время компиляции и считается константой. Оно может быть использовано везде, где требуется константное значение, в том числе в качестве размера встроенного массива. Например:

// правильно: константное выражение

int array[ sizeof( some_type_T )];

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

<climits> (limit.h) определяет размеры целочисленных типов.
Этот заголовок определяет константы с ограничениями фундаментальных целочисленных типов для конкретной используемой системы и используемой реализации компилятора.

8. Заголовок float описывает характеристики типа данных с плавающей точкой для конкретной системы и компилятора. Значение с плавающей точкой (вещественное число) состоит из четырех элементов:

  • знак: либо отрицательный, либо положительный;
  • основание: выражает количество значений, для кодирования чисел, которые могут быть представлены одной цифрой (2 для двоичной, 10 для десятичной, 16 для шестнадцатеричной, и т. д. )
  • мантисса: значение, стоящее перед основанием. Количество цифр в этом значении определяет точность.
  • степень: значение в которое возводится основание следующим образом:

вещественное значение = мантисса * основаниестепень, с соответствующим знаком.

Ниже, в таблице показаны названия различных макросов, определенных в этом заголовочном файле, и их минимальные величины. Любая конкретная реализация может иметь значения характеристик больших, чем показано здесь:

За исключением FLT_RADIX, имена которых начинаются с FLT относятся к типу данных с плавающей точкой, DBL - double и LDBL - long double.

Имя Значение Описание
FLT_RADIX 2 Основание для всех типов данных с плавающей точкой (long double, double, float и ).
FLT_MANT_DIG (float) DBL_MANT_DIG (double) LDBL_MANT_DIG (long double) 24 53 64 Количество цифр мантиссы, соответственно для указанных типов данных.
FLT_DIG (float) DBL_DIG (double) LDBL_DIG (long double) 6 15 18 Количество десятичных цифр, которые могут быть округлены в число с плавающей точкой и обратно, без потери данных.
FLT_MIN_EXP (float) DBL_MIN_EXP (double) LDBL_MIN_EXP (long double) -125 -1021 -16381 Минимальное отрицательное целое значение для степени, которое генерирует нормализованное число с плавающей точкой (запятой).
FLT_MIN_10_EXP (float) DBL_MIN_10_EXP (double) LDBL_MIN_10_EXP (long double) -37 -307 -4931 Минимальное отрицательное целое значение степени основания 10 выражение, которое будет генерировать нормализованное число с плавающей точкой (запятой).
FLT_MAX_EXP (float) DBL_MAX_EXP (double) LDBL_MAX_EXP (long double) 128 1024 16384 Максимальное целое значение для степени в нормализованной форме представления числа с плавающей точкой (запятой).
FLT_MAX_10_EXP (float) DBL_MAX_10_EXP (double) LDBL_MAX_10_EXP (long double) 383084932 Максимальное целое значение для степени с основанием 10 в нормализованной форме представления числа с плавающей точкой (запятой).
FLT_MAX (float) DBL_MAX (double) LDBL_MAX (long double) 3.40282e+38 1.79769e+308 1.18973e+4932 Максимальные значения чисел с плавающей точкой (запятой).
FLT_EPSILON (float) DBL_EPSILON (double) LDBL_EPSILON (long double) 1.19209e-07 2.22045e-16 1.0842e-19 Разница между 1 и минимальным значением, большим единицы, которое может быть представлено указанными типами данных.
FLT_MIN (float) DBL_MIN (double) LDBL_MIN (long double) 1.17549e-38 2.22507e-308 3.3621e-4932 Минимальные значения чисел с плавающей точкой (запятой)

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

 

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

 

функции классификации символов ;

функции преобразования символов.

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

 

tolower -    Преобразование заглавного символа в строчный.

toupper       -     Преобразование строчного символа в заглавный.

13 и 14.

15. Целочисленные литералы выражаются в двух типах, т.е.

  1. Префиксы, которые указывают на базу. Например, 0x10 указывает значение 16 в шестнадцатеричном формате с префиксом 0x .
  2. Суффиксы, которые указывают на тип. Например, 12345678901234LL указывает значение 12345678901234 как длинное длинное целое число с суффиксом LL .

Синтаксис

  • Префиксы: в основном они представлены в четырех типах.
    1. Десятичный литерал (основание 10) : — ненулевая десятичная цифра, за которой следуют ноль или более десятичных цифр (0, 1, 2, 3, 4, 5, 6, 7, 8, 9). Например, 56, 78 .
    2. Восьмерично-буквальное (основание 8) : — ноль, за которым следует ноль или более восьмеричных цифр (0, 1, 2, 3, 4, 5, 6, 7). Например, 045, 076, 06210 .
    3. Шестнадцатеричный литерал (основание 16) : — 0x или 0X, за которым следуют одна или несколько шестнадцатеричных цифр (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C, D, D, E, E, F, F). Например, 0x23A, 0Xb4C, 0xFEA .
    4. Двоично-буквенный (основание 2) : — 0b или 0B, за которыми следуют одна или несколько двоичных цифр (0, 1). Например, 0b101, 0B111 .
  • Суффиксы: они представлены многими способами в соответствии с их типами данных.
    1. int : — Суффикс не требуется, поскольку целочисленная константа по умолчанию назначается типом данных int.
    2. unsigned int : символ u или U в конце целочисленной константы.
    3. long int : символ l или L в конце целочисленной константы.
    4. unsigned long int : символ ul или UL в конце целочисленной константы.
    5. long long int : символ ll или LL в конце целочисленной константы.
    6. unsigned long long int : символ ULL или ULL в конце целочисленной константы.
// C ++ программа для демонстрации использования // целочисленный литерал #include <iostream> using namespace std; int main() { // ПРЕФИКСЫ cout << 213 << '\n' // десятичное целое литерал << 0213 << '\n' // Восьмеричное целое число << 0x213A << '\n' // шестнадцатеричный целочисленный литерал << 0b101 << '\n' // двоичный целочисленный литерал // СУФФИКСЫ // длинный длинный литерал << 1234567890123456789LL << '\n' // без знака длинный длинный литерал << 12345678901234567890ull << '\n' // автоматическое преобразование unsigned long long even // без длинного длинного префикса << 12345678901234567890u; return 0; }

Output:213

139

8506

5

1234567890123456789

12345678901234567890

12345678901234567890

1221300

Составные типы данных.

1.

2.

3 и 4.

5. Массив — это набор однотипных данных. Например, вы можете хранить все носки в одном месте. Для этого вы используете полку. В C++ множество элементов хранятся в массивах.

Для лучшего понимания давайте рассмотрим следующею картинку:

По ней мы можем понять следующее:

· Каждый массив должен иметь свое название.

· Он может в себе содержать от одного элемента до бесконечности (это в теории, на практике размер массива ограничивается памятью компьютера).

· Все элементы должны быть одного типа. Так, например, вы не можете в одном массиве хранить переменные типа int и типа double.

Пользовательские типы данных.

1.

3.

4.

5.


Дата добавления: 2021-07-19; просмотров: 182; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!