40958

Концепция типов данных

Лекция

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

C поддерживают концепцию соглашение типов данных которая включает следующие договорённости: каждая переменная константа выражение функция относятся к некоторому типу; тип объекта либо определяется по внешнему виду либо задаётся специальным описанием; тип Т определяет множество значений допустимых для данных этого типа множество допустимых операций множество функций определённых для данных этого типа Т. Тип Т = {DomT OPT FunT} { некоторая область памяти её размер способ представления...

Русский

2013-10-22

121.5 KB

4 чел.

Лекция 4 (проектор)

3.Концепция типов данных.  

С/C++ поддерживают концепцию (соглашение) типов данных, которая включает следующие договорённости:

  1.  каждая переменная, константа, выражение, функция относятся к некоторому типу;
  2.  тип объекта либо определяется по внешнему виду, либо задаётся специальным описанием;
  3.  тип Т определяет множество значений, допустимых для данных этого типа, множество допустимых операций, множество функций, определённых для данных этого типа Т.

Тип Т = {Dom(T), OP(T), Fun(T)}+

             { некоторая область памяти, её размер, способ представления    (формат) значения ,способ обработки данных этого типа}   (реализация типа)

~ЗАЧЕМ НУЖЕН ТИП?

Описание типа позволяет транслятору проверять допустимость написанных в программе конструкций, а также от типа зависят и машинные команды, которые транслятор использует для описания действий.

Все типы можно поделить на

=основные (стандартные), они определены в языке и являются простыми типами, т.е. значение этого типа есть скалярная величина;

=составные, которые программист может строить сам, на основе стандартных типов, а также ранее определённых составных.

Основные стандартные  типы данных C++.

Целый (int), символьный (char), логический (bool) и вещественный (float, double, long double).

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

Типы int, char, bool , float, double, long double  в С++  называют арифметическими, т.к. данные этих типов можно использовать в арифметических выражениях.

int, char, bool называют в С++ целыми, а float, double, long double – вещественными. Внутренние представления данных вещественных типов отличаются от представления целых.

Есть ещё спецификаторы типа, которые уточняют размер памяти и внутреннее представление (а значит и диапазон значений):

short – короткий;   signed  -  знаковый;

long  - длинный;    unsigned  -  беззнаковый;

Целый тип:

Имя типа              Размер(байт)                 Диапазон значений

int                           4(32разр.МП)                  -2147483648 ÷ 2147483647   

int                           2(16разр.МП)

short int                   2                                     -32768 ÷ 32767

long int                    4                                     -2147483648 ÷ 2147483647

Все целые типы по умолчанию знаковые (signed м.б. опущены), для беззнаковых (не хранится знак, подразумевается +) необходимо указывать unsigned.

unsigned short int          2              0 ÷ 65535

unsigned long  int          4              0 ÷  4294967295

unsigned int                   4               0 ÷  4294967295

Возможные сокращенные записи имён типов:

short int  ≈  short

long int   ≈     long

signed int  ≈  signed

Мы уже говорили, что размер переменных типа  int является аппаратно-зависимым.  Переменные типов long и short, напротив, имеют фиксированный размер, не зависящий от используемой системы. Размер типа long всегда равен 4 байтам и совпадает с размером типа int в  случае 32-разрядных систем, подобных Windows. Тип short в любой операционной системе имеет размер, равный двум байтам.

Многие компиляторы позволяют определять целые типы с указанием нужной разрядности (в битах). Имена таких типов начинаются с двойного символа подчеркивания:__ int8,__ intl6, __int32, __int64. Тип__ int8 соответствует типу  char, типы __intl6 и __int32 — соответственно типу short и паре типов int и long (справедливо как минимум для 32-разрядных систем).  Тип__ int64 используется для хранения больших целых чисел разрядностью до 19 десятичных знаков

#include <iostream>  //pr1

using namespace std;

const int n=100;

int main()

{int i;

__int32 k=1;

__int64 m;

double a[n];

m=k+2;

cout<<"m="<<sizeof (m)<<"k="<<sizeof (k)<<endl;//m=8 k=4

return 0;}

Операции для целого типа(в порядке убывания приоритета после ;):

OP(целый)={+оо ;  * / % ;  + - ;  <<  >> ;  <  <=  >=  > ; ==   != }

Функции для целого типа:     #include<cstdlib>    

Fun(целый)={abs(x), rand(), srand(a)}

      rand()-генерирует случайное число 0 ÷ RAND_MAX   .(32767)

     srand(a)- устанавливает начальное псевдослучайное число.

Константы целого типа– последовательность цифр, константа десятичная, если цифры десятичные тип константы – тип с наименьшим диапазоном ,включающим эту константу. Для указания типа константы можно записывать её с суффиксами L,l и U,u: 127Lu - константа типа long беззнаковая.

Восьмеричная  константа.  За нулем следуют восьмеричные цифры: 043, 0175.

Шестнадцатеричная константа.  За  0x или 0X следуют шестнадцатеричные  цифры:  0xA,  0X1B7, 0X00FF.

Вещественный тип

Стандарт С++ определяет три вещественных типа данных:

 float                 4 байта                   1.17*10-38 <|x|<3.4*10+38 ; x=0

 double             8 байтов                  2.2*10-308 <|x|<1.7*10+308 ; x=0

 long double     10 байтов                3.4*10-4932 <|x|<1.19*10+4932 ; x=0

Операции для вещественного  типа:  

OP(вещественный)={+оо ; * / ; + - ; <  <=  >=  >  ;== != }

Функции для вещественного типа:      #include<cmath>  

Fun(вещественный)={fabs(x), sin(x), cos(x), log(x), log10(x), exp(x), pow(a,b), tan(x), atan(x), asin(x), acos(x), sqrt(x)}

Константы вещественного типа

например,  естественный вид:     [xxxx].[xx..xx],  136.25,  136. , .25

Константа с порядком: :     [xxxx][.][xx..xx] [{E/e}  [{+/-}]xx],  

например  .15е1  , 3Е5 , 1.25Е-3  это константы  0.15*101 ,3*105 ,1.25*10-3 

По умолчанию у вещественной константы тип double, можно явно указать тип  с помощью суффиксов  F,f (для float),  L,l(для long double).

Логический тип: bool

Множество значений логического типа  {false, true}(эти слова зарезервированы как константы  логического типа),  false представляется значением 0, любое другое значение интерпретируется как  true, если true преобразуется к целому типу, оно имеет значение 1. Переменные логического типа чаще всего используются для хранения результатов сравнения или некоторого условия.

Операции для логического   типа:

Op (bool )={ !  ; <  <=  >=  >;  ==   != ; && ; || }

Функции для логического типа:  Fun (bool)= ø (нет стандартных) 

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

Возможны типы

Signed char (≈ char)      1байт          -128 ÷ 127

Unsigned char               1байт            0 ÷ 255

Множество значений типа  char – множество символов ASCII, каждый символ в байте представлен своим кодом (0 ÷ 255),

  •  часть символов (с кодами 0÷31)является управляющими , они не имеют графического изображения,
  •  символы с кодами 32÷127 имеют фиксированное графическое написание ,
  •  наборы символов с кодами 128÷255 отличаются для разных операционных систем , платформ и часто не содержат русских букв.

Коды цифр 0….9 упорядочены по возрастанию и идут без пропусков. Коды больших латинских букв упорядочены по алфавиту и идут без пропусков. То же самое верно и для малых латинских букв.

Операции для символьного   типа:   -те же, что и для целого типа 

 (в операциях отношения сравниваются коды символов)

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

#include <cctype>  //подключение функций классификации и преобразования    //символов

isalnum (int ch)-проверка является ли символ буквой или цифрой.

isalpha (int ch)-проверка является ли символ буквой .

isdigit (int ch)-проверка является ли символ цифрой.

iscntrl (int ch)-проверка является ли символ управляющим.

Константы символьного типа

Символьные константы записываются в одиночных кавычках: 'А',’+' и т. д. (это символы, имеющие графическое изображение).

Управляющие символы не  имеют графического написания  и изображаются '\ символ', говорят в виде управляющей последовательности, это означает, что символ \ «управляет»  интерпретацией следующих за ним символов последовательности. Так, ‘\t’  воспринимается не как символ 't', а как символ табуляции.  (Символ табуляции означает, что весь поток вывода будет условно разделен на фрагменты одинаковой длины, определяемой шагом табуляции, и следующий символ будет напечатан в начале  следующего фрагмента, а не сразу за предыдущим символом. В консольных программах шаг табуляции равен восьми позициям.)  Символьная константа '\п' означает перевод курсора в начало следующей строки. Управляющие символы могут использоваться и в составе строк.

Символ обратной косой черты  используется  для представления символов     ’   ” \ ? :   ‘\’’,   ‘\\’,   ‘\”’ , ‘\?’.

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

Структура описания функции:  

Заголовок_функции  { тело функции  }

int   main()  

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

Программа содержит:

<Директивы препроцессора>

<описания>

< описание функции>

…….

< описание функции>

Функции не могут быть вложенными. Одна из функций обязательно есть функция main(). Программа может состоять из одного текстового файла (его наз. исходный модуль) или из нескольких исходных модулей.  

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

Объявление и определение переменной

До первого использования  переменной, её обязательно надо объявить (описать). Объявления переменных могут располагаться в любом месте  программы. Не обязательно делать все объявления переменных до появления первого исполняемого оператора, как это было принято в С. Тем не менее, объявления наиболее часто употребляемых переменных целесообразно производить в  начале программы, чтобы обеспечить ее удобочитаемость.

Объявление переменной предполагает указание имени переменной  и ее типа (в простейшем случае):   

имя_типа  имя_переменной [инициализатор];

Возможно указание  нескольких имён:

 тип  имя [,имя …];

Например:  

int a,b;

float x, y, s;

При описании  можно присвоить переменной начальное значение, говорят инициализировать её, есть 2 способа сделать это:

 short  k,I=1;    // тип  имя =значение ;

 int  x(10);      // тип  имя (значение);

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

const int   N=100;   

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

Описание переменной  определяет её область действия – часть программы, где её можно использовать для доступа к выделенной ей области памяти. Если переменная определена в блоке  (внутри{  }) , то она говорят явл. локальной и область её действия от места описания и до конца блока. Если переменная определена вне любого блока, она наз. глобальной, область её действия – весь файл, где она описана.

Есть  разница  между терминами   объявление переменной и определение переменной.

Если при объявлении переменной  одновременно выделяется память под нее, то происходит определение переменной. Предложения – объявления  переменных, описанные выше,  являются и объявлениями, и определениями.

 Выражение языковая конструкция, которая задаёт правило для вычисления значения. Тип этого значения – тип выражения. Выражение содержит операнды , знаки операции и круглые скобки. Операнды: переменные,  константы, функции (вызовы функций) и выражения , заключённые в круглые скобки. В языке определены приоритеты операций. (см. список операций с их приоритетами). Записываются  выражения в строку, без опущенных и приподнятых символов.  a/(b+c)

При вычислении  выражения операции выполняются в соответствии с их приоритетами.Чтобы изменить этот порядок, используют круглые скобки.  Последовательные операции одного приоритета выполняются так: унарные, условная операция(тернарная) и операции присваивания справа налево, остальные слева направо.т.е.       a+b+c-d ≈ (((a+b)+c)-d) а x=y=z  ≈ x=(y=z).

Порядок вычисления подвыражений внутри  выражений не определён: (sin(x+1)+cos(y-2)), какое слагаемое будет считаться раньше –неясно.

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

int x;

float z;   // В выражении x+z  x преобразуется к типу float.

Правила преобразования обеспечивают преобразование более коротких типов в более длинные (чтобы обеспечить сохранение значимости и точности). Все типы выстраиваются в иерархическую цепочку:

Int < unsigned int < long < unsigned long < float < double < long double

Операнды типов char, unsigned char,short int, unsigned short int преобразуются к типу int.

Часто бывает необходимо значение одного типа преобразовать в значение другого типа. Есть два способа записи явного преобразования типа:

== традиционная в С запись приведения к типу, например (double)a. Это унарная операция.

==функциональная запись double(a), она не применима к типам , у которых нет простого имени.

char * p= (char *)0777;

Или          Typedef char * Pchar;

                char * p= Pchar(0777);

Некоторые особенности выражений в С++:

1)Присваивание является операцией выражения, у неё самый низкий приоритет (кроме ,). Простое присваивание:

