I am trying to define a constant that would have the following in it
ch[co].gold < 10000*100
how can I make it, something like
define x = ch[co].gold < 10000*100;
so that every time I write
if (x) {say(cn,"You need 10 000 gold coins");}
Or that is not possible?
Function:
int x(int val) {
return (val < 10000 * 100);
}
Usage
// ...
if (x(ch[co].gold)) {
printf("You need 10 000 gold coins.\n");
}
// ...
Well, here is my solution
struct s {
int gold;
};
const int co = 2;
struct s ch[] = {112,2321,3234};
#define x() ch[co].gold < 10000*100
int main(){
if (x()) {
}
return 0;
}
Is this what you are expecting?
#define x (ch[co].gold < 10000*100)
Add this line of code before the place you use it, usually it's just below the #includes.
Conventionally, we use capital letters with clearer meanings instead of x.
#define is simply text substition performed by the preprocessor.
To do what you say you want use the following #define:
#define x ch[co].gold < 10000*100
Every time the preprocessor encounters the symbol x it will replace it with ch[co].gold < 10000*100.
I think that what you really want is to make it a proper function as suggested by pmg. It is a wiser choice.
Related
#define PUMP [0,1]
when I call a function like this:
for (index = 0;index < 8; index++)
{
get_motor_current(PUMP[index]);
}
The intent is to do get_motor_current([0][index]) and get_motor_current([1][index])
Thank you very much.
You can do it by having the macro expand into a compound literal.
#include <stdio.h>
#define PUMP ((const int[]){0, 1})
int main(void) {
for (int index = 0;index < 2; index++)
{
printf("%d\n", PUMP[index]);
}
}
Long story short, you can't do what you're trying to do the way you're trying to do it. All the C preprocessor does is perform direct text substitutions. So, after preprocessing, your code snippet would look like:
for (index = 0;index < 8; index++)
{
get_motor_current([0,1][index]);
}
which is not valid C.
Also, square brackets [] are only used for indexing an existing array. If you want to initialize an array with a list of values, you write a list of values enclosed in curly braces {} like so:
int some_array[] = {1, 2, 3, 4};
You don't need to define an array size here (i.e. say some_array[4]) because the compiler just counts the number of items in the list and does that for you.
Which is considered the best behavior in C and what are the pros cons of the two possible following options?
OPTION 1 (global variable):
int x;
for (x = 0; x < 100; x++) {
// do something
}
OPTION 2 (local variable):
for (int x = 0; x < 100; x++) {
// do something
}
EDIT: Assume I don't need the variable after looping over it.
The main benefit of option 1 is that you can use x outside the body of the loop; this matters if your loop exits early because of an error condition or something and you want to find which iteration it happened on. It's also valid in all versions of C from K&R onward.
The main benefit of option 2 is that it limits the scope of x to the loop body - this allows you to reuse x in different loops for different purposes (with potentially different types) - whether this counts as good style or not I will leave for others to argue:
for ( int x = 0; x < 100; x++ )
// do something
for ( size_t x = 0; x < sizeof blah; x++ )
// do something;
for ( double x = 0.0; x < 1.0; x += 0.0625 )
// do something
However, this feature was introduced with C99, so it won't work with C89 or K&R implementations.
This is not an answer. This is a third option, that is sort of intermediate:
{
int x;
for (x = 0; x < 100; x++) {
// do something
}
// use x
}
This is equivalent to the 2nd option, if there's no code between the two closing brackets.
Always try to declare variables in minimum scopes where they are used.
This makes your code more readable and clear.
For example consider the first code snippet with a modification
int x;
//... some other code
for (x = 0; x < 100; x++) {
// do something
}
When the reader will read this code snippet and encounter the declaration
int x;
he well not know what this variable means and where it is used.
If you will rewrite this code snippet the following way
int x;
for (x = 0; x < 100; x++) {
// do something
}
then this code will confuse readers because they will think that the variable x is used somewhere else after the for loop though actually it is used only in the for loop.
So the best way is to write
for ( int x = 0; x < 100; x++) {
// do something
}
General good practice in C is to always reduce scope of variables as much as possible. This reduces namespace clutter and naming collisions, plus it is good design to encapsulate logic as much as possible to make it self-contained and readable.
Meaning that option 2, declaring the loop iterator inside the loop, is the preferred practice.
The only time you should use option 1 is when you need to use the value after the loop has ended, or when you are stuck with an old C90 compiler.
If you call something like this in C:
#include <stdio.h>
#define REPS ,a
...
int a = 1;
printf("%d" REPS);
It will work, but is it possible to call the REPS macro multiple times based on an unknown value, like for example, that I want to have five inputs in a scanf, yet I want my code to automate it (for example, if #define REPS ,a[i] then: ... ,a[1] ,a[2])?
It will work, but is it possible to call the REPS multiple times based in an unknown value
No. #define creates a preprocessor macro that you can use in your code, but when the compiler compiles your code, the actual value is substituted for the macro. If you have:
#define FOO 7
for example, then every occurrence of FOO in your code is replaced by 7 before the code is compiled; by the time the compiler sees your code, there's no #define and no FOO, only 7 wherever FOO was. Although there are some other preprocessor commands (e.g. #if) that can control whether a given #define is evaluated at all, there are no other preprocessor control structures (loops etc.).
I want to have five inputs in a scanf, yet I want my code to automate it (for example, if #define REPS ,a[i] then: ... ,a[1] ,a[2])?
You can certainly automate something like that; it's just that the preprocessor isn't the right tool for the job. Consider:
int reps = 5
//...
for (int i = 0; i < reps; i++) {
scanf(" %d", &a[i]);
}
REPS is evaluated at compile time, so it cannot depend on run-time values in this case a. There are hacks but in general you cannot do compile loops with macros.
I suggest you write a function along these lines instead:
#include <stdio.h>
void print_int_array(size_t n, int a[n]) {
for(int i = 0; i < n; i++)
printf("%d%s", a[i], i + 1 < n ? ", " : "\n");
}
int main() {
print_int_array(0, (int []) {});
print_int_array(1, (int []) {1});
print_int_array(2, (int []) {1, 2});
}
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.
I'm writing for a very limited resource embedded processor. I have a struct that captures a time series of events, and I'd like to use the same graphing function against different values of different types. Something like (very stripped down; don't sweat uninitialized values, etc):
#define GRAPH_ONE 1
#define GRAPH_TWO 2
struct _event_t {
unsigned long timestamp;
int sensorOne;
float sensorTwo;
}
typedef struct _event_t event_t;
event_t[10] MyEvents;
void GraphSensor(byte graphType) {
for (unsigned int i = 0; i < 9; i++) {
// Get minimum value from series
if (MyEvents[i].?????) ...
}
}
How can I have my function operate on different members of the struct? I can see doing it with a ton of switch (graphType) statements, but that's pretty ugly. There could easily be 8 or 10 members of the struct. I could move all of those to a separate function and make every bit of data access call that function, always returning a float (which should be OK for my graph). Finally I could convert to C++ classes, which opens other means.
None of those feel right. Is there a better approach, preferably a very lightweight one?
You could wrap the accessor you need in a function, and pass that to the function that walks the array and aggregates the results. For example
float getSensor1(const event_t* t)
{
return t->sensorOne;
}
float getSensor2(const event_t* t)
{
return t->sensorTwo;
}
void GraphSensor(float (*accessor)(const event_t*)) {
// Get minimum value from series
float min_value = MAX_FLOAT;
for (unsigned int i = 0; i < 9; i++) {
float x = accessor(MyEvents + i);
if (x < min_value)
min_value = x;
}
}
/* later on . . . */
GraphSensor(getSensor1);
GraphSensor(getsensor2);
You are basically decoupling the access of the data from the operation on it, and homogenizing it all to floats. The aggregation operation could also be encapsulated into a function, too. But that's getting pretty close to map-reduce. :)
You could change the struct to an array which uses perhaps all floats. In that way the data handling is completely homogeneous.
#define N_SENSORS 12
#define N_EVENTS 10
float MyEvents [N_EVENTS] [N_SENSORS];
void GraphSensor(byte graphType)
{
float min = 1e38;
for (unsigned int i = 0; i < N_EVENTS; i++)
{
// Get minimum value from series
if (MyEvents[i][graphType] < min)
min = MyEvents[i][graphType];
}
}
Perhaps the timestamp could be there too in element zero maybe using spreadsheet conventions: integer part is days since 1970 or 1900 and fractional part is portion of the day (so noon = .5).