Why is void returning a value? - c++

I can't understand one weird thing. Here is my program :
#include <iostream>
using namespace std;
void Swap(int *a , int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int a=0;
int b=0;
cout<<"Please enter integer A: ";
cin>>a;
cout<<"Please enter integer B: ";
cin>>b;
cout<<endl;
cout<<"************Before Swap************\n";
cout<<"Value of A ="<<a<<endl;
cout<<"Value of B ="<<b<<endl;
Swap (&a , &b);
cout<<endl;
cout<<"************After Swap*************\n";
cout<<"Value of A ="<<a<<endl;
cout<<"Value of B ="<<b<<endl;
return 0;
}
Now if you look at the function "Swap", I have used "void Swap". Therefore it must not return any value to main function (only "int" returns a value (at least that's what my teacher has taught me)). But if you execute it, the values are swaped in main function! How come ? Can anyone tell me how its possible ?

Swap function in your example just swaps two integers, but does NOT return anything.
In order to check what function has retuned, you have to assign it to some variable, like this
int a = swap(&a, &b);
but this piece of code has an error because swap function doesn't return anything.
Another example:
int func() {
return 18;
}
int main() {
int a = func();
cout << a;
}
Is fine, cause variable a is int and function func returns an int.

Swap may not return any values, but it can still modify them. You're passing in pointers to two variables into the function. If you change the value the pointer maps to in the Swap function, that change persists throughout the program.

Actually, the function is NOT returning the value. It is just accessing the values through the variables' addresses and swapping them from their reference. Your code is right and now I have cleared your concept without any long explanation. That's all.

This is correct.
Your Swap method does work with pointers, not real values.
In your main your are calling this method and tell it to swap the values in the variables. They are in the sme context at this point.

Your code looks very similar to this:
http://www.tutorialspoint.com/cplusplus/cpp_function_call_by_pointer.htm
What it does it uses pointers addresses. You use them as parameters and then you use them to access the information stored at that location, which is the values of a and b, and then change them.

I think you are misunderstand what your teacher said.
What he/she said might be Swap() will not return value, but change value by passing address is still valid.
like this:
int Swap();
int GetReturnValue = Swap(); // Get return value from Swap()
Let's look the second one:
void Swap();
int GetReturnValue = Swap();
Though the second one might really get value, but this value is meaningless.
Sometimes, you will get a compiler warning if you do like the second one, GCC Compiler will report warnings about casting

Swap procedure can only modify your variables because you've passed them by reference.
Remember procedures, unlike functions, cannot return a value.

Related

How can I initialize a variable but when said function is initiated the value of the variable is not reset?

I've made this example to show what I'm talking about. I want to know if there is a way to run through main() without resetting value to 0.
int main(){
int value = 0;
value++;
cout << value << endl;
main();
}
Before answering the question, your example has two big problems
Calling, or even taking the address of, main is not allowed.
Your function has infinite recursion which makes your program have undefined behavior.
A different example where value is saved between calls could look like this. It uses a static variable, initialized to 0 the first time the function is called, and is never initialized again during the program execution.
#include <iostream>
int a_function() {
static int value = 0;
++value;
if(value < 100) a_function();
return value;
}
int main(){
std::cout << a_function(); // prints 100
}
If you want to keep the variable value local to the main function, you can declare it as static int value = 0;.
As has been pointed out in various comments though, recursively calling any function without an escape mechanism like you are is a bad idea. Doing it with main is a worse idea still apparently not even possible.

How is C++ function's default parameter passed?

Say I have the following code:
#include <iostream>
using namespace std;
int defaultvalue[] = {1,2};
int fun(int * arg = defaultvalue)
{
arg[0] += 1;
return arg[0];
}
int main()
{
cout << fun() << endl;
cout << fun() << endl;
return 0;
}
and the result is:
2
3
which make sense because the pointer *arg manipulated the array defaultvalue. However, if I changed the code into:
#include <iostream>
using namespace std;
int defaultvalue[] = {1,2};
int fun(int arg[] = defaultvalue)
{
arg[0] += 1;
return arg[0];
}
int main()
{
cout << fun() << endl;
cout << fun() << endl;
return 0;
}
but the result is still:
2
3
Moreover, when I print out the defaultvalue:
cout << defaultvalue[0] <<endl;
It turn out to be 3.
My question is, in the second example, should the function parameter be passed by value, so that change of arg will have no effect on defaultvalue?
My question is, in the second example, should the function parameter be passed by value, so that change of arg will have no effect on defaultvalue?
No.
It is impossible to pass an array by value (thanks a lot, C!) so, as a "compromise" (read: design failure), int[] in a function parameter list actually means int*. So your two programs are identical. Even writing int[5] or int[24] or int[999] would actually mean int*. Ridiculous, isn't it?!
In C++ we prefer to use std::array for arrays: it's an array wrapper class, which has proper object semantics, including being copyable. You can pass those into a function by value just fine.
Indeed, std::array was primarily introduced for the very purpose of making these silly and surprising native array semantics obsolete.
When we declare a function like this
int func(int* arg);
or this
int (func(int arg[])
They're technically the same. It's a matter of expressiveness. In the first case, it's suggested by the API author that the function should receive a pointer to a single value; whereas in the second case, it suggests that it wants an array (of some unspecified length, possibly ending in nullptr, for instance).
You could've also written
int (func(int arg[3])
which would again be technically identical, only it would hint to the API user that they're supposed to pass in an int array of at least 3 elements. The compiler doesn't enforce any of these added modifiers in these cases.
If you wanted to copy the array into the function (in a non-hacked way), you would first create a copy of it in the calling code, and then pass that one onwards. Or, as a better alternative, use std::array (as suggested by #LightnessRacesinOrbit).
As others have explained, when you put
int arg[] as a function parameter, whatever is inside those brackets doesn't really matter (you could even do int arg[5234234] and it would still work] since it won't change the fact that it's still just a plain int * pointer.
If you really want to make sure a function takes an array[] , its best to pass it like
template<size_t size>
void func (const int (&in_arr)[size])
{
int modifyme_arr[100];
memcpy(modifyme_arr, in_arr, size);
//now you can work on your local copied array
}
int arr[100];
func(arr);
or if you want 100 elements exactly
void func (const int (&arr)[100])
{
}
func(arr);
These are the proper ways to pass a simple array, because it will give you the guaranty that what you are getting is an array, and not just a random int * pointer, which the function doesn't know the size of. Of course you can pass a "count" value, but what if you make a mistake and it's not the right one? then you get buffer overflow.

Changing address of variables using reference

in below code why its displaying 2,3 though we change the address. why not 3,2.
#include <iostream>
using namespace std;
void Addresschange(int *a, int *b)
{
int *t;
t = a;
a = b;
b = t;
cout << *a<<endl<< *b<<endl;//here its displaying 3,2
}
int main ()
{
int a = 2 ,b = 3;
Addresschange(&a ,&b);
cout << a<<endl<< b;//why its displaying 2,3 here
return 0;
}
So after going out of this function the addresses of the actual parameters (a and b) would be changed. Is it possible at all?
In the Addresschange function, a and b are local variables. When you change their values, that only changes their values inside the function. So your code just swaps the values of a and b inside the Addresschange function. It doesn't use any pointer operations, so even though the values happen to be pointers. that doesn't change the fact that they're passed by value and that means that changing the value won't propagate out of the function.
If you want to change something's value using a pointer, you have to pass a pointer to it and change the value the pointer points to. So if you want to change the value of an int *, you need to pass the function an int **.
Your function passes an int * (pointer to int), which lets you change the value of an int. For example, *a = 3; will make a equal to 3 instead of 2 in the caller, using the pointer that was passed by value to change the value of the thing it points to.
(You can also use references in C++. You still can't "reseat" a reference to make it refer to something else unless you use something like std::reference_wrapper.)

Returning arrays from a function in c++

I am trying to return an array from a function:
#include <iostream>
using namespace std;
int* uni(int *a,int *b)
{
int c[10];
int i=0;
while(a[i]!=-1)
{
c[i]=a[i];
i++;
}
for(;i<10;i++)
c[i]=b[i-5];
return c;
}
int main()
{
int a[10]={1,3,3,8,4,-1,-1,-1,-1,-1};
int b[5]={1,3,4,3,0};
int *c=uni(a,b);
for(int i=0;i<10;i++)
cout<<c[i]<<" ";
cout<<"\n";
return 0;
}
I pass two arrays from my main() into my uni() function. There I create a new array c[10] which I return to my main().
In my uni() function I try to merge the non-negative numbers in the two arrays a and b.
But I get something like this as my output.
1 -1078199700 134514080 -1078199656 -1216637148 134519488 134519297 134519488 8 -1078199700
Whereas when I try to print the values of c[10] in the uni() function it prints the correct values. Why does this happen??
Is this something related to the stack?? Because I have tried searching about this error of mine, and I found a few places on stackoverflow, where it says that do not allocate on stack but I couldn't understand it.
Further it would become very easy if I allocate my array globally, but if this is the case then everything shall be declared globally?? Why are we even worried about passing pointers from functions?? (I have a chapter in my book for passing pointers)
Admittedly, the std::vector or std::array approach would be the way to go.
However, just to round things out (and if this is a school project, where the teacher gives you the obligatory "you can't use STL"), the other alternative that will avoid pointer usage is to wrap the array inside a struct and return the instance of the struct.
#include <iostream>
using namespace std;
struct myArray
{
int array[10];
};
myArray uni(int *a,int *b)
{
myArray c;
int i=0;
while(a[i]!=-1)
{
c.array[i]=a[i];
i++;
}
for(;i<10;i++)
c.array[i]=b[i-5];
return c;
}
int main()
{
int a[10]={1,3,3,8,4,-1,-1,-1,-1,-1};
int b[5]={1,3,4,3,0};
myArray c = uni(a,b);
for(int i=0;i<10;i++)
cout << c.array[i] << " ";
cout << "\n";
return 0;
}
Note that the struct is returned by value, and this return value is assigned in main.
You have the value semantics of returning an instance, plus the struct will get copied, including the array that is internal within it.
Live Example
You're returning a pointer to a local object. In the uni function, the variable c is allocated on the stack. At the end of that function, all of that memory is released and in your for loop you are getting undefined results.
As suggested in the comments, std::array or std::vector will give you copy constructors that will allow you to return the object by value as you're trying to do. Otherwise you'll have to resort to something like passing your output array in as an argument.
You are returning a pointer to an array that is being deallocated at the return statement. It's a dangling pointer. It's UB.
Use an std::vector or std::array and return by value. There are compiler optimizations that will avoid inefficiencies.

C++ Defining Global Variable

Very simple question:
I was fiddling with basic C++ (being very new to programming) and I got into trouble while declaring a global variable to do some addition
#include <iostream>
int x,y;
int sum(int, int)
{
return x + y;
}
int main()
{
using namespace std;
cout << "The sum of 10 and 4 is: " << sum(10,4) << endl;
return 0;
}
Changing "int x,y;" to "int x,y = 0" has the same result: The sum equates to 0.
Could someone explain this odd behavior? Thanks!
Your function always returns the sum of global variables x and y, which are always 0. x and y are implicitly set to zero at the program startup. You never change their values, so they remain zero forever. The sum of two zeros is zero, no surprise here.
You pass 10 and 4 to your function, but the function itself completely ignores what is passed to it, i.e. it ignores its parameters (they are not even named). It always sums global x and y, which are always 0.
If you want your function to sum its arguments, you have to name the function parameters and use them
int sum(int a, int b)
{
return a + b;
}
And now you don't need any global variables at all. (main remains as is.)
Alternatively, if you so desire, you can get rid of the parameters completely and sum the global variables instead
int x,y;
int sum()
{
return x + y;
}
but in this case you will have to pass the values to sum through those global variables, not as function arguments
int main()
{
using namespace std;
x = 10;
y = 4;
cout << "The sum of 10 and 4 is: " << sum() << endl;
return 0;
}
This latter approach is here just for illustrative purposes. It is definitely not a good programming practice.
What you have in your code is a weird disconnected hybrid of these two approaches, which can't possibly work.
In order to fix the issue, the thing requires changing is the sum function.
int sum(int a, int b){
return a+b; //a,b here are referring to the inputs, while what you did was referring to the global variable..
}
Besides, try not to use global variables, usually you would end up with lots of troubles.
Another thing, I don't think your way of defining a function is correct. The inputs have to look like this instead:
int sum(int a, int b)
Unless you wanna declare the function first and provide the actual implementation later, you are not suppose to miss the name of the inputs!
when you are just globally declare the variables x,y ,they implicitly set to zero value.in your function definition,you are just giving the datantype of args, not the args names.so when you returning the sum of x,y ,it returns zero.and the value passed by the main function goes nowhere.
your program must look like this
#include<iostream>
int x,y;
int sum(x,y)
{
return x+y;
}
int main()
{
int v,a,b;
cout<<"values of a and b";
cin>>a>>b;
v=sum(a,b)
cout<<"their sum is"<<v;
}
when you explicitly define the value in second case
i.e int x,y=0;
you are just explicitly giving the value of value y to 0 while the x implicitly remains 0 and since you are not giving the args name,the ultimately result return biy the function is zero,
Seems that you only need x and y inside your add function, so make them local to the function. There is no reason to make them global. Follow the "least accessibility" idiom to prevent other parts of your program from mistakenedly modifying variables.
You might need a global variable supposed you want to define a well known parameter that every function needs to know and yet modifiable during run time. If you want it fixed, then a global constant would be more proper.
Hope that helps.