операнд1 =операнд2;  означает, что значение операнд2 получает и операнд1, который размещается слева и называется L-value (L-значение),т.е.то, чему можно присвоить значение.

Присваивание  может быть и внутри выражения, но так,чтобы левый операнд был L-value, например,  a+b*(c=2), но выражение a+c=3-b является ошибочным (a+с не явл. L-value).

В языке С++ есть сложное присваивание  += ,-=, *=, /=, %=, <<=, >>= и др. При выполнении операции в правой части используется  и L-значение из левой части: оператор a+=b; означает  a=a+b;

 n%=b/10; эквивалентно           n=n % (b/10);

2)Операция определения  размера sizeof имеет две формы и применяется  для вычисления размера в  байтах некоторого объекта или типа:

a) sizeof  выражение    //  cout << sizeof (x+1.0);   (8)

b) sizeof (тип)         // cout << sizeof(float);      (4)

3)Операции инкремента (++)- увеличения на 1 и декремента (--) –уменьшения на 1 имеют две формы записи префиксную (++х или --х)  и постфиксную (х++ или х--). В префиксной операции сначала  изменяется операнд, а затем его новое значение используется в следующей операции, а в постфиксной  -  используется  исходное значение операнда, а после  он изменяется на 1. Операнд в операции всегда является L-значением. Пример:

