Можно ли привести простой блок кода в структуру? - PullRequest
0 голосов
/ 18 февраля 2019

Рассмотрим этот код:

#include <stdio.h>

int main()
{
  struct test {
    int i;
    int t;
  };

  struct test hello = (struct test) {
    .i = 0, 
    .t = 1
  };

  printf("%d, %d\n", hello.i, hello.t);

  return 0;
}

Вывод:

0, 1

У меня вопрос, что делает эта строка (struct test) {.i = 0, .t = 1 }?

это приведение блокакода для ввода структуры теста?это вообще возможно?

если нет, скажите, пожалуйста, что он делает, и спасибо.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

В C (и многих связанных с ним языках программирования) фигурные скобки часто означают:

{ это то место, где начинается код
} это то место, где код заканчивается

Они также могут иметь несколько разных значений.Они относятся не только к коду, но и к структурам данных:

struct point {
    int x;
    int y;
};

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

struct point pythagoras = {
    .x = 3,
    .y = 4
};

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

В заключение, { означает начало, а } означает конец.Ничего более.

«Код», который инициализирует ваш struct test, на самом деле не код, хотя на самом деле он выглядит так.Здесь это снова:

struct test hello = (struct test) {
    .i = 0, 
    .t = 1
};

Обычно (type) означает приведение типа.Но в этом случае за (struct test) следует открывающая скобка {, и эта комбинация называется составным литералом .Это литерал для переменной составного типа данных.

0 голосов
/ 18 февраля 2019

struct test hello = (struct test) { .i = 0, .t = 1 }; использует две функции C, называемые составные литералы и обозначенные инициализаторы .

Общая форма составного литерала: ( имя типа ) { список инициализаторов }.(Также может быть запятая после списка.) Например, это составные литералы:

(int) { 3 }
(int []) { 0, 1, 2 }
(union { float f; unsigned int u; }) = { 3.4 }

Составной литерал - это объект без имени.

В простом списке инициализаторавы просто перечисляете значения для элементов в инициализируемом объекте.Однако вы также можете использовать назначенные инициализаторы.Назначенный инициализатор использует либо имя элемента структуры, либо индекс элемента массива, чтобы указать, какой части объекта должно быть присвоено указанное значение:

{ struct { int a, b, c; }) = { .b = 4, .c = 1, .a = 9 }
(int a[1024]) = { [473] = 1, [978] = -1 }

Итак, в struct test hello = (struct test) { .i = 0, .t = 1 }; мысоздаем struct test с i, инициализированным в 0, и t, инициализированным в 1. Затем этот struct test используется для инициализации другого структурного теста с именем hello.

Это конкретное использование бессмысленно,поскольку он создает временный объект с целью чего-то, что могло бы быть сделано напрямую.Номинально он создает временный struct test, который инициализируется, а затем копируется в struct test hello.Тогда временный struct test больше не используется.Эффект такой же, как простое написание struct test hello = { .i = 0, .t = 1};.Это инициализирует hello без использования временного объекта.Однако хороший компилятор оптимизирует их под тот же код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...