Структурные типы данных и переменные этих типов .- 


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



ЗНАЕТЕ ЛИ ВЫ?

Структурные типы данных и переменные этих типов .-



Структурные типы данных и переменные этих типов.-

Структурный тип – это тип созданный на основе компонентов базовых типов или ранее созданных структурных типов. При создании структурного типа его имя пишется после struct, а после имени в {} пишется список компонентов. Имена этих компонентов могут совпадать с именами обычных переменных, так как их можно различать по контексту. Имя структурного типа может и не задаваться при описании нового структурного типа. Описание структурного типа не резервирует память, память выделяется только при описании какой-либо переменной структурного типа. Доступ к отдельным компонентам структурного типа осуществляется при помощи конструкции имя переменной _ компонент.

Struct Kristina {

Int a;

Float b;

};

Struct Kristina obsch

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

Struct point a;

&a …. A=b; b…

B=a; a….

 

Передача структурных переменных функциям.-

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

Main ()

{struct vect screen;

Struct point middle;

Struct point makepoint (int,int);

Screen.pt1=makepoint(0,0);

Screen.pt2=makepoint(xMax,yMax);

Middle=makepoint((screen.pt1.x+screen.pt2.x);screen.pt1.y+screen.pt2.y)/2);

}

Struct point makepoint (int x, int y)

{struct point tmp;

Tmp.x=x;

Tmp.y=y;

Return tmp;}

Struct point addpoint (struct point p1,struct point p2)

{p1.x+=p2.x;

P1.y+=p2.y;

Return p1;}

Как правило при передачи структурных переменных функции используется передача по адресу. Наличие скобок необходима из-за того, что приоритет оператора «.» выше приоритета оператора «*», а запись без () неверна.

 

 

Указатели на структурные переменные.

При работе с указателем на переменную со структурным типом используют операцию «->». Операторы доступа к компонентам структурных переменных вместе с операторами вызова функции и обращение к элементам массивов занимают самое высокое положение в таблице приоритетов и выполняются раньше других операторов.

Struct {int len;

Char str;

}*p;

++p->len

В этом примере на единицу увеличится значение компонента len, а не указателя *p.

Массивы структурных переменных.

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

Struct key

{chfr *word;

Int count;

}keytab[100];

For (i=0;I<=100;i++)

Massiv[i].count++

Struct key *p;

For (p=keytab;p<keytab+99;p++)

If (p->count>0)

Printf(“%d %s\n”,p->count,p->word);

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

5 )Объединения (для экономии памяти)

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

Union {

Int klasha;

Float glasha;

Long double sasha;

}kreslo;

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

Понятие макроподстановки.

Понятие макроподстановки – имеет вид: #define_имя_заменяющий текст.

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

#define PI 3.14

Void main()

{printf (“%f\n”,PI);

}

Обычно заменяющий текст находится в строке, в которой расположено слово #define, но в длинных определениях его можно продолжить на следующих строчках, поставив в конце каждой продолжаемой строки «\»

#define matr for (i=1;i<=n;i++)\

For (j=1;j<=m;j++)

Область действия имени в макроподстановке простирается от данного определения, до конца файла. В определение макроподстановки могут фигурировать более ранние #define определения. Подстановка осуществляется только для тех имен, которые расположены вне текста, заключенных в «». Макроподстановку можно определить с аргументами, вследствие чего заменяющий текст будет варьироваться в зависимости от задаваемых параметров.

#define max(A,b) ((A>(B)?(A):(B))

Хотя обращение к max выглядит, как обычное к функции оно будет вызывать только текст значений каждый формальный параметр будет заменяться соответствующим аргументом. так строка x=max(a+b,c+d) будет заменена на строку x=((a+b)>(c+d)?(a+b):(c+d)).

То, что было в define можно скрыть от предпроцессора с помощью директивы undef_имя. Как правило это делается, чтобы перекрыть макроопределение настройки функции с этим именем.

#define vasia A

Void main ()

{int vasia;

#undef vasia

Vasia ()

}

Vasia (){….}

Включение файлов.

