C struct: C: структуры

Содержание

Linux, DevOps и системное администрирование










DevOops

Operating systems

main()

Scripting/coding

Самое читаемое

Архив месяца

Ноябрь 2021
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
2930 

« Окт
 
 

Архивы по годам

Архивы по годам
Выберите месяц Ноябрь 2021  (6) Октябрь 2021  (4) Сентябрь 2021  (5) Август 2021  (5) Июль 2021  (6) Июнь 2021  (6) Май 2021  (6) Апрель 2021  (11) Март 2021  (8) Февраль 2021  (6) Январь 2021  (1) Декабрь 2020  (1) Ноябрь 2020  (9) Октябрь 2020  (9) Сентябрь 2020  (4) Август 2020  (8) Июль 2020  (4) Июнь 2020  (3) Май 2020  (5) Апрель 2020  (9) Март 2020  (8) Февраль 2020  (9) Январь 2020  (2) Декабрь 2019  (9) Ноябрь 2019  (9) Октябрь 2019  (11) Сентябрь 2019  (11) Август 2019  (10) Июль 2019  (2) Июнь 2019  (4) Май 2019  (9) Апрель 2019  (13) Март 2019  (32) Февраль 2019  (20) Январь 2019  (10) Декабрь 2018  (9) Ноябрь 2018  (12) Октябрь 2018  (15) Сентябрь 2018  (12) Август 2018  (14) Июль 2018  (17) Июнь 2018  (18) Май 2018  (21) Апрель 2018  (6) Март 2018  (18) Февраль 2018  (7) Январь 2018  (13) Декабрь 2017  (14) Ноябрь 2017  (6) Октябрь 2017  (24) Сентябрь 2017  (13) Август 2017  (15) Июль 2017  (11) Июнь 2017  (11) Май 2017  (11) Апрель 2017  (7) Март 2017  (18) Февраль 2017  (13) Январь 2017  (14) Декабрь 2016  (12) Ноябрь 2016  (15) Октябрь 2016  (13) Сентябрь 2016  (21) Август 2016  (19) Июль 2016  (14) Июнь 2016  (8) Май 2016  (24) Апрель 2016  (15) Март 2016  (19) Февраль 2016  (21) Январь 2016  (19) Декабрь 2015  (17) Ноябрь 2015  (17) Октябрь 2015  (14) Сентябрь 2015  (13) Август 2015  (1) Июль 2015  (20) Июнь 2015  (23) Май 2015  (26) Апрель 2015  (28) Март 2015  (30) Февраль 2015  (26) Январь 2015  (24) Декабрь 2014  (31) Ноябрь 2014  (21) Октябрь 2014  (28) Сентябрь 2014  (23) Август 2014  (31) Июль 2014  (23) Июнь 2014  (11) Май 2014  (14) Апрель 2014  (8) Март 2014  (11) Февраль 2014  (11) Январь 2014  (11) Декабрь 2013  (12) Ноябрь 2013  (23) Октябрь 2013  (20) Сентябрь 2013  (30) Август 2013  (20) Июль 2013  (6) Июнь 2013  (9) Май 2013  (5) Апрель 2013  (13) Март 2013  (22) Февраль 2013  (36) Январь 2013  (10) Декабрь 2012  (4) Ноябрь 2012  (8) Октябрь 2012  (13) Сентябрь 2012  (29) Август 2012  (24) Июль 2012  (18) Июнь 2012  (2) Май 2012  (4) Март 2012  (5) Февраль 2012  (5) Январь 2012  (25) Декабрь 2011  (15) Ноябрь 2011  (6) Август 2011  (13)

Linux, DevOps и системное администрирование










DevOops

Operating systems

main()

Scripting/coding

Самое читаемое

Архив месяца

Ноябрь 2021
ПнВтСрЧтПтСбВс
1234567
891011121314
15161718192021
22232425262728
2930 

« Окт
 
 

Архивы по годам

