簡體   English   中英

在C中聲明和初始化數組

[英]Declaring and initializing arrays in C

有沒有辦法先聲明然后在C中初始化一個數組?

到目前為止,我一直在初始化一個這樣的數組:

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

但我需要做這樣的事情

int myArray[SIZE];

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

在C99中,您可以使用復合文字與memcpy結合使用

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

(假設源的大小和目標的大小相同)。

在C89 / 90中,您可以通過聲明一個額外的“源”數組來模擬它

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

不,您不能在一個語句中將它們設置為任意值(除非作為聲明的一部分完成)。

您可以使用代碼執行此操作,例如:

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

或(如果有公式):

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

另一種可能是保持周圍設置在聲明時一些模板,並用它們來初始化您的數組,是這樣的:

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應該非常快,可能比1,229賦值語句快,但肯定更少打字你的部分:-) 。

有沒有辦法先聲明然后在C中初始化一個數組?

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

您無法使用逗號分隔列表進行初始化,這僅在聲明中允許。 但是你可以初始化......

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

要么

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

這是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)}

你申報時為什么不能初始化?

您使用的是哪個C編譯器? 它支持C99嗎?

如果它支持C99,您可以在需要的地方聲明變量,並在聲明它時對其進行初始化。

我不能想到的唯一理由是因為你需要聲明它但是在使用它之前提前退出,所以初始化器會被浪費掉。 但是,我懷疑任何這樣的代碼都沒有應有的清晰組織,可以編寫,因此不是問題。

在聲明一次之后,沒有這種特殊的方法可以初始化數組。

僅有三個選項:

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

這是實現目標的最佳途徑。

3.)如果您的要求是在一行中自己初始化數組,則必須至少定義一個帶初始化的數組。 然后將其復制到目標數組,但我認為這樣做沒有任何好處,在這種情況下,您應該在一行中定義和初始化您的數組。

我可以問你為什么要這么做?

OP從問題中遺漏了一些重要信息,並僅將其置於對答案的評論中。

我需要在聲明之后進行初始化,因為根據條件會有所不同,我的意思是這樣的東西我的艾瑞[SIZE]; if(condition1){myArray {x1,x2,x3,...}} else if(condition2){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;
}

您可以硬編碼並分配像 - array[0] = 1等值。

如果已經將數據存儲在數組中,也可以使用Memcpy。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM