Из Википедии, свободной энциклопедии
Перейти к навигацииПерейти к поиску

Структура в языке программирования Си (и во многих производных) является составным типом данных (или запись ) Декларация , которая определяет физически сгруппирован список переменных под одним именем в блоке памяти, позволяя различные переменные , которые будут доступны через один указатель или по объявленному имени структуры, которое возвращает тот же адрес. Тип данных struct может содержать другие типы данных, поэтому используется для записей смешанного типа, таких как запись каталога жесткого диска (длина файла, имя, расширение, физический адрес и т. Д.) Или других записей смешанного типа (имя , адрес, телефон, баланс и т. д.).

Структура C напрямую ссылается на непрерывный блок физической памяти, обычно ограниченный (размерный) границами длины слова. Это соответствует одноименной функции, доступной в некоторых ассемблерах для процессоров Intel. Будучи блоком непрерывной памяти, каждое поле в структуре расположено с определенным фиксированным смещением от начала.

Поскольку содержимое структуры хранится в непрерывной памяти, оператор sizeof должен использоваться для получения количества байтов, необходимых для хранения структуры определенного типа, точно так же, как он может использоваться для примитивов . Выравнивание определенных полей в структуре (относительно границ слов ) зависит от реализации и может включать заполнение, хотя современные компиляторы обычно поддерживают #pragma packдирективу, которая изменяет размер в байтах, используемых для выравнивания. [1]

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

На других языках

Тип данных struct в C был производным от типа данных структуры ALGOL 68 . [2]

Как и его аналог в C, тип данных struct в C # ( Structure в Visual Basic .NET ) похож на класс . Самая большая разница между структурой и классом в этих языках заключается в том, что когда структура передается в качестве аргумента функции, любые изменения структуры в этой функции не будут отражены в исходной переменной (если только передача по ссылке не указана). использовал). [3]

Это отличается от C ++, где классы или структуры могут выделяться статически или динамически выделяться либо в стеке (аналогично C #), либо в куче с явным указателем. В C ++ единственная разница между структурой и классом состоит в том, что члены и базовые классы структуры по умолчанию являются общедоступными . (Класс, определенный с помощью classключевого слова, по умолчанию имеет частные члены и базовые классы.)

Декларация

Общий синтаксис объявления структуры в C:

struct  tag_name  {  type  member1 ;  тип  member2 ;  / * объявляем столько членов, сколько нужно, но компилятору должен быть известен полный размер структуры. * / };

Здесь не tag_nameявляется обязательным в некоторых контекстах.

Такое structобъявление может также появляться в контексте объявления typedef псевдонима типа или объявления или определения переменной:

typedef  struct  tag_name  {  тип  member1 ;  тип  member2 ; }  struct_alias ;

Инициализация

Есть три способа инициализировать структуру. Для structтипа

/ * Объявляем структуру с целыми членами x, y * / struct  point  {  int  x ;  int  y ; };

Инициализаторы в стиле C89 используются, когда могут быть заданы смежные члены. [4]

/ * Определение переменной p типа point и инициализация ее первых двух членов на месте * / struct  point  p  =  {  1 ,  2  };

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

/ * Определение переменной p типа point и установка членов с использованием назначенных инициализаторов * / struct  point  p  =  {  . у  =  2 ,  . х  =  1  };

Если указан инициализатор или объект статически размещен , пропущенные элементы инициализируются значением 0. [6]

Третий способ инициализации структуры - скопировать значение существующего объекта того же типа.

/ * Определить переменную q типа point и установить для членов те же значения, что и у p * / struct  point  q  =  p ;

Назначение

Структура может быть назначена другой структуре. Компилятор может использовать memcpy()для выполнения такого назначения.

struct  point  {  int  x ;  int  y ; };int  main ( void ) {  точка структуры  p = { 1 , 3 }; / * инициализированная переменная * / struct point q ; / * неинициализировано * / q = p ; / * копируем значения членов из p в q * / return 0 ; }                 

Указатели на структуру

Указатели могут использоваться для ссылки на объект structпо его адресу. Это полезно для передачи структур в функцию. Указатель можно разыменовать с помощью *оператора. ->Оператор разыменовывает указатель на структуру (левый операнд) , а затем получает доступ значения члена структуры (правый операнд).

struct  point  {  int  x ;  int  y ; }; struct  point  my_point  =  {  3 ,  7  }; struct  point  * p  =  & my_point ;  / * p - указатель на my_point * / ( * p ). х  =  8 ;  / * устанавливаем первый член структуры * / p -> x  =  8 ;  / * эквивалентный метод для установки первого члена структуры * /

См. Также

Ссылки

  1. ^ "Структура памяти в C" . Переполнение стека .
  2. ^ Ричи, Деннис М. (март 1993). «Развитие языка Си» . Уведомления ACM SIGPLAN . 28 (3): 201–208. DOI : 10.1145 / 155360.155580 . Схема набора шрифтов, принятая в Си, в значительной степени обязана Алголу 68, хотя, возможно, она не возникла в той форме, которую одобрили бы приверженцы Алгола. Центральным понятием, которое я уловил из Алгола, была структура типов, основанная на атомарных типах (включая структуры), составленных в массивы, указатели (ссылки) и функции (процедуры). Концепция объединений и приведений в Алголе 68 также оказала влияние, появившееся позже.
  3. ^ "Передача параметров в C #" .
  4. ^ Келли, Эл; Поль, Ира (2004). Книга о C: Программирование на C (Четвертое изд.). С.  418 . ISBN 0-201-18399-4.
  5. ^ "Компиляторы IBM Linux. Инициализация структур и объединений" .
  6. ^ "Новый стандарт C, инициализация §6.7.8" .