Архивы по годам
Выберите месяц Ноябрь 2021  (6) Октябрь 2021  (4) Сентябрь 2021  (5) Август 2021  (5) Июль 2021  (6) Июнь 2021  (6) Май 2021  (6) Апрель 2021  (11) Март 2021  (8) Февраль 2021  (6) Январь 2021  (1) Декабрь 2020  (1) Ноябрь 2020  (9) Октябрь 2020  (9) Сентябрь 2020  (4) Август 2020  (8) Июль 2020  (4) Июнь 2020  (3) Май 2020  (5) Апрель 2020  (9) Март 2020  (8) Февраль 2020  (9) Январь 2020  (2) Декабрь 2019  (9) Ноябрь 2019  (9) Октябрь 2019  (11) Сентябрь 2019  (11) Август 2019  (10) Июль 2019  (2) Июнь 2019  (4) Май 2019  (9) Апрель 2019  (13) Март 2019  (32) Февраль 2019  (20) Январь 2019  (10) Декабрь 2018  (9) Ноябрь 2018  (12) Октябрь 2018  (15) Сентябрь 2018  (12) Август 2018  (14) Июль 2018  (17) Июнь 2018  (18) Май 2018  (21) Апрель 2018  (6) Март 2018  (18) Февраль 2018  (7) Январь 2018  (13) Декабрь 2017  (14) Ноябрь 2017  (6) Октябрь 2017  (24) Сентябрь 2017  (13) Август 2017  (15) Июль 2017  (11) Июнь 2017  (11) Май 2017  (11) Апрель 2017  (7) Март 2017  (18) Февраль 2017  (13) Январь 2017  (14) Декабрь 2016  (12) Ноябрь 2016  (15) Октябрь 2016  (13) Сентябрь 2016  (21) Август 2016  (19) Июль 2016  (14) Июнь 2016  (8) Май 2016  (24) Апрель 2016  (15) Март 2016  (19) Февраль 2016  (21) Январь 2016  (19) Декабрь 2015  (17) Ноябрь 2015  (17) Октябрь 2015  (14) Сентябрь 2015  (13) Август 2015  (1) Июль 2015  (20) Июнь 2015  (23) Май 2015  (26) Апрель 2015  (28) Март 2015  (30) Февраль 2015  (26) Январь 2015  (24) Декабрь 2014  (31) Ноябрь 2014  (21) Октябрь 2014  (28) Сентябрь 2014  (23) Август 2014  (31) Июль 2014  (23) Июнь 2014  (11) Май 2014  (14) Апрель 2014  (8) Март 2014  (11) Февраль 2014  (11) Январь 2014  (11) Декабрь 2013  (12) Ноябрь 2013  (23) Октябрь 2013  (20) Сентябрь 2013  (30) Август 2013  (20) Июль 2013  (6) Июнь 2013  (9) Май 2013  (5) Апрель 2013  (13) Март 2013  (22) Февраль 2013  (36) Январь 2013  (10) Декабрь 2012  (4) Ноябрь 2012  (8) Октябрь 2012  (13) Сентябрь 2012  (29) Август 2012  (24) Июль 2012  (18) Июнь 2012  (2) Май 2012  (4) Март 2012  (5) Февраль 2012  (5) Январь 2012  (25) Декабрь 2011  (15) Ноябрь 2011  (6) Август 2011  (13)

struct (C++) | Microsoft Docs





  • Чтение занимает 2 мин


Были ли сведения на этой странице полезными?

Оцените свои впечатления




Да



Нет



Хотите оставить дополнительный отзыв?

Отзывы будут отправляться в корпорацию Майкрософт. Нажав кнопку «Отправить», вы разрешаете использовать свой отзыв для улучшения продуктов и служб Майкрософт. Политика конфиденциальности.


Отправить



В этой статье

struct Ключевое слово определяет тип структуры и (или) переменную типа структуры.

Синтаксис

[template-spec] struct [ms-decl-spec] [tag [: base-list ]]
{
   member-list
} [declarators];
[struct] tag declarators;
Параметры

Спецификация шаблона
Необязательные спецификации шаблона. Дополнительные сведения см. в разделе спецификации шаблонов.

struct
struct Ключевое слово.

MS-decl-Spec
Необязательная спецификация класса хранения. Дополнительные сведения см. в разделе ключевое слово __declspec .

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

base-list
Необязательный список классов или структур, из которых эта структура будет наследовать члены. Дополнительные сведения см. в разделе базовые классы . Каждому базовому классу или имени структуры может предшествовать спецификатор доступа (открытый, частный, защищенный) и ключевое слово Virtual . Дополнительные сведения см. в таблице доступ к элементам в разделе Управление доступом к членам класса .

Список участников
Список членов структуры. Дополнительные сведения см. в разделе Обзор членов класса . Единственное отличие заключается в том, что struct используется вместо class .

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

Remarks

Тип структуры — это пользовательский составной тип. Он состоит из полей или членов, которые могут иметь разные типы.

В C++ структура является такой же, как и класс, за исключением того, что ее члены по public умолчанию имеют значение.