Директива #include предписывает компилятору поместить на ее место содержимое другого файла. Обычно эта директива применяется в так называемом включенном или заголовочном файле *.h. Однако существует возможность включить в текст программы любой другой исходный файл.

#include <имя файла> или #include “имя файла”. Если имя файла не является полным именем, то в первом случае поиск происходит только в пределах специфицированных каталогах включаемых файлов. При использовании кавычек сначала просматривается текущий каталог, а затем каталоги, включающих файлов.

 

Условная компиляция.

В Си существует возможность избирательно компилировать части файла в зависимости от значения некоторого константного выражения или идентификатора. Для этого существуют #if,#endif,#elif,#else.

#if (выражение 1)

Текст 1

#elif (выражение 2)

Текст 2

#else

Текст 3

#endif

Каждая из этих директив записывается на отдельной строке. Константные выражения в #if и последующий #elif вычисляются по порядку, пока не обнаружится выражение с ненулевым значением. Текст следуемый за строкой с ненулевым значением выбрасывается. Текст, расположенный за директивой с ненулевым значением обрабатывается обычным образом. Под словом текст имеется ввиду любая последовательность строк включая строки предпроцессора, которые не являются частью условия структуры. Если все выражения имеют ненулевые значения и есть строка #else, то следующий за ней текст обрабатывается.

#if SYSTEM==BCD

#include “bcd.h”

#elif SYSTEM==MSDOS

#include “msdos.h”

#else

#include “default.h”

#endif

 

 


10)Стандартные библиотеки <math.h> и <string.h>.


<math.h> (математические функции)

1)Синус

Double sin(double x)

A=sin(x)

2)Косинус

Double cos(double x)

3)Тангенс

Double tan(double x)

4)Арксинус

Double asin(double x)

5)Арккосинус

Double acos(double x)

6)Арктангенс

Double atan(double x)

7)

Double exp(double x)

8)Натуральный логарифм (x>0)

Double log(double x)

9)Десятичный логарифм

Double log10(double x)

10)Возведение в степень

Double pow(double x,double y)

11)

Double sqrt(double x)

12)Округление с избытком

Double ceil(double x)

13)Округление с недостатком

Double floor(double x)

14)Модуль для целых чисел |x|

Int abs(int x)

15)Модуль для вещественных чисел

Double fabs(double x)

16)Модуль для длинного целого

Long int labs(long int x)

 

<string.h>( функции обработки строк)

1)char *strcpy(char *s,const char *t)

Копирует строчку t в строчку s включая \0

2)char *strcat (char *s,const char *t)

Присоединяет строку t к строке s и возвращает s

3)char *strchr (const *s,int c)

Возвращает указатель на первое вхождение символа “c” в строку “s” или если такого нет, то возвращает NULL

4) char *strrchr(const char *s,int c)

Тоже самое, только на последний символ.

5)int strlen (const char *s)

Возвращает длину строки S, но без \0.

 


 

11) Стандартные библиотеки <ctype.h> и <stdlib.h>


<ctype.h> (функции проверки класса символов)

1)int isalpha (int c)

Возвращает не 0, то есть истину, если с-буква и 0 в противном случае.

2) int isupper (int c)


Возвращает не 0, если с-буква верхнего регистра и 0 в противном случае.

3) int islower (int c)

Возвращает не 0, если с-буква нижнего регистра и 0 в противном случае.

4) int isdigit (int c)

Возвращает не 0, если с-цифра и 0 в противном случае.

5) int isaalnum (int c)

Возвращает не 0, если с-буква или цифра и 0 в противном случае.

6) int isspace (int c)

Возвращает не 0, если с-пробел и 0 в противном случае.

7) int ispunct (int c)

Возвращает не 0, если с-печатаемый символ,кроме пробела, буквы или цифры.

8) int iscntrl (int c)

Возвращает не 0, если с-управляемый символ.

9) int tolower (int c)

Переводит с на нижний регистр, иначе не меняет.

10) int toupper (int c)

Переводит с на верхний регистр, иначе ничего не делает.

 

<stdlib.h>( функции общего назначения)

1)double afof(const char *s)

Переводит строку s в тип double. Рассматривает начальные символы до 1го не подходящего, а пробелы игнорирует. Пример – на входе ______3,78bsdfc на выходе будет 3,78

