#include <stdlib.h>
#include <stdio.h>
void roll_three(int* one, int* two, int* three)
{
int x,y,z;
x = rand()%6+1;
y = rand()%6+1;
z = rand()%6+1;
one = &x;
two = &y;
three = &z;
printf("%d %d %d\n", *one,*two,*three);
}
int main()
{
int seed;
printf("Enter Seed: ");
scanf("%d", &seed);
srand(seed);
int x,y,z;
roll_three(&x,&y,&z);
printf("pai: %d %d %d\n", x,y,z);
if((x==y)&&(y==z))
printf("%d %d %d Triple!\n",x,y,z);
else if((x==y)||(y==z)||(x==z))
printf("%d %d %d Double!\n",x,y,z);
else
printf("%d %d %d\n",x,y,z);
return 0;
}
This the terminal, I type 123 for the seed. However, the printf in roll_three and the printf in main give me different output? Why *one and x are different?
The problem is here:
one = &x;
two = &y;
three = &z;
Since one, two, and three are pointers you've changed what they point to, but now they no longer point to main's x, y and z. It is similar to this...
void foo(int input) {
input = 6;
}
int num = 10;
foo(num);
printf("%d\n", num); // it will be 10, not 6.
Instead you want to change the value stored in the memory they point to. So dereference them and assign them the new value.
*one = x;
*two = y;
*three = z;
You can even eliminate the intermediate values.
*one = rand()%6+1;
*two = rand()%6+1;
*three = rand()%6+1;
In roll_three, you need to change the following:
one = &x;
two = &y;
three = &z;
To:
*one = x;
*two = y;
*three = z;
The first version just points to them to the local variables. The corrected version updates the values in the caller.
Why *one and x are different?
one = &x;
should be
*one = x;
The way you did it ( one = &x ) is wrong, because you assign pointer one to the address of local variable x which no longer exists after function roll_three.
You function should look like this:
void roll_three(int* one, int* two, int* three)
{
int x,y,z;
x = rand()%6+1;
y = rand()%6+1;
z = rand()%6+1;
*one = x;
*two = y;
*three = z;
printf("%d %d %d\n", *one,*two,*three);
}
In your roll_three function,
void roll_three(int* one, int* two, int* three)
{
int x,y,z;
x = rand()%6+1; // local variable x will have a value
y = rand()%6+1;
z = rand()%6+1;
one = &x; // variable one is assigned with local variable x's address
// so *one equals to x inside the function.
// However, variable one supposed is the variable x's address in
// the main function, but now it is changed to the local x's address,
// the main function variable x's value can't be updated as expected.
// *one = x is the way you want to go.
two = &y;
three = &z;
printf("%d %d %d\n", *one,*two,*three);
}
Related
Suppose I have a pointer
int *x;
Then I need to let the pointer point to an int of value, say 42.
Should I do this:
*x = 42;
or this:
int y = 42;
x = &y;
? What is the usual practice?
After this declaration
int *x;
the pointer x either is equal to NULL (if it is declared outside any function) or has an indeterminate value. So dereferencing the pointer like
*x = 42;
invokes undefined behavior.
You can write either
int y = 42;
x = &y;
or
x = malloc( sizeof( int ) );
*x = 42;
When you do:
int *x = 42;
you assigne the pointeur x to the memory case 42, that gonna make a segmentation fault.
The right way to do what you wan't is:
int y = 42;
x = &y;
x gets the adress of y (&y)
#include <stdio.h>
int main()
{
int y=42;
int x=&y;
printf("\nY = %d is at adress X = %d \n",y,x);
}
#include<stdio.h>
// Function to swap two values but does not work
void swapDoesNotWork (int *ptrX, int *ptrY);
// Function to swap two values and works fine
void swap (int *ptrX, int *ptrY);
void swap (int *px, int *py) {
int temp;
temp = *px;
*px = *py;
*py = temp;
}
void swapDoesNotWork (int *px, int *py) {
printf("\n\n");
int temp;
temp = *px;
px = py;
py = &temp;
}
int main() {
int x = 5;
int y = 10;
swapDoesNotWork(&x, &y);
printf("++++++++++++++++++\n");
printf("pre x:%d\n", x);
printf("pre y:%d\n", y);
printf("\n");
printf("After calling swapDoesNotWork(&x, &y)...\n");
printf("post x:%d\n", x);
printf("post y:%d\n", y);
printf("++++++++++++++++++\n\n");
x = 5;
y = 10;
printf("= = = = = = = = =\n\n");
printf("pre x:%d\n", x);
printf("pre y:%d\n", y);
swap(&x, &y);
printf("\n");
printf("After calling swap(&x, &y)...\n");
printf("post x:%d\n", x);
printf("post y:%d\n", y);
printf("= = = = = = = = =\n\n");
return 0;
The output of the above program when compiled and executed is:
infi#linux% ./swap_test.o
++++++++++++++++++
pre x:5
pre y:10
After calling swapDoesNotWork(&x, &y)...
post x:5
post y:10
++++++++++++++++++
= = = = = = = = =
= = = = = = = = =
pre x:5
pre y:10
After calling swap(&x, &y)...
post x:10
post y:5
As can be seen, the swapDoesNotWork function does not seem to change the values as is the case with the swap function.
I am new to C language, coming from mostly scripting background. Can someone help me why swapDoesNotWork functon is not changing the values?
Here are all the modifications performed by swapDoesNotWork:
temp = ...
px = ...
py = ...
All of these are assignments to local variables. Local variables are destroyed when the function returns, so swapDoesNotWork has no lasting effects. It only changes variables that are about to stop existing anyway.
On the other hand, swap contains these lines:
*px = ...
*py = ...
These are assignments to locations pointed to by px and py, respectively. Even though px and py are local variables themselves, they can point to variables outside of the current function (in this case the function is called as swap(&x, &y), so they point to the x and y variables in main).
With what you are doing you just cancelled the whole point of using pointers.
What you are doing is basically the same as this:
temp = a;
a = b;
b = temp;
which means that you are acting on a copy of the original variables. So what you do although it is changing the values of the pointers (if you try a printf inside the function the results should be correct) after the function is finished the results disappear. In order for that function to work you would have to pass as an argument a double pointer. Hope I helped
I thought that calling function by value will never work, and I should always use call by reference, but trying this code...
// call by value
#include<stdio.h>
int Add(int a, int b)
{
int c = a + b ;
return c ;
}
int main()
{
int x = 2 , y = 4 ;
int z = Add(x,y);
printf("%d\n",z);
}
output will be: 6
it works fine in both ways (call by value & call by reference),
// call by reference
#include<stdio.h>
int Add(int* a, int* b)
{
int c = *a + *b ;
return c ;
}
int main()
{
int x = 2 , y = 4 ;
int z = Add(&x,&y);
printf("%d\n",z);
}
output will be: 6
not like the famous swap function example - when calling by value it doesn't swap -
// call by value
#include <stdio.h>
void swap(int a, int b)
{
int temp;
temp = b;
b = a;
a = temp;
}
int main()
{
int x = 1 , y = 2;
printf("x = %d , y = %d\n", x,y);
swap(x, y);
printf("after swapping\n");
printf("x = %d , y = %d\n", x,y);
return 0;
}
.. it only worked calling by reference
// call by reference
#include <stdio.h>
void swap(int *a, int *b)
{
int temp;
temp = *b;
*b = *a;
*a = temp;
}
int main()
{
int x = 1 , y = 2;
printf("x = %d , y = %d\n", x,y);
swap(&x, &y);
printf("after swapping\n");
printf("x = %d , y = %d\n", x,y);
return 0;
}
So How can I judge if "calling by value" going to work or not ?!
So How can I judge that call by value method is valid or not ?!
Well, it depends on what your function is about to do.
In your above example, you only need the values of (x,y) for computing, but you never plan to change their value during your function. While call-by-reference will work in this case, it is unneccessary.
In the other (indirectly given) example you obviously want to change two variable's content (that is - swap it). You can access these variables from the main-function in your Swap-function, but how can you make the change persistent? That's only possible by call-by-reference, because you have to write the changed content into a variable that survives the function.
The following will not work:
// call by value
#include<stdio.h>
void Swap(int a, int b)
{
int c = a;
a = b;
b = c;
// from here on a, b, c will be destroyed
// therefore the change cannot be seen outside the function
}
int main()
{
int x = 2 , y = 4 ;
Swap(x,y);
printf("x: %d --- y: %d\n",x,y);
}
So as a rule to keep in mind:
If you want to make a change that's supposed to survive the function's end, use call-by-reference. If you just work with some data but do not want to (or must not) change their value, use call-by-value.
Right now I'm working on a program in C that takes 3 parameters; the address of a "first" integer, address of the "second" integer and the address in which to store the maximum of the two integers. So far I have the following basic code:
void max(int* x, int* y, int* z)
{
if (x > y) {
z = x;
}
else if (y > x){
z = y;
}
}
int main()
{
int x = 6;
int y = 4;
int z;
max(&x, &y, &z);
printf("max of %d and %d = %d\n", x, y, z);
x = 12;
y = 17;
max(&x, &y, &x);
printf("x = %d, y = %d\n", x, y);
}
When executed it outputs the following:
max of 6 and 4 = 32767
x = 12, y = 17
HOWEVER! I want it to output this instead:
max of 6 and 4 = 6
x = 17, y = 17
I'm not sure where I'm going wrong in my max function. Z should not be so huge and in the second print statement x should equal y. Any help is greatly appreciated, thanks!
As you probably already know, a pointer is a variable which contains the address in memory of another variable.
To access that memory we use The Unary operator & which gives us the address of a variable.
But accessing that memory is not all what a Pointer can do, we can with that pointer modify the value of that variable where the pointer points to.
For that we need to supply * to that pointer like this *ptr.
Let's take a look at the following program:
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
int main(void){
int a = 5;
int b = 10;
printf("A = %d\nB = %d\n\n\n",a,b);
int *pa = &a;
int *pb = &b;
*pa = 50;
*pb = 100;
printf("A = %d\nB = %d\n*PA = %d\n*PB = %d\n",a,b,*pa,*pb);
return 0;
}
The output will be:
A = 5
B = 10
A = 50
B = 100
*PA = 50
*PB = 100
As you can see A and B got new values. I hope you understand that.
when you pass things by pointer, if you want to get to the values, you need to do
(*x > *y)
Which gets the value pointed at by the pointer. (x and y are pointers, so they are going to contain memory addresses of the where the values are stored)
Needs to be:
if (*x > *y) {
*z = *x;
}
else if (*y > *x){
*z = *y;
}
You are comparing pointer addresses. You should de-reference the pointers for comparisons and assignments.
void max(int* x, int* y, int* z)
{
if (*x > *y) {
*z = *x;
}
else if (*y > *x){
*z = *y;
}
}
I'm trying to do the calculation inside a function, but i'm not sure why it's not working:
int calculate(int x){
x = x + 2;
return x;
}
int main(){
int x = 0;
int i;
for(i=0;i<10;i++){
calculate(x);
}
printf("i = %d, x = %d\n", i, x);
}
I understand that x is 0 every time it passes through the function. But how do I fix it?
Supposedly i should return 10, and x should return 20.
You can actually pass the pointer of that integer you want to change, not the value itself. In that case, the new (increased) integer will be stored in the original level of scope (actually at the exact same memory spot), where it was defined, which is in this case is your main function. So your code, should look like this:
void calculate(int *x)
{
*x += 2;
}
int main(void)
{
int x = 0;
for (int i=0; i<10; i++)
{
calculate(&x);
printf("i=%d, x=%d\n", i, x);
}
return 0;
}
OUTPUT:
i=0, x=2
i=1, x=4
i=2, x=6
i=3, x=8
i=4, x=10
i=5, x=12
i=6, x=14
i=7, x=16
i=8, x=18
i=9, x=20
Variables can shadow each other. You don't have to ensure that you never, ever use i anywhere else in fear of messing with the i in your for loop, because a new scope will get a new copy of the same name (like when two different people have the same name).
To fix this, you can return the value from your calculate function. I named it x2 to clearly differentiate it from your original x:
int calculate(int x2){
x2 = x2 + 2;
return x2;
}
int main(){
int x = 0;
int i;
for(i=0;i<10;i++){
x = calculate(x);
}
printf("i = %d, x = %d\n", i, x);
}
If you want x to change, you need to pass it by reference, not by value.
void calculate(int *x){
*x = *x + 2;
}
int main(){
int x = 0;
int i;
for(i=0;i<10;i++){
calculate(&x);
}
printf("i = %d, x = %d\n", i, x);
}
You're passing x by value, so calculate only changes a local copy. When calculate returns, the result is lost. You need to return the modified value from calculate and assign it to something in main.
You're passing in x as a value (ie. it is copied). So x inside the calculate function is not the same as x outside of it. Thus, when you change its value, the change is not reflected in the x that is in main.
The following would be preferable. Note that you need to return a value from the calculate function, and then assign what it returns to some value.
int calculate(int x){
return x + 2; /* CHANGED */
}
int main(){
int x = 0;
int i;
for(i=0;i<10;i++){
x = calculate(x); /* CHANGED */
}
printf("i = %d, x = %d\n", i, x);
}
Change:
for(i=0;i<10;i++){
calculate(x);
}
to:
for(i=0;i<10;i++){
x = calculate(x);
}
Your function returns a value, thus you need to store it somewhere.
In the function you can just change one thing and iguess it will work
Int calculate(int &x)
And keep rest other things same
Basically u can use "alias"