mcg1nley
mcg1nley

Reputation: 15

How to assign the same value to multiple members in a struct in C

I was wondering if there was a more concise way to assign the same variable to multiple members of the same struct?

Currently my code looks like this:

                image[i][j].rgbtBlue = average;
                image[i][j].rgbtGreen = average;
                image[i][j].rgbtRed = average;

It just seems like a lot of repitition. I don't want to alter the struct in any way I just wondered if there is any way I can make the above code more neat? But here is the code for the struct anyway.

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

TIA

Upvotes: 1

Views: 1158

Answers (4)

Steve Summit
Steve Summit

Reputation: 47952

One way would be

image[i][j].rgbtBlue = image[i][j].rgbtGreen = image[i][j].rgbtRed = average;

If you're getting tired of typing "image[i][j]", and you're doing a lot with it in the same stretch of code, you could set up a temporary variable:

RGBTRIPLE *trip = &image[i][j];

trip->rgbtBlue = trip->rgbtGreen = trip->rgbtRed = average;

Setting up a temporary variable like this has some pros and cons:

  • Pro: it saves typing
  • Con: but saving typing isn't really a goal, you only type it once
  • Pro: it can be easier to read
  • Con: if you're not careful (if i or j changes when you don't expect), it can introduce bugs

Upvotes: 2

Ian Abbott
Ian Abbott

Reputation: 17403

(Since everyone is supplying different solutions, I'll mention mine too!)

One option is to use a compound literal to hold a temporary RGBTRIPLE filled with the desired values. Since it seems convenient to specify the values in RGB order to match the name of the type, some handy macros can be defined to construct the compound literal:

#define MK_RGB(r, g, b) ((RGBTRIPLE){ .rgbtBlue = (b), .rgbtGreen = (g), .rgbtRed = (r) })
#define MK_GREY(g) MK_RGB(g, g, g)

Then the original lines of code:

                image[i][j].rgbtBlue = average;
                image[i][j].rgbtGreen = average;
                image[i][j].rgbtRed = average;

Can be changed to:

                image[i][j] = MK_RGB(average, average, average);

or:

                image[i][j] = MK_GREY(average);

Note: Compound literals were added in C11. To conform to older C standards, MK_RGB could be changed to a function that returns an RGBTRIPLE:

RGBTRIPLE MK_RGB(BYTE r, BYTE g, BYTE b)
{
    RGBTRIPLE rgb;
    rgb.rgbtRed = r;
    rgb.rgbtGreen = g;
    rgb.rgbtBlue = b;
    return rgb;
}

Upvotes: 1

Mike Stallone
Mike Stallone

Reputation: 52

2 easy ways I can think of off the top of my head:

  1. Use a function:

ie.

void RGBstructSet(RGBTRIPLE *lStruct,uint8_t value){
lStruct->rgbtBlue = value;
lStruct->rgbtGreen = value;
lStruct->rgbtRed = value;
}

And your above 3 lines would then be replaced by:

structSet(&image[i][j], average);
  1. use memset which is only guaranteed to work since your struct is "PACKED" ie.

     memset(&image[i][j],average,3)
    

1 has the benefit of working regardless of your struct being packed or not, 2 is slightly easier for you to do, and is more clear what is going on

Upvotes: 0

Lundin
Lundin

Reputation: 213842

You can create a read-only struct containing the default initialization values:

const RGBTRIPLE RGB_default = 
{ 
  .rgbtBlue  = average, 
  .rgbtGreen = average,
  .rgbtRed   = average,
};

And then:

RGBTRIPLE something[n];
for(size_t i=0; i<n; i++)
{
  something[i] = RGB_default;
}

Upvotes: 3

Related Questions