4

I have 2 arrays, one is commented, I would like to make universal printf that will plot the values:

int values [] = { 88, 56, 100, 2, 25 };
//float values[] = {88.5f, 56.5f, 100.0f, 2.234f, 88.12f};

if (value[0] is int) {
    for(i; i < 5; ++i)
    printf("%d ", *(values + i));
} else {
    for(i; i < 5; ++i)
    printf("%f ", *(values + i));
}

Is there any way to check it? For example when I wanted to see if element is char or int then I used sizeof

8
  • Yes I know. But I need to do program for classes. Ill comment the int values and uncomment float values then start program, then Ill comment float and uncomment int. Those arrays are used for sorting. Commented Jan 5, 2014 at 21:16
  • I dont need a way to store 2 value types in one. I need info how to find out if the element of array is int or float. Commented Jan 5, 2014 at 21:17
  • 3
    You are probably trying to do the wrong thing. This said, you can use in the latest C standard, _Generic(values[0], int: 0, float:1, default:2) Commented Jan 5, 2014 at 21:19
  • _Generic(values[0], int: 0, float:1, default: 2); thats interesting but won't compile. I'm latest Dev-C++ 5.5.3 currently. [Error] expected expression before 'int' Commented Jan 5, 2014 at 21:22
  • 2
    You forgot to initialize i to 0. And why are you using *(values + i) rather than values[i]? Commented Jan 5, 2014 at 21:51

2 Answers 2

3

With the caveat that this is a lot of sophistication for a “feature” that you are only going to use while debugging your program, you can use C11's _Generic construct:

_Generic(values[0], int: 0, float:1, default:2)

What you should probably do instead that would be more consistent with your intentions is conditional compilation:

#define FLOAT_CASE

#ifdef FLOAT_CASE
float values[] = {88.5f, 56.5f, 100.0f, 2.234f, 88.12f};
#else
int values [] = { 88, 56, 100, 2, 25 };
#endif

... // all the code that is independent of the type of values here

for(i; i < 5; ++i)
#ifdef FLOAT_CASE
  printf("%f ", *(values + i));
#else
  printf("%d ", *(values + i));
#endif
Sign up to request clarification or add additional context in comments.

2 Comments

Why do you write *(value + i) rather than values[i]? And you forgot to initialize i to 0.
@KeithThompson You should direct all these remarks to the OP. I took program lines verbatim from the question to make it clear that my answer was to use #ifdef or _Generic, not to fix stylistic issues (that wouldn't help with the problem of writing generic code for int and float)
2

An ugly solution: if you only need to distinct between int and float you can assign a non-integer value, say 0.1 to the variable and then test the actual value. This gives something like:

#define IS_INT_TYPE(x) (x=0.1, x==0)

However, this will destroy the original value of the macro parameter. If you use gcc, you can use typeof() extension to cast the value:

#define IS_INT_TYPE(x) (((typeof(x)) 0.1) == 0)

And Pascal's notes gave me the idea to the solution:

#define IS_INT_TYPE(x) (((x*0+1)/2) == 0)

3 Comments

If you want to go in this direction, a solution if one knows that x is neither 0 nor within a factor of two of the limits of its type is x / (x + x) == 0
Removing the limitation for 0: x==0 ? ((x+1) / 2 == 0) : …
Only requiring x, if float, to be finite: x == 0 ? ((x+1) / 2 == 0) : (x/x) / (x/x + x/x) == 0. [after seeing edit] Well, okay, your solution is clearly better but still requires x to be finite. This is easy to test: !(x < INT_MIN) && !(x > INT_MAX) && …

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.