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

КЭкзCPP / СТРУКТУРЫ

.docx
Скачиваний:
31
Добавлен:
23.02.2015
Размер:
28.27 Кб
Скачать

СТРУКТУРЫ

Структура – набор элементов почти произвольных типов

struct nameStruct

{

type1 name1;

type2 name2; …

typeN nameN;

} [var1, var2];

Переменная типа структуры определяется обычным образом

nameStruct variable1, variable2;

Например,

struct student

{

char* name;

unsigned mark[4];

unsigned age;

} Ivan, Nobody;

Доступ к конкретным полям структуры производится при помощи оператора “.”

Например,

cout<<”возраст студента ”<<Ivan.name<<” составляет ”<<Ivan.age<<endl;

Ivan.mark[0]=2;

Ivan.name = new char[20];

//cout<<student.age; - ОШИБКА – доступ через имя типа

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

student urfu = {“Petr_Petrov”, {4,4,3,5}, 18};

Две структуры являются разными типами, даже если состоят из одинаковых элементов

Например,

struct One{int a; char ch};

struct Two{int a; char ch};

Поэтому

One x; …

Two y = x; - ОШИБКА требуется

y.a=x.a;

y.ch = x.ch;

Но если

One a, b;…

b=a; / /допустимо

int c = x; - ОШИБКА( x – не предопределенный тип)

Каждая структура должна иметь единственное определение в программе.

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

объявление_поля : константное_выражение;

struct student{

char* name;

unsigned mark[4];

unsigned age;

};

может быть объявлена как (тип поля – целочисленный, конст_выр в битах)

struct student{

char* name;

unsigned mark[4];

unsigned age :8;

};

Имя тип можно использовать немедленно после его появления, до завершения всего объявления

struct Node{

char ch;

Node* next;

Node* prev;};

До полного завершения объявления структуры запрещается использовать ее имя для объявления других объектов

struct list{list my_list};

Структуры можно передавать в функции (и возвращать )

struct house

{

unsigned short reg_num;

char street[51];

char house_num[6];

bool parking;

};

void show_adress(house);

int main(){

house my_house;

my_house.reg_num = 66;

strcpy(my_house.street,"pr. Lenina");

strcpy(my_house.house_num,"51-a");

my_house.parking = false;

show_adress(my_house);

return 0;

}

void show_adress(house home)

{

cout << home.street<<", ";

cout<<home.house_num<<endl;

}

Можно объявлять массивы структур

house urgu[20];

или динамически

house * urgu = new house[20];

Таким образом, можно обращаться к элементам структуры через указатели

Например,

house* phouse;

phouse = &my_house;

phouse->parking = true;

cout<<my_house.parking; //cout<<phouse->parking;

Оператор “->” разыменования указателя на структуру эквивалентен записи (*phouse).parking = true;

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

Например,

int fun_struct(house* one, house& two);

Появляется возможность моделирования новых типов данных на базе уже имеющихся.

typedef struct

{

double x;

double y;

double z;

} coord;

coord my_point;

my_point.x = 2.; my_point.y = 2.1; mypoint.z = 3.14;

или массив координат точек //coord points[25];

пример работы с полиномом

struct dk{int deg; double k;};

dk* read_p(int&);

void show_p(dk*, int);

dk* add_p(dk*, dk*, int, int, int&);

void main()

{

dk *one, *two, *third;

int n_one,n_two,n_third;

one = read_p(n_one);

two = read_p(n_two);

show_p(one,n_one);

show_p(two,n_two);

//third=add_p(one,two,n_one,n_two,n_third);

//show_p(third, n_third);

delete [] one;

delete [] two;

//delete [] third;

}

dk* read_p(int& n)

{

cout<<"input number elementov ";

cin>>n; cout<<endl;

dk* p = new dk[n];

for(int i = n-1; i >-1; i--)

{

cout<<"input degree ";cin>>p[i].deg;

cout<<"input koeff ";cin>>p[i].k; cout<<endl;

}

return p;

}

void show_p(dk p[], int n)

{

for(int j=n-1; j>-1; j--)

if(p[j].deg!=0) {cout<<p[j].k<<"*x";

if(p[j].deg!=1) {cout<<'^'<<p[j].deg;};

if((j>0)&&p[j-1].k>0) cout<<'+';}

else cout<<p[j].k;

cout<<endl;

}

