#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.
Related
So I was casually doing my usual theory proving code (testing things with code) and those code differences really got me thinking
#include <stdio.h>
int mutate(int a){
a+=1;
printf("%d\n", a);
}
void main(){
int b = 1;
mutate(b);
printf("%d", b);
}
and
#include <stdio.h>
int mutate(int *a){
*a+=1;
printf("%d\n", *a);
}
void main(){
int b = 1;
mutate(&b);
printf("%d", b);
}
Why in the first code there's a change without pointers in the first place.? Why there is a temporary change? The code with pointers I already understand though. Could someone explain though?
You use two different ways to pass parameters.
The first implementation of the mutate function uses call by value where a copy of the input parameter is created on the stack which is locally modified as you see in your print result. The value of the original input variable remains unmodified.
The second uses call by reference where a reference to the input variable is given and hence the input variable's value gets modified.
For a nice explanation see https://en.wikipedia.org/wiki/Evaluation_strategy, it also contains the following example which is extremely close to what you are doing:
void modify(int p, int* q, int* r) {
p = 27; // passed by value: only the local parameter is modified
*q = 27; // passed by value or reference, check call site to determine which
*r = 27; // passed by value or reference, check call site to determine which
}
int main() {
int a = 1;
int b = 1;
int x = 1;
int* c = &x;
modify(a, &b, c); // a is passed by value, b is passed by reference by creating a pointer (call by value),
// c is a pointer passed by value
// b and x are changed
return 0;
}
Now your example with output:
#include <stdio.h>
void mutate1(int a) {
a+=1;
printf("value of a inside mutate1: %d\n", a);
}
void mutate2(int *a){
*a+=1;
printf("value of *a inside mutate2: %d\n", *a);
}
int main(){
int b = 1;
printf("value of b before mutate1: %d\n", b);
mutate1(b);
printf("value of b after mutate1: %d\n\n", b);
b = 1;
printf("value of b before mutate2: %d\n", b);
mutate2(&b);
printf("value of b after mutate2: %d\n", b);
return 0;
}
$ gcc -Wall mutate.c
$ ./a.out
value of b before mutate1: 1
value of a inside mutate1: 2
value of b after mutate1: 1
value of b before mutate2: 1
value of *a inside mutate2: 2
value of b after mutate2: 2
$
As can be observed b does not get modified when using call by value but it does when using call by reference.
I am wondering that unlike the double pointers (int**) , can we have double function pointer?
I mean the function pointer pointing to the address of the another function pointer ?
I want something like
int add(int A , int B){
return A+B;
}
int main(void){
int (*funcpointerToAdd)(int,int) = add; // single function pointer pointing to the function add
printf("%d \n",funcpointerToAdd(2,3));
int (**doubleFuncPointerToAdd)(int,int) = &funcpointerToAdd;
printf("%d \n",doubleFuncPointerToAdd(2,3));
return 0;
}
but this gives me an error called object ‘doubleFuncPointerToAdd’ is not a function or function pointer
is this possible to do this thing anyway ?
You can use pointers to pointers to functions, but you have to deference them once first:
int add(int A , int B){
return A+B;
}
int main(void){
int (*funcpointerToAdd)(int,int) = &add;
//By the way, it is a POINTER to a function, so you need to add the ampersand
//to get its location in memory. In c++ it is implied for functions, but
//you should still use it.
printf("%d \n",funcpointerToAdd(2,3));
int (**doubleFuncPointerToAdd)(int,int) = &funcpointerToAdd;
printf("%d \n",(*doubleFuncPointerToAdd)(2,3));
//You need to dereference the double pointer,
//to turn it into a normal pointer, which you can then call
return 0;
}
This is also true for other types:
struct whatever {
int a;
};
int main() {
whatever s;
s.a = 15;
printf("%d\n",s.a);
whatever* p1 = &s;
printf("%d\n",p1->a); //OK
//x->y is just a shortcut for (*x).y
whatever** p2 = &p1;
printf("%d\n",p2->a); //ERROR, trying to get value (*p2).a,
//which is a double pointer, so it's equivalent to p1.a
printf("%d\n",(*p2)->a); //OK
}
I have a function which returns an integer pointer type:
int* f(int a, int b){
int *result;
result = &a;
*result += b;
return result;
}
and when I call this on main:
int main(){
int a = 5;
int b = 2;
int *result = f(a,b);
printf("The result is: %d \n", *result);
return 0;
}
It gives me the correct output(in this case 7). I was under the impression that by assigning the address of the parameter a to result I would get a segmentation fault when I ran this function.
My assumption is that C treats function parameters as local in scope to the function definition. But, I see that this is not the case so why is this specific program working ?
I'm using Code::Blocks 16.01 with gcc compiler.
Just because it works on your machine doesn't mean it isn't undefined behaviour. This works by fluke, but it's invalid.
It may produce the correct result because that stack is not overwitten or otherwise mangled by the time you do something later on.
For example, if you make another function call:
#include <stdio.h>
#include <stdlib.h>
int noop(int x, int y) {
return x + y;
}
int* f(int a, int b){
int *result;
result = &a;
*result += b;
return result;
}
int main(){
int a = 5;
int b = 2;
// Do something with undefined behaviour
int *result = f(a,b);
// Do something else which uses the stack and/or the same memory
int x = 10;
int y = 11;
int z = noop(x, y);
printf("The result is: %d \n", *result);
return 0;
}
Now the output gets stomped with the definition of x which coincidentally takes the same piece of memory so the output is 10. As this is undefined behaviour, though, anything could happen, including a crash.
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?
This is the code here:
#include<stdio.h>
void assign (int *a1, int *a2) {
a1 = a2;
}
int main() {
int *a; int b; int *c; int d;
b = d = 5;
a = &b;
printf("%d", *a);
assign(c, &d);
printf("\n%d", *c);
return 0;
}
It's fine when I assign pointers manually in the main() function, but the segmentation fault appears when I assign it in the function. Why is this so?
The function assign has no effect. All it's doing is performing a local assignment which has no effect on the caller. As a result, c is undefined in main and you get a segmentation fault.
In order for assign to do what you intend, you have to pass it the address of c, then do a pointer assignment in assign.
Try the following:
#include <stdio.h>
void assign (int **a1, int *a2) {
*a1 = a2;
}
int main() {
int *a; int b; int *c; int d;
b = d = 5;
a = &b;
printf("%d\n", *a);
assign(&c, &d);
printf("%d\n", *c);
return 0;
}
The output is:
5
5
I also moved the newlines to the end of the format strings, which is the normal place to put them.
c is passed by value into the function assign. This means that modifying a1 from the function will not affect c.
To get the expected results, pass c by reference, i.e, pass the address of c:
assign(&c, &d);
and make slight modifications to the function:
void assign (int **a1, int *a2) {
*a1 = a2;
}
and you are good to go! :-)
Arguments are passed by value in C, so modyfying a1 in assign() won't affect c in main().
c remains uninitialized and it has automatic storage duration, so its value is indeterminate.
Then, you used this inderminate value in printf("\n%d", *c);.
This invokes undefined behavor and the program just happened to cause segmentation fault.