Question's Background:
void dash(int *n, char c) is to draw characters c separated by '+'.
Parameter n is an array of ints, e.g. {1, 3, 2} and '-' for c should give "+-+---+--+", which works fine.
To use dash I do {int f={1, 3, 2}; dash(f, '-');}, which makes the construct copy&pastable.
The question itself:
To avoid copy&pasting I wanted to do #define F(X, Y) {int f=X; dash(f, Y);},
resulting in a nicely usable F({1, 3, 2}, '-').
Unfortunately the compiler complains about F getting 4 (array's length + 1) arguments instead of 2.
So how can you give {1, 3, 2} as parameter to a macro?
Variadic macros are a feature of C99.
#define F(Y,...) dash((int[]){__VA_ARGS__},Y)
So how can you give {1, 3, 2} as
parameter to a macro?
F('-',1,3,2);
Here is my version:
#include <stdio.h>
void dash(int len, int *n, char c){
int i;
printf("dash( %i, {", len );
for( i=0; i<len-1; i++ )
printf(" %i,", n[i] );
printf(" %i }, '%c')\n", n[i], c );
}
#define NOPAREN(...) __VA_ARGS__
#define F1(arr,char) { int f[]={NOPAREN arr}; dash(sizeof(f)/sizeof(f[0]),f,char); }
#define F2(char,...) { int f[]=__VA_ARGS__; dash(sizeof(f)/sizeof(f[0]),f,char); }
int main(void){
F1( (1,3,2), '-' );
F2( '-', {4,6,5} );
}
Result:
dash( 3, { 1, 3, 2 }, '-')
dash( 3, { 4, 6, 5 }, '-')
Instead of trying to use a macro to set up and make these calls, I'd probably consider changing the interface to dash() to use varargs:
#include <stdarg.h>
void dash( char c, ...)
{
// ...
}
int main() {
dash( '+', 1, 3, 2, -1); // note: negative number indicates
// the end of the list of numbers
return 0;
}
Using varargs isn't the best thing in the world (they're difficult to use and aren't typesafe), but I think it would be better than the macro concoction you're trying to gen up.
Also, remember that even if you stick with your current interface for dash() and come up with a macro that does what you want, you still need to have a way to indicate the end of the sequence of numbers to be passed into dash(). Otherwise there's no way for dash to know when it has reached the end of the array. You have several choices:
use a sentinel value, such as 0, -1, or any negative number (like in the vararg example above)
pass the number of elements in the array as another argument
set the size of the array as a part of dash()'s interface. In your example, dash() might require that an array of 3 ints be passed in. No more, no less (actually more would be OK - they just wouldn't be used). If you did this, fixing your macro would be much easier, but I suspect it's not how you want dash to behave.
You can pass { 1, 3, 2 } as an argument to a macro if you define { 1, 3, 2 } as another macro
#define PARAMS { 1, 3, 2 }
F(PARAMS, '-')
#undef PARAMS
Unfortunately, there seems to be no direct way to do literally what you ask, i.e. pass specifically { 1, 3, 2 } in this specific form. It might be worth switching to alternative methods, including the C99-specific ones suggested in other answers.
Related
I'm learning C, and I created a simple addNumbers(int num, ...) function, that takes any number of int arguments, and returns the sum of them.
This issue is that when I get the output of addNumbers(4, 2), the output is 14823901. Which is obviously incorrect.
When I call the function addNumbers(4, 2, 4, 7, 10), it outputs 23, which is also incorrect because it should be 27, but at least it's closer.
Here's my code:
#include<stdio.h>
#include<stdarg.h>
// Functions with variable number of arguments
int addNumbers(int num, ...)
{
int i;
int sum = 0;
// List to hold variable amount of parameters
va_list parameters;
// Initialize "parameters" list with arguments
va_start(parameters, num);
for(i = 0; i < num; i++)
{
// Adds each "int" argument from "parameters" to sum
sum += va_arg(parameters, int);
}
// Cleans memory
va_end(parameters);
return sum;
}
int main()
{
printf("%i", addNumbers(4, 2, 4, 7, 10));
return 0;
}
Should I not be using va_list, va_arg, etc...?
What's the best way to be able to take in a variable number of arguments?
for addNumber(4, 2) you are using the first parameter as counter which there are 4 parameter to addup but your giving just 1, so the for loop continue reading from the memory expecting more parameter and just pick up ramdom values and add them up.
Here I know that the following code simply copies the character i rather than its value to the preprocessor statement (which makes a error for undefined symbol i in compile-time).
What I want is:
Is their a way such that the compiler treats, i as a variable with some value rather than a character ?
#include <stdio.h>
#define PRINT(x) printf("%d \n", y ## x)
int main(void) {
int y1=0 , y2=1 , y3=4;
for(int i=1; i <= 3; ++i) {
PRINT(i);
}
return 1;
}
About the pre-processor
First of all, I think there's a need to clarify how the preprocessor works: it pre-processes the input files, which means it runs before the compiler. Unfortunatly, for historical reasons, it doesn't know anything about C or C++, doesn't parse anything, and just does very simple textual operations on words and parenthesis. Just to illustrate my point:
#define this __FILE__
#define file -- Hell no!
#define fine(a, b) fine: a ## _ ## b
Ok, so this is not a valid C or C++ file
But the preprocessor will run just fine(go, try!)
Run this with a pre-processor, for example gcc -x c -E -P test.txt and you'll get:
Ok, so "test.txt" is not a valid C or C++ -- Hell no!
But the preprocessor will run just fine: go_try!
So, obviously, when the preprocessor sees PRINT(i) in your code, it replaces it with printf("%d \n", yi) without thinking much about it. And it has absolutely no idea i is a variable, don't even think about evaluating it's value.
Solutions
Basically, what you want is print a bunch of numbers.
You could simply do
printf("0\n1\n4\n");
But this lacks makes changing numbers cumbersome,
so let's go with
printf("%d\n%d\n%d\n", 0, 1, 4);
Which makes it easy to change a number, but not to add/remove one.
Ok so how about:
printf("%d\n", 0);
printf("%d\n", 1);
printf("%d\n", 4);
Yeah, you can change/add/remove numbers easily but as any sane programmer you hate repetition. So, we need some kind of loop.
By far the simplest and most straightforward way to iterate in C is at runtime, using an array:
int [] y = { 0, 1, 4 };
for(int i = 0; i < sizeof(y)/sizeof(int); ++i) {
printf("%d\n", y[i]);
}
If you want, you can hide the printf using a function:
inline void print_int(int* y, int i) { print_int(y[i]); }
int [] y = { 0, 1, 4 };
for(int i = 0; i < sizeof(y)/4; ++i) print_int(y, i);
And going further with functions:
inline void print_int(int x) { printf("%d\n", x); }
inline void print_int(int* y, int i) { print_int(y[i]); }
inline void print_ints(int * y, int n)
{
for(int i = 0; i < n; ++i)
print_int(y, i);
}
template<int n> // C++
inline void print_ints(const int[n] & y) { print_ints(&y[0], n); }
int [] y = { 0, 1, 4 };
print_ints(y); // C++
// or in C:
print_ints(y, sizeof(y)/sizeof(int));
Now, what if you absolutely want the generated code to look like solution 3. ? This means you need the iteration to happen at compile-time. Tricky!
That's where the preprocessor can come into play. There are (hacky) ways to make it do this kind of things. I strongly recommend not implementing this yourself (except to play), but use the Boost.preprocessor library instead:
#define PRINTER(R,D, NUMBER) printf("%d\n", NUMBER);
#define NUMBERS (0, 1, 4)
BOOST_PP_LIST_FOR_EACH(PRINTER, _, BOOST_PP_TUPLE_TO_LIST(NUMBERS))
// will expand to printf("%d\n", 0); printf("%d\n", 1); printf("%d\n", 4);
Under standard C, this is not possible; during preprocessing, the compiler simply sees the identifier i as simply that - an identifier. It does not know that i is of type int, or that it's even a variable in the first place.
The easiest way to achieve what's intended is to use an array, like so:
int i;
int y[] = { 0, 1, 4 };
for (i = 0; i < 3; i++) // NOTE: arrays in C start at index 0, not 1
{
printf("%d \n", y[i]);
}
Also note that I got rid of the macro, as you want to use the value of a runtime variable i to select another runtime variable.
The output of the below program is 24. But I could not understand the behaviour of the function f1(parameters).
There is a recursive call of f1 in m1 nad m2. Considering m1 and m2 holding the function f1's stack. m1 stack will contain:
1]0,12,a 2]0,6,a 3]0,3,a 4]0,1,a 5]0,0,a
And m2 stack will contain:
1]13,12,a 2]20,6,a 3]24,3,a 4]26,1,a 5]27,0,a
What m1 and m2 values hold? please explain this behaviour of the recursive function.
#include <stdio.h>
main()
{
int i, n, m, b, x[25];
int f1(int, int, int j[25]);
for(i=0;i<25;i++) x[i] = i;
i=0; m = 24;
b=f1(i, m, x);
printf("res %d\n",b);
}
int f1( int p, int q, int a[25])
{
int m1,m2;
if (q==0)
return(a[p]);
else
{
m1 = f1 (p, q/2, a);
m2 = f1(p+q/2+1,q/2,a);
if(m1<m2)
return (m2);
else
return(m1);
}
}
Well, there are two points to understanding the code:
Uncovering the actual algorithm among the heaps of terrible C and
understanding the recursive function itself.
What always helped me when trying to understand such code was to:
Clean up the C code. In this case it means:
Mentally tracing the initialization and rewriting to static initialization, so you see what the values look like:
int x[25] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
Getting rid of the useless assignment to i and x so you have the initial call in plain sight.
Rewrite the function to mathematical notation, pseudocode or even human laguage.
f(p, q, array) = larger of f(p, q/2, array) and f(p+q/2+1, q/2, array)
if you continue a little bit further in using human language, you'll clearly see what is was supposed to do.
Now I said "was supposed to do" on purpose. The (p, q/2) and (p+q/2+1, q/2) look like the first and second half... except they are not.
The code is supposed to return 24, but it's totally wrong and the stacks quoted in the question actually prove it. The m2 stack contains as last point "f1(27, 0, a)" and that invocation is going to do a[27], but the array only has 25 elements! (by pure chance the memory above was probably 0-initialized, so it did return the 24, but if it was initialized by some debug pattern instead (I've seen 0xdeadbeef, 0xa5a5a5a5 and 0xcccccccc), it would return that).
In C it's by design (and C++ uses them everywhere) easiest to use half-open intervals. [start, one-past-end) or start+length, which convert to each other nicely. However here the function gets (start, length-1) and treats it inconsistently inside.
As a student, you have to be able to understand such code, because you'll meet lots of crappy unreadable bug ridden code that only works by accident in the wild. But if you ever present something like this, you will rightfully fail the exam.
Here you can't think of an m1 stack and an m2 stack as non-terminating calls to f1 result in an m1 and an m2 recursive call.
To analyze what's happening try it for a small value of p and q.
f1( 0, 1, a)
m1 = f1( 0, 0, a); /* q/2 == 1/2 == 0 */
/* q now 0 so return a[0] */
m2 = f1( 1, 0, a);
/* q now 0 so return a[1] */
overall result the larger of a[0] and a[1].
Now try it for f1( 0, 2, a) and so on, till you see what's happening.
I'd like to know how to get an array rows & columns size. For instance it would be something like this:
int matrix[][] = { { 2, 3 , 4}, { 1, 5, 3 } }
The size of this one would be 2 x 3. How can I calculate this without including other libraries but stdio or stdlib?
This has some fairly limited use, but it's possible to do so with sizeof.
sizeof(matrix) = 24 // 2 * 3 ints (each int is sizeof 4)
sizeof(matrix[0]) = 12 // 3 ints
sizeof(matrix[0][0]) = 4 // 1 int
So,
int num_rows = sizeof(matrix) / sizeof(matrix[0]);
int num_cols = sizeof(matrix[0]) / sizeof(matrix[0][0]);
Or define your own macro:
#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
int num_rows = ARRAYSIZE(matrix);
int num_cols = ARRAYSIZE(matrix[0]);
Or even:
#define NUM_ROWS(a) ARRAYSIZE(a)
int num_rows = NUM_ROWS(matrix);
#define NUM_COLS(a) ARRAYSIZE(a[0])
int num_cols = NUM_COLS(matrix);
But, be aware that you can't pass around this int[][] matrix and then use the macro trick. Unfortunately, unlike higher level languages (java, python), this extra information isn't passed around with the array (you would need a struct, or a class in c++). The matrix variable simply points to a block of memory where the matrix lives.
It cannot be "something like this". The syntax that involves two (or more) consecutive empty square brackets [][] is never valid in C language.
When you are declaring an array with an initializer, only the first size can be omitted. All remaining sizes must be explicitly present. So in your case the second size can be 3
int matrix[][3] = { { 2, 3, 4 }, { 1, 5, 3 } };
if you intended it to be 3. Or it can be 5, if you so desire
int matrix[][5] = { { 2, 3, 4 }, { 1, 5, 3 } };
In other words, you will always already "know" all sizes except the first. There's no way around it. Yet, if you want to "recall" it somewhere down the code, you can obtain it as
sizeof *matrix / sizeof **matrix
As for the first size, you can get it as
sizeof matrix / sizeof *matrix
sizeof (matrix) will give you the total size of the array, in bytes. sizeof (matrix[0]) / sizeof (matrix[0][0]) gives you the dimension of the inner array, and sizeof (matrix) / sizeof (matrix[0]) should be the outer dimension.
Example for size of :
#include <stdio.h>
#include <conio.h>
int array[6]= { 1, 2, 3, 4, 5, 6 };
void main() {
clrscr();
int len=sizeof(array)/sizeof(int);
printf("Length Of Array=%d", len);
getch();
}
In C, is there a nice way to track the number of elements in an enum? I've seen
enum blah {
FIRST,
SECOND,
THIRD,
LAST
};
But this only works if the items are sequential and start at zero.
If you don't assign your enums you can do somethings like this:
enum MyType {
Type1,
Type2,
Type3,
NumberOfTypes
}
NumberOfTypes will evaluate to 3 which is the number of real types.
I don't believe there is. But what would you do with such a number if they are not sequential, and you don't already have a list of them somewhere? And if they are sequential but start at a different number, you could always do:
enum blah {
FIRST = 128,
SECOND,
THIRD,
END
};
const int blah_count = END - FIRST;
Old question, I know. This is for the googlers with the same question.
You could use X-Macros
Example:
//The values are defined via a map which calls a given macro which is defined later
#define ENUM_MAP(X) \
X(VALA, 0) \
X(VALB, 10) \
X(VALC, 20)
//Using the map for the enum decl
#define X(n, v) [n] = v,
typedef enum val_list {
ENUM_MAP(X) //results in [VALA] = 0, etc...
} val_list;
#undef X
//For the count of values
#define X(n, v) + 1
int val_list_count = 0 + ENUM_MAP(X); //evaluates to 0 + 1 + 1 + 1
#undef X
This is also transparent to an IDE, so auto-completes will work fine (as its all done in the pre-processor).
Unfortunately, no. There is not.
I know this is a very old question, but as the accepted answer is wrong, I feel compelled to post my own. I'll reuse the accepted answer's example, slightly modified.
(Making the assumption that enums are sequential.)
// Incorrect code, do not use!
enum blah {
FIRST = 0,
SECOND, // 1
THIRD, // 2
END // 3
};
const int blah_count = END - FIRST;
// And this above would be 3 - 0 = 3, although there actually are 4 items.
Any developer knows the reason: count = last - first + 1.
And this works with any combination of signs (both ends negative, both positive, or only first end negative). You can try.
// Now, the correct version.
enum blah {
FIRST = 0,
SECOND, // 1
THIRD, // 2
END // 3
};
const int blah_count = END - FIRST + 1; // 4
Edit: reading the text again, I got a doubt. Is that END meant not to be part of the offered items? That looks weird to me, but well, I guess it could make sense...
Well, since enums can't change at run-time, the best thing you can do is:
enum blah {
FIRST = 7,
SECOND = 15,
THIRD = 9,
LAST = 12
};
#define blahcount 4 /* counted manually, keep these in sync */
But I find it difficult to envisage a situation where that information would come in handy. What exactly are you trying to do?
int enaumVals[] =
{
FIRST,
SECOND,
THIRD,
LAST
};
#define NUM_ENUMS sizeof(enaumVals) / sizeof ( int );
#include <stdio.h>
// M_CONC and M_CONC_ come from https://stackoverflow.com/a/14804003/7067195
#define M_CONC(A, B) M_CONC_(A, B)
#define M_CONC_(A, B) A##B
#define enum_count_suffix _count
#define count(tag) M_CONC(tag, enum_count_suffix)
#define countable_enum(tag, ...) \
enum tag {__VA_ARGS__}; \
const size_t count(tag) = sizeof((int []) {__VA_ARGS__}) / sizeof(int)
// The following declares an enum with tag `color` and 3 constants: `red`,
// `green`, and `blue`.
countable_enum(color, red, green, blue);
int main(int argc, char **argv) {
// The following prints 3, as expected.
printf("number of elements in enum: %d\n", count(color));
}