Pointers in C Programming- Coordinate conversion - c

I should write a program to convert Cartesian coordinates to Polar and vice versa with use of pointers, I wrote the following code but my function gives me segmentation fault. I tried to do it without the pointers and still it doesn't send my numbers to the function, can someone help to modify my pointer code? I'm new with C.
#include <stdio.h>
#include <math.h>
void cart(float *radius,float *degree)
{
float *x,*y,*radians;
*radians= (3.14159265359/180) * *degree;
*x= *radius * cos(*radians);
*y= *radius * sin(*radians);
}
int main()
{
float radius, radians, degree;
float x,y;
int M;
char C,P;
printf(" Enter C if you are converting Cartesian to Polar \n");
printf(" Enter P if you are converting Polar to Cartesian \n");
scanf("%c",&M);
if (M=='P')
{
printf("Enter the Radius and Angle separated by comma \n");
scanf("%f,%f",&radius,&degree);
cart(&radius,&degree);
printf("Cartesian form is (%f,%f) \n",x,y);
}
else if (M=='C')
{
printf("Enter values of X and Y separated by comma \n");
scanf("%f,%f",&x,&y);
radius=sqrt(((x*x)+(y*y))); // finding radius
radians=atan(y/x); //finding angle in radians
printf("Polar form is (%f,%f) \n",radius,radians); //angle is in radians
}
return 0;
}

The first thing to note is in your 'cart' function:
void cart(float *radius,float *degree)
{
float *x,*y,*radians;
*radians= (3.14159265359/180) * *degree;
*x= *radius * cos(*radians);
*y= *radius * sin(*radians);
}
You have declared pointers named x, y and radians, but they do not yet point to anything.
So when you 'de-reference' them with *x, *y and *radians you are accessing memory that does not exist, which will result in undefined behavior, possibly a segmentation fault.
I would assume that your goal is to get the x, y and radians from your main function to match up with those, so you should be passing them into the function as well.

I think what you mean is this:
void cart(float radius, float degree, float *x, float *y)
{
float radians;
if ((x == NULL) || (y == NULL))
return;
radians = 3.14159265359 / 180.0 * degree;
*x = radius * cos(radians);
*y = radius * sin(radians);
}
and call it like this
float x, y, radius, degree;
if (scanf("%f,%f", &radius, &degree) == 2)
cart(radius, degree, &x, &y);
else
{
fprintf(stderr, "error: invalid input expexted <radius,degree>\n");
exit(1);
}
In your original implementation you were declaring x and y as pointers but you hadn't initialized them, since you mean to modify them in the function you need to pass pointers which contain the addresses of the variables you wish to modify, for that you use the & address of operator.

Related

Function that implements Taylor Series in C return the value of the argument

I was experimenting with the Taylor Series expansion for tan(x) in C. I've created a super simple function whose purpose is to return the answer of the expansion (see code below). The issue is that when one invokes it, the answer is the argument of the tangent, i.e. if you call the function tangent as tangent(0.7853981634), which is pi/4 btw, you get that same number 0.7853981634.
#include <stdio.h>
float power(float x, int pow);
float tangent(float x);
void main(){
float ans;
ans = tangent(0.7853981634);
printf("La tangente da %f \n", ans);
}
float tangent(float x){
return x + 1/3 * (x * x * x) + 2/15 * (x * x * x * x * x);
}
NOTE: I know that there are plenty of things to improve, it's just that I don't know why this code does not work properly.

Math expression with cos() not returning expected value

