I'm currently learning C, and I was wondering if there was a really elegant way of a struct variable being able to self assign to it's member variables.
i.e.
typedef struct {
double x; double y; double magn = sqrt(pow(x,2) + pow(y, 2));
} vector2d_t
Clearly this does not work. Is it possible to make some type of pre-proc macro, or wrap the structure within something else so the magnitude is automatically assigned every time the members x, y are changed?
Is there some sort of agreed upon method for doing this, or is it necessary to create a function:
void magnitude(vector2d_t *A){A->magn = sqrt(pow(A->x, 2) + pow(A->y, 2));}
and call it every time you create a new vector2d_t?
Unfortunately this is not supported in C and never will be. C is the kind of programming language that allows you do to almost everything, this means everything manually!
Best you can do is create functions of macros that autoupdate this for you:
void update_x(vector2d_t * v, double x) {
v->x = x;
v->magn = sqrt(pow(x,2) + pow(v->y, 2));
}
Your magn is not a property. It is a value depending on two other values. Not only it can't be done automatically, I think that it should never be done automatically. It is yours, as a programmer, choice when and how such value is updated. Lazily, whenever you access it, or proactively, whenever x or y are changed. Or maybe you want to update it periodically, whenever, say, a frame is rendered?
Moreover, logically, mathematically, magn is a function. It is a function with two other parameters. It seems kid of logical to make a function which handles this value somehow.
Related
I get an error in visual studio with the code:
struct coordinates {
int x;
int y;
};
struct coordinates point;
point.x = 5;
point.y = 3;
int main() {
return 0;
}
it works if I initialize point.x and point.y in main() and / or if I give the point values like this: struct coordinates point = {5, 3}. Why can't you initialize point.x and point.y outside of main()?
Other answers are (correctly) explaining that there are ways to initialize structs by named member outside main statically but I want to add, for the OP or for others.
The basic idea here is that C doesn't allow executable statements ("code") outside of functions. A new C programmer may be coming from another language where code is sort of frequently executed in a "global scope" and you define functions or set variables here and there as you wish. C is way older and much more structured than this. There are global variables (like your point), which are things you declare outside of any particular function, but you can't really "do stuff" with those variables in the global space itself, except indicate their initial values (static initialization).
C doesn't "run through the file executing everything it finds in order"-- each file gets compiled into a unit of object code which then gets linked together with other units and main is (essentially) the entry point for execution, which in turn calls other functions, and so on-- when your code is running, its always "inside" of a function somewhere.
It is true that ordering of declarations and definitions within a file matter in C, but this is essentially for the convenience of the compiler, not because things are "executed" or "evaluated" in that order at runtime. (By the time your code is executing, it's been utterly transformed into something else and the order of statements in the original files has essentially disappeared from view.)
So! With all that said: it is useful and often desirable to have the values of global variables pre-set at program initialization time. So static initialization is sort of special in that it sorta looks like an executable statement but isn't, and thus it has traditionally had a goofy syntax. We had that sort of strange ordered = {2, 3} syntax, and now there are more accommodations for the named members to help you accomplish this static initialization. But you should still think of it as static (one-time, fixed) initialization, not as executing an assignment in the global space, because that isn't what you're actually doing.
The form you've written is not initialization; it's an uninitialized (or rather default-initialized, to zero) declaration and definition followed by assignment statements outside of a scope where they're valid.
If you want to initialize the members by name, write:
struct coordinates point = {
.x = 5,
.y = 3,
};
Why can't you initialize point.x and point.y outside of main()?
You can, using static initialization - but you can't call a function or perform impure operations. When using static-initialization prior to C99 you need to ensure fields are set in the correct order, while C99 and later allow for designated initializers that allow arbitrary field initialization.
C code outside of a function are not executable instructions - they're static declarations, consequently they don't have a defined evaluation order.
As a thought-experiment, consider this:
int x;
int y;
x = 2;
y = 3;
y = x;
x = y;
int main() {
return x; // what is returned?
}
Maybe you learned Javascript but you are a newbie in c/c++.
Every c/c++ program starts with the main function, and every executive code must be in a function.
So if you want to initialize the value of a struct, you should do this in main function.
struct coordinates {
int x;
int y;
};
struct coordinate point;
int main(){
point.x = 5;
point.y = 3;
}
I want to use Brents method as present in the Numerical Recepies Book to minimize a function. The signature of the minimzation routine essentially looks like this:
float brent(float (*f)(float), float *xmin, "other parameters not relevant to question")
As you can guess brent returns the minimum value of f and stores its argument in xmin.
However, the exact form of the function I want to minimize depends on additional parameters. Say
float minimize_me(float x, float a, float b)
Once I decided on the values of a and b I want to minimize it with respect to x.
I could simply add additional arguments to all functions called, all the way down to brent, thus changing its signature to
float brent(float (*f)(float,float,float),float a ,float b , float *xmin, ...)
and consequently call (*f)(x,a,b) inside brent every time. This, however, seems not really elegant to me since I would now have to pass not only the pointer to minimize_me, but also two additional parameters down a whole chain of functions.
I suspect there could be a more elegant solution, like creating a pointer to a version of the function with a and b as fixed values.
Even if it is a really obscure solution, please don't keep it from me, since I feel it could improve my overall understanding of the language.
A viable way of achieving this is to use a struct to store all the values and pass a pointer to that to the function.
struct parameters{
int valueA;
int valueB;
};
int function(void* params){
parameters* data = (parameters*) params;
return data->valueA + data->valueB; // just an example
}
int main(){
parameters myData;
myData.valueA = 4;
myData.valueB = 2;
function(&myData);
return 0;
}
What you need is currying, say for example:
given a function of three variables f(x,y,z) and two values a and
b, construct the function g of one variable such that g(z)=f(a,b,z).
Alas C language is not able to let you currying. Such a construction is available to functional languages only and C is not one. This doesn't mean that you really can't do it, but there is no given construction for it in the language. So you need to reconstruct the mechanism by yourself. See Currying/binding with ISO C99 or Is there a way to do currying in C? for examples.
GCC's local functions extension is a pure joy to use (use -std=gnu11):
float brent(float (*f)(float), float *xmin);
float minimize_me(float x, float a, float b);
int main() {
...
float min_me_local(float x) { return minimize_me(x, 1, 2); }
brent(min_me_local, xmin);
...
}
I wish it was standard, but it isn't. So prefer answer from #Nefrin when aiming at portability.
For example:
int f1() {
return 3;
}
void f2(int *num) {
*num = 3;
}
int n1, n2;
n1 = f1();
f2(&n2);
With f1, we can return a value and do "variable=f1()"
But the same can be done with a void function that updates the value of that variable given its address without having to do "variable=f1()".
So, does this mean that we can actually just use void functions for everything? Or is there something that a void function cannot do to replace another int function/(type) function?
The main problem with making everything a void function (which in some people's lexicon is called a "routine") is that you can't chain them easily:
f(g(x))
becomes, if you really want to chain it:
int gout;
f((g(x, &gout), gout))
Which is painful.
Yes you could use void return types for everything and rely exclusively on returning via modified parameters. In fact, you could avoid using functions entirely and put everything in your main method.
As with any other feature of the language, return values give you particular advantages, and its up to you to decide if you want them. Here are some advantages of return values off the top of my head:
Returned values can be assigned to const variables, which can make your code easier to reason about
Certain types of optimisation can be applied by the compiler for returned values (this is more applicable to C++ RVO but may also apply to C's structs; I'm not sure)
Code which uses returned values is often easier to read, especially when the functions are mathematical (e.g. imagine having to declare all the temporaries manually for a large mathematical operation using sin/cos/etc. if they required the output to be via parameters). Compare:
double x = A*sin(a) + B*cos(b);
with
double tmpA, tmpB;
sin(&tmpA, a);
cos(&tmpB, b);
double x = A * tmpA + B * tmpB;
or to use a similar structure as John Zwinck suggested in his answer:
double tmpA, tmpB;
double x = A * (sin(&tmpA, a), tmpA) + B * (cos(&tmpB, b), tmpB);
It is guaranteed that the value will be set no matter what happens inside the function, as this is enforced by the compiler (except some very special cases such as longjumps)
You do not need to worry about checking if the assigned value is used or not; you can return the value and if the requester doesn't need it, they can ignore it (compare this to needing NULL-checks everywhere in your alternative method)
Of course there are also disadvantages:
You only get a single return value, so if your function logically returns multiple types of data (and they can't logically be combined into a single struct), returning via parameters may be better
Large objects may introduce performance penalties due to the need to copy them (which is why RVO was introduced in C++, which makes this much less of an issue)
So, does this mean that we can actually just use void functions for everything?
Indeed. And as it turn out, doing so is a fairly common coding style. But rather than void, such styles usually state that the return value should always be reserved for error codes.
In practice, you usually won't be able to stick to such a style consistently. There are a some special cases where not using the return value becomes inconvenient.
For example when writing callback functions of the kind used by standard C generic functions bsearch or qsort. The expect a callback of the format
int compare (const void *p1, const void *p2);
where the function returns less than zero, more than zero or zero. Design-wise it is important to keep the parameters passed as read-only, you wouldn't want your generic search algorithm to suddenly start modifying the searched contents. So while there is no reason in theory why these kind of functions couldn't be of void return type too, in practice it would make the code uglier and harder to read.
Of course you could; but that does not make it a good idea.
It may not always be convenient or lead to easy to comprehended code. A function returning void cannot be used directly as an operand in an expression. For example while you could write:
if( f1() == 3 )
{
...
}
for f2() you would have to write:
f2( &answer ) ;
if( answer )
{
...
}
Another issue is one of access control - by passing a pointer to the function you are giving that function indirect access to the caller's data, which is fine so long as the function is well behaved and does not overrun. A pointer may refer to a single object or an array of objects - the function taking that pointer has to impose appropriate rules, so it is intrinsically less safe.
I am trying to do something interesting(automation) in C. What I want to do is.
Expose an interface to the outer world(developer).
That interface declares some argument based functions.
Will invite developers to implement those functions.
The backend system will calculate some parameters.
Then it will call those implementations by passing the parameters(something like callback).`
It should not be a big deal. But I didn't get any success after going through "think-try" loop so many times. I am getting more and more confused every time.
I am unable to write the code to achieve the functionality. Here is some example code.
Assume I created the below interface.
MyInterface.h
int doSomething(int x, int y);
int doSomethingElseNow(int x, int y);
And asked the developer to include the header file and implement his own definitions for the above specified functions.(some thing like "Interfaces" in Java). Assume he did something like this(might be wrong)
Developer1.c
#include<"MyInterface.h">
int doSomething(int x, int y)
{
return x*y;
}
int doSomethingElseNow(int x, int y)
{
return x+y;
}
Now, my question is how do I call these functions(defined) from some other class. What should be my backend code. This code has to generic. It will be written before developer are asked to define functions. Want to do something like.(is wrong for sure)
Backend.c
#include<"MyInterface.h">
int main()
{
int x, y;
// calculating values of x and y
//calling doSomething
int result = doSomething(x, y);
// doing some calculations on result variable
//calling doSomethingElseNow
int result2 = doSomethingElseNow(x, result);
//do something with result2...
}
Please show me some direction to move on.
You definitely can do this by only declaring and then not implementing your callback functions, as this will force the developer to implement them (if he doesn't, he'll get a linker error). This is what e. g. the SDL library does when it re-#defines the main() function (ugh!)
However, this is not a too wise solution. ("you can" doesn't mean "you should".) Here's why:
On some systems, you won't be able to make a dynamic library out of your code because linkage will fail with undefined symbols.
Only one callback function can be implemented per executable. Sometimes that's insufficient.
The developer can't call his callback function what he wants to call it. This may even introduce name collisions.
It is ugly and conceptually backwards.
So, instead of forcing the implementation of some arbitrarily named functions, make your interfaces expect an explicit pointer to a callback function. This is way more flexible and elegant than your current approach.
I am bit new to C programming and i would like to ask a certain question.
I'm using MPLAB c18 Compiler.
At first when I started coding and ended up with lot of variables some were global and some were extern.
I found a certain statement in an article about encapsulation of variables.
Replacing
float x;
float y;
float z;
with these
float X();
float Y();
float Z();
Is that an intention to do with
local variables inside the respective functions and assign
local float x= float x(); local float y= float y();
I would appreciate your inputs and clarifications in this case.Am i Wrong regarding the interpretation.
So my question is ,whether the encapsulation is for reducing global and using more local variables in functions?
Regards
Replacing "float x" (probably extern float x in some header) effectively encapsulates the variable.
You would probably need something like:
float x(); /* get x */
void setX(float newVal); /* set x here */
But that's rather general, the real implementation needs to be tailored to your needs (do you need a setter? do you need a getter? do you need to optimize this?).
In general, especially if you are rather new to C, encapsulation helps with a cleaner design and prevents simple mistakes.
For example, assuming that changing the value X involves performing some other task (say, X is the countdown for a nuclear missile launch sequence).
When encapsulating, your code would look something like:
void setX(float newVal){
x = newVal;
startNuclearLaunchSequence();
}
If you don't have this setter, you need to find all the places you set X (maybe by your colleagues as well) and manually launch your rockets, otherwise you'd get a misfire and then - bye bye apocalypse.
We don't want that, do we?