在 C 中初始化结构数组
Initializing Array of Structure in C
我有以下结构
typedef struct {
int buf[BUF_SIZE]; // the buffer
size_t len; // number of items in the buffer
pthread_mutex_t mutex; // needed to add/remove data from the buffer
pthread_cond_t can_produce; // signaled when items are removed
pthread_cond_t can_consume; // signaled when items are added
};
最初我只是简单地初始化如下
buffer_t buffer = {
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
.can_produce = PTHREAD_COND_INITIALIZER,
.can_consume = PTHREAD_COND_INITIALIZER
};
虽然我想用这些值初始化一个 buffer_t 的数组,但我不太确定如何正确地做到这一点。
类似于
buffer_t buffer[NUM_ARRAY] = {
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
.can_produce = PTHREAD_COND_INITIALIZER,
.can_consume = PTHREAD_COND_INITIALIZER
};
(我意识到这是不正确的)
编辑:我最终使用了
buffer_t buffers[NUM_THREADS];
for (i = 0, i < 3, i ++) {
buffers[i] = (buffer_t) {
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
.can_produce = PTHREAD_COND_INITIALIZER,
.can_consume = PTHREAD_COND_INITIALIZER
};
}
如果你的缓冲区是全局的,你可以在这种特殊情况下保留初始化,因为PTHREAD_MUTEX_INITIALIZER是一个全零的结构。否则,您别无选择,只能初始化所有成员或以编程方式对其进行循环。
如果NUM_ARRAY
不是太大,你可以这样做:
#define NUM_ARRAY 3
buffer_t buffer[NUM_ARRAY] = {
{ {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER},
{ {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER},
{ {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER}
};
或者您可以像这样显式编码:
buffer_t buffer[NUM_ARRAY];
int i;
for (i=0; i<NUM_ARRAY; i++) {
memset(buffer[i].buf, 0, sizeof(buffer[i].buf));
buffer[i].len = 0;
buffer[i].mutex = PTHREAD_MUTEX_INITIALIZER;
buffer[i].can_produce = PTHREAD_COND_INITIALIZER;
buffer[i].can_consume = PTHREAD_COND_INITIALIZER;
}
编辑:
所以看起来 PTHREAD_MUTEX_INITIALIZER
和 PTHREAD_COND_INITIALIZER
宏不能用在这样的赋值中,因为它只能用于初始化并且包含 {
和 }
个字符。
因此您需要使用其他人建议的初始化语法:
buffer_t buffer[NUM_ARRAY];
int i;
for (i=0; i<NUM_ARRAY; i++) {
buffer[i] = (buffer_t) {
0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER
};
}
通常你可以像这样初始化一个结构数组:
#include <stdio.h>
#include <stdlib.h>
typedef struct buffer_t {
int a;
int b;
int c;
} buffer_t;
int main()
{
int i;
int NUM_ARRAY=4;
buffer_t buffer[NUM_ARRAY];
for(i=0; i<NUM_ARRAY; i++)
{
buffer[i].a = 0;
buffer[i].b = 1;
buffer[i].c = 2;
};
return 0;
}
不过我觉得你追求的不止于此?
你需要指定大括号来初始化数组,所以你最后的例子确实不正确。
有多种方法每次都用相同的struct
初始化整个数组:
显式初始化每个数组成员。示例:
buffer_t buffer[NUM_ARRAY] = {
{
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
...
},
{
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
},
...
};
虽然这很乏味。标准的方法是...
使用 for
循环:
buffer_t buffer[NUM_ARRAY];
for (size_t i = 0; i < NUM_ARRAY; ++i) {
buffer[i] = (buffer_t) {
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
...
};
}
方式更好1。然而,还有...
Designated initializer lists。其中一些已经像您正在使用的那样标准化,但这个还没有。因此它是一个非标准的 GCC 扩展,但无论如何都值得一提。示例:
buffer_t buffer[NUM_ARRAY] = {
[0 ... (NUM_ARRAY - 1)] = {
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
...
}
};
不过我推荐第 2nd 选项。
1 (buffer_t) { }
语法仅在 C99 之后可用。如果您的编译器不支持它,请对每个 struct
成员使用简单赋值。
我有以下结构
typedef struct {
int buf[BUF_SIZE]; // the buffer
size_t len; // number of items in the buffer
pthread_mutex_t mutex; // needed to add/remove data from the buffer
pthread_cond_t can_produce; // signaled when items are removed
pthread_cond_t can_consume; // signaled when items are added
};
最初我只是简单地初始化如下
buffer_t buffer = {
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
.can_produce = PTHREAD_COND_INITIALIZER,
.can_consume = PTHREAD_COND_INITIALIZER
};
虽然我想用这些值初始化一个 buffer_t 的数组,但我不太确定如何正确地做到这一点。
类似于
buffer_t buffer[NUM_ARRAY] = {
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
.can_produce = PTHREAD_COND_INITIALIZER,
.can_consume = PTHREAD_COND_INITIALIZER
};
(我意识到这是不正确的)
编辑:我最终使用了
buffer_t buffers[NUM_THREADS];
for (i = 0, i < 3, i ++) {
buffers[i] = (buffer_t) {
.len = 0,
.mutex = PTHREAD_MUTEX_INITIALIZER,
.can_produce = PTHREAD_COND_INITIALIZER,
.can_consume = PTHREAD_COND_INITIALIZER
};
}
如果你的缓冲区是全局的,你可以在这种特殊情况下保留初始化,因为PTHREAD_MUTEX_INITIALIZER是一个全零的结构。否则,您别无选择,只能初始化所有成员或以编程方式对其进行循环。
如果NUM_ARRAY
不是太大,你可以这样做:
#define NUM_ARRAY 3
buffer_t buffer[NUM_ARRAY] = {
{ {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER},
{ {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER},
{ {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER}
};
或者您可以像这样显式编码:
buffer_t buffer[NUM_ARRAY];
int i;
for (i=0; i<NUM_ARRAY; i++) {
memset(buffer[i].buf, 0, sizeof(buffer[i].buf));
buffer[i].len = 0;
buffer[i].mutex = PTHREAD_MUTEX_INITIALIZER;
buffer[i].can_produce = PTHREAD_COND_INITIALIZER;
buffer[i].can_consume = PTHREAD_COND_INITIALIZER;
}
编辑:
所以看起来 PTHREAD_MUTEX_INITIALIZER
和 PTHREAD_COND_INITIALIZER
宏不能用在这样的赋值中,因为它只能用于初始化并且包含 {
和 }
个字符。
因此您需要使用其他人建议的初始化语法:
buffer_t buffer[NUM_ARRAY];
int i;
for (i=0; i<NUM_ARRAY; i++) {
buffer[i] = (buffer_t) {
0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER
};
}
通常你可以像这样初始化一个结构数组:
#include <stdio.h>
#include <stdlib.h>
typedef struct buffer_t {
int a;
int b;
int c;
} buffer_t;
int main()
{
int i;
int NUM_ARRAY=4;
buffer_t buffer[NUM_ARRAY];
for(i=0; i<NUM_ARRAY; i++)
{
buffer[i].a = 0;
buffer[i].b = 1;
buffer[i].c = 2;
};
return 0;
}
不过我觉得你追求的不止于此?
你需要指定大括号来初始化数组,所以你最后的例子确实不正确。
有多种方法每次都用相同的struct
初始化整个数组:
显式初始化每个数组成员。示例:
buffer_t buffer[NUM_ARRAY] = { { .len = 0, .mutex = PTHREAD_MUTEX_INITIALIZER, ... }, { .len = 0, .mutex = PTHREAD_MUTEX_INITIALIZER, }, ... };
虽然这很乏味。标准的方法是...
使用
for
循环:buffer_t buffer[NUM_ARRAY]; for (size_t i = 0; i < NUM_ARRAY; ++i) { buffer[i] = (buffer_t) { .len = 0, .mutex = PTHREAD_MUTEX_INITIALIZER, ... }; }
方式更好1。然而,还有...
Designated initializer lists。其中一些已经像您正在使用的那样标准化,但这个还没有。因此它是一个非标准的 GCC 扩展,但无论如何都值得一提。示例:
buffer_t buffer[NUM_ARRAY] = { [0 ... (NUM_ARRAY - 1)] = { .len = 0, .mutex = PTHREAD_MUTEX_INITIALIZER, ... } };
不过我推荐第 2nd 选项。
1 (buffer_t) { }
语法仅在 C99 之后可用。如果您的编译器不支持它,请对每个 struct
成员使用简单赋值。