我在 C 中有一个大型数组(如果这有区别的话,不是 C++)。我希望将所有成员初始化为相同的值。
我记得曾经知道一种简单的方法来做到这一点。虽然我可以在我的情况下使用 memset()
,但是否有一种内置于 C 语法中的方法来实现这一点呢?
我在 C 中有一个大型数组(如果这有区别的话,不是 C++)。我希望将所有成员初始化为相同的值。
我记得曾经知道一种简单的方法来做到这一点。虽然我可以在我的情况下使用 memset()
,但是否有一种内置于 C 语法中的方法来实现这一点呢?
如果数组的大小事先已知,可以使用Boost预处理器C_ARRAY_INITIALIZE宏来帮助您完成繁琐的工作:
#include <boost/preprocessor/repetition/enum.hpp>
#define C_ARRAY_ELEMENT(z, index, name) name[index]
#define C_ARRAY_EXPAND(name,size) BOOST_PP_ENUM(size,C_ARRAY_ELEMENT,name)
#define C_ARRAY_VALUE(z, index, value) value
#define C_ARRAY_INITIALIZE(value,size) BOOST_PP_ENUM(size,C_ARRAY_VALUE,value)
int a[5] = {3,3,3,3,3};
正式的初始化技术。
方法2:
int a[100] = {0};
但值得注意的是
int a[10] = {1};
不要将所有值初始化为1
这种初始化方式仅适用于0
如果你只是这样做
int a[100];
一些编译器倾向于采用垃圾值,因此最好这样做。
int a[1000] = {0};
作为Clemens Sielaff答案的跟进,这个版本需要C++17。
template <size_t Cnt, typename T>
std::array<T, Cnt> make_array_of(const T& v)
{
return []<size_t... Idx>(std::index_sequence<Idx...>, const auto& v)
{
auto identity = [](const auto& v, size_t) { return v; };
return std::array{identity(v, Idx)...};
}
(std::make_index_sequence<Cnt>{}, v);
}
你可以在这里看到它的效果。
// macros.h
#define INDEX_SEQUENCE(X) _indexseq_expand(X)
#define _indexseq_expand(X) _indeseq_concat(_indexseq, X)
#define _indexseq_concat(a, b) _indexseq_concat_expand(a, b)
#define _indexseq_concat_expand(a, b) a##b
#define _indexseq1 0
#define _indexseq2 _indexseq1, 1
// generate as above to a given max size
#define APPLY_FOR_EACH(macro, ...) _foreach(macro, _vaargsn(__VA_ARGS__), __VA_ARGS__)
#define _foreach(macro, n, ...) _foreach_concat(_foreach, n)(macro, __VA_ARGS__)
#define _foreach_concat(a, b) _foreach_concat_expand(a, b)
#define _foreach_concat_expand(a, b) a##b
#define _foreach1(macro, i) macro(i)
#define _foreach2(macro, i, ...) macro(i) _foreach1(__VA_ARGS__)
// generate as above to a given max size
#define _vaargsn(...) _vaargsnpp(__VA_ARGS__, _vaargsnidx())
// macros below shall be generated as well until a given max size
#define _vaargsnpp(_1, _2, _3, N, ...) N
#define _vaargsnidx() 3, 2, 1
#define CONFIGURED_SIZE 42
struct complex_struct {
int zero, one;
float pi;
unsigned index;
};
#define INIT(I) { 0, 1, 3.14159f, I },
struct complex_struct array[CONFIGURED_SIZE] = {
APPLY_FOR_EACH(INIT, INDEX_SEQUENCE(CONFIGURED_SIZE))
};
回到过去的日子里(我并不是说这是一个好主意),我们会设置第一个元素,然后:
memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);
甚至不确定它现在是否还能工作(这取决于memcpy的实现),但它通过重复将初始元素复制到下一个元素来工作 - 甚至适用于结构体数组。
memcpy
的函数,但在重叠的情况下指定自下而上或自上而下的复制顺序,但它没有这样做。 - supercat#include<stdio.h>
int main(){
int i,a[50];
for (i=0;i<50;i++){
a[i]=5;// set value 5 to all the array index
}
for (i=0;i<50;i++)
printf("%d\n",a[i]);
return 0;
}
它将输出5 5 5 5 5 5 ...... 直到整个数组的大小
我在问题中没有看到任何要求,因此解决方案必须是通用的:初始化一个可能是多维数组的未指定可能是结构元素的数组,并具有初始成员值:
#include <string.h>
void array_init( void *start, size_t element_size, size_t elements, void *initval ){
memcpy( start, initval, element_size );
memcpy( (char*)start+element_size, start, element_size*(elements-1) );
}
// testing
#include <stdio.h>
struct s {
int a;
char b;
} array[2][3], init;
int main(){
init = (struct s){.a = 3, .b = 'x'};
array_init( array, sizeof(array[0][0]), 2*3, &init );
for( int i=0; i<2; i++ )
for( int j=0; j<3; j++ )
printf("array[%i][%i].a = %i .b = '%c'\n",i,j,array[i][j].a,array[i][j].b);
}
结果:
array[0][0].a = 3 .b = 'x'
array[0][1].a = 3 .b = 'x'
array[0][2].a = 3 .b = 'x'
array[1][0].a = 3 .b = 'x'
array[1][1].a = 3 .b = 'x'
array[1][2].a = 3 .b = 'x'
编辑:将start+element_size
更改为(char*)start+element_size
sizeof(void)
是否有效。 - Chris Lutzmemcpy()
中的源数据与目标空间重叠。使用天真的memcpy()
实现可能会起作用,但系统不要求它能够正常工作。 - Jonathan Leffler
enum { HYDROGEN = 1, HELIUM = 2, CARBON = 6, NEON = 10, … };
和struct element { char name[15]; char symbol[3]; } elements[] = { [NEON] = { "Neon", "Ne" }, [HELIUM] = { "Helium", "He" }, [HYDROGEN] = { "Hydrogen", "H" }, [CARBON] = { "Carbon", "C" }, … };
。如果删除省略号…
,这些片段可以在C99或C11下编译通过。 - Jonathan Lefflermemset()
特定讨论:https://dev59.com/qmw05IYBdhLWcg3wfx80 我认为它只适用于0。 - Ciro Santilli OurBigBook.commemset()
只适用于值为0
、UINT_MAX
和元素大小为char
的数组。 - user16217248