Сведения об управляемых классах и структурах в C++/CLI см. в разделе классы и структуры.

Использование структуры

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

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

Переменные структуры можно инициализировать. Инициализация каждой переменной должна быть заключена в скобки.

Связанные сведения см. в разделе класс, объединениеи перечисление.

Пример

#include <iostream>
using namespace std;

struct PERSON {   // Declare PERSON struct type
    int age;   // Declare member types
    long ss;
    float weight;
    char name[25];
} family_member;   // Define object of type PERSON

struct CELL {   // Declare CELL bit field
    unsigned short character  : 8;  // 00000000 ????????
    unsigned short foreground : 3;  // 00000??? 00000000
    unsigned short intensity  : 1;  // 0000?000 00000000
    unsigned short background : 3;  // 0???0000 00000000
    unsigned short blink      : 1;  // ?0000000 00000000
} screen[25][80];       // Array of bit fields

int main() {
    struct PERSON sister;   // C style structure declaration
    PERSON brother;   // C++ style structure declaration
    sister.age = 13;   // assign values to members
    brother.age = 7;
    cout << "sister.age = " << sister.age << '\n';
    cout << "brother.age = " << brother.age << '\n';

    CELL my_cell;
    my_cell.character = 1;
    cout << "my_cell.character = " << my_cell.character;
}
// Output:
// sister.age = 13
// brother.age = 7
// my_cell.character = 1



c — typedef struct, но сохраняйте пространство имен нового типа под ключевым словом struct

Как я могу ввести определение структуры, но при этом оставить имя нового типа в пространстве под ключевым словом «структура»?

Пример:

struct foo {
    int x; 
}; 

typedef struct foo struct bar; 


int main(void) {
    struct bar bar; 
    bar.x = 10; 

    return 0; 
}

Но это не работает, очевидно. Вот ошибки, если кому-то интересно:

main.c:5:20: error: two or more data types in declaration specifiers
 typedef struct foo struct bar;
                    ^
main.
main.c: In function 'main':
main.c:9:13: error: storage size of 'bar' isn't known
  struct bar bar;

1

user13865989

23 Июл 2020 в 21:58

5 ответов

Лучший ответ

Как я могу typedef struct, но по-прежнему держать пространство имен нового типа под ключевым словом struct?

Итак, кажется, что вы хотите определить псевдоним структуры для другого типа структуры.

Это невозможно с typedef, так как создает псевдоним из одного слова. Новый псевдоним не может состоять из нескольких слов, разделенных пробелами.

Но вы можете использовать одно имя, например struct_bar с struct, реализованным внутри имени, чтобы показать, что bar является структурой.

#include <stdio.h>

struct foo {
    int x; 
}; 

typedef struct foo struct_bar;


int main(void) {
    struct_bar bar;
    bar.x = 10; 

    return 0; 
}

4

RobertS supports Monica Cellio
23 Июл 2020 в 19:20

C не имеет поддержки типов для пространств имен (по крайней мере, в том смысле, в котором это делает C ++).

Когда вы создаете typedef, имя нового типа представляет собой один идентификатор, а не несколько слов. Так что struct bar не может быть псевдонимом для другого типа. Вам нужно будет назвать его bar или другим именем из одного слова.

1

dbush
23 Июл 2020 в 19:08

Я нашел решение, которое работает для Cygwin:

struct foo {
    int x; 
}; 

struct bar {
    struct foo; 
};

0

topoly
26 Июл 2020 в 15:36

Ты не можешь Это не так, как это работает.

Вы не можете «создать» тип, имя которого состоит более чем из одного слова, и при этом вы не можете ссылаться на псевдоним типа, используя ключевое слово struct.

Цель написания struct в этом контексте — ссылаться на тип структуры по имени, которое не было введено как псевдоним. Ключевое слово здесь, чтобы сказать, что это то, что вы хотите сделать. Но это не часть имени; это не может быть частью имени.

К счастью, нет причин нуждаться или даже хотеть этого.

1

Asteroids With Wings
23 Июл 2020 в 20:17

Как я могу ввести определение структуры, но при этом сохранить новый тип пространство имен под ключевым словом «struct»? .

Ты не можешь. Пространство имен — это декларативная область, которая обеспечивает область видимости для идентификаторов (имен типов, функций, переменных и т. Д.) Внутри него. Концепция пространства имен, как она определена в C++, не присуща C.

Так что, если вы в порядке с небольшими изменениями в ваших требованиях, вместо того, чтобы делать что-то неестественное, используйте простой typedef:

Вместо этого:

