Составные литералы (compound literals) позволяют сократить код и использовать литералы, которые представляют структуру, без определения переменной структурыю Например, рассмотрим следующую программу:
#include <stdio.h>
typedef struct{
int x;
int y;
} Point;
void print_point(Point p){
printf("(X:%d; Y:%d)\n", p.x, p.y);
}
int main() {
print_point((Point){.x=1, .y=2});
print_point((Point){3, 4});
return 0;
}
Здесь определена простейшая структура Point с двумя полями. Для вывода этой структуры на консоль определена функция print_point. В функции main мы передаем две структуры в функцию print_point. Однако мы явным образом не определяем переменные этой структуры, а используем составные литералы, которые будут преобразованы в структуру Point. В первом случае используем форму литерала с передачей полям значений по именованными
print_point((Point){.x=1, .y=2});
во втором случае значения передаются позиции
print_point((Point){3, 4});
Консольный вывод:
(X:1; Y:2) (X:3; Y:4)
Аналогичным образом мы можем использовать составные литералы везде, где требуется структура. Например, частая задача - возврат структуры из функции:
#include <stdio.h>
typedef struct{
int x;
int y;
} Point;
void print_point(Point p){
printf("(X:%d; Y:%d)\n", p.x, p.y);
}
Point create_point(int x, int y){
return (Point) {x, y};
}
int main() {
Point p = create_point(170, 150);
print_point(p);
return 0;
}
Функция create_point возвращает структуру, используя составной литерал. Определять переменную при это не надо.
Причем мы также можем использовать и массивы:
#include <stdio.h>
typedef struct{
int x;
int y;
} Point;
void print_points(Point* points, size_t count){
for(size_t i=0; i<count; ++i){
printf("(X:%d; Y:%d)\n", points[i].x, points[i].y);
}
}
int main() {
print_points((Point[]){{5, 10}, {10, 15}, {15, 20}}, 3);
print_points((Point[]){{.x=6, .y=11}, {.x=11, .y=16}, {.x=16, .y=21}}, 3);
return 0;
}
Здесь в функцию print_points передаются массивы структур, для определения которых применяются составные литералы.