在C语言中声明和初始化数组
有没有一种方法可以在C中先声明然后初始化数组 到目前为止,我一直在初始化一个数组,如下所示:在C语言中声明和初始化数组,c,arrays,initialization,C,Arrays,Initialization,有没有一种方法可以在C中先声明然后初始化数组 到目前为止,我一直在初始化一个数组,如下所示: int myArray[SIZE] = {1,2,3,4....}; 但我需要这样做 int myArray[SIZE]; myArray = {1,2,3,4....}; 为什么在声明时不能初始化 您使用的是哪种C编译器?它支持C99吗 如果它支持C99,您可以在需要的地方声明变量,并在声明时初始化它 我能想到的不这样做的唯一借口是,你需要声明它,但在使用它之前要提前退出,这样初始化器就浪费了。
int myArray[SIZE] = {1,2,3,4....};
但我需要这样做
int myArray[SIZE];
myArray = {1,2,3,4....};
为什么在声明时不能初始化 您使用的是哪种C编译器?它支持C99吗 如果它支持C99,您可以在需要的地方声明变量,并在声明时初始化它
我能想到的不这样做的唯一借口是,你需要声明它,但在使用它之前要提前退出,这样初始化器就浪费了。然而,我怀疑任何这样的代码都没有像它应该的那样干净地组织,并且可以编写,因此它不是一个问题。在C99中,您可以使用复合文字和
memcpy
memcpy(myarray, (int[]) { 1, 2, 3, 4 }, sizeof myarray);
(假设源和目标的大小相同)
在C89/90中,您可以通过声明一个额外的“源”数组来模拟它
有没有办法先申报,再申报
然后用C初始化一个数组
有!但是不要使用你描述的方法
不能使用逗号分隔的列表进行初始化,这仅在声明中允许。但是,您可以使用
myArray[0] = 1;
myArray[1] = 2;
...
或
for(int i=1;iNo),不能在一条语句中将它们设置为任意值(除非作为声明的一部分进行设置)
您可以使用以下代码执行此操作:
myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 27;
:
myArray[99] = -7;
static const int onceArr[] = { 0, 1, 2, 3, 4,..., 99};
static const int twiceArr[] = { 0, 2, 4, 6, 8,...,198};
:
int myArray[7];
:
memcpy (myArray, twiceArr, sizeof (myArray));
或者(如果有公式):
这种方法的优点是(很可能)速度更快,并且允许您创建比模板更小的数组。我曾在必须快速重新初始化数组,但要将其重新初始化到特定状态的情况下使用过这种方法(如果状态都为零,我只会使用memset
)
您甚至可以将其本地化为初始化功能:
void initMyArray (int *arr, size_t sz) {
static const int template[] = {2, 3, 5, 7, 11, 13, 17, 19, 21, ..., 9973};
memcpy (arr, template, sz);
}
:
int myArray[100];
initMyArray (myArray, sizeof(myArray));
静态数组(几乎可以肯定)将在编译时创建,因此不会产生运行时成本,而且memcpy
应该非常快,可能比1229条赋值语句快,但肯定会少键入:-).在声明数组一次后,没有这种特殊的方法可以初始化数组
只有三种选择:
1。)在不同的行中初始化它们:
int array[SIZE];
array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
//...
//...
//...
但我想那不是你想要的
2。)使用for或while循环初始化它们:
for (i = 0; i < MAX ; i++) {
array[i] = i;
}
(i=0;i{
数组[i]=i;
}
这是实现目标的最佳途径
3。)如果您需要在一行中初始化数组本身,则必须至少定义一个具有初始化功能的数组。然后将其复制到目标数组,但我认为这样做没有好处,在这种情况下,您应该在一行中定义并初始化数组本身
我可以问你为什么要这么做吗?这是AndreyT接受答案的附录,其中有Nyan对不匹配数组大小的评论。我不同意他们自动将第五个元素设置为零。它应该是5——1,2,3,4之后的数字。因此,我建议使用memcpy()的包装器,在尝试复制不同大小的数组时产生编译时错误:
#define Memcpy(a,b) do { /* copy arrays */ \
ASSERT(sizeof(a) == sizeof(b) && /* a static assert */ \
sizeof(a) != sizeof((a) + 0)); /* no pointers */ \
memcpy((a), (b), sizeof (b)); /* & unnecesary */ \
} while (0) /* no return value */
如果数组长度为1,则此宏将生成编译时错误。这也许是一个特点
因为我们使用的是宏,C99复合文字似乎需要一对额外的括号:
Memcpy(myarray, ((int[]) { 1, 2, 3, 4 }));
这里ASSERT()是一个“静态断言”。如果您还没有自己的平台,我将在多个平台上使用以下功能:
#define CONCAT_TOKENS(a, b) a ## b
#define EXPAND_THEN_CONCAT(a,b) CONCAT_TOKENS(a, b)
#define ASSERT(e) enum {EXPAND_THEN_CONCAT(ASSERT_line_,__LINE__) = 1/!!(e)}
#define ASSERTM(e,m) /* version of ASSERT() with message */ \
enum{EXPAND_THEN_CONCAT(m##_ASSERT_line_,__LINE__)=1/!!(e)}
OP遗漏了问题中的一些关键信息,仅将其放在对答案的评论中 我需要在声明后初始化,因为将不同 取决于一个条件,我指的是类似于int的东西 myArray[大小];如果(条件1){myArray{x1,x2,x3,…}}else 如果(条件2){myArray{y1,y2,y3,…}。等等 记住这一点,所有可能的数组无论如何都需要存储到数据中的某个地方,因此不需要(或需要)memcpy,只需要一个指针和一个2d数组
//static global since some compilers build arrays from instruction data
//... notably not const though so they can later be modified if needed
#define SIZE 8
static int myArrays[2][SIZE] = {{0,1,2,3,4,5,6,7},{7,6,5,4,3,2,1,0}};
static inline int *init_myArray(_Bool conditional){
return myArrays[conditional];
}
// now you can use:
//int *myArray = init_myArray(1 == htons(1)); //any boolean expression
非内联版本在x86_64上提供此结果程序集:
init_myArray(bool):
movzx eax, dil
sal rax, 5
add rax, OFFSET FLAT:myArrays
ret
myArrays:
.long 0
.long 1
.long 2
.long 3
.long 4
.long 5
.long 6
.long 7
.long 7
.long 6
.long 5
.long 4
.long 3
.long 2
.long 1
.long 0
对于其他条件/数组,只需将myArrays中的2更改为所需的数字,并使用类似的逻辑获取指向正确数组的指针。初始化后,不可能一次将值全部分配给数组。 最好的选择是使用循环
for(i=0;i<N;i++)
{
array[i] = i;
}
for(i=0;iThanks用于快速回复!我需要在声明后进行初始化,因为根据条件会有所不同,我的意思是类似于int-myArray[SIZE];if(condition1){myArray{x1,x2,x3,}}或者if(condition2){myArray{y1,y2,y3,}…等等。我使用的是XcodeArray是常量吗?如果是,一种可能是使用两个单独的初始化常量数组,然后设置一个指针(指向常量数据)指向相关数组。你也可以将数组设置为静态。如果数组不是常量,那么我相信你必须依次计算每个元素。是的,数组是常量,我也会尝试这种方法,谢谢。我肯定会说静态
。我认为在我的情况下,最方便的方法是,不分配每个元素元素,将每个所需数组复制到全局数组。非常感谢您为C99添加了+1;)memcpy(myarray,(int[sizeof(myarray)/sizeof(myarray[0]){1,2,3,4},sizeof myarray);将其余部分初始化为适当的零。@Nyan:好主意。如果初始值设定项太多,这也会触发一个错误。我在你的答案中发布了一个附录,如果初始值设定项太少,这也会触发编译时错误。谢谢,但我要找的是能够在逗号分隔的列表中初始化它,因为e阵列将非常大,我认为这样会更方便
//static global since some compilers build arrays from instruction data
//... notably not const though so they can later be modified if needed
#define SIZE 8
static int myArrays[2][SIZE] = {{0,1,2,3,4,5,6,7},{7,6,5,4,3,2,1,0}};
static inline int *init_myArray(_Bool conditional){
return myArrays[conditional];
}
// now you can use:
//int *myArray = init_myArray(1 == htons(1)); //any boolean expression
init_myArray(bool):
movzx eax, dil
sal rax, 5
add rax, OFFSET FLAT:myArrays
ret
myArrays:
.long 0
.long 1
.long 2
.long 3
.long 4
.long 5
.long 6
.long 7
.long 7
.long 6
.long 5
.long 4
.long 3
.long 2
.long 1
.long 0
for(i=0;i<N;i++)
{
array[i] = i;
}