struct foo {
    int x; 
};  

Сделай это:

typedef struct {
    int x; 
}foo;  

Тогда это будет работать:

typedef foo bar;

int main(void )
{   
    bar b;  
  
    b.x = 10;
    return 0;  
}

Примечание. Хотя пространства имен не являются неотъемлемой частью C, как и в C++, существуют некоторые интерпретации, например: , как обсуждалось здесь , которые подтверждают это.

3

ryyker
23 Июл 2020 в 21:14

Структура

(C ++) | Документы Microsoft

  • 2 минуты на чтение

Эта страница полезна?

Оцените свой опыт

да

Нет

Любой дополнительный отзыв?

Отзыв будет отправлен в Microsoft: при нажатии кнопки «Отправить» ваш отзыв будет использован для улучшения продуктов и услуг Microsoft.Политика конфиденциальности.

Представлять на рассмотрение

В этой статье

Ключевое слово struct определяет тип структуры и / или переменную типа структуры.

Синтаксис

  [спецификация-шаблон] структура [ms-декларация-спецификация] [тег [: базовый-список]]
{
   Список пользователей
} [деклараторы];
деклараторы тегов [struct];
  
Параметры

template-spec
Дополнительные спецификации шаблона.Для получения дополнительной информации см. Спецификации шаблона.

struct
Ключевое слово struct .

ms-decl-spec
Дополнительная спецификация класса хранения. Для получения дополнительной информации обратитесь к ключевому слову __declspec.

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

base-list
Необязательный список классов или структур, из которых эта структура будет выводить свои члены. См. Базовые классы для получения дополнительной информации. Каждому базовому классу или имени структуры может предшествовать спецификатор доступа (общедоступный, частный, защищенный) и ключевое слово virtual. См. Таблицу доступа к членам в разделе Управление доступом к членам класса для получения дополнительной информации.

список членов
Список членов структуры. См. Обзор членов класса для получения дополнительной информации.Единственная разница здесь в том, что struct используется вместо class .

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

Замечания

Тип структуры — это определяемый пользователем составной тип. Он состоит из полей или членов, которые могут иметь разные типы.

В C ++ структура такая же, как и у класса, за исключением того, что по умолчанию ее членами являются общедоступные .

Для получения информации об управляемых классах и структурах в C ++ / CLI см. Классы и структуры.

Использование структуры

В C вы должны явно использовать ключевое слово struct для объявления структуры.В C ++ вам не нужно использовать ключевое слово struct после определения типа.

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

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

Для получения дополнительной информации см. Class, union и enum.

Пример

  #include 
используя пространство имен std;

struct PERSON {// Объявить тип структуры PERSON
    int age; // Объявить типы членов
    длинные сс;
    вес поплавка;
    имя символа [25];
} family_member; // Определяем объект типа PERSON

struct CELL {// Объявление битового поля CELL
    беззнаковый короткий символ: 8; // 00000000 ????????
    беззнаковый короткий передний план: 3; // 00000 ??? 00000000
    беззнаковая короткая интенсивность: 1; // 0000? 000 00000000
    беззнаковый короткий фон: 3; // 0 ??? 0000 00000000
    беззнаковое короткое мигание: 1; //? 0000000 00000000
} экран [25] [80]; // Массив битовых полей

int main () {
    сестра struct PERSON; // Объявление структуры стиля C
    ЧЕЛОВЕК брат; // Объявление структуры стиля C ++
    сестра.возраст = 13; // присваиваем значения членам
    Brother.age = 7;
    cout << "sister.age =" << sister.age << '\ n';
    cout << "brother.age =" << brother.age << '\ n';

    CELL my_cell;
    my_cell.character = 1;
    cout << "my_cell.character =" << my_cell.character;
}
// Выход:
// sister.age = 13
// Brother.age = 7
// my_cell.character = 1
  

Структура в C

Структура в C позволяет нам создавать сложные типы данных.Этот новый тип может содержать несколько значений разных типов. Если вы знакомы с enum в C, синтаксис для определения структуры будет легким для вас.

Синтаксис

