Ошибка при умножении типа int на struct

#c #cs50

Вопрос:

Приведенный ниже код выдает следующую ошибку при попытке компиляции:

invalid operands to binary expression ('int' and 'RGBTRIPLE')

В принципе, я не знаю, как правильно умножить temp[i][j] на коэффициент.

Я пробовал 2 * int(temp[i][j]) , например, набирать типы, но это не работает. Как мне поступить с этим делом? Что мне нужно, чтобы больше понять о типах в этом случае?

 void edges(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE temp[height][width];

    for (int i = 0; i < height; i  )
    {
        for (int j = 0; j < width; j  )
        {
            temp[i][j].rgbtRed   = image[i][j].rgbtRed;
            temp[i][j].rgbtGreen = image[i][j].rgbtGreen;
            temp[i][j].rgbtBlue  = image[i][j].rgbtBlue;
        }
    }

    int red_gx, green_gx, blue_gx, red_gy, green_gy, blue_gy;

    for (int i = 0; i < height; i  )
    {
        for (int j = 0; j < width; j  )
        {
            // Top Left Corner
            if (i == 0 amp;amp; j == 0)
            {
                red_gx   = 0;
                green_gx = 0;
                blue_gx  = 0;

                red_gy   = 0;
                green_gy = 0;
                blue_gy  = 0;
            }

            //
            // <-- some other elif statements here in between
            //

            // Any other pixel
            else
            {
                red_gx   = (-1 * (temp[i - 1][j - 1]))   temp[i - 1][j   1]   (-2 * (temp[i][j - 1]))   (2 * (temp[i][j   1]))   (-1 * (temp[i   1][j - 1]))   (temp[i   1][j   1]);
            //     green_gx = (-1 * temp[i - 1][j - 1])   temp[i - 1][j   1]   (-2 * temp[i][j - 1])   (2 * temp[i][j   1])   (-1 * temp[i   1][j - 1])   temp[i   1][j   1];
            //     blue_gx  = (-1 * temp[i - 1][j - 1])   temp[i - 1][j   1]   (-2 * temp[i][j - 1])   (2 * temp[i][j   1])   (-1 * temp[i   1][j - 1])   temp[i   1][j   1];

            //     red_gy   = (-1 * temp[i - 1][j - 1])   (-2 * temp[i - 1][j])   (-1 * temp[i - 1][j   1])   temp[i   1][j - 1]   (2 * temp[i   1][j])   temp[i   1][j   1];
            //     green_gy = (-1 * temp[i - 1][j - 1])   (-2 * temp[i - 1][j])   (-1 * temp[i - 1][j   1])   temp[i   1][j - 1]   (2 * temp[i   1][j])   temp[i   1][j   1];
            //     blue_gy  = (-1 * temp[i - 1][j - 1])   (-2 * temp[i - 1][j])   (-1 * temp[i - 1][j   1])   temp[i   1][j - 1]   (2 * temp[i   1][j])   temp[i   1][j   1];
            }

            image[i][j].rgbtRed   = round(sqrt(pow(round(red_gx), 2)   pow(round(red_gy), 2)));
            image[i][j].rgbtGreen = round(sqrt(pow(round(green_gx), 2)   pow(round(green_gy), 2)));
            image[i][j].rgbtBlue  = round(sqrt(pow(round(blue_gx), 2)   pow(round(blue_gy), 2)));
        }
    }
    return;
}
 

Комментарии:

1. Первый цикл в коде показывает вам, что вам нужно сделать.

2. @user3386109 извините, я, кажется, не понимаю, на что вы указываете. Возможно, сначала придется отоспаться, лол, скоро взойдет солнце

3. RGBTRIPLE — это структура с тремя членами. В структуре в целом не допускается никаких математических операций. Вы должны получить доступ к участникам по отдельности, как показано в этом первом цикле. Хорошо отдохните 🙂

4. @user3386109 о, черт возьми, я только что осознал свою глупую ошибку. точечная нотация. лол. Спасибо!

Ответ №1:

Вот определение RGBTRIPLE:

Структура RGBTRIPLE (wingdi.h)

 typedef struct tagRGBTRIPLE {
  BYTE rgbtBlue;
  BYTE rgbtGreen;
  BYTE rgbtRed;
} RGBTRIPLE, *PRGBTRIPLE, *NPRGBTRIPLE, *LPRGBTRIPLE;
 

Это «структура», элементы которой состоят из 3 байтов. Должно быть совершенно очевидно, что вы не можете просто рассматривать его как целое число. « 2 * int(temp[i][j]) » явно незаконно.

Что вы МОЖЕТЕ сделать, так это собрать rgbtBlue, rgbtGreen и rgbtRed в одно 32-разрядное целое число, если хотите. Возможно, что-то вроде:

 unsigned int color = (temp[i][j].rgbtRed << 16) | (temp[i][j].rgbtGreen << 8) | (temp[i][j].rgbtBlue); 
 

Вы также можете определить объединение.

Но почему? Может быть, вам лучше всего было бы просто рассматривать R, G и B как «отдельные»?

Ответ №2:

вы можете объединить их в одно 32-разрядное целое
число, а затем выполнить математику, а затем вернуть ее обратно, есть макросы, wingdi.h которые могут вам помочь

вингди.ч

 #define GetRValue(c) ((BYTE)(c))
#define GetGValue(c) ((BYTE)(((WORD)(c))>>8))
#define GetBValue(c) ((BYTE)((c)>>16))
#define RGB(r,g,b) ((COLORREF)((BYTE)(r)|((BYTE)(g) << 8)|((BYTE)(b) << 16)))
 

вы можете поступить следующим образом:

 for (int i = 0; i < height; i  )
{
    for (int j = 0; j < width; j  )
    {
        // RGB macro takes 3 arguments of type BYTE(red, green ,blue)
        // and returns 32-bit integer

        int iColor  =  RGB(image[i][j].rgbtRed, image[i][j].rgbtGreen, image[i][j].rgbtBlue);

        // do whatever you want with iColor
        // then back to image

        image[i][j].rgbtRed      =   GetRValue(iColor);  //  retrieves red value(BYTE)
        image[i][j].rgbtGreen    =   GetGValue(iColor);  //  retrieves green
        image[i][j].rgbtBlue     =   GetBValue(iColor);  //  retrieves blue
    }
}
 

Ответ №3:

 typedef union 
{
    struct
    {
        BYTE rgbtBlue;
        BYTE rgbtGreen;
        BYTE rgbtRed;
    };
    unsigned rawRGB;
} RGBTRIPLE, *PRGBTRIPLE, *NPRGBTRIPLE, *LPRGBTRIPLE;
 

тогда вы сможете 2 * temp[i][j].rawRGB

Кстати, скрывать указатели typedef -очень плохая практика. Избегайте, так как это обычно приводит к очень трудным для поиска и отладки ошибкам.