We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
my doubt is a general C doubt.. we know if we are using enum the variables which we declare inside automatically increments by one than the previous variable.. but is there any method by which we could make the variables to decrement by one instead of incrementing...
Example
enum my_enum { var1=90, var2,var3 };
for this code var2 and var3 will be 91 & 92 respectively, is there any method (possible) to get them 89 & 88... It was asked in an interview.. any one knows the answer..?
Next step up is to play with the preprocessor.
#include <stdio.h> #define _(x) \ x##tmp1, \ x = base-(x##tmp1-base),\ x##tmp2 = x##tmp1 enum { base = 90, _(alt1), _(alt2), _(alt3) }; int main() { printf("%u %u %u %u\n",base,alt1,alt2,alt3); return 0; }
Impressively horrible. Note that the printf() format specifiers require the 'b' modifier for C51 (and ought to be 'd' rather than 'u').
I'm surprised nobody has suggested:
enum my_enum{var3=88, var2, var1};
or does that not fit with the spirit of the thing?
Well, it doesn't answer the specific question about having the compiler automatically assign decreasing values - although it does achieve the required end of the given example.
If I were the interviewer, I would certainly give credit for that!
Generally, interview questions aren't about showing what you know, but showing that you can think...
Impressively horrible
Yes, something the preprocessor is good at :)
The reason for the %u was that I did test the code with values way above the range of signed integers.
I wanted to compare the two macros:
#define _(x) \ x##tmp1, \ x = 2*base-x##tmp1, \ x##tmp2 = x##tmp1
and
#define _(x) \ x##tmp1, \ x = base-(x##tmp1-base),\ x##tmp2 = x##tmp1
with values large enough that the construct "2*base" would overflow. There should be no difference between the two on a modern processor using two's complement numbers.
But one note here about the formatting character for printf() is that the standard says (in 2.7.2.2): "Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined [...]"
In the case of C51 the type can be either char or int depending on the range of values used, so the general solution for printf() would be to cast the parameters to int and use %d.
I think a generous interpretation of the paragraph you quoted would allow this. Maybe.
I tend to prefer a combination of both.
By the way, out here in the world wide jungle 'interview question' is a euphemism for 'homework question'.
I don't think the interpretation need to be generous. The paragraph seems to give a carte blanche. A signed integer type or unsigned integer type means that any integer size is allowed. And they obviously allow either signed or unsigned.
I just noted that in the general case, are there any note in the standard that printf() should use %d and not %u? Isn't that one of the non-portable things that people have to be aware of?
Note that this thread doesn't specify any architecture, so I can't assume that we are talking about the C51 compiler.
Based on the quotation you provided it seemed to me that the intent was that the implementation should choose an integer type, document it and stick to it. I thought that interpreting it to mean that the implementation could select from the available integer types for every enumerated type created was pushing it a bit - but after a bit of research it seems that is exactly what happens.
No, but C51 uses either signed char or signed int for enumerated types, so %bd or %d would be appropriate, or just %d and cast the enum to int.
Indeed, I did qualify my comments as being applicable to C51 though.
It is also interesting to note that the enumeration constants have type int, so one might expect that any variable of that type would only need to hold the range of int. I don't know exactly what the outcome of this should be:
enum x{a=MAX_INT, b};
I read your original text as if the 'b' qualifier was required for the C51 architecture, but that the 'd' should be used for all architectures.
My original intention was that the entire comment was applicable to C51, by 'general' I meant that 'd' and a cast to int would work whichever type (char or int) C51 chose to use for the enumeration type.
However, it seems that the standard requires the enumeration constants to be of type int, so this would suggest to me that the enumeration type itself will only hold values representable as type int (although it may be capable of a wider or narrower range), irrespective what actual integer type is chosen for the enumerated type, or rather, what integer type the enumerated type is 'compatible with'. If my interpretation is correct I would therefore suggest that this:
//y is a variable of an enumerated type printf("%d\n",(int)y);
is a general solution outwith C51.
My preference is to avoid enum altogether as it provides a level of abstraction that I don't particularly want.