Мы создаем структуры с ключевым словом struct . Обычно мы создаем их в отдельном файле заголовка. Другой
вариант - определить их в наших файлах .c вне какой-либо функции.

 структура [Тег]
{
    [Определение члена];
    [Определение члена];
    ...
    [Определение члена];
} [Список создаваемых переменных];
 
  • Ключевое слово struct сообщает компилятору, что
    мы создаем структуру
  • Тег - это имя типа структуры.Мы можем использовать это позже
    для создания переменных. Мы называем эти переменные экземплярами. Тег не является обязательным.
  • Внутри тела мы определяем элементы. Мы
    можем определить столько, сколько нам нужно. Их тип может быть любым допустимым типом C,
    включая другие структуры, объединения и т. д.
  • После тела у нас есть возможность создать список переменных
    текущего типа. Для этого мы просто пишем их имена и разделяем их знаком.
    запятая.
  • Не забывайте точку с запятой в конце! Это обязательно.

Пример: определение структуры в C

чел.ч

 struct Employee
{
    имя символа [30];
    символьный адрес [50];
    int age;
};
 

Создание экземпляров

Есть несколько способов создания переменных
созданного вами типа структуры. The
Первый способ
- перечислить имена переменных после
определение структуры вроде этого:

 struct Employee
{
    имя символа [30];
    символьный адрес [50];
    int age;
} сотрудник1, сотрудник 2, сотрудник 3;
 

Теперь вы можете работать с тремя сотрудниками
переменные.

Мне нравится разделять типы и
переменные, поэтому я предпочитаю второму способу .
После определения структуры используйте ее тег и ключевое слово struct для создания переменной:

struct Employee
worker1;

Также вы можете объявить указатель:


struct
Сотрудник *
worker2;

Доступ к участникам

Чтобы получить доступ к члену структуры в C, мы
используйте точку ‘.’И стрелки‘ -> ’.

  • Мы используем оператор точки
    когда мы работаем с инстансом:
 struct Employee worker1;
worker1.age = 20;
 
  • Используем стрелку
    оператор
    , когда мы работаем с , указатель на
    экземпляр:
 struct Employee * worker2;
worker2-> age = 20;
 

Создание сложной конструкции на языке C

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

 struct Employee
{
    struct Address
    {
        символ страны [30];
        char city [30];
        улица Чарская [30];
        char addressField [30];
    } адрес;
    имя символа [30];
    int age;
};
 

или так:

адрес. H

 адрес структуры
{
    символ страны [30];
    char city [30];
    улица Чарская [30];
    char addressField [30];
};
 

сотрудников.h

 struct Employee
{
    struct Address адрес;
    имя символа [30];
    int age;
};
 

Вот как информация в этом комплексе
структура наблюдает за тем, как я ввожу и вывожу:

Набивка

В C по умолчанию данные в структуре автоматически
мягкий. Заполнение добавляет пустые байты в память, чтобы выровнять
данные. Это делается по двум причинам:

  • Для более быстрого доступа к данным
  • На многих процессорах выравнивание данных является обязательным.

По данным большинства архитектур процессоров
выравнивание обязательно - например, на процессорах с архитектурой RISC (ARM, MIPS…). Невыровненный
данные разрешены на процессорах с архитектурой CISC (почти все настольные
компьютеры x86, x64 ..).

Вот как мы определяем пример структуры в C:

 структура A
{
    символ char;
    int число;
    короткий идентификатор;
};
 

А вот как это действительно выглядит в
память:

 структура A
    {
        символ char; // 1 байт в памяти
        char CHAR_PADDING [3]; // заполнение 3 байтами
        int число; // 4 байта - заполнение не требуется
        короткий идентификатор; // 2 байта в памяти
        char SHORT_PADDING [2]; // заполнение 2 байтами
    };
 

Итак, результат sizeof (struct
A)
составляет 12 байтов.

Мы можем оптимизировать наши структуры, отсортировав
их члены по размеру. Это приводит к более эффективному размещению в памяти.
и меньше байтов заполнения. Например, мы можем оптимизировать приведенное выше определение как
это:

 структура A
{
    int число;
    короткий идентификатор;
    символ char;
};
 

Теперь необходимо заполнить только 1 байтом в
конец определения. В памяти это выглядит так:

 структура A
{
    int число; // 4 байта - заполнение не требуется
    короткий идентификатор; // 2 байта в памяти
    символ char; // 1 байт в памяти
    char PADDING [1]; // заполнение 1 байтом
};
 

Теперь sizeof (struct A) возвращает 8 байтов.

Примеры загрузки исходного кода

После большинства статей я предоставляю вам источник примеров. Этот
время ничем не отличается, но я действительно призываю вас взглянуть на них. Вы можете
загрузите zip-архив, содержащий исходный и заголовочный файлы, отсюда:
structure-in-c-examples.zip

См. Также:

Хаки для программирования на языке C

01: Дизайн структур, эффективных с точки зрения памяти | by Gunavaran Brihadiswaran

