Pointer and printf() - c

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?

Related

How do I call a print function in other functions in 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.

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);
}

what is the error in the below c program-0001?

#include<stdio.h>
int areaOfRectangle(int,int);
int perimeter(int,int);
int main()
{
int l,b;
scanf(" %d %d",&l,&b);
printf("%d %d %d %d",l,b,areaOfRectangle(l,b),perimeter(l,b));
return 0;
}
int areaOfRectangle(int a,int b)
{
int area;
area=a*b;
return area;
}
int perimeter(int c,int d)
{
int meter;
meter=2(c+d);
return meter;
}
why this error:called object is not a function or function pointer at line: meter=2(c+d)?
Also, can I use the same variable a,b to pass in perimeter function?
Your code meter=2(c+d);should be changes as meter=2*(c+d);
You can use the same variable a,b to pass in perimeter function, A parameter is just a local variable.
In this statement:
int perimeter(int c,int d)
{
int meter;
meter=2(c+d);
return meter;
}
You'll obviously get a syntax error since the compiler won't detect 2(c+d) as you're trying to implicitly multiply 2 with (c + d). Rather, if you explicitly define 2 * (c + d) then it'll no longer show you any error.
One side tip, you don't need to use any local variables inside a function if you just want to return a simple return statement, rather you may use:
return 2 * (c + d);
The declaration is redundant thence.

1.#QNANO in output in C language?

#include <stdio.h>
float diff_abs(float,float);
int main() {
float x;
float y;
scanf("%f", &x);
scanf("%f", &y);
printf("%f\n", diff_abs(x,y));
return 0;
}
float diff_abs(float a, float b) {
float *pa = &a;
float *pb = &b;
float tmp = a;
a = a-b;
b = *pb-tmp;
printf("%.2f\n", a);
printf("%.2f\n", b);
}
Hello guys, i'm doing a C program which should keep in a variable a-b, and in b variable b-a.
It's all ok, but if i run my code at the end of output, compiler shows me this message:
3.14
-2.71
5.85
-5.85
1.#QNAN0
what does means 1.#QNANO?
In this piece of code printf("%f\n", diff_abs(x,y)) you are telling the compiler to print a float type of variable which should be the return value of the function diff_abs. But in your function diff_abs you are not returning any value.
So %f which is waiting for a float, will not get any value and it will print #QNAN0 which means Not A Number. So you can change your code as follows:
In your main:
//printf("%f\n", diff_abs(x,y)); //comment this line
diff_abs(x,y); //just call the function
In the function:
void diff_abs(float a, float b) { //change the return value to void
//float *pa = &a; //you are not using this variable
float *pb = &b;
float tmp = a;
a = a-b;
b = *pb-tmp;
printf("%.2f\n", a);
printf("%.2f\n", b);
return;
}
The problem is, you don't return a value from the called function diff_abs() and you're trying to use the return-ed value. It invokes undefined behavior.
Quoting C11, chapter ยง6.9.1, Function definitions
If the } that terminates a function is reached, and the value of the function call is used by
the caller, the behavior is undefined.
Based on your comments, it appears, you are not needed to have any return value from the function. In that case,
Change the function signature to return type void
Just call the function, get rid of the last printf() call in main() altogether. The printf()s inside the called function will get executed and the prints will appear on their own, you don't need to pass the function as an argument to another printf() for that.

Function not returning value at all - not a void

I have this function that is not returning a function value. I've added some random testers to try and debug but no luck. Thanks!
#include <stdio.h>
#include <math.h>
#include <time.h>
#define N 100
float error(int a, int b);
int main(){
printf("START\n");
srand(time(NULL));
int a, b, j, m;
float plot[N+1];
printf("Lower bound for x: ");
scanf("%d", &a);
printf("Upper bound for x: ");
scanf("%d", &b);
printf("okay\n");
for(j = 0; j < N; j++)
plot[j] = 0;
printf("okay1\n");
m = error(a,b);
printf("%f\n",m);
return 0;
}
float error(int a, int b){
float product = a*b;
printf("%f\n",product);
return product;
}
so the m = error(a,b) always gives 0 no matter what!
Please help. I apologise for not cleaning this up...
This is because you declared m as int. Declare it as float and cast a*b to float because a and b are also ints. Another way is change the return type of your function to int;
int error(int a, int b){
int product = a*b;
printf("%f\n",product);
return product;
}
and print m and product with %d specifier. Also do not forgot to change you function prototype in latter case.
int m;
m = error(a,b);
printf("%f\n",m);
You are trying to display m as float while it is int.
This shoud be:
m = error(a,b);
printf("%d\n",m);
My advice: stick to ints for now.
I think we have misunderstanding of how types work in C. It's not like in PHP that a variable can hold an int, then a float and some time later some string. In C variables are like steel buckets. They can change content, but never their shape. If you assign a float to an int, the floating point value will be converted into a integer value. Once you declare m as int, it will remain int to the end of it's life, capable of holding only int values.

Resources