What's wrong with my structs? - c

Ok, i'm writing in c here. Compiling in mingw gcc.
I'm trying to do something really simple. create a vector struct containing 3 floats x,y,z.
then I want to be able to do some math with them.
This is my short test program:
#ifndef _PHYSICS_C_
#define _PHYSICS_C_
#define SUCCESS 0
#define FAILURE 1
typedef struct {
float x;
float y;
float z;
}vector;
int add ( vector* a, vector* b, vector* destination ){
(*destination).x = (float)( ((*a).x) + ((*b).x) );
(*destination).y = (float)( ((*a).y) + ((*b).y) );
(*destination).z = (float)( ((*a).z) + ((*b).z) );
return SUCCESS;
}
int main(int argc, char** argv){
printf("creating vectors\n\n");
vector a = {1.0f,5.0f,3.0f};
vector b = {2.0f,3.0f,6.0f};
vector destination;
printf("adding vectors\n\n");
if(add(&a, &b, &destination) == SUCCESS){
printf("result: (%d, %d, %d)\n\n",destination.x,destination.y,destination.z);
} else {
printf("the program failed somehow...\n\n");
}
printf("Press any key to continue...\n");
getchar();
return SUCCESS;
}
#endif
When I compile and run it, it should return (3, 8, 9) the sum of vectors a and b.
instead it returns (0, 1074266112, 0)...
I can't figure out what is wrong.
for some reason I think that I must somehow be writing over memory I'm not supposed to.

x,y,z are floats but you are trying to print them as integers.
try:
printf("result: (%f, %f, %f)\n\n",destination.x,destination.y,destination.z);
check man printf or your documentation to see all of the specifiers for printf.

%d expects int. Use %f or %g for floats/doubles.

