How do I call a print function in other functions in C? - c

I have to call for one printf function for X number of different functions. I am struggling to call the printf function from the returnString function in the other two functions. I am new to C and I am used to Java so I am not sure how to fix this. This is what I have tried:
char returnString(double a, double b, double c, double x, double y) {
char str[] = "time = %f, distance = %f, passengers = %f, value = %f, value = %f", a, b, c, x, y;
printf("%s", str);
return str[];
}
double findTime(double b, double c, double x, double y) {
double a;
a = 50;
printf(returnString);
return a;
}
double findDistance(double a, double c, double x, double y) {
double b;
b = 30;
return b;
}

Allocating the string buffer in main() as a local variable and passing its address to the returnString() function would work and you do not have to be bothered by freeing the memory occupied by the OutputStr[] because the storage of local variables is freed automatically when the function ends.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
char* returnString(char* OutputStr, double a, double b, double c, double x, double y) {
sprintf(OutputStr, "time = %f, distance = %f, passengers = %f, value = %f, value = %f", a, b, c, x, y);
return OutputStr;
}
double findTime(double b, double c, double x, double y) {
double a;
a = 50;
return a;
}
double findDistance(double a, double c, double x, double y) {
double b;
b = 30;
return b;
}
int main()
{
char OutputStr[1024];
printf ("%s \n %f \n %f \n", returnString(OutputStr, 1.0, 2.0, 3.0, 4.0, 5.0), findTime(6.0, 7.0, 8.0, 9.0), findDistance(10.0, 11.0, 12.0, 13.0));
return 0;
}
Of course this begs for buffer overflow if the string returned by the returnString() is longer than 1023 characters, so don't use this in a production code.
Also, allocating large variables on the stack is not a good practice, but 1024 bytes will not break anything nowadays.
In another solution it would be possible to dynamically allocate the memory for the output string ( e.g. by malloc() ) inside of the function returnString() and return the address of this memory from this function, but then you would have to remember to free this memory in main(). If you forgot then a memory leak would result, because in C there is no garbage collector to hold your hand.
Offtopic: In C++ you could use a smart pointer to do this automatically but C++ STL already has a string class that does it for you.

Related

Function Pointer with void* return and void* parameters

I wrote a function pointer that has all void* so that it can be used for any numeric value
int
float
double.
But it is working only for the int addition function
For float and double addition functions, it throws compile time error.
Why is that so ?
If you uncomment the last two printf lines, you would receive error
#include<stdio.h>
int int_add(int x, int y) {
return x + y;
}
float float_add(float x, float y) {
return x + y;
}
double double_add(double x, double y) {
return x + y;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
printf("Sum= %d\n",(int*) do_operation(int_add, 1, 2));
/*printf("Sum= %f\n",(float*) do_operation(float_add, 1.20, 2.50));*/
/*printf("Sum= %lf\n",(double*) do_operation(double_add, 1.20, 2.50));*/
}
void * is a pointer type. You're not passing pointers, you're passing values, so that's not going to compile. It accidentally "works" for int because pointers themselves are represented as integers by most C compilers.
If you pass pointers to int, float, and double instead of the int, float, and double themselves, you will avoid that compiler error. You'd also need to change int_add and friends to take pointers, and you'd have to make sure you dereferenced the pointers before using them. You'll also have to return pointers, which means you'll have to malloc some memory on the heap, because the stack memory assigned to your local variables will be invalid once your function exits. You'll then have to free it all later... in the end, this is going to result in something considerably more complicated than the problem it appears you are trying to solve.
I have to ask why you are trying to do this? C is really not the best language for this type of pattern. I'd suggest just calling the int_add, float_add, etc. functions directly instead of trying to abstract them in this way.
So as per #charles-srstka suggestion I rewrote the code and then it worked as I wanted
#include<stdio.h>
#include<stdlib.h>
int* int_add(int *x, int *y) {
int *c = (int *)malloc(sizeof(int));
*c = *(int*)x + *(int*)y;
return c;
}
float* float_add(float *x, float *y) {
float *c = (float*)malloc(sizeof(float));
*c = *(float*)x + *(float*)y;
return c;
}
void* do_operation(void* (*op)(void*, void*), void* x, void* y) {
return op(x, y);
}
void main(void) {
int a = 1;
int b = 2;
int *c;
c = do_operation(int_add, &a, &b);
printf("%d\n",*c);
free(c);
float x = 1.1;
float y = 2.2;
float *z;
z = do_operation(float_add, &x, &y);
printf("%f\n",*z);
free(z);
}

Pointer and printf()

