I am practicing functions in C++. In some random notes, I found an example of functions call by value and call by reference.
The code is
#include <string.h>
#include <iostream>
#include<stdio.h>
using namespace std;
void F1(float a, float b)
{
a++;b++;
}
void F2 (float &a, float &b)
{
a++;
b++;
}
int main ()
{
float a=9,b=5;
float *ptrA=&a;
float *ptrB=&b;
F1(a,b);
cout<<"\na:"<<a<<"\nb:"<<b;
F2(a,b);
cout<<"\na:"<<a<<"\nb:"<<b;
}
Now for the function F2, I am confused that in the main function I have passed the value of a and b and in the definition it received the address of the variable a and b. Then how will the increment be done in the values of a and b?
The call
F2(a,b);
Actually sends the addresses of a and b, and not their values, because of the way F2 is declared. In C++, references are like pointers, just with a cleaner syntax. So F2 actually gets the addresses of a and b, and then a++ and b++ operate on the original variables defined in main().
It looks like you're after passing a float pointer to the function
void F1(float a, float b)
{
a++;b++;
}
void F2 (float* a, float* b)
{
a++;
b++;
}
int main()
{
float a, b;
a = 5;
b = 7;
F1(a, b);
// a is still 5 and b 7
F2(&a, &b);
// a is 6 b is 8
}
Related
There is this C code:
*(*(A+i)+j) = aaa(*bbb,0,PI)/(16*PI);
aaa is a function, and bbb is another function:
double bbb(double x, double y)
{
int i,j,k,l,m,n;
*(K+1)=sin(x)*cos(y);
*(K+2)=sin(x)*sin(y);
*(K+3)=cos(x);
...
...
My question is, when bbb is called inside the function aaa, there isn't any parentheses following bbb, that is, no variable is passed into function bbb. So what are the values of x and y in the function bbb? Both zero?
Alright, this is part of a really long code:
*(*(A+i)+j) = aaa(*bbb,0,PI)/(16*PI);
aaa and related functions:
double aaa(double (*func)(double, double), double x1, double x2)
{
double qgaus(double (*func)(double), double a, double b);
double f1(double x);
nrfunc=func;
return qgaus(f1,x1,x2);
}
double f1(double x)
{
double qgaus(double (*func)(double), double a, double b);
double f2(double y);
double yy1(double),yy2(double);
xsav=x;
return qgaus(f2,yy1(x),yy2(x));
}
double f2(double y)
{
return (*nrfunc)(xsav,y);
The capital variable K in function bbb is a global variable defined in main().
I just want to know what are the x and y values passed into function bbb.
Most probably (assuming the code compiles) aaa is a function that takes as its first parameter a pointer-to-function. It doesn't matter if you dereference the pointer-to-function, the call is still valid. So in your case *b is simply decaying to a function pointer, which presumably is used inside aaa (of which definition you don't provide). Simple example:
#include <iostream>
void f(int x)
{
std::cout << "void f(int) invoked, with x = " << x << std::endl;
}
void a(void (*fptr)(int), int x)
{
fptr(x); // call the function pointed by fptr with argument x
}
int main()
{
a(f, 10);
a(*f, 20); // same as above
a(****f, 42); // still the same
}
So in your code you first pass the pointer to function, then the arguments of the function, which are then used when calling the latter via the pointer-to-function.
I am using function overload to have a general version of a behaviour and a more usual one. The usual function just picks a default value for the second argument that actually depends on the first, and the compiler is giving me an error because it does not even recognize the existence of the second function. I also tried to do it with default values, but because the default depends on the first argument, the compiler does not seem to accept it.
So, here are simplified examples just for illustration.
Function overloading case:
#include <stdio.h>
struct pair {
int x;
int y;
};
int func(pair a){
return func(a, a.y);
}
int func(pair a, int b) {
return a.x*b;
}
int main() {
pair z;
z.x = 2;
z.y = 4;
printf("%d\n", func(z));
printf("%d\n", func(z,12));
}
This gives me the error:
a.c: In function ‘int func(pair)’:
a.c:9:21: error: too many arguments to function ‘int func(pair)’
a.c:8:5: note: declared here"
Example with default values:
#include <stdio.h>
struct pair {
int x;
int y;
};
int func(pair a, int b = a.y) {
return a.x*b;
}
int main() {
pair z;
z.x = 2;
z.y = 4;
printf("%d\n", func(z));
printf("%d\n", func(z,12));
}
Gives me the following error: "local variable a may not appear in this context"
So, is there any way in C++ to emulate this behaviour? I never had this problem in other languages, like Java or even in ASP.
Thank you all.
In C and C++, before the function call, that function should be declared or defined. Here you are making a call to return func(a, a.y); but the function func(pair, int) has not yet been declared or defined.
You need to change the definitions of the two functions, or just declare the functions in the beginning of your code. As other answers have explained the first approach, here is the snippet with second approach.
#include <stdio.h>
//Function Declaration
int func(pair);
int func(pair, int);
struct pair {
int x;
int y;
};
int func(pair a){
return func(a, a.y);
}
int func(pair a, int b) {
return a.x*b;
}
int main() {
pair z;
z.x = 2;
z.y = 4;
printf("%d\n", func(z));
printf("%d\n", func(z,12));
}
Switch the order of the definitions of func(), such that the 2 argument version is defined before the one argument version. The compiler doesn't know the 2 argument version exists until it encounters the definition, so you can't call it until you've told the compiler it exists.
You have to change the order of the definitions:
int func(pair a, int b) {
return a.x*b;
}
int func(pair a){
return func(a, a.y);
}
LIVE DEMO
This is happening because in int func(pair a) you are calling int func(pair a, int b) which is not visible. Changing the order of definitions like above solves this problem.
So I know it is disallowed to have functions with the same parameters and names:
int a(int b) {
return b;
}
int a(int b) {
return b;
}
int main() {
int c = a(4);
}
This above won't compile. But then I got thinking, what if I passed one by reference, and one by value?
int a(int b) {
return b;
}
int a(int& b) {
return b;
}
int main() {
int c = a(4);
}
The above does compile, I guess because you can't pass 4 to by reference, so it assumes you want the first a, which means the compiler can distinguish which function you want to call. If I then change main to this:
int main() {
int c = a(4);
a(c);
}
It will fail to compile, I assume because c can be passed to either function, so the compiler doesn't know which function to call.
But what about... THIS?
int a(const int& b) {
return b;
}
int a(int& b) {
return b;
}
int main() {
int c = a(4);
a(c);
}
This does compile. Why? I expected it to not, because c can be passed to both the first and second a. Is there some misconception I have?
My question specifically is, how come this (code below) does not compile, and the final one does?
int a(int b) {
return b;
}
int a(int& b) {
return b;
}
int main() {
int c = a(4);
a(c);
}
If I was the compiler, and I could choose which function to call based how close the parameters matched, for the call a(c), I could choose from both the first and second. Is there any reason that the first or second a cannot be chosen from in this example?
The process of choosing the correct function to use from a function call is called Overload Resolution. When a function is called, the compiler searches for all functions with that name (overloads) and compiles them into an overload set. Simply put, a best match is chosen by picking the functions that require the least conversions as possible from their parameters.
These are the two functions compiler chooses from a(c):
int a(const int& b);
int a( int& b);
The second overload is chosen because the first overload requires a const-qualification. The variable with which you called the function with, c, is non-const, so it is a perfect match for the second overload and can be bound to the non-const reference.
int a(const int& b) {
return b;
}
int a(int& b) {
return b;
}
int main() {
int c = a(4);
a(c);
}
When you call it with a(4) 4 is a literal and only your version taking a const reference can bind it, so that's the one being called.
Now when you call a(c) you got c as a non-const int it will therefore prefer the function taking a non-const reference.
Why is there a difference in the results when I call an array inside a void function and when I call a scalar inside a void function:
Pass an array into a void function:
#include <iostream>
const int n_cells = 1;
using namespace std;
void function1(int c[n_cells], int a, int b)
{
c[0] = a + b;
}
int main(){
int a = 3;
int b = 4;
int c[n_cells];
function1(c, a, b);
cout<<"c = "<<c[0];
return 1;
}
Result:
c = 7
Pass a scalar into a void function
#include <iostream>
using namespace std;
void function1(int c, int a, int b)
{
c = a + b;
}
int main(){
int a = 3;
int b = 4;
int c;
function1(c, a, b);
cout<<"c = "<<c;
return 1;
}
Result:
c = 2130567168 //Some trash value
P.S. Any comments on why I receive the same trash value as given above every single time?
void function1(int c[n_cells], int a, int b)
effectively passes a pointer to the caller's array. function1 then operates on the caller's array meaning that any updates are available to the caller.
void function1(int c, int a, int b)
passes a copy of c. It does not have access to the caller's variable so cannot update it. main never assigned c so you print out an uninitialised value.
If you want to update an integer argument, you can pass it by reference instead
void function1(int& c, int a, int b)
// ^
Rather than passing a copy of the caller's c, this now passes a pointer to the caller's variable, allowing function1 to update it.
The array parameter is actually transformed to the type int*, so what you're actually doing is passing a pointer to the first element of the array declared in main. So when you assign to the first element of this array, you are modifying the array in main.
However, when you pass an int, the int is copied into the function and you modify that copy. This modification will not be seen in main.
You could get the same result in the second program if you would define the function the following way
void function1(int *c, int a, int b)
{
c[0] = a + b;
}
When you pass an array by value it is converted implicitly by the compiler to pointer to its first element. So these function declarations are equivalent and declare the same function
void function1(int c[n_cells], int a, int b);
void function1(int c[10], int a, int b);
void function1(int c[], int a, int b);
void function1(int *c, int a, int b);
Compare the last declaration with the declaration I showed you for the second program.
In the second program the function gets a copy of its argument. Its parameter is a local variable of the function. So any changes of this local variable will be discarded after exiting the function that is the local variable will be destroyed.
In the first program the function gets the address of the first element of the array. It makes changes at this address. So the corresponding element of the original array will be changed.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How does dereferencing of a function pointer happen?
Hi All,
Why these two codes give the same output,
Case 1:
#include <stdio.h>
typedef void (*mycall) (int a ,int b);
void addme(int a,int b);
void mulme(int a,int b);
void subme(int a,int b);
main()
{
mycall x[10];
x[0] = &addme;
x[1] = &subme;
x[2] = &mulme;
(x[0])(5,2);
(x[1])(5,2);
(x[2])(5,2);
}
void addme(int a, int b) {
printf("the value is %d\n",(a+b));
}
void mulme(int a, int b) {
printf("the value is %d\n",(a*b));
}
void subme(int a, int b) {
printf("the value is %d\n",(a-b));
}
Output:
the value is 7
the value is 3
the value is 10
Case 2 :
#include <stdio.h>
typedef void (*mycall) (int a ,int b);
void addme(int a,int b);
void mulme(int a,int b);
void subme(int a,int b);
main()
{
mycall x[10];
x[0] = &addme;
x[1] = &subme;
x[2] = &mulme;
(*x[0])(5,2);
(*x[1])(5,2);
(*x[2])(5,2);
}
void addme(int a, int b) {
printf("the value is %d\n",(a+b));
}
void mulme(int a, int b) {
printf("the value is %d\n",(a*b));
}
void subme(int a, int b) {
printf("the value is %d\n",(a-b));
}
Output:
the value is 7
the value is 3
the value is 10
I'll simplify your question to show what I think you want to know.
Given
typedef void (*mycall)(int a, int b);
mycall f = somefunc;
you want to know why
(*f)(5, 2);
and
f(5.2);
do the same thing. The answer is that a function name both represent a "function designator". From the standard:
"A function designator is an expression that has function type. Except when it is the
operand of the sizeof operator or the unary & operator, a function designator with
type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to
function returning type’’."
When you use the indirection operator * on a function pointer, that dereference is also a "function designator". From the standard:
"The unary * operator denotes indirection. If the operand points to a function, the result is
a function designator;..."
So f(5,2) becomes essentially (*f)(5,2) by the first rule. This becomes call to function designated by f with parms (5,2) by the second. The result is that f(5,2) and (*f)(5,2) do the same thing.
Because function pointers are automatically resolved whether you use them with or without the dereference operator.
you don't have to use & before function name
x[0] = addme;
x[1] = subme;
x[2] = mulme;
however both ways are valid.