int a,b,c;

a=2;  b=3;

c=a*b++ +a*a*b;  // c=2*3+2*2*3; а затем b становится равным 4.

4) Операции отношения сравнивают два операнда  арифметического типа(или указатели), результат логического типа true или false, причём приоритет операций сравнения на равенство или неравенство меньше приоритета остальных операций  отношения.

4) Логические операции И (&&)  и ИЛИ (||) выполняются над арифметическими операндами или указателями. Если операнды разных типов, то преобразования их не производится, каждый операнд оценивается  с точки зрения его эквивалентности нулю. Результат операции true или false. Если по значению первого опранда  можно определить результат операции, второй  операнд не вычисляется.

5)Условная операция (?:)или тернарная(три операнда).Её формат:

оп1 ? оп2: оп3  Результат операции :. оп1 сравнивается с нулём, если он равен true, результатом условной операции будет значение оп2, иначе – оп3. Например,

Int a,b,m;

m= (a<b) ? a : b;

6) операция  : xy= exp( ln(xy) )= exp(y*ln(x ))

остальные операции рассмотрим позже.

Основные управляющие  структуры С++.

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

Развилки:

Цикл «пока»:

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

Операторы С++.

1)Оператор ввода данных с клавиатуры.

Ввод данных с клавиатуры выполняется с помощью объекта cin, который определён в С++ для работы со стандартным потоком ввода. Этот поток содержит данные, вводимые с клавиатуры (если он не переопределён). Оператор ввода записывается так