Identifiers starting with an underscore followed by an uppercase letter are reserved; don't use them in your own code.
Include guards (#ifndef _PHYSICS_C_ ...) are for header files, not for .c files.
printf requires #include <stdio.h>.
You're returning the value SUCCESS from main(). That's ok, since SUCCESS happens to be 0, but it would be clearer to use either EXIT_SUCCESS (declared in <stdlib.h> or just return 0;.
You add function always returns SUCCESS. It might as well be a void function (and the test for its value in main is not useful). Unless you anticipate adding error checking later on.
The casts in your add function are unnecessary; the expression is already of type float. And (*foo).bar is better written as foo->bar. For example, the first assignment can be simplified to destination->x = a->x + y->x;.
The real problem (which has already been pointed out) is that you're using a "%d" format for values of type float.
It's usual to use double rather than float. It has more precision, and modern hardware is often optimized for double-precision operations.
If you enable warnings in your compiler, it will probably tell you about some of these problems.

You are printing float with format specifier %d which is intended for signed int. Use %f or %g or %e instead .
Also, why don't you do:
destination->x = a->x + b->x;
Its much easier on the eyes. (although not a problem).

Related

I have trouble with the following code with different variable types and pointers for finding Bessel functions

This assignment is one of my labs and it wants us to find the value of the 1st order Bessel function according to the input-ed user value. So long, my mindset is: first I will ask the user for input, then I use the number's rounding, the number above and the number below. After that, I perform the interpolation according to the numbers, find the error, then present everything on screen. (We must use pointers and arrays else we will not get any marks. That makes sense, how are we gonna list out every case for every rounded number from 0 to 10......)
The problem is, I seem to not get the pointers right, and the program always say that we have long int and *double mixed, even though I explicitly told the program that this is a double.
Code:
#include <stdio.h>
#include <math.h>
#include <Stdlib.h>
int y;
int readdata(double rho[y], double Jrho[y])
{
double a, b, c, x;
FILE* fp;
fp= fopen("Bessel1.dat", "r");
for (y=0; y<=10; y++)
{
fscanf(fp, "%lf %lf", &rho[y], &Jrho[y]);
}
}
double Lagrange2nd(int y, double rho[y], double Jrho[y], double x)
{
double a, b, c;
double output;
a=(x-rho[(y+1)])*((x-rho[y])*Jrho[((y-1))]+(rho[((y-1))]-
x)*Jrho[y])/(rho[((y-1))]-rho[y]);
b=(((rho[(y-1)]-x)*((x-rho[(y+1)])*Jrho[y]+(rho[y]-
x)*Jrho[(y+1)]))/(rho[y]-rho[(y+1)]));
output = c = (a+b)/(rho[(y-1)]-rho[(y+1)]);
return output;
}
double errx(int y, double rho[y], double Jrho[y], double x)
{
double a, b, c;
double output;
output= (abs(c-(Jrho[(y-1)]*(x-rho[y])+Jrho[y]*(rho[(y-1)]-x)))+abs(c-
(Jrho[y]*(x-rho[(y+1)])+Jrho[(y+1)]*(rho[y]-x))))/2;
return output;
}
int main()
{
double x, Jrho[y], rho[y];
printf("x=");
scanf("%lf", &x);
y=round(x);
Lagrange2nd(&rho[y], &x, &Jrho[y], y);
errx(&Jrho[y], &x, &rho[y], y);
printf("%d, %d", Lagrange2nd, errx);
return(0);
}
I know this is messy, but I did not know any programming until 2 months ago, yet we now have to do this......gee, I am not very good at this, am I?
What compiler do you use ? with gcc you will get MANY warnings. In particular, you have few functions that declare to return void, but return an int.
Looks like you compiler does treat 'void' as 'int' - which will cause lot of precision issue. If you have turned of warning - consider re-enabling them, or use better compiler :-)
void errx(double* rho[y], double* Jrho[y], double* x)
{
...
double output;
output= (abs(c-(Jrho[(y-1)]*(x-rho[y])+Jrho[y]*(rho[(y-1)]-x)))+abs(c-(Jrho[y]*(x-
rho[(y+1)])+Jrho[(y+1)]*(rho[y]-x))))/2;
return output;
}
Style note: consider combing declaration and assignment in one statement. It will reduce many possible errors, and will get you better grade!
double output = (abs(c-(Jrho[(y-1)]*(x-rho[y])+Jrho[y]*(rho[(y-1)]-x)))+abs(c-(Jrho[y]*(x-rho[(y+1)])+Jrho[(y+1)]*(rho[y]-x))))/2;

Expected Expression with square roots

#define PI = 3.141593
#define G = 6.67259E-11
#define g = 9.80665
#define M = 5.972E+24
#define r = 6378000
#define h = 220
#include <stdio.h>
#include <math.h>
int main(void)
{
int value;
value =sqrt((G/M)/(r+h))
printf("This is the tangential speed:") value;
return 0;
}
I am very new to coding, and my program is giving me several errors in code blocks, can anyone give me some guidance?
Remove the = from all the #define statements. They are preprocessor macro definitions, not assignment statements, and they do not use equal signs.
Change int value to double value, to use floating-point instead of integers.
Add a ; after value =sqrt((G/M)/(r+h)). Statements in C generally end with a semicolon.
Change printf("This is the tangential speed:") value; to printf("This is the tangential speed: %g.\n", value);. printf is a function call, not a statement, so you pass everything it needs inside a set of parentheses. The string is a format string; it contains both literal text you want printed and conversion specifications like %g that tell it to convert an argument to a string. %g tells it to convert a double argument to a general floating-point display form.
I see two problems:
Smallest problem, but might be significant, is that I assume you want value to be a float or double instead of an int, thus replace
int value;
by
float value;
The print statement is incorrect:
printf("This is the tangential speed:") value;
Assuming value is a float, change it to
printf("This is the tangential speed: %f\n", value);
\n makes a new line.
And of course don't forget the remark by chux.

Please help me to understand these error

#include<stdio.h>
float func (float t, float y){
return y ;
}
int main (){
float t0,y0,t,y;
printf ("the value of t: ");
scanf ("%f",&t0);
printf ("the value of y: ");
scanf ("%f",&y0);
t=t0;
y=y0;
static int n=0;
// t[0]=t0;
// y[0]=y0;
for (n=0;n<=3;n++){
y[1]=y[0];
printf ("value of y %f %f \n",t,y);
}
return 0;
}
The error is:
Building prog.obj.
D:\master\c language\ch3\prog.c(166): warning #2117: Old-style function definition for 'main'.
D:\master\c language\ch3\prog.c(182): error #2144: Type error: pointer expected.
D:\master\c language\ch3\prog.c(182): error #2144: Type error: pointer expected.
*** Error code: 1 ***
You cannot array index something that is not an array, or a pointer into an array.
Your y and t floats are not pointers into arrays in your program.
You should make them float *y, *t into pointers so you can point them into array.
Change float t0,y0,t,y; to float t0,y0,*t,*y;
and
t=&t0; //assign address of t0 to t
y=&y0;
Change printf ("value of y %f %f \n",t,y); to
printf ("value of y %f %f \n",*t,*y); //note to dereference t and y here, to get their values
Here's a example of your program I fixed to work
The 'Old-style function definition for main()' message means that you've not given a prototype definition. The correct forms are:
int main(void) { ... }
int main(int argc, char **argv) { ... }
The version int main() is fine in C++, but not strictly a prototype in C, and hence gets the 'old-style' tag.
The other messages are more inscrutable; the line numbers do not correspond to the code you show. However, as Tony The Lion notes in his answer, the line
y[1] = y[0];
is erroneous since y is not an array. There is room to think that should be:
y = y0;
and you'd need a companion:
t = t0;
in order to have defined values printed in the printf() statement.
Even with these changes, the code does not make a lot of sense. However, given that you removed 150-odd lines, we can suppose that the missing code would make more sense.
There is no need to make n into a static variable; it is better not to do so.
Please make sure, in future, that your error messages correspond to the source code you post, not to some variant version of the code you post. The line numbers should not be as large as 166 or 182; they should be single digit numbers or small double digit numbers. But even more importantly, they should match the code!

How to printf long long

I'm doing a program that aproximate PI and i'm trying to use long long, but it isn't working.
Here is the code
#include<stdio.h>
#include<math.h>
typedef long long num;
main(){
num pi;
pi=0;
num e, n;
scanf("%d", &n);
for(e=0; 1;e++){
pi += ((pow((-1.0),e))/(2.0*e+1.0));
if(e%n==0)
printf("%15lld -> %1.16lld\n",e, 4*pi);
//printf("%lld\n",4*pi);
}
}
%lld is the standard C99 way, but that doesn't work on the compiler that I'm using (mingw32-gcc v4.6.0). The way to do it on this compiler is: %I64d
So try this:
if(e%n==0)printf("%15I64d -> %1.16I64d\n",e, 4*pi);
and
scanf("%I64d", &n);
The only way I know of for doing this in a completely portable way is to use the defines in <inttypes.h>.
In your case, it would look like this:
scanf("%"SCNd64"", &n);
//...
if(e%n==0)printf("%15"PRId64" -> %1.16"PRId64"\n",e, 4*pi);
It really is very ugly... but at least it is portable.
Your scanf() statement needs to use %lld too.
Your loop does not have a terminating condition.
There are far too many parentheses and far too few spaces in the expression
pi += pow(-1.0, e) / (2.0*e + 1.0);
You add one on the first iteration of the loop, and thereafter zero to the value of 'pi'; this does not change the value much.
You should use an explicit return type of int for main().
On the whole, it is best to specify int main(void) when it ignores its arguments, though that is less of a categorical statement than the rest.
I dislike the explicit licence granted in C99 to omit the return from the end of main() and don't use it myself; I write return 0; to be explicit.
I think the whole algorithm is dubious when written using long long; the data type probably should be more like long double (with %Lf for the scanf() format, and maybe %19.16Lf for the printf() formats.
First of all, %d is for a int
So %1.16lld makes no sense, because %d is an integer
That typedef you do, is also unnecessary, use the type straight ahead, makes a much more readable code.
What you want to use is the type double, for calculating pi
and then using %f or %1.16f.
// acos(0.0) will return value of pi/2, inverse of cos(0) is pi/2
double pi = 2 * acos(0.0);
int n; // upto 6 digit
scanf("%d",&n); //precision with which you want the value of pi
printf("%.*lf\n",n,pi); // * will get replaced by n which is the required precision

C complex number and printf

How to print ( with printf ) complex number? For example, if I have this code:
#include <stdio.h>
#include <complex.h>
int main(void)
{
double complex dc1 = 3 + 2*I;
double complex dc2 = 4 + 5*I;
double complex result;
result = dc1 + dc2;
printf(" ??? \n", result);
return 0;
}
..what conversion specifiers ( or something else ) should I use instead "???"
printf("%f + i%f\n", creal(result), cimag(result));
I don't believe there's a specific format specifier for the C99 complex type.
Let %+f choose the correct sign for you for imaginary part:
printf("%f%+fi\n", crealf(I), cimagf(I));
Output:
0.000000+1.000000i
Note that i is at the end.
Because the complex number is stored as two real numbers back-to-back in memory, doing
printf("%g + i%g\n", result);
will work as well, but generates compiler warnings with gcc because the type and number of parameters doesn't match the format. I do this in a pinch when debugging but don't do it in production code.
Using GNU C, this works:
printf("%f %f\n", complexnum);
Or, if you want a suffix of "i" printed after the imaginary part:
printf("%f %fi\n", complexnum);

Resources