I'm trying to use cosine and sine, however they do not return the value I'm expecting.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main() {
float magnitudeForce;
int force;
float theta;
float angle;
double x;
double y;
int i = 0;
while(i < 3){
printf("Please enter the value of the force"
" and the angle from the x-axis of the force:\n");
scanf("%d %f", &force, &angle);
printf("The force and the angle are: %d %.2lf.\n", force, angle);
x = force * cos(angle);
printf("%lf\n", x);
++i;
}
return 0;
}
So if the force is 8 and the angle 60 then the return should be 4, but it is returning -7.62.
The C cos function requires its argument to be in radians rather than degrees.
While the cosine of sixty degrees is 0.5, the cosine of 60 radians is about -0.95, which is why you're seeing -7.62 when you multiply it by eight.
You can fix this by doing something like:
x = force * cos(angle * M_PI / 180.0);
Keep in mind that M_PI is a POSIX thing rather than an ISO thing so it may not necessarily be in your C implementation. If it's not, you can just define it yourself with something like:
const double M_PI = 3.14159265358979323846264338327950288;

C Program to Calculate Hypotenuse

I'm fairly new to coding and am currently learning C. In class I was given an assignment to write a program that calculates the hypotenuse of the triangle by using our own functions. However, there seems to be something wrong with the code that I have written.
#include <stdio.h>
#include <math.h>
double hypotenuse(double x, double y, double z);
int main(void) {
double side1, side2, side3, counter;
side3 = 1;
for (counter = 0; counter <= 2; counter++) {
printf("Enter values for two sides: ");
scanf_s("%d %d", &side1, &side2);
printf("%.2f\n", hypotenuse(side1, side2, side3));
}
return 0;
}
double hypotenuse(double x, double y, double z) {
x *= x;
y *= y;
z = sqrt(x + y);
return z;
}
My instructor said that we're allowed to use the square root function sqrt of the math library. The main errors that I'm facing are:
1) side3 is not defined (This is why I just arbitrarily set it to 1, but is there some other way to prevent this error from happening?)
2) If I, for example, inputted 3 and 4 as side1 and side2, then side3 should be 5. However, the printed result is an absurdly long number.
Thank you for the help! Any words of advice are appreciated.
You don't need side3 variable - it is not used in calculation. And you function hypotenuse returns the result, so you can directly output the result of sqrt.
I use Ubuntu Linux and write it this way. Please look if you like it.
#include <stdio.h>
#include <math.h>
double hypotenuse(double x, double y) {
double z = sqrt(x * x + y * y);
return z;
}
int main(void) {
double b1, b2, counter;
for (counter = 0; counter <= 2; counter++) {
printf("Enter values for two sides: ");
scanf("%lf %lf", &b1, &b2);
printf("%.2f\n", hypotenuse(b1, b2));
}
return 0;
}
Test
$ ./a.out
Enter values for two sides: 1 1.73
2.00
OP's code has some problems:
Key problem: Code should have generated a compiler warning as scanf() is directed to treat &side1 as an int *. Turn on all compiler warnings to save you time. Code used "%d" rather than the matching "%lf" to read a double. Also the return value should be checked to validate input.
double side1, side2, side3, counter;
...
// scanf_s("%d %d", &side1, &side2);
if (scanf_s("%lf %lf", &side1, &side2) != 2) puts("Input error");
size3 is not needed. Call hypotenuse() with 2 arguments. #ghostprgmr
// printf("%.2f\n", hypotenuse(side1, side2, side3));
printf("%.2f\n", hypotenuse(side1, side2));
// double hypotenuse(double x, double y, double z) {
double hypotenuse(double x, double y) {
double z = ...
Minor: Code used "%.2f" to print the value of the hypotenuse. This may be OK with select input values to OP's code, but is a poor choice, in general. If input values are vary small like 0.001 and 0.002, the output will print rounded value of 0.00. With very large values, the result will show many non-important digits as OP found with 130899030500194208680850288727868915862901750748094271410143‌​232.00.
For development and debugging, consider using "%e" ,"%g" or "%a" to see a relevant double.
Note that x * x + y * y is prone to over/under flow, even when mathematically sqrt(x * x + y * y) is in the double range. That is one advantage of the standard function hypot(x,y) as it usually handles those edge cases well.
As a reference for anyone viewing this question:
You don't need to write your own function. Standard C provides functions to calculate the hypotnuse:
7.12.7.3 The hypot functions
Synopsis
#include <math.h>
double hypot(double x, double y);
float hypotf(float x, float y);
long double hypotl(long double x, long double y);
Note that you likely need to link with -lm, though that's not listed explicitly in the function documentation in the C standard nor the latest POSIX documentation. It might be documented elsewhere in the standards.
(Link to C11 [draft] standard - likely to be much longer-lived.)
Use correct format specifiers!
Format Specifier for double is not %d! Rest is fine.
#include <stdio.h>
#include <math.h>
double hypotenuse(double x, double y, double z);
int main(void) {
double side1, side2, side3, counter;
side3 = 1;
for (counter = 0; counter <= 2; counter++) {
printf("Enter values for two sides: ");
scanf("%lf %lf", &side1, &side2);
printf("%.2f\n", hypotenuse(side1, side2, side3));
}
return 0;
}
double hypotenuse(double x, double y, double z) {
x *= x;
y *= y;
z = sqrt(x + y);
return z;
}
Also you could modify it to this:
#include <stdio.h>
#include <math.h>
double hypotenuse(double x, double y);
int main(void) {
double side1, side2, counter;
for (counter = 0; counter <= 2; counter++) {
printf("Enter values for two sides: ");
scanf("%lf %lf", &side1, &side2);
printf("%.2f\n", hypotenuse(side1, side2));
}
return 0;
}
double hypotenuse(double x, double y) {
x *= x;
y *= y;
return sqrt(x + y);
}

How to modify this function to use structs as arguments rather than doubles

/* the struct */
typedef struct atom {
double x;
double y;
double z;
char line[200];
int is_connected;
struct atom *next;
} p_atom;
/* the existing function */
double
calcdist (double px, double py, double pz, double lx, double ly, double lz )
{
double x, y, z, sqr_sum;
x = px - lx;
y = py - ly;
z = pz - lz;
sqr_sum = pow (x, 2) + pow (y, 2) + pow (z, 2);
return sqrt (sqr_sum);
}
The above program is written to calculate distance between 2 points
in 3D. If I want to write a new function that accepts x,y,z
coordinates via my struct and calculates distance (same as above), is it
possible...if so how?
How do I execute a c program giving multiple input files on the command line.
Perhaps the first thing to do is to read a C book, especially on how a function works.. I'll give you some hints anyway.
If i want to write a subroutine that accepts x,y,z coordinates and calculates distance (same as above), is it possible...if so how?
It is possible, and actually the good way to do it. You can pass as many parameters to function as you want. In this case, however, it's probably better to pass pointer to struct. That way is usually more convenient and more efficient than passing several parameters.
double calcdist( p_atom *point1, p_atom *point2 )
Inside that function, you can do the calculation with point1->x, point1->y, etc. as you currently do with your px, py, etc.
How to execute a c program by giving multiple input files in command line
You can cat multiple input files and then pipe them to your program. Something like:
cat file1 file2 | ./a.out
the elegant:
typedef struct {
double x;
double y;
double z;
}COORD_3D;
typedef struct atom {
COORD_3D coord;
char line[200];
int is_connected;
struct atom *next;
} p_atom;
double calc3Ddist (COORD_3D *coord1, COORD_3D *coord2)
{
double x, y, z, sqr_sum;
x = coord1->x - coord2->x;
y = coord1->y - coord2->y;
z = coord1->z - coord2->z;
sqr_sum = pow (x, 2) + pow (y, 2) + pow (z, 2);
return sqrt (sqr_sum);
}
int HowToDo(){
p_atom a, b;
int dist;
dist=calcdist( &a.coord, &b.coord);
}
the simpler:
double
calcdist (p_atom *patom, p_atom *latom )
{
double x, y, z, sqr_sum;
x = patom->x - latom->x;
y = patom->y - latom->y;
z = patom->z - latom->z;
sqr_sum = pow (x, 2) + pow (y, 2) + pow (z, 2);
return sqrt (sqr_sum);
}

Model using Euler method and pointer arithmetic not functioning

I'm new to C, and quite unfamiliar with writing any program larger than a few lines.
I'm trying to write a model for an object in freefall acted upon by gravity and drag. It uses Eulers method to solve two first order differential equations, one for position and one for velocity.
So we have: F = m dv/dt = -mg - k|v|v and dy/dt = v
These are solved by: Vn+1 = Vn - (delta t*(g+(k/m)|Vn|Vn)) and Yn+1 = Yn + (delta t * Vn)
(In this Vn+1 is the n+1th term etc.)
In my program i've tried to have two functions, for position and velocity, which work by passing pointers with Y and V values between them and the main function, and it should then loop until Y=0 and print off the values at each step.
When I run it it comes up with something like this: http://imgur.com/DNHIhHI
Could anyone tell me either what is wrong with this, or if I need to use a different approach completely?
Many Thanks, Code below
#include <stdio.h>
void Velocity(double *ptr, double m, double k, double t);
void Position(double *pst, double *ptr, double t );
int main()
{
double k = 18833.5608;
double t = 0;
double m;
double speed = 0;
double *ptr = &speed;
double y = 1000;
double *pst = &y;
printf("Enter mass of object: \n");
scanf("%f" , &m);
do
{
Velocity( ptr, m, k, t );
printf("Velocity at time %f is: %f\n" , t, speed);
Position( pst, ptr, t);
printf("Position at time %f is: %f\n" , t , y);
t++;
}
while((y>0));
return 0;
}
void Velocity(double *velo, double m, double k, double t)
{
double g = 9.80665;
*velo = *velo - (t*(g+((k/m)*fabs(*velo)**(velo))));
}
void Position(double *Y , double *velo, double t )
{
*Y = *Y+(t*(*velo));
}
When writing programs that do calculations -- in any language, not just C -- try to make the code that does the computation take arguments and return results but not mutate variables. That is, do not write:
void do_calculation( double * result, double x, double y)
{
*result = x + y;
}
...
double r;
do_calculation(&r, 123, 456);
instead write
double do_calculation(double x, double y)
{
return x + y;
}
...
double r = do_calculation(123, 456);
Make sense?
If you want to modify an existing value, again, don't pass it in as a variable to be mutated. Instead of
void do_calculation(double * accumulator, double x, double y)
{
*accumulator = *accumulator + x + y;
}
...
double r = 10;
do_calculation(&r, 123, 456);
instead say
double do_calculation(double original, double x, double y)
{
return original + x + y;
}
...
double r = 10;
r = do_calculation(r, 123, 456);
Now, once you've got your program architected more sensibly, you need to learn how to debug small programs. Some good advice on that subject can be found here:
http://ericlippert.com/2014/03/05/how-to-debug-small-programs/
A misconcept. I believe you're trying to solve the equations by using small increments of time. Nothing wrong with that, just make the time increment as small as possible, and correct the formulas:
#include <stdio.h>
#include <math.h>
void Velocity(double *velocity, double m, double k, double t)
{
double g = 9.80665;
double velo = *(velocity);
velo = velo - (t*(g+((k/m)*abs(velo)*(velo))));
*(velocity)=velo;
}
void Position(double *position , double *velocity, double t )
{
double Y = *(position);
double velo = *(velocity);
Y = Y+(t*(velo));
*(position)=Y;
}
int main()
{
double k = 18833.5608;
double t = 0;
double dt = 0.001; //making a small increment of time
double m=100;
double speed = 0;
double y = 1000;
//printf("Enter mass of object: \n");
//scanf("%f" , &m);
do
{
Velocity( &speed, m, k, dt );
printf("Velocity at time %f is: %f\n" , t, speed);
Position( &y, &speed, dt);
printf("Position at time %f is: %f\n" , t , y);
t+=dt; //increment time by delta t
}
while((y>0));
return 0;
}

Resources