2)int afoi (const char *s)

Переводит строку s в тип int

3)long int afol(const char *s)

Переводит в long

4)int rand (coid)

Возвращает целое случайное число в диапазоне от 0 до max числа в данной реализации.


Произвольный доступ.

Организация произвольного доступа к компонентам файла позволяет считывать значения из любой позиции файла, а так же записывать новую информацию в любое место в файле. Все компоненты файлов с произвольным доступом должны иметь одинаковую длину. Для изменения места файла, откуда будет производиться операция чтения или записи служит функция fseek. Ее прототип содержится в файле <stdio.h>, а заголовок имеет вид: int fseek(File *stream,long offset,intwhence)

Параметры:

File *stream – указатель на открытый файловый поток.

Long offset – число байтов, на которое нужно перемещения в обратную сторону offset должен быть отрицанием.

Int whence – указатель на положение точки отсчета от которого будет происходить перемещение файлового указателя.

Void main ()

{FILE *giena;

Int x;

Giena=fopen(“ttt.dat”,”rb”);

Fseek (giena,25*sizeof(int),SEEK_SET);

Fread (&x,sizeof(int),1,giena);

Printf (“Прочитано 25е число:%d\n”,x);

Fclose(giena);}

 

Использование ссылок.

В си++ используется видоизмененная форма указателя, называемая ссылкой. Для ссылки не требуется дополнительного пространства памяти, так как она является по сути другим именем переменной. Для описания ссылки используется:

Int &k;

Main ()

{int t;

Int &sh=t;}

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

 

#include <stdio.h>

Const int j=10;

Int mass[j];

Int &aaa (int i)

{return mass[i];}

Void Main ()

{for (int i=1;i<j;i++)

Aaa(i)=i*I;

For (i=1;i<j;i++)

Printf (“mass[%d]=%d\n”,I,aaa(i));

Ссылка может быть использована как тип возвращаемой функции, что позволит «присваивать функции значение».

 


Встроенные функции.-


В Си++ при определении функции можно использовать слово inline, оно предписывает компилятору помещать расширение тела функции везде, где происходит обращение к ней вместо того, чтобы генерировать код вызова.

Обычно встроенными делаются малые по размеру функции, так как их использование делает текст программы больше, хотя такая программы выполняется быстрее. На содержимое функции, объявляем как inline сущ. список ограничений, так не допускается inline для функций принимающих оператор цикла, операторы switch и goto можно. Кроме того определение встроенной функции должно обязательно предшествовать ее вызову. Кроме того компилятор может без всякого предупреждения проигнорировать inline.

 

Пространства имен.

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

Namespace имя {…}


Для явного обращения к переменной из конкретного пространства имен используют префикс с названием соответствующего пространства имен и операцией разрешения видимости.

Namespace sonya {

Int x;

Namespace sonya1{

Int x;}}

T=sonya::sonya1::x+2;

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

Namespace AAA {int Fun (int I){return I;}}

Namespace BBB {int Fun (int i){return i*I;}}

Void main (void) {using BBB::Fun;

Int x=7,y;

Y=Fun(x)

Printf (“%d\n”,y);}

Вторая форма использования using: using namespace имя.

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

Namespace A1{int x=11; int y=111; int w=1111;}

Namespace A2{int x=22; int y=222; int z=2222;}

Void main (void)

{using namespace A1;

Using namespace A2;

Using A2::x;

Printf (“x=%d;y=%d;z=%d;w=%d”,x,A1::y,::z,w);}

В итоге программы выведет: x=22,y=111,z=2222,w=1111

 

Перегруженные функции.-

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

Void showmes (int nom)

{printf (“message:%s\n”,spisok[nom]);}

Void showmes (char *msg)

{printf (“message:%s\n”,msg);}


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

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

 

19)Особенности описания переменных в программах на Си++-


В языке Си локальные переменные должны определяться в начале блока. В Си++ можно определять в любом месте. Это полезно тем, то переменную можно описать в непосредственной близости от первого места ее использования, кроме того модификатор const, который в Си запрещает изменять переменную после инициализации в Си++ делает это переменную истинно константным выражением, что позволяет использовать ее в любом месте программы, где разрешено использование константы.В Си++ имя структурного типа при описании принято использовать без слова struct.

 

Определение классов.

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

-Определение класса может одержать один или несколько спецификаторов доступа (public, private, protected)

-На ряду с элементами данных определения класса как правило включает в себя элементы функций.

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


Class vyalov {int n;

Point sovest

Public:vyalov (int t);

Vyalov ();

};

 

Элементы класса.

Элементы класса делятся на 2 категории: данные хранящие информацию о представителе класса и элементы функции, реализующие поведение этих представителей.

Элементы данных классов Си++ не могут быть представителями самого этого класса, не могут объявляться как extern и regiset. Элементы данные могут быть перечислениями, битовыми полями, представителями ранее объявленных классов, указателем или ссылкой на этот класс. Элемент-функция – это функция, прототип которой объявлен внутри тела класса. Тело функции так же может записываться прямо в определении класса. В этом случае вместо прототипа будет заголовок. Такая функция автоматически будет встроенной. Если функция определена вне тела класса, то в заголовке перед именем функции помещается имя класса и операция разрешения видимости

Float kvadrat::proverka

 

Конструктор и деструктор.

Специальная функция – элемент класса конструктор вызывается компилятором всегда, когда создается представитель класса. Конструктор является функцией элементом с тем же именем, что и ее класс. Если никаких конструкторов не определено, то компилятор генерирует конструктор по умолчанию, не имеющий параметров. Для конструктора не указывают возвратный тип и он не может возвращать значения. Как правило в теле конструктора инициализируются элементы данных класса, хотя конструктор является обычной функцией и в его теле можно писать все что угодно. Определение конструктора может содержать список инициализации, который определяется:: под заголовка определения функции и содержит элементы данных, разделяющих «,».

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

 

Перегрузка операций.

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

Функции операций, реализующие перегрузку операций имеют вид:

тип возвращаемого значения_operator_знак операции (операнды).

Если функция является элементом класса, то первый операнд соответствующей операции будет самим объектом для которого вызвана функция операции. В случае унарной операции список параметров будет пуст, для бинарной имеет 1 параметр, соответствующий второму операнду.

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

Class proverka {int a,b;

Public:proverka (i(nt aa,int bb):a(aa);b(bb));{}

Proverka operator + (const proverka &);

};

Proverka proverka::operator +(const proverka &zaval)

{proverka marazm(0,0);

Marazm.a=a+zaval.a;

Marazm.b=b+zaval.b;

Return marazm;

}

Void main ()

{proverka q(10,10);

Proverka w(6,6);

Proverka summa(0,0);

Summa=q+w;

}

 

Дружественные функции.

Специальные спецификаторы доступа класса позволяют указывать: могут ли функции вне определенного класса обращаться к его элементам. Может возникнуть ситуация, когда потребуется обеспечить определенной функции или классу доступ к элементам данного класса, определенного как private или protected. Для обеспечения доступа используется ключевое слово friend, строка начинается с этого ключевого слова встроенного в качестве оператора описания в определении данного класса. Объявить другом можно другой класс целиком, функцию член другого класса или функцию, не являющуюся членом класса.

ПРИМЕРЫ!

Наследование классов.

 

Визуалка.



 

Структурные типы данных и переменные этих типов.-

Структурный тип – это тип созданный на основе компонентов базовых типов или ранее созданных структурных типов. При создании структурного типа его имя пишется после struct, а после имени в {} пишется список компонентов. Имена этих компонентов могут совпадать с именами обычных переменных, так как их можно различать по контексту. Имя структурного типа может и не задаваться при описании нового структурного типа. Описание структурного типа не резервирует память, память выделяется только при описании какой-либо переменной структурного типа. Доступ к отдельным компонентам структурного типа осуществляется при помощи конструкции имя переменной _ компонент.

Struct Kristina {

Int a;

Float b;

};

Struct Kristina obsch

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

Struct point a;

&a …. A=b; b…

B=a; a….

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 293; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.15.237.255 (0.13 с.)