I have the followin code of C :
float *dv(int a, int b);
int main() {
int x ,y;
scanf("%d%d",&x,&y);
float *pt;
pt = dv(x,y);
printf("The div is %f", pt);
return 0;
}
float *dv(int a, int b){
float d;
d = (float) a / b;
return &d;
}
and I have some questions about it! If I skip the pointer declaration/initialization
pt = dv(x,y);
and I write into
printf("The div is %f", *dv(x,y));
it plays normally! But WHY? Where is my mistake??
In your case, float d defines a local variable with automatic storage, so the lifetime ends with the return of the function.
You need a variable which stays alive throughout the usage, try changing the variable definition to make it static storage (which has a lifetime throughout the program), like
static float d;
Then, the returned pointer will be valid in the caller also.
That said, you have a type mismatch
printf("The div is %f", pt);
should be
printf("The div is %f", *pt);
as you're trying to print a float, not a float *.
You have undefined behavior in both the cases.
pt = dv(x,y);
or
printf("The div is %f", *dv(x,y));
As you are returning address of local variable which will be vanished when control reaches end of function.
Don't make it complicated when it can be simple:
float dv(int a, int b);
int main() {
int x ,y;
scanf("%d%d",&x,&y);
float pt;
pt = dv(x,y);
printf("The div is %f", pt);
return 0;
}
float dv(int a, int b){
float d;
d = (float) a / b;
return d;
}
You don't need pointers here at all.
Also read this: How to access a local variable from a different function using pointers?

How to create an iterative structure?

I have created some code that has multiple functions, and when an X value is entered it outputs a line that has computed the number for the given X value and h value that has been declared. However, in the terminal it only outputs one line of each value, and I need to implement some type of iterative structure that varies h from 10^-1 to 10^-8. Here is the code:
#include <stdio.h>
#include <math.h>
int main()
{
double u(double x)
{
return(pow(x,3.0));
}
double dudx(double x)
{
return(3.0 * pow(x,2.0));
}
double fdiff(double x, double h)
{
return((u(x+h) - u(x))/h);
}
double bdiff(double x, double h)
{
return((u(x) - u(x-h))/h);
}
double cdiff(double x, double h)
{
return((u(x+h)-u(x-h))/(2*h));
}
double fderr(double x, double h)
{
return(fabs(fdiff(x,h)-dudx(x)));
}
double bderr(double x, double h)
{
return(fabs(bdiff(x,h)-dudx(x)));
}
double cderr(double x, double h)
{
return(fabs(cdiff(x,h)-dudx(x)));
}
double x;
double h=1.0 * pow(10,-1.0);
printf("Enter an Integer ");
scanf("%lf",&x);
printf("u(x): %lf du/dx: %lf fd: %lf bd: %lf cd: %lf fderr: %lf bderr: %lf cderr: %lf\n", u(x), dudx(x), fdiff(x,h), bdiff(x,h), cdiff(x,h), fderr(x,h), bderr(x,h), cderr(x,h));
}
I'm pretty sure I have to use some type of for loop around this area:
double h=1.0 * pow(10,-1.0);
But, I do not know how to implement it! So to reiterate, how do I create an iterative structure that starts with an h value of 10^-1 and ends with 10^-8?
Thank you in advance!

numerical integration using a pointer to a function always return 0

I am trying to use the function that I was given by my professor to calculate the integral of a polynomial function (polynomial such as: ax^2+bx+c). the function is:
double numbericalIntegration(double a ,double b ,double(*func)(double)){
double delta = (b - a)/32;
double sum=0, x;
for(x= a+0.5*delta; x<b ; x+=delta)
{
sum+=(*func)(x);
}
return sum*delta;
}
I changed a lot in order to integrate a polynomial function. but I was get the answer 0. why is that? and I'd appreciate if anybody tried to correct my work. my code is:
double integralPoly(double x, double a, double b, double c){
return (a*pow(x,3))/3 +(b*pow(x,2))/2 + (c*x);
}
double numbericalIntegration(double a ,double b ,double(*func)(double,double,double,double), double firstNum, double secondNum, double thirdNum){
double delta = (b - a)/32;
double sum=0, x;
for(x= a+0.5*delta; x<b ; x+=delta)
{
sum+=(*func)(x, firstNum, secondNum, thirdNum);
}
return sum*delta;
}
int main()
{
double (*func)(double,double,double,double);
func = integralPoly;
double sum = numbericalIntegration(2,4,func,1,1,4);
printf("sum = %d",sum);
return 0;
}
You need to change two things. First your polynomial function doesn't make any sense. You said it needs to be in the form of ax^2+bx+c but in your code polynomial is (ax^3)/3+(bx^2)/2+c*x. Your function should be:
double integralPoly(double x, double a, double b, double c){
return (a*pow(x,2)) +(b*x) + c;
}
Also you need to change your printf. %d is integer type specifier and you need double, so you need to use %f for example:
printf("sum = %f",sum);
Now the output of your program is:
sum = 32.666016
which is correct for your parameters.

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