cin >> <переменная>; Например, cin>>x;

Операция >> является операцией извлечения. Она извлекает данные из потокового объекта, стоящего   в левой части, и присваивает эти данные переменной в правой части. В конце оператора ставится ;. Вводить  можно последовательно значения нескольких переменных: cin >> a>>b>>c;  Значения их должны стоять во входном потоке в соответствующем порядке, набираются они в символьном виде по одному и за ним нажимается Enter ,либо одно за другим, разделяются пробелами и за последним значением   нажимается Enter (клавиша исполнения). Тип переменной в правой части операции >> определяет  интерпретации вводимых символов и то, куда будут записываться значения из входного потока.

Int k;

 cin>>k;// считывается целое значение в k

double x;

cin>>x; // считывается вещественное число удвоенной точности в x

2)Оператор вывода данных  на экран дисплея.

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

сout << <выражение>;

Можно вывести несколько значений        сout <<x<<y;

Операция << называется операцией вставки, она копирует значение выражения в  правой части в объект сout. Операция << и объект cout знают, каким образом отличать целое число от строки и как обрабатывать каждое из них. Если мы выводим на печать целое число, то оно отображается в числовом формате. Если мы печатаем строку, то она выводится в виде текста. Это кажется очевидным, но за этими действиями стоит механизм перегрузки операций, типичный для C++.  Например,

сout<<”vvedite a,b,c\n”;//это вывод строки-подсказки для ввода. cin>>a>>b>>c;  //\n обеспечит перевод курсора на                                                                                                                                                               //  экране в начало следующей строки.

3)Оператор присваивания.

<переменная> = <выражение>;

=сначала вычисляется значение выражения в правой части;      

=если тип значения выражения не совпадает с типом переменной в левой части, то это значение преобразуется к типу переменной;  

=значение выражения присваивается переменной, т.е. записывается в память, отведённую для переменной.

В С++ любое выражение с ; в конце рассматривается как оператор. Выполнение его – вычисление значения.

i++;                a*=b+c;

4)Составной оператор. Блок.

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

{оператор;  оператор;…. оператор;}

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

5)Пустой  оператор, т.е. пусто; – иногда полезен, чтобы соответствовать синтаксису.

Разветвляющиеся алгоритмы. – алгоритмы, в которых в зависимости от некоторого условия выполняется один из предусмотренных вариантов действий. Для описания таких алгоритмов в языке предусмотрены операторы if, goto, switch.

6)Условный оператор. Переключатель.Оператор перехода.

Условный оператор:

if (выражение) оператор1; else  оператор2 ;

Если значение выражения истинное, выполняется оператор1, иначе оператор2.,а затем оператор , стоящий за if,т.е.if задаёт альтернативу: выполнить оператор1 или оператор2, это полный if.

Возможен и короткий: if (выражение) оператор1 ; он задаёт альтернативу: выполнить или нет оператор1.Если на месте оператора1 или оператора2 нужно поставить группу операторов, их заключают в фигурные скобки и синтаксически группа становится одним оператором.

 if (выражение) { оператор; … оператор;}; еlse { оператор;… оператор; };