Объем данных, извлеченных и обработанных процессором за одну инструкцию, называется «размером слова».Просто процессор будет читать по одному слову за раз. В 32-битной системе размер слова составляет 32 бита (4 байта), аналогично в 64-битной системе размер слова составляет 64 бита (8 байтов). Мы будем основывать остальную часть обсуждения на 64-битной системе.

Рисунок 1: 24 байта памяти

Давайте посмотрим на рисунок 1. Каждый квадратный прямоугольник представляет 1 байт памяти. Для простоты адреса памяти обозначены 0–23. Поскольку мы имеем дело с 64-битной системой, процессор будет читать ячейки памяти 0–7 (синий сегмент) вместе, 8–15 (желтый сегмент) вместе и 16–23 (зеленый сегмент) вместе.Предположим, если мы объявим целое число так:

 int var; 

Обычно для типа данных int требуется 32 бита или 4 байта. Вы можете выделить память для var в любом месте от 0 до 23. Некоторые из возможностей следующие.

Одно очевидное, но важное наблюдение здесь заключается в том, что выравнивания 2, 3 и 4 заставляют процессор извлекать нашу var за два цикла (процессор должен получить синий сегмент в одном цикле и желтый сегмент в следующем цикле), тогда как выравнивания 1 и 5 требуется только один цикл (только синий сегмент для трассы 1 и только желтый сегмент для трассы 5).Итак, очевидно, что выравнивания 1 и 5 повышают эффективность. Ждать!! При чем здесь наша проблема?

Оказывается, система не распределяет память случайным образом, но требует выравнивания данных. Переменным в C выделяется память таким образом, что они начинаются с адреса памяти, кратного их размеру. Например, char длиной в один байт может начинаться откуда угодно, short длиной 2 байта должен начинаться с адресов памяти, кратных 2, int длиной 4 байта должен начинаться с адресов памяти, которые являются кратные 4 и т. д.Если вы рассмотрите выравнивания 1 и 5, выделенные ячейки памяти начинаются с 4 и 8, которые кратны 4.

Затем мы должны понять, что такое заполнение, почему оно требуется и как оно работает. Теперь мы знаем, что для выделения памяти существует требование выравнивания. Чтобы обеспечить это требование выравнивания, система использует отступы. Заполнение - это просто вставка пустых байтов (иногда оставляя их пустыми). Если мы вернемся к нашему примеру struct Node1 ,

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

  struct  Node1 {
uint8_t num1;
char padding [7]; // отступ
uint64_t num2;
uint8_t num3;
char padding [7]; // заполнение
}

Это причина, по которой он потребляет 24 байта памяти вместо 10 байтов.

Однако мы можем обойти эту проблему и уменьшить объем потребляемой памяти с 24 до 16 байт.

  struct  Node1 {
uint8_t num1;
uint8_t num3;
char padding [6];
uint64_t num2;
}

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

Надеюсь, что эта статья окажется полезной !!!

Введение в микропроцессорные системы - UW – Madison

Обзор

Структуры используются в C для определения нового типа данных. Этот новый тип данных состоит из других примитивных типов (int, char, float и т. Д.) вместе с другими структурами. Они позволяют нам инкапсулировать связанные данные.

Определение структуры

Структура определяется ключевым словом struct

 Узел структуры
{
    значение uint16_t;
    uint32_t * следующий;
}; 

Структура создается в такой программе:

 void main (недействительно)
{
     struct Node myNode;
} 

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

 #include 

typedef struct {
    uint16_t size;
    uint32_t * следующий;
}Узел;

void main (пусто)
{
     Node myNode;
} 

Если ваша структура содержит указатель на тот же тип структуры, который вы определяете, вам нужно будет объявить структуру следующим образом:

 #include 

typedef struct Node Node;

struct Node {
    uint16_t size;
    Узел * следующий;
};

void main (пусто)
{
     Node myNode;
} 

Упаковано против.Распакованные конструкции

При определении структуры иногда поля в структуре не выравниваются по словам. Итак, что значит быть выровненным по словам? Считается, что данные выровнены по словам, если адрес данных кратен 4 байтам. Адреса 0x20000000, 0x20000004, 0x20000008 и т. Д. Выровнены по словам, потому что младший полубайт кратен 4 (0x0, 0x4, 0x8 и 0xC). Адреса, такие как 0x20000001, не выровнены, потому что младший полубайт не кратен 4.

