Обработка математики: 0%
 

printМассивы, строки и структуры

printСтруктуры

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

В языке C структуру сначала рекомендуется определить как тип и только после этого определять наборы такого типа:

typedef  
или
tt"typedef" quad tt"struct" quad { "тип"_1 quad "элемент"_1; quad "тип"_2 quad "элемент"_2; quad ...} quad "имя";

В C++
tt"struct" quad "имя" { "тип"_1 quad "элемент"_1; quad "тип"_2 quad "элемент"_2; quad ...};
определяет тип с тем же именем. При использовании такого определения в C вместо простого имени придется указывать struct "имя".

typedef часто используется для сокращения названия типа из нескольких слов:

typedef unsigned long long ull;
typedef unsigned char byte;
ull a; // unsigned long long a;
byte b; // unsigned char b;

Для доступа к элементам структуры (полям) используется операция .: "имя_структуры" tt"." "имя_поля"

Список начальных значений для набора-структуры указывается в {} через запятую. Можно явно указать, какому полю присваивается значение: tt"." "имя_поля" ="выражение". Если значение какого-либо поля явно не указано, то оно получает значение 0.

Примеры структур:

typedef struct { double x, y, z; } coord; // координаты в пространстве
typedef struct { // дата
  char day; // день 1-31
  char month; // месяц 1-12
  int year; // год
} date;
typedef struct { // информация о человеке
  char name[51]; // имя
  date birthday; // дата рождения
  char addr[101]; // адрес
  char job[16]; // должность
  int salary; // зарплата
} person;

Примеры определения и инициализации наборов-структур:

coord p1={1, 7, 2.5};
date d1;
person joe={"Joseph",{20,11,1942},"Washigton, DC","President",100000};
person team[5]= // массив лиц
  { {"Kamala", .job="Vice-president",.salary=150000},
    {"Antony", .job="Secretary"}
  };

Обращение к полям структуры:

printf("%lf lf lf\n",p1.x, p1.y,p1.z);
d1.day=12;
joe.birthday.day=d1.day;

В отличие от массивов структуры можно копировать целиком обычным присваиванием, в том числе в случаях, когда одним из полей является массив. Для копирования отдельного поля-массива нужно использовать memcpy или strcpy. Вместо присваивания полям значений по отдельности можно присвоить структуру-значение: ("спецификаторы" quad "тип") {"список_значений_для_полей"}

d1=joe.birthday; // копируем все поля
team[4]=joe; // копируем все поля
team[3]=team[2]; // копируем все поля
strcpy(team[3].addr,joe.addr); // но копируем одно поле-строку
joe.birthday=(date){30,4,1945}; // присваивание структуры-значения вместо joe.birthday.day=30; joe.birthday.month=4; ...
team[4]=(person){"Karine", {12,8,1974}, .job="Press Secretary"};

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

typedef struct { 
  char name[51]; // имя
  struct { char day, month; int year; } birthday; // дата рождения
  int salary; // зарплата
} person;
...
person p;
p.birthday.day=11;

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

#include <stdio.h>
#include <stdbool.h>
typedef struct {
  int a:4; // число от -8 до 7
  bool flag:1; // 0 или 1 
  unsigned b:10; // число от 0 до 1023
// +1 бит так как тип short требует выравнивание на 2 байта
  short c; // попробуйте изменить на int
} packed;
typedef struct { // то же без упаковки
  int a; // 4 байта
  bool flag; // 1 байт +3 байта для выравнивание на 4 байта
  unsigned b; // 4 байта
  short c; // 2 байта +2 байта для выравнивание на 4 байта
} unpacked; 
int main() {
  packed x;
  unpacked y;
  printf("%d %d\n",sizeof(x),sizeof(y)); // 4 16
}
Р’РІРѕРґ:

Выполнить
Вывод:
loading