Если вместо оператора1 стоит условный оператор, то необходимо разрешить возникающую иногда коллизию; для этого есть правило: else всегда относится к ближайшему if.

If (a>b) if (x>c)m=0; else m=1;

Возможны 2 толкования этого оператора:

If (a>b) if (x>c)m=0; else m=1;  (1) – по правилу это работает.

If (a>b) if (x>c)m=0; else m=1;   (2)

Если нужен (2), можно If (a>b) { if (x>c)m=0; } else m=1;

Примеры.

Int a,b,m;

a)if (a>b) m=a; else m=b;

b)m=a; if (b>m) m=b;

c)m=(a+b)/2 + fabs(a-b)/2;

Все три примера решают такую задачу m=max(a,b); ,

но вариант a) более наглядный.

Переключатель реализует развилку на несколько направлений.

Общий вид оператора:

Switch (выражение)

{Case константное_выражение1 :[оператор; … оператор;]

 Case константное_выражение2 :[оператор; … оператор;]

………………………………………………………………………………………Case константное_выражениеN :[оператор; … оператор;]

[default : оператор; … оператор;]

}

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

Switch передает управление тому из операторов, помеченных с помощью case, у которого значение константного выражения совпадает со значением селектора. Если же оно не совпадает ни с одним  из константных выражений, то управление получает оператор, помеченный меткой  default. Если нет группы default, то оператор Switch не выполнит ничего. Если выбран некоторый вариант и группа его операторов выполняется, последним в этой группе часто стоит оператор break, который выполняет выход из переключателя на оператор, следующий за ним. Если группа операторов варианта не заканчивается  оператором break  и никуда не передаёт управление, то выполняется группа операторов следующего варианта.

#include <iostream>

using namespace std;

int main()

{int n=10,c;

for(c=10;c<18;c++)

{switch  (c%n)

{case 0:cout <<"monday\n"; break;

case 1:cout <<"tusday\n"; break;

case 2:cout <<"wednesday\n"; break;

case 3:cout <<"thursday\n"; break;

case 4:cout <<"friday\n"; break;

case 5:cout <<"saturday\n"; break;

case 6:cout <<"sunday\n"; break;

default:cout <<"noday\n";

}} return 0; }

Замечание. Оператор break в составе другого оператора выполняет выход из этого другого оператора на оператор, следующий за ним.

Основные операции языка С++

(по убыванию приоритетов, в группе приоритеты одинаковые)

Олерация.

Действие

Унарные операции

++

--

Sizeof

!

-

+

&

*

new

delete

(тип)

Увеличение на 1

Уменьшение на 1

Размер

Поразрядное отрицание

Логическое  отрицание

Унарный минус (арифметическое отрицание)

Унарный плюс

Взятие адреса

Разыменование

Выделение  динамической  памяти

Освобождение динамической  памяти

Преобразование типа

Бинарные и тернарная операции

*

/

%

Умножение

Деление

Остаток от деления

+

-

сложение

вычитание

<<

>>

Сдвиг влево

Сдвиг вправо

<

<=

>

>=

Меньше

Меньше или равно

больше

Больше  или равно

==

!=

Равно

Не равно

&

Поразрядная конъюнкция (И)

^

Поразрядная исключающее ИЛИ

|

Поразрядная дизъюнкция (ИЛИ)

&&

Логическое И

||

Логическое ИЛИ

?  :

Условная операция (тернарная)

=

*=

/=

%=

+=

-=

<<=

>>=

&=

|=

^=

Присваивание

Умножение с присваиванием

Деление с присваиванием

Остаток  от деления с присваиванием

Сложение с присваиванием

Вычитание с присваиванием

Сдвиг влево с присваиванием

Сдвиг вправо с присваиванием

Поразрядное И с присваиванием

Поразрядное ИЛИ  с присваиванием

Поразрядное  исключающее ИЛИ  с присваиванием

,

Последовательное  вычисление


 

А также другие работы, которые могут Вас заинтересовать

77101. Единство и многообразие общественной жизни 110 KB
  Представление о мире как о замкнутой сфере перенесенное на развитие общества привело к идеям согласно которым общество развивается не бесконечно а в ограниченном круге повторяя уже пройденные в определенном ритме этапы Пифагор.
77104. Отбор кадров 25.56 KB
  Чтобы правильно определить критерии отбора, следует ясно сформулировать качества работника, необходимые для соответствующего вида деятельности. Критерии следует формировать так, чтобы они всесторонне характеризовали работника: опыт, здоровье и личностные характеристики