Так почему это важно, если данные выровнены по словам? При загрузке данных из памяти более эффективно с точки зрения тактовых циклов загружать как слова, а не как полуслова или байты.Фактически, если данные выровнены по словам, мы можем использовать команды LDM / STM в некоторых ситуациях. Большинство компиляторов автоматически выравнивают ваши структуры по словам, вставляя неиспользуемое пространство для любой структуры, которая не выровнена по словам.

Глядя на следующую структуру, у вас может возникнуть соблазн сказать, что для нее требуется 3 байта памяти. В большинстве случаев компилятор захочет выровнять эти данные по словам, чтобы он мог более эффективно загружать / сохранять данные из памяти. Чтобы выровнять структуру по словам, компилятор вставляет дополнительный байт данных для каждой структуры.Этот байт данных гарантирует, что каждая структура типа Example_Struct будет начинаться на границе слова. Таким образом, на самом деле структура потребляет 4 байт данных.

 структура typedef
{
  uint8_t id;
  uint8_t type;
  значение uint8_t;
} Example_Struct; 

Однако в некоторых ситуациях мы можем не захотеть «выбрасывать» лишний байт данных или могут быть другие требования к макету данных, когда вам действительно нужно только 3 байтов данных на Example_Struct.Чтобы компилятор создал структуру, не выровненную по словам, нам нужно использовать директиву компилятора __packed .

 typedef __packed struct
{
  uint8_t id;
  uint8_t type;
  значение uint8_t;
} Example_Struct; 

Инициализация структуры

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

 #include 
#include 

typedef struct Node Node;

struct Node {
    uint16_t size;
    Узел * следующий;
};

// Инициализировать массив структур вне подпрограммы.// Обратите внимание на дополнительный набор "{" и "}", который
// обозначаем каждый элемент в массиве
Узел MyNodeArray [] =
{
   {
     0,
     НУЛЕВОЙ
   },
   {
     0,
     НУЛЕВОЙ
   }
};

void main (пусто)
{
    // ********************************
    // Инициализируем во время создания экземпляра
    // ********************************
    // Единая структура
    Узел MyNode =
    {
        0,
        НУЛЕВОЙ,
    };

    // ********************************
    // Инициализируем как операторы присваивания
    // ********************************
    MyNode.size = 0;
    MyNode.next = NULL;

    MyNodeArray [0]. Размер = 0;
    MyNodeArray [0] .next = NULL;
    MyNodeArray [1] .size = 0;
    MyNodeArray [1] .next = NULL;

} 

C: typedef имя структуры {...}; VS typedef struct {...} имя;

Здесь происходит несколько вещей. Во-первых, как говорили другие, жалоба компилятора на неизвестный тип может быть связана с тем, что вам нужно определить типы перед их использованием. Однако более важным является понимание синтаксиса трех вещей: (1) определение структуры, (2) объявление структуры и (3) определение типа.

При определении структуры структура может быть названа или безымянной (если она не названа, то ее необходимо использовать немедленно (что это означает далее, поясняется ниже)).

  Имя структуры {
   ...
};
  

Это определяет тип, называемый «имя структуры», который затем можно использовать для объявления переменной структуры:

  Имя структуры myNameStruct;
  

Объявляет переменную с именем myNameStruct , которая является структурой типа Имя структуры .

Вы также можете определить структуру и одновременно объявить переменную структуры:

  Имя структуры {
   ...
} myNameStruct;
  

Как и раньше, здесь объявляется переменная с именем myNameStruct , которая является структурой типа Имя структуры ... Но одновременно с этим определяется тип Имя структуры .
Тип можно снова использовать для объявления другой переменной:

  Имя структуры myOtherNameStruct;
  

Теперь typedef - это просто способ псевдонима типа с определенным именем:

  typedef OldTypeName NewTypeName;
  

Учитывая приведенный выше typedef, каждый раз, когда вы используете NewTypeName , это то же самое, что и OldTypeName . В языке программирования C это особенно полезно для структур, потому что это дает вам возможность опускать слово «структура» при объявлении переменных этого типа и обрабатывать имя структуры просто как отдельный тип (как мы делать в C ++). Вот пример, в котором сначала определяется структура, а затем определяется тип структуры:

  Имя структуры {
   ...
};

typedef имя структуры Name_t;
  

В приведенном выше OldTypeName - это имя структуры , а NewTypeName - Name_t .Итак, теперь, чтобы объявить переменную типа struct Name, вместо того, чтобы писать:

  Имя структуры myNameStruct;
  

Я могу просто написать:

  Name_t myNameStruct;
  

