Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中声明和初始化数组_C_Arrays_Initialization - Fatal编程技术网

在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,您可以在需要的地方声明变量,并在声明时初始化它 我能想到的不这样做的唯一借口是,你需要声明它,但在使用它之前要提前退出,这样初始化器就浪费了。

有没有一种方法可以在C中先声明然后初始化数组

到目前为止,我一直在初始化一个数组,如下所示:

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