C语言 在 C 中声明和初始化数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3137671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:45:34  来源:igfitidea点击:

Declaring and initializing arrays in C

carraysinitialization

提问by Dave H

Is there a way to declare first and then initialize an array in C?

有没有办法先声明然后在 C 中初始化数组?

So far I have been initializing an array like this:

到目前为止,我一直在初始化这样的数组:

int myArray[SIZE] = {1,2,3,4....};

But I need to do something like this

但我需要做这样的事情

int myArray[SIZE];

myArray = {1,2,3,4....};

采纳答案by AnT

In C99 you can do it using a compound literal in combination with memcpy

在 C99 中,您可以使用复合文字与 memcpy

memcpy(myarray, (int[]) { 1, 2, 3, 4 }, sizeof myarray);

(assuming that the size of the source and the size of the target is the same).

(假设源的大小和目标的大小相同)。

In C89/90 you can emulate that by declaring an additional "source" array

在 C89/90 中,您可以通过声明一个额外的“源”数组来模拟它

const int SOURCE[SIZE] = { 1, 2, 3, 4 }; /* maybe `static`? */
int myArray[SIZE];
...
memcpy(myarray, SOURCE, sizeof myarray);

回答by paxdiablo

No, you can't set them to arbitrary values in one statement (unless done as part of the declaration).

不,您不能在一个语句中将它们设置为任意值(除非作为声明的一部分完成)。

You can either do it with code, something like:

您可以使用代码来完成,例如:

myArray[0] = 1;
myArray[1] = 2;
myArray[2] = 27;
:
myArray[99] = -7;

or (if there's a formula):

或(如果有公式):

for (int i = 0; i < 100; i++) myArray[i] = i + 1;

The other possibility is to keep around some templates that areset at declaration time and use them to initialise your array, something like:

另一种可能是让周围的一些模板设定在声明时并用它们来初始化您的数组,是这样的:

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));

This has the advantage of (most likely) being faster and allows you to create smaller arrays than the templates. I've used this method in situations where I have to re-initialise an array fast but to a specific state (if the state were all zeros, I would just use memset).

这具有(很可能)更快的优点,并允许您创建比模板更小的数组。我在必须快速重新初始化数组但要重新初始化为特定状态的情况下使用了此方法(如果状态全为零,我将只使用memset)。



You can even localise it to an initialisation function:

您甚至可以将其本地化为初始化函数:

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));

The static array will (almost certainly) be created at compile time so there will be no run-time cost for that, and the memcpyshould be blindingly fast, likely faster than 1,229 assignment statements but very definitely less typing on your part :-).

静态数组将(几乎可以肯定)在编译时创建,因此不会有运行时成本,并且memcpy应该非常快,可能比 1,229 个赋值语句还要快,但您的输入肯定会更少:-)。

回答by Jacob

Is there a way to declare first and then initialize an array in C?

有没有办法先声明然后在 C 中初始化数组?

There is! but not using the method you described.

有!但没有使用您描述的方法。

You can't initialize with a comma separated list, this is only allowed in the declaration. You can however initialize with...

你不能用逗号分隔的列表初始化,这只能在声明中使用。但是,您可以使用...初始化

myArray[0] = 1;
myArray[1] = 2;
...

or

或者

for(int i = 1; i <= SIZE; i++)
{
  myArray[i-1] = i;
}

回答by Joseph Quinsey

This is an addendum to the accepted answer by AndreyT, with Nyan's comment on mismatched array sizes. I disagree with their automatic setting of the fifth element to zero. It should likely be 5--the number after 1,2,3,4. So I would suggest a wrapper to memcpy() to produce a compile-timeerror when we try to copy arrays of different sizes:

这是 AndreyT 接受的答案的附录,其中包含 Nyan 对不匹配数组大小的评论。我不同意他们将第五个元素自动设置为零。它应该有可能是51,2,3,4后--the号。因此,当我们尝试复制不同大小的数组时,我建议使用 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 */

This macro will generate a compile-time error if your array is of length 1. Which is perhaps a feature.

如果您的数组长度为 1,此宏将生成编译时错误。这可能是一个功能。

Because we are using a macro, the C99 compound literal seems to need an extra pair of parentheses:

因为我们使用的是宏,所以 C99 复合文字似乎需要一对额外的括号:

Memcpy(myarray, ((int[]) { 1, 2, 3, 4 }));

Here ASSERT() is a 'static assert'. If you don't already have your own, I use the following on a number of platforms:

这里的 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)}

回答by Jonathan Leffler

Why can't you initialize when you declare?

为什么声明的时候不能初始化?

Which C compiler are you using? Does it support C99?

您使用的是哪种 C 编译器?支持C99吗?

If it does support C99, you can declare the variable where you need it and initialize it when you declare it.

如果它确实支持 C99,您可以在需要它的地方声明该变量,并在声明时对其进行初始化。

The only excuse I can think of for not doing that would be because you need to declare it but do an early exit before using it, so the initializer would be wasted. However, I suspect that any such code is not as cleanly organized as it should be and could be written so it was not a problem.

我能想到的不这样做的唯一借口是因为您需要声明它但在使用它之前提前退出,因此初始化程序将被浪费。但是,我怀疑任何此类代码都没有应有的组织得那么干净并且可以编写,因此这不是问题。

回答by technosaurus

The OP left out some crucial information from the question and only put it in a comment to an answer.

OP 从问题中遗漏了一些关键信息,仅将其放在对答案的评论中。

I need to initialize after declaring, because will be different depending on a condition, I mean something like this int myArray[SIZE]; if(condition1) { myArray{x1, x2, x3, ...} } else if(condition2) { myArray{y1, y2, y3, ...} } . . and so on...

我需要在声明后初始化,因为根据条件会有所不同,我的意思是这样的 int myArray[SIZE]; if(condition1) { myArray{x1, x2, x3, ...} } else if(condition2) { myArray{y1, y2, y3, ...} } . . 等等...

With this in mind, all of the possible arrays will need to be stored into data somewhere anyhow, so no memcpy is needed (or desired), only a pointer and a 2d array are required.

考虑到这一点,所有可能的数组都需要以任何方式存储到数据中,因此不需要(或不需要)memcpy,只需要一个指针和一个二维数组。

//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

The not-inlined version gives this resulting assembly on x86_64:

非内联版本在 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

For additional conditionals/arrays, just change the 2 in myArrays to the desired number and use similar logic to get a pointer to the right array.

对于其他条件/数组,只需将 myArrays 中的 2 更改为所需的数字,并使用类似的逻辑来获取指向正确数组的指针。

回答by Tush_08

It is not possible to assign values to an array all at once after initialization. The best alternative would be to use a loop.

初始化后不可能一次为数组赋值。最好的选择是使用循环。

for(i=0;i<N;i++)
{
     array[i] = i;
}

You can hard code and assign values like --array[0] = 1and so on.

您可以硬编码并分配诸如 -- 之类的值array[0] = 1

Memcpy can also be used if you have the data stored in an array already.

如果您已经将数据存储在数组中,也可以使用 Memcpy。

回答by Kumar Alok

There is no such particular way in which you can initialize the array after declaring it once.

没有这种特殊的方式可以在声明一次后初始化数组。

There are three options only:

只有三个选项:

1.)initialize them in different lines :

1.)在不同的行中初始化它们:

int array[SIZE];

array[0] = 1;
array[1] = 2;
array[2] = 3;
array[3] = 4;
//...
//...
//...

But thats not what you want i guess.

但我猜这不是你想要的。

2.)Initialize them using a for or while loop:

2.)使用 for 或 while 循环初始化它们:

for (i = 0; i < MAX ; i++)  {
    array[i] = i;
}

This is the BEST WAY by the way to achieve your goal.

这是实现目标的最佳方式。

3.)In case your requirement is to initialize the array in one line itself, you have to define at-least an array with initialization. And then copy it to your destination array, but I think that there is no benefit of doing so, in that case you should define and initialize your array in one line itself.

3.)如果您的要求是在一行中初始化数组,则必须至少定义一个带初始化的数组。然后将其复制到您的目标数组,但我认为这样做没有任何好处,在这种情况下,您应该在一行中定义和初始化您的数组。

And can I ask you why specifically you want to do so???

我能问你为什么要这样做吗???