ПРИМЕЧАНИЕ ТАКЖЕ, typedef МОЖЕТ БЫТЬ КОМБИНИРОВАН с определением структуры, и это то, что вы делаете в своем коде:

  typedef struct {
   ...
} Name_t;
  

Это также можно сделать при присвоении имени структуре, но это излишне:

  typedef имя структуры {
   ...
} Name_t;
  

ЗАМЕТКА: В приведенном выше синтаксисе, поскольку вы начали с «typedef», весь оператор представляет собой оператор typedef , в котором OldTypeName является определением структуры. Поэтому компилятор интерпретирует имя, идущее с после правой фигурной скобки} как NewTypeName ... это НЕ имя переменной (как это было бы в синтаксисе без typedef, и в этом случае вы определяете структуру и объявление структурной переменной одновременно).

Кроме того, если вы укажете typedef, но опустите Name_t в конце, то вы фактически создали оператор INCOMPLETE typedef , потому что компилятор считает все в " struct Name {...} " как OldTypeName, и вы не предоставляете NewTypeName для typedef. Вот почему компилятор недоволен кодом в том виде, в каком вы его написали (хотя сообщения компилятора довольно загадочны, потому что он не совсем уверен, что вы сделали не так).

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

  struct {
   ...
} myNameStruct; // объявляет myNameStruct как переменную с этой структурой
                 // определение, но его нельзя использовать повторно.
  

Или вы можете использовать безымянный тип структуры в typedef:

  typedef struct {
   ...
} Name_t;
  

Этот последний синтаксис - это то, что вы на самом деле сделали, когда написали:

  typedef struct {
   char firstName [56];
   char lastName [56];
} Автор;
  

И компилятор был доволен.HTH.

По поводу комментария / вопроса о суффиксе _t:

Суффикс

_t - это соглашение, указывающее людям, читающим код, что символическое имя с _t является именем типа (в отличие от имени переменной). Компилятор не анализирует и не знает о _t.

Стандартные библиотеки C89, и особенно C99, определили многие типы И ВЫБЕРИТЕ ИСПОЛЬЗОВАНИЕ _t для имен этих типов. Например, стандарт C89 определяет wchar_t, off_t, ptrdiff_t. Стандарт C99 определяет множество дополнительных типов, таких как uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t и т. Д.Но _t не зарезервирован, не анализируется специально и не замечается компилятором, это просто соглашение, которому хорошо следовать, когда вы определяете новые типы (через typedef) в C.В C ++ многие люди используют соглашение для начала имен типов с прописными буквами, например MyNewType (в отличие от соглашения C my_new_type_t). HTH

Синтаксис typedef следующий:

  typedef old_type новый_тип
  

В первой попытке вы определили тип struct Book , а не Book .Другими словами, ваш тип данных называется struct Book , а не Book .

Во второй форме вы использовали правильный синтаксис typedef , поэтому компилятор распознает тип с именем Book .

Примеры исходного кода для наших учебных модулей

Компоненты веб-решения Пример из учебного курса Well House Consultants
Подробнее о компонентах веб-решения [ссылка]

Исходный код: examples.txt Модуль: A100

Эта страница является только примером - вы запустили сценарий «Пример исходного кода
» на веб-сайте Well House Consultants, но
вы не сказали нам, какой пример вам нужен.Перейдите по ссылкам
, чтобы найти конкретный пример
, который вы ищете.

Узнать об этом предмете

Книги по этой теме

да. В нашей библиотеке более 700 книг. Книги
Прикрывающее развертывание лампы перечислены здесь, и когда вы выбрали
соответствующую книгу мы свяжем вас с Amazon для заказа.

Другие примеры

Этот пример взят из нашего учебного модуля «Компоненты веб-решения». Вы найдете описание темы и некоторые
другие тесно связанные примеры на индексной странице модуля «Компоненты веб-решения».

Полное описание исходного кода

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

Многие другие учебные модули доступны для загрузки (для ограниченного использования) с
наш центр загрузки под
Лицензия Open Training Notes.

Прочие ресурсы

• В нашем центре решений есть ряд более длинных технических статей.
• В нашем архиве форумов Opentalk есть центр вопросов и ответов.
• Лошадиный рот дает ежедневный совет или мысль.
• Дополнительные ресурсы доступны через ресурсный центр.
• Все эти ресурсы можно найти с помощью нашей поисковой системы
• И здесь есть глобальный индекс.

Назначение сайта

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

Автор веб-сайта

Этот веб-сайт написан и поддерживается
Консультанты Well House.

Условия использования

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *