Difference between passing an arguement - c++

Hi All I have written two codes
1.
#include<iostream>
using namespace std;
void swap(int *x, int *y)
{
int t;
t = *x;
*x = *y;
*y = t;
}
int main()
{
int a = 10, b = 20;
cout << "value of a before swap " << a << endl;
cout << "value of b before swap " << b << endl;
swap(&a, &b);
cout << "value of a after swap " << a << endl;
cout << "value of b after swap " << b << endl;
cin.get();
}
2.
#include<iostream>
using namespace std;
void swap(int *x, int *y)
{
int t;
t = *x;
*x = *y;
*y = t;
}
int main()
{
int a = 10, b = 20;
cout << "value of a before swap " << a << endl;
cout << "value of b before swap " << b << endl;
swap(a, b);
cout << "value of a after swap " << a << endl;
cout << "value of b after swap " << b << endl;
cin.get();
}
In both cases I am getting same output as
value of a before swap 10
value of b before swap 20
value of a after swap 20
value of b after swap 10
My First question is
Does swap(&a,&b) and swap(a,b) makes no difference to swap function??
But when i give same arguments to given below swap function
void swap(int &x, int &y)
{
int t;
t = x;
x = y;
y = t;
}
swap(a,b) gives no issue and work fine but when i pass value as swap(&a,&b) code gives Error
error C2665: 'swap': none of the 3 overloads could convert all the argument types
Why??

The problem is this evil line:
using namespace std;
In your second example, you're actually calling ::std::swap. Since your version of swap takes pointers, you must use the & operator.
See Why is “using namespace std;” considered bad practice?

In the first program there is called your own swap function for pointers.
In the second program there is called the standard function std::swap for objects of the type int due to unqualified name-lookup and presence of the using directive.
In the third program (when you supplied a and b) there is called your own function swap that accepts objects of the type int by reference. The compiler prefers to use a non-template function if both template and non-template functions are suitable.
But your swap function in the fourth program is not designed to swap pointers. So the compiler tries to select a standard swap function std::swap. But it is not designed to swap temporary (rvalues) objects. So the compiler issues an error.
You could call the standard swap function if you introduced intermediate variables that will contain pointers to variables a and b.
Here is a demonstrative program.
#include<iostream>
using namespace std;
void swap(int &x, int &y)
{
int t;
t = x;
x = y;
y = t;
}
int main()
{
int a = 10, b = 20;
int *pa = &a;
int *pb = &b;
cout << "value of *pa before swap " << *pa << endl;
cout << "value of *pb before swap " << *pb << endl;
swap( pa, pb);
cout << "value of *pa after swap " << *pa << endl;
cout << "value of (pb after swap " << *pb << endl;
cin.get();
}
Its output is
value of *pa before swap 10
value of *pb before swap 20
value of *pa after swap 20
value of (pb after swap 10
In this program your own function swap is not called because its parameters are references to objects of the type int but you are calling swap passing objects (pointers) of the type int *.
So the standard function std::swap specialized for objects of the type int * is called.
It swaps the pointers themselves not the objects pointed to by the pointers..

There is definitly a difference between 1 and 2
You are taking the address of actually reserved memory devoted to ( holding ) your variables a and that is OK, you can effectively swap their content.
You are considering the value of a and b to be a valid address but what I can assure you is that no OS gives you acces of those paricular zones in normal use so the address is wrong and the programs ends with a SEGFAULT and that is NOK.

Related

Difference in the usage of function prototype with / without pointers

I'm following simple C++ tutorial.
#include <iostream>
using namespace std;
int main()
{
int a = 1, b = 2;
cout << "Before swapping " << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(a,b);
cout << endl;
cout << "After swapping " << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int &n1, int &n2)
{
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
The above code works fine (both g++ and icc), but if I were to use pointers in the functions the code fails if I do not include the prototype at the head of the program.
#include <iostream>
using namespace std;
void swap(int*, int*); // The code fails if I comment this line.
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << endl;
cout << "After swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
As far as I know, C++ compiling process is top-bottom, so the 2nd code seems more reasonable in which the information of the function is provided before int main() is encountered. My question is, why the 1st code works fine even without the knowledge of function before int main()?
The issue with the first program is you're not actually calling your own swap function. At the top of the file, you have:
using namespace std;
which brings std::swap into scope and that's the function that you're actually calling. If you put a cout statement in your own swap you'll see that it's never actually called. Alternatively, if you declare your swap before main, you'll get an ambiguous call.
Note that this code is not required to behave like this, since iostream doesn't necessarily bring std::swap into scope, in which case you'll get the error that there is no swap to call.
In the second program, the call to swap(&a, &b) fails because there is no overload of std::swap that accepts 2 temporary pointers. If you declare your swap function before the call in main, then it calls your own function.
The real bug in your code is the using namespace std;. Never do that and you'll avoid issues of this nature.
The reason why the first version works is because it doesn't call your swap(...) function at all. The namespace std provides - Edit: depending on the headers you (and the standard headers themselves) include - swap(...) functions for various types and integers are one of them. If you would remove using namespace std you would have to type std::swap(...) to achieve the same effect (same goes for std::cout, std::endl).
That's one reason why using namespace is a double-edged sword for beginners in my opinion but that's another topic.
Your code is fine; but you're right, it fails if you comment on the line you point to.
But actually, as the others tell you, there is a Swap function in c ++, so it doesn't matter if you create a prototype of the function and do it later because the compiler calls its own swap function.
But since swap works for any data type, except for pointers, then you will understand the reason for your problem, since in this case you do have to create your own swap function that accepts pointers as parameters.
Just move your function above main to make it work correctly, nothing more:
#include <iostream>
using namespace std;
//void swap(int*, int*); // The code fails if I comment this line.
void swap(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(&a, &b);
cout << endl;
cout << "After swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}

function pointer syntax in c++

I'm just learning about function pointers in C++. The following examples do all compile and return the expected result, but I was taught that example 3 was the way to go. Why do the other examples still work?
There is another thing that seemed strange are the examples f,g,h,i which in contrast to the the examples above do not all work. Why don't they work, comparing to the examples 1-8?
int executeOperator1(int a, int b, int f(int,int)){
return f(a,b);
}
int executeOperator2(int a, int b, int f(int,int)){
return (*f)(a,b);
}
int executeOperator3(int a, int b, int (*f)(int,int)){
return f(a,b);
}
int executeOperator4(int a, int b, int (*f)(int,int)){
return (*f)(a,b);
}
int op(int x, int y){
return x+y;
}
int main(int argc, char *argv[])
{
int a = 2, b=3;
//the following 8 examples compile nicely:
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,op) <<endl; //1
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,op) <<endl; //2
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,op) <<endl; //3
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,op) <<endl; //4
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,&op) <<endl; //5
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,&op) <<endl; //6
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,&op) <<endl; //7
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,&op) <<endl; //8
//int f(int,int) = op; //does not compile
int (*g)(int,int) = op; //does compile
//int h(int,int) = &op; //does not compile
int (*i)(int,int) = &op;//does compile
return 0;
}
All your examples work because of wonderful so-called pointer decay rule. A function name decays to a pointer to function in almost all contexts. (Decay here means that original type information is lost, and all what is left is the pointer. Arrays do decay to pointers too in certain contexts).
So all your examples are semantically the same thing, and I would not call any of them preferred.
And just for the fun of it, this would compile too:
int executeOperator_insane(int a, int b, int f(int,int)){
return (***************f)(a,b);
}
Function, like arrays when passed as an argument to a function, decays into a pointer. For eg: A function taking two int parameters and returning an int would have a type of int (*) (int, int). But you can pass the function as reference as well, in which case you would have a type of int (&) (int, int).
To declare a value of type of above function pointer you would simply write :
typedef int (*FuncType) (int, int);
FuncType myFunc = op;
// OR
FuncType myFunc = &op;
The second way is usually preffered as it is more clear, but most of the compilers let the user do away with the first style.
Would recommend to go through below link:
http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions
When you use:
int f(int,int);
in main (or any place that is not an argument to a function), it declares f to be a function, not a pointer to a function. Hence, you cannot use
int f(int,int) = op;
On the other hand,
int (*g)(int,int) = op;
declares g to be a pointer to a function. Hence, it works.
When int f(int,int) is used as an argument to a function, it is equivalent to sing int (*f)(int, int).

without declaration the function first, I can swap the value of the variables?

#include <iostream>
using namespace std;
void swap(int, int);
int main()
{
int a=10;
int b=20;
swap (a, b);
cout << "a: " << a << endl;
cout << "b: " << b << endl;
return 0;
}
void swap(int x, int y)
{
int t;
t = x;
x = y;
y = t;
}
those code above can't swap the value of a and b.
but my question is , when I forgot to type the third line "void swap(int, int);
" , the values of a and b swaped !! why?
It's because you have
using namespace std;
At the beginning of your source code.
This is a a bad programming practice, whose consequences you just experienced, first hand. You told the compiler that you want to invoke std::swap, without having any clue that you actually did that.
It's ironical, because you version of swap() won't work right, but std::swap does; so you were operating under the mistaken impression that your code was working, when it didn't.
Never use "using namespace std;" with your code. Simply forget that this part of the C++ language ever existed.
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int b = 20;
cout << "a: " << a << endl;
cout << "b: " << b << endl;
system("pause");
swap(a, b);
cout << "a: " << a << endl;
cout << "b: " << b << endl;
system("pause");
return 0;
}
void swap is unnecessary
If you put the function definition above main then you don't need a prototype otherwise you do need it and the compiler should give you an error if you don't have a prototype

C++ How would the calling of these functions change if i change the parameter argument from an int* to int [duplicate]

