Структуры
Теория
Массив хранит набор данных одинакового типа. Некоторые объекты нужно описывать данными разного типа. Например, для описания одного студента нужны строки (имя, фамилия, отчество), целые числа (номер факультета, номер группы, номер в единой системе учета оценок) и массивы (оценки за экзамен в 1 семестре). Чтобы хранить в одной переменной значения разного типа создают новый тип данных с помощью ключевого слова struct.Объявление нового типа данных
Создадим структуру, которая описывает человека и хранит его рост в сантиметрах (целое число), вес в килограммах, размер обуви и год рождения.struct Human { int height; // высота в сантиметрах float weight; // вес в килограммах int foot; // размер обуви int bdate; // год рождения }; // в конце обязательно ТОЧКА С ЗАПЯТОЙ

Объявление переменных и их использование
Создадим переменную х типа int. Присвоим х число 7. Увеличим x на 2.Создадим переменную alex типа struct Human. И опишем человека ростом 180 см, весом 70.1 кг, с 42 размером обуви 1997 года рождения. После коллоквиума по математике он похудел на 1.24 кг.
int x; // объявили переменную х типа int x = 7; // переменной х присвоили число 7 (запись в х) x = x + 2; // прочитали значение переменной х, вычисли х+2 и результат записали в х struct Human alex; // объявили переменную alex типа struct Human alex.height = 180; // в поле height переменной alex записали число 180 alex.foot = 42; // в поле foot переменной alex записали число 42 alex.bdate = 1997; // в поле bdate переменной alex записали число 1997 alex.weight = 70.1; // в поле weight переменной alex записали число 70.1 // после коллоквиума он похудел на 1.24 кг alex.weight = alex.weight - 1.24;

Явная инициализация при объявлении
Данные можно присвоить сразу при объявлении переменной.
struct Human alex = {180, 70.1, 42, 1997};
x = y
При присвоении структур идет копирование той области памяти, где расположена переменная y, в область памяти, где расположена х. Это называется побитовым копированием.
struct Human mike; // объявили новую переменную mike того же типа, что и alex mike = alex; // mike тоже теперь весит 70.1 кг, при росте 180 см, нога 42 размера и родился в 1997 году.
Структуры в функции передаются по значению
В языке С в функцию все аргументы передаются по значению. Любого типа. Для структур делается побитовая копия.#include <stdio.h> struct Human { int height; float weight; }; void cut (struct Human h) { h.height = 100; } int main() { struct Human alex = {180, 70.1}; cut(alex); printf("height=%d weight=%f\n", alex.height, alex.weight); return 0; }
Структура в виде возвращаемого значения
Можно вернуть из функции значение какой-либо структуры. Вернем из функции cut значение struct Human:#include <stdio.h> struct Human { int height; float weight; }; struct Human cut (struct Human h) { h.height = 100; } int main() { struct Human alex = {180, 70.1}; struct Human mike; mike = cut(alex); printf("height=%d weight=%f\n", alex.height, alex.weight); printf("height=%d weight=%f\n", mike.height, mike.weight); return 0; }
height=180 width=70.1
height=100 width=70.1
Указатели на структуры
Как передавать переменную в функцию, чтобы изменять значение внутри функции? Надо передать функцию значение адреса этой переменной.#include <stdio.h> void cut (struct Human * adr) { // оператор ->, так как у adr тип УКАЗАТЕЛЬ на struct Human adr -> height = 100; } int main() { struct Human alex = {180, 70.1}; cut(& alex); // оператор точка, так как у alex тип struct Human printf("height=%d weight=%f\n", alex.height, alex.weight); return 0; }
-> удобнее читать.
Задачи
Отрезок двухмерный (на осях Х и У) (КИТАЙ)
#include <stdio.h> struct Point { int x; int y; }; struct Line { struct Point start; struct Point end; }; void printPoint( struct Point p) { printf("(%d, %d) ", p.x, p.y); } struct Point getPoint( void) { struct Point p; scanf("%d%d", & p.x, & p.y); return p; } struct Point movePointX(struct Point p, int dx) { struct Point res; res.x = p.x + dx; res.y = p.y; return res; } void printLine( struct Line lin) { printPoint (lin.start); printPoint (lin.end); printf("\n"); } struct Line getLine( void) { struct Line t; t.start = getPoint(); t.end = getPoint(); return t; } struct Line moveLine(struct Line lin, int dx) { struct Line res; res.start = movePointX(lin.start, dx); res.end = movePointX(lin.end , dx); return res; } int main() { struct Line a; struct Line b; int dx; a = getLine(); scanf("%d", &dx); printLine(a); b = moveLine (a, dx); printLine(b); return 0; }
Отрезок одномерный (на оси Х)
#include <stdio.h> struct Line { // название структуры int start; // поля структуры int finish; }; struct Line readLine(); // читает отрезок void printLine (struct Line a); // печатает отрезок int lengthLine(struct Line a); // длина отрезка struct Line moveLine (struct Line a, int dx); // двигает отрезок на dx int main() { struct Line a, b; int dx; a = readLine(); scanf("%d", &dx); printf("length = %d\n", lengthLine(a)); b = moveLine(a, dx); printLine(a); printLine(b); return 0; } struct Line readLine() { struct Line t; scanf("%d%d", &t.start, &t.finish); return t; } void printLine(struct Line a) { printf("(%d, %d)\n", a.start, a.finish); } int lengthLine(struct Line a) { return a.finish - a.start; } struct Line moveLine(struct Line a, int dx) { struct Line tmp; tmp.start = a.start + dx; tmp.finish = a.finish + dx; return tmp; }
Отрезок одномерный (с указателями)
/* Отрезок на оси Х. Научимся его читать, печатать и сдвигать на dx */ #include <stdio.h> struct Line { // название структуры int start; // поля структуры int finish; }; void readLine(struct Line * pa); // читает отрезок void printLine (struct Line a); // печатает отрезок int lengthLine(struct Line a); // длина отрезка void moveLine (struct Line * pa, int dx); // двигает отрезок на dx int main() { struct Line a; int dx; readLine(&a); scanf("%d", &dx); printf("length = %d\n", lengthLine(a)); printLine(a); moveLine(&a, dx); printLine(a); return 0; } void readLine(struct Line * pa) { scanf("%d%d", &(pa->start), &(pa->finish)); return t; } void printLine(struct Line a) { printf("(%d, %d)\n", a.start, a.finish); } int lengthLine(struct Line a) { return a.finish - a.start; } void moveLine(struct Line * pa, int dx) { pa->start = pa->start + dx; pa->finish += dx; }
Отрезок на плоскости ХУ
/* Отрезок на плоскости ХY. Научимся его читать, печатать и сдвигать Какой отрезок больше? */ #include <stdio.h> #include <math.h> struct Direction { // для описания сдвига int x; int y; }; struct Point { int x; int y; }; struct Line { // название структуры struct Point start; // поля структуры struct Point finish; }; struct Line readLine(); // читает отрезок void printLine (struct Line a); // печатает отрезок float lengthLine(struct Line a); // длина отрезка struct Line moveLine (struct Line a, int dx); // двигает отрезок на dx int main() { struct Line a, b; int dx; a = readLine(); scanf("%d", &dx); printf("length = %f\n", lengthLine(a)); b = moveLine(a, dx); printLine(a); printLine(b); return 0; } struct Point readPoint() { struct Point t; scanf("%d%d", &t.x, &t.y); return t; } struct Line readLine() { struct Line t; struct Point a, b; a = readPoint(); b = readPoint(); t.start = a; t.finish = b; return t; } void printPoint(struct Point a) { printf("(%d, %d) ", a.x, a.y); } void printLine(struct Line lin) { printPoint(lin.start); printPoint(lin.finish); printf("\n"); } float lengthLine(struct Line lin) { int x = lin.start.x - lin.finish.x; int y = lin.start.y - lin.finish.y; float length = sqrt(x*x + y*y); return length; } struct Line moveLine(struct Line a, int dx) { struct Line tmp = a; tmp.start.x += dx; tmp.finish.x += dx; return tmp; }
Прямоугольник на плоскости
/* Прямоугольник на плоскости ХY. Научимся его читать, печатать и сдвигать */ #include <stdio.h> struct Direction { int x; int y; }; struct Point { int x; int y; }; struct Rect { // название структуры struct Point lt; // поля структуры struct Point rb; }; struct Direction readDirection() { struct Direction t; scanf("%d%d", &t.x, &t.y); return t; } struct Point readPoint() { struct Point t; scanf("%d%d", &t.x, &t.y); return t; } void printPoint(struct Point a) { printf("(%d, %d) ", a.x, a.y); } struct Rect readRect() { struct Rect t; struct Point a, b; a = readPoint(); b = readPoint(); t.lt = a; t.rb = b; return t; } void printRect(struct Rect rect) { printPoint(rect.lt); printPoint(rect.rb); printf("\n"); } void moveRect(struct Rect * p, struct Direction dir) { p->lt.x = p->lt.x + dir.x; p->lt.y = p->lt.y + dir.y; p->rb.x += dir.x; p->rb.y += dir.y; } int main() { struct Rect rect; struct Direction d; rect = readRect(); d = readDirection(); moveRect(&rect, d); printRect(rect); return 0; }
Еще теории
Декларации
Анонимные структуры
union
Битовые поля
-- TatyanaDerbysheva - 07 Nov 2014