Mat*_*att 934 c arrays array-initialize initialization
我在C中有一个大数组(如果有所不同,则不是C++).我想将所有成员初始化为相同的值.我发誓我曾经知道一个简单的方法来做到这一点.我可以memset()在我的情况下使用,但是没有办法在C语法中构建这样做吗?
aib*_*aib 1195
除非该值为0(在这种情况下,您可以省略初始化程序的某些部分,并且相应的元素将初始化为0),否则没有简单的方法.
但是,不要忽视明显的解决方案:
int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };
Run Code Online (Sandbox Code Playgroud)
缺少值的元素将初始化为0:
int myArray[10] = { 1, 2 }; // initialize to 1,2,0,0,0...
Run Code Online (Sandbox Code Playgroud)
所以这会将所有元素初始化为0:
int myArray[10] = { 0 }; // all elements 0
Run Code Online (Sandbox Code Playgroud)
在C++中,空的初始化列表也会将每个元素初始化为0. C 不允许这样做:
int myArray[10] = {}; // all elements 0 in C++
Run Code Online (Sandbox Code Playgroud)
请记住,如果未指定初始化程序,具有静态存储持续时间的对象将初始化为0:
static int myArray[10]; // all elements 0
Run Code Online (Sandbox Code Playgroud)
而"0"并不一定意味着"所有位为零",因此使用上述内容比memset()更好,更便携.(浮点值将初始化为+0,指向空值的指针等)
qrd*_*rdl 383
如果您的编译器是GCC,您可以使用以下语法:
int array[1024] = {[0 ... 1023] = 5};
Run Code Online (Sandbox Code Playgroud)
查看详细说明:http: //gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html
mou*_*iel 176
要静态初始化具有相同值的大型数组,而不使用多个复制粘贴,您可以使用宏:
#define VAL_1X 42
#define VAL_2X VAL_1X, VAL_1X
#define VAL_4X VAL_2X, VAL_2X
#define VAL_8X VAL_4X, VAL_4X
#define VAL_16X VAL_8X, VAL_8X
#define VAL_32X VAL_16X, VAL_16X
#define VAL_64X VAL_32X, VAL_32X
int myArray[53] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };
Run Code Online (Sandbox Code Playgroud)
如果您需要更改该值,则必须仅在一个地方进行更换.
您可以通过以下方式轻松概括:
#define VAL_1(X) X
#define VAL_2(X) VAL_1(X), VAL_1(X)
/* etc. */
Run Code Online (Sandbox Code Playgroud)
可以使用以下方法创建变体:
#define STRUCTVAL_1(...) { __VA_ARGS__ }
#define STRUCTVAL_2(...) STRUCTVAL_1(__VA_ARGS__), STRUCTVAL_1(__VA_ARGS__)
/*etc */
Run Code Online (Sandbox Code Playgroud)
适用于结构或复合数组.
#define STRUCTVAL_48(...) STRUCTVAL_32(__VA_ARGS__), STRUCTVAL_16(__VA_ARGS__)
struct Pair { char key[16]; char val[32]; };
struct Pair p_data[] = { STRUCTVAL_48("Key", "Value") };
int a_data[][4] = { STRUCTVAL_48(12, 19, 23, 37) };
Run Code Online (Sandbox Code Playgroud)
宏名称可以协商.
Fra*_*rba 62
如果要确保显式初始化数组的每个成员,只需省略声明中的维:
int myArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Run Code Online (Sandbox Code Playgroud)
编译器将从初始化列表中推断出维度.不幸的是,对于多维数组,只能省略最外层的维度:
int myPoints[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
Run Code Online (Sandbox Code Playgroud)
没关系,但是
int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
Run Code Online (Sandbox Code Playgroud)
不是.
abe*_*nky 49
我看到一些使用这种语法的代码:
char* array[] =
{
[0] = "Hello",
[1] = "World"
};
Run Code Online (Sandbox Code Playgroud)
如果您正在创建一个使用枚举作为索引的数组,它变得特别有用:
enum
{
ERR_OK,
ERR_FAIL,
ERR_MEMORY
};
#define _ITEM(x) [x] = #x
char* array[] =
{
_ITEM(ERR_OK),
_ITEM(ERR_FAIL),
_ITEM(ERR_MEMORY)
};
Run Code Online (Sandbox Code Playgroud)
这样可以使事情保持正常,即使您碰巧无序地编写了一些枚举值.
Tar*_*ski 22
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
myArray[i] = VALUE;
}
Run Code Online (Sandbox Code Playgroud)
我认为这比
int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...
Run Code Online (Sandbox Code Playgroud)
加入数组大小的变化.
pli*_*nth 13
你可以像上面详细描述的那样完成整个静态初始化器的事情,但是当你的数组大小改变时(当你的数组嵌入时,如果你没有添加适当的额外初始化器你得到垃圾),它可能是一个真正的无赖.
memset为您的工作提供了运行时命中,但没有正确执行的代码大小不受阵列大小更改的影响.几乎在所有情况下,当数组大于几十个元素时,我会使用此解决方案.
如果静态声明数组非常重要,我会编写一个程序来为我编写程序并使其成为构建过程的一部分.
这是另一种方式:
static void
unhandled_interrupt(struct trap_frame *frame, int irq, void *arg)
{
//this code intentionally left blank
}
static struct irqtbl_s vector_tbl[XCHAL_NUM_INTERRUPTS] = {
[0 ... XCHAL_NUM_INTERRUPTS-1] {unhandled_interrupt, NULL},
};
Run Code Online (Sandbox Code Playgroud)
看到:
指定的内容
然后问一个问题:什么时候可以使用C扩展?
上面的代码示例位于嵌入式系统中,永远不会看到来自其他编译器的光.
对于初始化'普通'数据类型(如int数组),您可以使用括号表示法,但如果数组中仍有空格,它将在最后一个之后将值归零:
// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};
Run Code Online (Sandbox Code Playgroud)
一个略微诙谐的答案; 写下声明
array = initial_value
Run Code Online (Sandbox Code Playgroud)
用您最喜欢的支持数组的语言(我的是Fortran,但还有很多其他语言),并将其链接到您的C代码.你可能想把它包装成一个外部函数.
有一种快速的方法可以用给定的值初始化任何类型的数组。它适用于大型阵列。算法如下:
对于1 000 000元素int数组,它比常规循环初始化快 4 倍(i5,2 核,2.3 GHz,4GiB 内存,64 位):
loop runtime 0.004248 [seconds]
memfill() runtime 0.001085 [seconds]
#include <stdio.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 1000000
void memfill(void *dest, size_t destsize, size_t elemsize) {
char *nextdest = (char *) dest + elemsize;
size_t movesize, donesize = elemsize;
destsize -= elemsize;
while (destsize) {
movesize = (donesize < destsize) ? donesize : destsize;
memcpy(nextdest, dest, movesize);
nextdest += movesize; destsize -= movesize; donesize += movesize;
}
}
int main() {
clock_t timeStart;
double runTime;
int i, a[ARR_SIZE];
timeStart = clock();
for (i = 0; i < ARR_SIZE; i++)
a[i] = 9;
runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
printf("loop runtime %f [seconds]\n",runTime);
timeStart = clock();
a[0] = 10;
memfill(a, sizeof(a), sizeof(a[0]));
runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
printf("memfill() runtime %f [seconds]\n",runTime);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道最初的问题明确提到了 C 而不是 C++,但是如果你(像我一样)来这里寻找 C++ 数组的解决方案,这里有一个巧妙的技巧:
如果您的编译器支持折叠表达式,您可以使用模板魔术并使用std::index_sequence您想要的值生成一个初始化列表。你甚至constexpr可以感觉像一个老板:
#include <array>
/// [3]
/// This functions's only purpose is to ignore the index given as the second
/// template argument and to always produce the value passed in.
template<class T, size_t /*ignored*/>
constexpr T identity_func(const T& value) {
return value;
}
/// [2]
/// At this point, we have a list of indices that we can unfold
/// into an initializer list using the `identity_func` above.
template<class T, size_t... Indices>
constexpr std::array<T, sizeof...(Indices)>
make_array_of_impl(const T& value, std::index_sequence<Indices...>) {
return {identity_func<T, Indices>(value)...};
}
/// [1]
/// This is the user-facing function.
/// The template arguments are swapped compared to the order used
/// for std::array, this way we can let the compiler infer the type
/// from the given value but still define it explicitly if we want to.
template<size_t Size, class T>
constexpr std::array<T, Size>
make_array_of(const T& value) {
using Indices = std::make_index_sequence<Size>;
return make_array_of_impl(value, Indices{});
}
// std::array<int, 4>{42, 42, 42, 42}
constexpr auto test_array = make_array_of<4/*, int*/>(42);
static_assert(test_array[0] == 42);
static_assert(test_array[1] == 42);
static_assert(test_array[2] == 42);
static_assert(test_array[3] == 42);
// static_assert(test_array[4] == 42); out of bounds
Run Code Online (Sandbox Code Playgroud)
你可以看看工作中的代码(在Wandbox)
| 归档时间: |
|
| 查看次数: |
1793608 次 |
| 最近记录: |