【问题标题】:initializing a 2 dimensional array of struct to zero (set the image to all black) in C在C中将结构的二维数组初始化为零(将图像设置为全黑)
【发布时间】:2020-12-06 11:51:31
【问题描述】:

我想将图像文件传递给函数并使其全黑。

这是我的做法:

typedef struct
{
    BYTE  rgbtBlue;
    BYTE  rgbtGreen;
    BYTE  rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

void black(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE black_image[height][width];
    
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            black_image[i][j] = {0}; 
        }
    }
    
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            image[i][j] = black_image[i][j]; 
        }
    }
}

但是,我收到了相同的错误消息:

expected expression before '{' token black_image[i][j] = {0};
                                                         ^      

注意指向大括号的指针。

我在这里做错了什么?请帮忙。

【问题讨论】:

    标签: arrays c struct initialization


    【解决方案1】:

    {0} 是在定义对象时用于初始化的语法。它不构成可以在赋值语句中使用的表达式。

    为此,您可以使用复合文字:

    black_image[i][j] = (RGBTRIPLE) { 0, 0, 0 };
    

    (这也可以用作(RGBTRIPLE) {0},但列出所有三个组件可以更清楚地显示意图,并且可以避免编译器警告。)

    由于您只是使用它来将image 设置为黑色,因此您可以消除black_image 和初始化它的循环并将image 直接设置为零。

    【讨论】:

    • 所以这里的概念是:我不能将一个 int '0' 分配给一个结构,即使结构里面的东西都是 int?
    • @heihei:您既不能将0 也不能将{0} 分配给结构。在赋值中,右操作数必须与左操作数的类型相同或可隐式转换为左操作数。 0int 并且不能隐式转换为结构;它们是根本不同的东西。 {0} 不是表达式,因此它不能是赋值的操作数。
    【解决方案2】:

    实现目标的最短途径是:

    void black(int height, int width, RGBTRIPLE image[height][width])
    {
        memset(image, 0, sizeof(RGBTRIPLE[height][width]));
    }
    

    【讨论】:

    • 我试过你的方法,但又出现一条错误信息:error: variable-sized object may not be initialized
    • @heihei 因为VLAs can't be initialized。代替RGBTRIPLE black_image[height][width] = { 0 };,您可以使用:RGBTRIPLE black_image[1][1] = { 0 }; 并使用它image[i][j] = black_image[0][0];)。
    • @P.P 好点。我看不出有任何理由不在这里进行 memset tbh
    • 谢谢。 @P.P 我刚刚用谷歌搜索了 memset,我同意 memset 是最简单的方法。
    【解决方案3】:

    除了现有的好答案之外,它完全解决了您的问题所带来的问题,并且为了简化起见,据我所知,您有一个额外的不需要的循环和一个额外的不需要的数组,RGBTRIPLE black_image[height][width]

    相反,您可以使用类似于@EricPostpischil posted 的复合文字直接将黑色结构分配给image,但放弃black_image 数组:

    void black(int height, int width, RGBTRIPLE image[][width])
    {
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                image[i][j] = (RGBTRIPLE){0, 0, 0}; //*
            }
        }
    }
    

    *如果你想在初始化中更加清晰,你可以使用指定的初始化器:

    image[i][j] = (RGBTRIPLE){.rgbtBlue = 0, .rgbtGreen = 0, .rgbtRed = 0};
    

    或者创建一个单一的黑色结构并在循环中将它分配给数组中的每个元素:

    void black(int height, int width, RGBTRIPLE image[][width])
    {
        RGBTRIPLE black_image = {0, 0, 0}; //**
    
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                image[i][j] = black_image;
            }
        }
    }
    

    **同样,你可以使用指定的初始化器:

    RGBTRIPLE black_image = {.rgbtBlue = 0, .rgbtGreen = 0, .rgbtRed = 0};
    

    也就是说,这些是我首选方法的替代方法,使用memset,在@M.M's answer 中已经提到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      • 2013-03-06
      • 2021-02-03
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多