This question already has an answer here:
C++ parameter passing queries (code examples and outputs included)
(1 answer)
Closed 8 years ago.
First of all, i have no idea how to word the title whilst keeping it descriptive if anybody has a better idea feel free to edit.
My question is as follows; I have been given a set of function definitions and calls to these functions which currently operate using an int* as the variable that is being passed in various ways to these functions.
My task is to without changing the function definitions make the program compile and produce the same output but this time use an int over an int*.
Desired output:
Result
first 43
second 43
third 44
fourth 0
fifth 69
This is the code for the when the variable is an int*
void MyIncrementFirst(int* i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int** i) {
*i = new int(0);
}
void MyIncrementFifth(int*& i) {
i = new int(69);
}
int main(){
int* a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " <<*a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
return 0;
}
Now here is what i have so far when changing the type of a to an int, not an int*:
Note: The function definitions are the same as above.
int main(){
int a = 42;
cout << "Result" << endl;
MyIncrementFirst(&a);
cout << "first " <<a << endl;
MyIncrementSecond(a);
cout << "second " <<a << endl;
MyIncrementThird(a);
cout << "third " <<a << endl;
/*
MyIncrementFourth(&a);
cout << "fourth " <<a << endl;
MyIncrementFifth(a);
cout << "fifth " <<a << endl;
*/
return 0;
}
Which prints:
Result
first 43
second 43
third 44
Calls to MyIncrementFourth and MyIncrementFith have been commented because i am not sure how to translate this to handle an int rather than an int*. Any attempts i do would just be fluke rather than knowledge.
Can anybody help me identify how to correctly complete the calls to MyIncrementFourth and MyIncrementFith in order to achieve a correct result.
Thanks,
Chris.
void foo(int a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
While with * it would be like this
void foo(int* a) {
...
}
int main() {
int a = 5;
foo(&a);
return 0;
}
However, this reminds of C.
You could use the & operator, instead of the *, like this:
void foo(int& a) {
...
}
int main() {
int a = 5;
foo(a);
return 0;
}
I assume you know what passing by value and by reference means. If you want a refresh, take a look in my example here.
[EDIT]
Also note that the code in the first block of yours is not OK, since you call new twice, but you never call delete.
Also, about what you are asking, you cannot do it without using an extra pointer. In other words, it can not be done by only having int a in the play.
Example:
int* a_pointer = &a;
MyIncrementFourth(&a_pointer);
cout << "fourth " << a << ", but a_pointer points to " << *a_pointer << endl;
Why the value of a did not change, despite the fact that we set the a_pointer to be equal with the address of a.
Because inside your function, you are calling new and as you know, it will return a pointer to the new allocated memory.
As a result, a_pointer is assigned a new value. Which value? The address of the new allocated memory.
When you use
int a = 42;
instead of
int* a = new int(42);
fourth and fifth function can't be used. The MyIncrementFourth and MyIncrementFifth (counterintuitive names, by the way) pretend to replace the pointer you allocated in the main with another pointer to another area, allocated inside the functions (and there will be a memory leak since you no longer will be able to delete the original a…). But if you stick to int a = 42 instead of int* a = new int(42), your variable is not a pointer, thus those functions have no pointer they can replace.
You can use:
int* ap = &a;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
// It does not change the value a.
You can also use:
int* ap = NULL;
MyIncrementFourth(&ap);
MyIncrementFifth(ap);
// These calls change what ap points to.
int* ptr;
MyIncrementFourth(&ptr);
a = *ptr;
delete ptr;
std::cout << "fourth " << a << std::endl;
MyIncrementFifth(ptr);
a = *ptr;
delete ptr;
std::cout << "fifth " << a << std::endl;

Parameter passing with const primitive reference and only primitive

Is there any difference between these two usage?
1.
void Foo(const double &n)
{
cout<< "Hello: " << n << endl;
}
2.
void Foo(double n)
{
cout<< "Hello: " << n <<endl;
}
I'm looking for a general answer, not only for this context. (1. usage makes me confused.)
You can't modify the value of the parameter in the first snippet, in the second one you can.
Outside the function, they both remain the same, because the second one passes by value.
void Foo(const double &n)
{
n = 3; //ERROR
}
void Foo(double n)
{
n = 3; //OK
}
For non-basic types, it makes a difference performance-wise. If you pass by reference (1.), you pass the original object, not a copy. If you pass by value, a copy is created.
If you use a reference and the value that the reference refers to changes, that change will be visible through the reference. If you pass by value, the change won't be visible. Example:
#include <iostream>
using namespace std;
double x;
void Foo1(const double& n) {
cout << n << endl;
x = 23.0;
cout << n << endl;
}
void Foo2(double n) {
cout << n << endl;
x = 23.0;
cout << n << endl;
}
int main()
{
x = 42.0;
Foo1(x); // Will print 42.0, then 23.0
x = 42.0;
Foo2(x); // Will print 42.0 twice
return 0;
}
Here is one more example that shows the difference between 'const double&' and 'double' types.
#include <iostream>
void foo1(const double &n)
{
const_cast<double&>(n) = 10.0; // <-- this code changes variable referenced by n
}
void foo2(double n)
{
const_cast<double&>(n) = 10.0; // <-- this code changes variable n
}
int main()
{
double x = 12.0;
foo1(x);
std::cout << x << std::endl; // <-- this will print '10'
x = 12.0;
foo2(x);
std::cout << x << std::endl; // <-- this will print '12'
return (0);
}
In the first case you send a reference (almost the same as pointer) to variable 'x'. In the second case you send a copy of variable 'x'.