【问题标题】:Use Initialization List in C after declaration声明后在 C 中使用初始化列表
【发布时间】:2016-10-31 15:56:01
【问题描述】:

我正在学习 C,有些事情让我感到困惑,我读过的书并没有真正帮助澄清我遇到的问题。

所以这是我的代码:

#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE 5

// gcc -std=c99 stackoverflow-example.c

int main () {

    // declare variable array1
    int array1[ARRAY_SIZE];
    // declare and init variable array2
    int array2[ARRAY_SIZE] = {}; // for integers, the default value is 0

    // not initialized
    for (int i = 0; i < ARRAY_SIZE; i++) {
        // can be anything, not guaranteed to be 0
        printf("array1[%d]: %d\n", i, array1[i]);
    }

    // initialized with initialization list
    for (int i = 0; i < ARRAY_SIZE; i++) {
        // element == 0
        printf("array2[%d]: %d\n", i, array2[i]);
    }

    // This is the part that confuses me.
    // array1 = {};  // error: expected expression before ‘{’ token
    // array1[] = {};  // same error

    return EXIT_SUCCESS;
}

有没有一种方便的方法可以在声明后初始化这个数组?或者设置array1 中的每个元素的唯一方法是使用 for 循环,例如:

for (int i = 0; i < ARRAY_SIZE; i++)
    array1[i] = 0;

// initialized with a for loop
for (int i = 0; i < ARRAY_SIZE; i++)
    // now it's guaranteed to be 0
    printf("array1[%d]: %d\n", i, array1[i]);

非常感谢您的帮助。我知道这有点像菜鸟问题,但它是在我试图更熟悉 C 语言并尝试一些非书籍示例代码时出现的。

如果您怀疑可能有一些我没有得到的基本知识,请告诉我,我会仔细阅读。

【问题讨论】:

  • 我认为你应该试试memset 函数。它经过优化以使用常量值初始化数据块。
  • 好的,谢谢。不过,它仅适用于使用 0 进行初始化(知道我在示例中使用了 0 初始化数组,因此它实际上可以工作)。和 -1 (and it's not really guaranteed)。不过还是谢谢你。
  • 哦,我的错。没错,memset 是特定于字节数组的。
  • 在 C 中,变量(数组或结构或...)只能在声明时“初始化”。此后,它必须被分配。分配时,不使用memset()之类的函数,必须分配每个实体。

标签: c arrays initialization declaration


【解决方案1】:

从技术上讲,initialization 只能在声明时执行一次,之后的任何值存储都是赋值或复制。

大括号括起来的初始化列表只能在声明时用于数组的初始化。

对于数组的单个元素(标量项),规则是:(引用 C11,第 §6.7.9 章

标量的初始值设定项应该是单个表达式,可选择用大括号括起来。

空列表{} 不是标量的有效初始化程序(表达式)。因此你得到了错误。

因此,对于已经定义的数组,重新设置也必须完成

  • 逐个成员,通过循环
  • 在允许的情况下使用memcpy()memset

【讨论】:

  • 那我换个说法:有没有办法(有点像“语法糖”,虽然我知道这不是 C 的著名之处)分配各种元素声明后的数组?
  • @VinceVarga 好吧,memset() 可能是你的朋友,但我担心不同的价值观。
  • memset() 会将所有字节设置为相同的值,如果您想将整数元素设置为相同的非零值,这可能没有多大用处。您通常可以使用memset() 将所有元素设置为整数0,但严格来说,这是不可移植的。要将元素设置为相同的非零值,循环可能是您最好的选择。要将元素设置为不同的值,可以通过单独的分配来完成,或者使用memcpy() 从另一个(可能是const)数组复制所有内容。
  • 除了我在之前的评论中写的关于memcpy() 的内容之外,memcpy() 的第二个(源)参数可以是复合文字数组,例如memcpy(array1, (int[ARRAY_SIZE]){ 1, 2, 3, 4, 5}, ARRAY_SIZE * sizeof(int));
  • 谢谢你,Ian,在我看来 memcpy 是我最初想要的最接近的东西
猜你喜欢
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多