Структуры могут быть вложенными. Уровень вложенности не ограничивается.

Структуры используются в различных библиотечных функциях. Например, для работы с датой и временем (#include<ctime>). Где, в частности, определена структура

struct tm

{

int tm_sec;

int tm_min;

int tm_hour;

int tm_mday;

int tm_mon;

int tm_year; //год текущий минус 1900

int tm_wday;//день недели

int tm_yday;//день в году

int tm_isday;//0, если зимнее время

}

С ней связана переменная

typedef long time_t;

Определены функции

asctime преобразует время и дату из tm в символьную строку;

clock возвращает число тиков процессора, от начала работы процесса;

ctime преобразует время и дату из time_t в символьную строку;

time возвращает время в секундах, прошедшее с 0ч0м0с 1.01.1970 по Гринвичу;

#include<iostream>

#include <ctime>

using namespace std;

int main()

{

time_t tt;

tm *p_my_time;

tt=time(NULL);

p_my_time = localtime(&tt);

cout<<"current time: "<<asctime(p_my_time)<<endl;

return 0;

}

Многомерные массивы

Мм – массив массивов. Определение должно содержать сведения о типе, размерности и количествах элементов каждой размерности

type name_array [n1][n2]…[nN];

например,

int array[4][3][6];

Размещается в памяти в порядке возрастания самого правого индекса – array[0][0][0], array[0][0][1] и т.д. В таком же порядке располагают элементы массива в списке инициализации

int array[4][3][6]={0, 1, 2, 3, 4, 5, 6, 7};

А именно,

array[0][0][0] ==0; array[0][0][1] ==1; array[0][0][2] ==2; array[0][0][3] ==3;

array[0][0][4] ==4; array[0][0][5] ==5; array[0][1][0] ==6; array[0][1][1] ==7;

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

int a[4][5][6] ={{{0}}, {{100},{110,111}}, {{200}, {210}, {220, 221, 222}}};

и получим

a[1][1][0] ==110; a[2][0][0] == 200; и т.д.

Допускается запись вида

double b[][4] = {{2},{3}};

когда компилятор может определить сам первую размерность по списку инициализации. Рассмотрим пример

void main()

{

int b[3][2][4] = { 0, 1, 2, 3,

10, 11, 12, 13,

100,101,102,103,

110,111,112,113,

200,201,202,203,

210,211,212,213

};

cout<<"\tadress of array b[][][]"<<endl;

cout<<"\nb = "<<b;

cout<<"\n\tadress of array b[0][][]"<<endl;

cout<<"\n*b = "<<*b;

cout<<"\n\tadress of array b[0][0][]"<<endl;

cout<<"\n**b = "<<**b;

cout<<"\n\telement of array b[0][0][0]"<<endl;

cout<<"\n***b = "<<***b;

cout<<"\n\tadress of array b[1][][]"<<endl;

cout<<"\n*(b+1) = "<<*(b+1);

cout<<"\n\tadress of array b[2][][]"<<endl;

cout<<"\n*(b+2) = "<<*(b+2);

cout<<"\n\tadress of array b[0][1][]"<<endl;

cout<<"\n*(*b+1) = "<<*(*b+1);

cout<<"\n*(*(*(b+1)+1)+1) = "<<*(*(*(b+1)+1)+1);

cout<<"\n*(b[1][1]+1) = "<<*(b[1][1]+1);

cout<<"\n\telement of array b[2][0][0]"<<endl;

cout<<"\n*(b[1]+1)[1] = "<<*(b[1]+1)[1];

cout<<endl;

}

Так элемент b[i][j][k] соответствует *(*(*(b+i)+j)+k).

Рассмотрим два различных определения

int *massiv[4]; //массив указателей на объекты типа int

int (*ptr)[4]; //указатель ptr на массив из 4 элементов, каждый из которых - int

Благодаря массиву указателей можно более эффективно расходовать память…

Например,

char list[][30] = {“rectangle”, ”circle”, ”segment”};

char *pointer [] = {“rectangle”, ”circle”, ”segment”};

Соседние файлы в папке КЭкзCPP