Problems with functions parameters in pass by references in C++ - c++

I am newbie in c++ and just learning it.
I have written the following code.
#include<iostream>
#include<cstdio>
using namespace std;
void first(int &x,int n)
{
int i;
for(i=0;i<n;i++)
{
cout<<x+i;
}
cout<<endl;
}
void second(int *x,int n)
{
int i;
for(i=0;i<n;i++)
{
cout<<*x+i;
}
cout<<endl;
}
int main()
{
int exm[5]={1,2,3,4,5};
first(exm[0],5);
second(exm,5);
return 0;
}
this program gives output correctly.but the problem is i don't understand the differences between using & and * in function parameters...
both are the techniques of passing arguments by references and when we pass by reference we just send the memory address...
but in function first when i tried to call the function as follows
first(exm,5);
function occurred an error.
why ?
but when i called the function as follows
first(exm[0],5);
it compiled properly and gave right output...but i know that the both calling is equivalent...
then why this error occured?
what is the difference between using & and * in function parameters?

The type of the variable exm is int[5], which doesn't meet the signature of first(int &x,int n).
But int[N] can be converted implicitly to int* that points to the first element of the array, hence second(exm,5) can compile.
what is the difference between using & and * in function parameters?
It's the difference between a reference and a pointer.
There are lots of differences between them.
In this case, I think the biggest difference is whether it accepts NULL or not.
See:
- What are the differences between a pointer variable and a reference variable in C++?
- Are there benefits of passing by pointer over passing by reference in C++?
- difference between a pointer and reference parameter?

Related

what is the difference in the following c++ codes regarding call by reference [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 3 years ago.
#include<iostream>
using namespace std;
void swap(int *x, int *y)
{
int temp=*x;
*x=*y;
*y=temp;
cout<<*x<<endl<<*y<<endl<<"Bro"<<endl;
}
int main()
{
int a=10,b=5;
swap(&a,&b);
cout<<"HI"<<endl;
cout<<a<<endl<<b<<endl;
return 0;
}
and
#include<iostream>
using namespace std;
void swap(int &x, int &y)
{
int temp=x;
x=y;
y=temp;
cout<<x<<endl<<y<<endl<<"Bro"<<endl;
}
int main()
{
int a=10,b=5;
swap(a,b);
cout<<"HI"<<endl;
cout<<a<<endl<<b<<endl;
return 0;
}
Both the codes do give the same output but i don't get the fact that if we are only passing only the variable, how do the addresses get swapped
Both of the codes do the same thing and both of them use call-by-reference for passing the variables to the swap function. but the methods are different. the first code uses pointers for achieving this goal, while the second code uses references. in the signature of the swap function in the second code you can see the & symbol which means the input arguments must be addresses not just values. by calling the swap function, the addresses of arguments will be passed automatically to the swap function rather than their values.
For further reading take a look at the differences between pointers and references.

Working of function pointers [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
In this Program, I am unable to understand the declaration of the "sum" function.
Please explain what is happening while calling the sum function and while declaring the function.
#include<iostream.h>
#include <conio.h>
int sum(int(*)(int),int);
int square(int);
int cube(int);
void main()
{
clrscr();
cout<<sum(square,4)<<endl;
cout<<sum(cube,4)<<endl;
getch();
}
int sum(int(*ptr)(int k),int n)
{
int s=0;
for(int i=1;i<=n;i++)
{
s+=(*ptr)(i);
}
return s;
}
int square(int k)
{
int sq;
sq=k*k;
return k*k;
}
int cube(int k)
{
return k*k*k;
}
The parameter is a function pointer - you should read here for an introduction, and heres a relevant SO post.
The idea is that you can pass around a function as a value - so you can make other general functions that you can give a specific function to in order to change the effect. An example would be map from functional programming.
Specifically in your case, the sum function takes this function pointer in order to sum a function of the values in the list given to it, rather than just the values themselves. This is demonstrated by passing it eg. a pointer to the square function, which will make it sum squares of the values given to sum.
This is the reason why some people does not like pointers in C and C++. See my explanation below in your program:-
#include<iostream.h>
# include <conio.h>
void main()
{
clrscr();
int sum(int(*)(int),int);// Here first parameter in `sum` is a pointer to a function which return type is int. `int(*)(int)` here int(*) is function pointer and (int) is its parameter type.
int square(int);
int cube(int);
cout<<sum(square,4)<<endl;// Now you are passing address of function `square` as first parameter and its parameter 4, like square(4)
cout<<sum(cube,4)<<endl; // Here you are passing address of function `cube` as parameter and 4 as parameter to cube function
getch();
}
int sum(int(*ptr)(int k),int n)
{
int s=0;
for(int i=1;i<=n;i++)
{
s+=(*ptr)(i); //This `ptr` is nothing but the address of function passed to sum
//hence it execute like below
//When you are calling function `sum` with function pointer `square` as first parameter
//it execute like `s = s + square(i);`
//Now at the second call to `sum` it execute like `s = s + cube(i);`
}
return s;
}
// The method sum
// First argument: a pointer to a function which accepts one integer
// as argument and returns an integer
// Second argument: an integer
int sum(int(*)(int),int);
That is why when you call sum in this line:
cout<<sum(square,4)<<endl;
You pass square as the first argument and since square is like this:
int square(int k)
{
}
it satisfies the call because it is a function which accepts one integer as argument and returns int.
Then inside the sum method, it calls the function which you passed in as the first argument like this (please read my comments inline for clarity):
int sum(int(*ptr)(int k),int n)
{
int s=0;
for(int i=1;i<=n;i++)
{
// Calls the function pointer (square in this case) and sends i to
// it as argument. It then takes the return value and adds it to s.
s+=(*ptr)(i);
}
return s;
}
Here are the different parts:
Here is another example to help you:
// fcnPtr is a pointer to a function that takes no arguments and returns an integer
int (*fcnPtr)();

unable to predict the output when a function returning reference is written on LHS

I know following about reference
eg. int &ref=x;
then ref and x are the names of same locations in memory.
Memory is not allocated for reference unlike pointers.
I was writting a simple swap program in C++ using references which I successfully wrote.
Then i decided to try out what happens when a function which returns reference is LHS of an expression and now I am unable to predict the output of the below code.
#include<iostream.h>
int & swap(int &,int &); //function returns reference
void main()
{
int x=10,y=20;
int &ref1=x,&ref2=y;
swap(ref1,ref2)=x; //what happens here?
cout<<x<<y;
}
int & swap(int &ref1,int &ref2)
{
int temp;
temp=ref1; //swap
ref1=ref2; //code
ref2=temp; //here
return ref2; //tried out this(has nothing to do with swapping)
}
O/P 20 20
There are two possible outcomes:
"2010"
"2020"
It depends on whether x on the right side is read before or after calling swap on the left.
The standard does not proscribe which happens, only that they are not interleaved.

Returning an array ... rather a reference or pointer to an array

I am a bit confused. There are two ways to return an array from a method. The first suggests the following:
typedef int arrT[10];
arrT *func(int i);
However, how do I capture the return which is an int (*)[]?
Another way is through a reference or pointer:
int (*func(int i)[10];
or
int (&func(int i)[10];
The return types are either int (*)[] or int (&)[].
The trouble I am having is how I can assign a variable to accept the point and I continue to get errors such as:
can't convert int* to int (*)[]
Any idea what I am doing wrong or what is lacking in my knowledge?
If you want to return an array by value, put it in a structure.
The Standard committee already did that, and thus you can use std::array<int,10>.
std::array<int,10> func(int i);
std::array<int,10> x = func(77);
This makes it very straightforward to return by reference also:
std::array<int,10>& func2(int i);
std::array<int,10>& y = func2(5);
First, the information you give is incorrect.
You write,
“There are two ways to return an array from a method”
and then you give as examples of the ways
typedef int arrT[10];
arrT *func(int i);
and
int (*func(int i))[10];
(I’ve added the missing right parenthesis), where you say that this latter way, in contrast to the first, is an example of
“through a reference or pointer”
Well, these two declarations mean exactly the same, to wit:
typedef int A[10];
A* fp1( int i ) { return 0; }
int (*fp2( int i ))[10] { return 0; }
int main()
{
int (*p1)[10] = fp1( 100 );
int (*p2)[10] = fp2( 200 );
}
In both cases a pointer to the array is returned, and this pointer is typed as "pointer to array". Dereferencing that pointer yields the array itself, which decays to a pointer to itself again, but now typed as "pointer to item". It’s a pointer to the first item of the array. At the machine code level these two pointers are, in practice, exactly the same. Coming from a Pascal background that confused me for a long time, but the upshot is, since it’s generally impractical to carry the array size along in the type (which precludes dealing with arrays of different runtime sizes), most array handling code deals with the pointer-to-first-item instead of the pointer-to-the-whole-array.
I.e., normally such a low level C language like function would be declared as just
int* func()
return a pointer to the first item of an array of size established at run time.
Now, if you want to return an array by value then you have two choices:
Returning a fixed size array by value: put it in a struct.
The standard already provides a templated class that does this, std::array.
Returning a variable size array by value: use a class that deals with copying.
The standard already provides a templated class that does this, std::vector.
For example,
#include <vector>
using namespace std;
vector<int> foo() { return vector<int>( 10 ); }
int main()
{
vector<int> const v = foo();
// ...
}
This is the most general. Using std::array is more of an optimization for special cases. As a beginner, keep in mind Donald Knuth’s advice: “Premature optimization is the root of all evil.” I.e., just use std::vector unless there is a really really good reason to use std::array.
using arrT10 = int[10]; // Or you can use typedef if you want
arrT10 * func(int i)
{
arrT10 a10;
return &a10;
// int a[10];
// return a; // ERROR: can't convert int* to int (*)[]
}
This will give you a warning because func returns an address of a local variable so we should NEVER code like this but I'm sure this code can help you.

passing variable to function with & in the header

I am doing a procedure and it's working but I'm not sure if it'll work in all cases as it's not conventional.
void func (int &num){
num=blah;
}
int main() {
int num;
func(num);
}
I know the conventional way of doing this is as below but still I have a lot of code in the previous format I prefer not to change as it works just fine. What I don't understand is whether I'm just being lucky.
void func (int* num){
*num=blah;
}
int main() {
int num;
func(&num);
}
In fact there is a bit more complicated version of it as well:
void func(float* &list){
list=new float[3];
}
int main() {
float *list;
func(list);
}
which again I understand the conventional way of doing it is as below.
void func(float** list){
*list=new float[3];
}
int main(){
float *list;
func(&list);
}
Your help is much appreciated as I'm in total confusion.
Your first example is correct - you're passing an int by reference to func().
Your second example also fine (now that you've edited it). In this case, you're passing an int * by value to func().
Your third and fourth examples are also both correct. In the third, you're passing a float * by reference. In the second case, you're passing a float ** by value (which is semantically similar to passing a float * by reference, which might be why you're confusing them).
There's nothing "conventional" or "unconventional" about any of your example code. All of it is 100% correct and will work fine. Though there are some subtle semantic differences between passing pointers by value and passing by references, these examples are ok.
The syntax with int & is not C, but C++. It is a so-called reference. If your C (not C++) compiler accepts is, then it is a non-standard extension (for a C++ compiler it's part of the language, of course).
The basic mechanics of a reference is that it acts as a name (or another name) for an existing object. For example:
int a;
int& b = a;
b = 3; /* equivalent to a = 3 */
One way to think about the reference is as an automatically dereferenced pointer (that's also how it is commonly implemented). That is, the above code is equivalent to
int a;
int* pb = &a;
*pb = 3;
The Form Func(int &x) is the c++ form of pass by reference c does not support this. It is logically equivocation of passing by a pointer. The comnplier take the address for you implicitly in the call.
In C you would allways declare
Func(int *x)
{ ... }
And call it
Func(&SomeInt);