Functions¶
Functions¶
#include <cmath> // to get sqrt
double dist(double x1, double y1, double x2, double y2) {
double dx = x1 - x2;
double dy = y1 - y2;
return sqrt(dx * dx + dy * dy);
}
this function is named dist
it returns a double
it takes four double
parameters as input
Functions¶
double dist(double x1, double y1, double x2, double y2) // header
{
double dx = x1 - x2;
double dy = y1 - y2; // body
return sqrt(dx * dx + dy * dy);
}
the first line of the function is the header (sometimes called the function’s signature)
the header has a lot of useful information
Functions¶
// declaration of a function: just a header, no body
double dist(double x1, double y1, double x2, double y2);
// definition of a function: header and body
double dist(double x1, double y1, double x2, double y2) // header
{
double dx = x1 - x2;
double dy = y1 - y2; // body
return sqrt(dx * dx + dy * dy);
}
the header is the interface to the function
the body is the implementation of a function
generally, calling code only needs to know the header (the interface) to be able to use a function — it does not need to know the implementation
Functions¶
double dist(double x1, double y1, double x2, double y2) {
double dx = x1 - x2;
double dy = y1 - y2;
return sqrt(dx * dx + dy * dy);
}
dx
and dy
are local variables visible only inside dist
x1
, y1
, x2
, y2
are also local to dist
they are automatically de-allocated when the function ends
Functions¶
double dist(double x1, double y1, double x2, double y2) {
double dx = x1 - x2;
double dy = y1 - y2;
return sqrt(dx * dx + dy * dy);
}
non-void
functions must return a value
you can replace any double
with a call to dist()
, since it returns a
double
Calling a Function¶
double dist(double x1, double y1, double x2, double y2) {
double dx = x1 - x2;
double dy = y1 - y2;
return sqrt(dx * dx + dy * dy);
}
// ...
double x = dist(1, 2, 3, 4);
the order of the arguments must match the order of the parameters in the function header
Parameter Passing¶
void set_to_zero(double x) {
x = 0.0; // our g++ settings signal an error here
} // because x is set but never used
double x = 3.14;
set_to_zero(x);
cout << x; // 3.14, x has not changed
C++ ordinarily passes parameters by value, i.e. it makes a copy of the passed-in parameter
pass by value means you can’t modify the actual parameter
Parameter Passing¶
void print(vector<string> v) {
for(auto s : v) {
cout << s << endl;
}
}
v
is passed by value, which means a copy of v
is made
this could be slow and waste memory if v
is big
Pass by Reference¶
void set_to_zero(double& x) {
x = 0.0;
}
double x = 3.14;
set_to_zero(x);
cout << x; // 0, x has changed
double&
means that x
in the set_to_zero
header is a reference to
the x
in the calling code
no copy is made
so x
really is changed
Pass by Reference¶
void print(vector<string>& v) {
for(auto s : v) {
cout << s << endl;
}
}
vector<string>&
means v
is passed by reference, so the vector is not
copied
much better, but perhaps a safety concern
what if print
modifies v
Pass by Constant Reference¶
void print(const vector<string>& v) {
for(auto s : v) {
cout << s << endl;
}
}
vector<string>&
means v
is passed by constant reference, so the vector
is not copied, and the compiler does not allow the body of the function to
modify v
passing by constant reference is fast and safe
Advice¶
pass by value is usually fine for basic numeric types
use pass by constant reference in other cases when you can
use (non-constant) pass by reference when you need to modify a passed-in variable
Overloaded Functions¶
void print() { /* ... */ }
void print(string s) { /* ... */ }
void print(char c) { /* ... */ }
void print(long long n) { /* ... */ }
void print(const vector<double>& v) { /* ... */ }
functions can have the same name if they have different parameter types
see textbook for (many) more details
Overloaded Functions¶
anothe example of function overloading
double dist(double x1, double y1, double x2, double y2) {
double dx = x1 - x2;
double dy = y1 - y2;
return sqrt(dx * dx + dy * dy);
}
struct Point {
double x;
double y;
};
double dist(const Point& a, const Point& b) {
return dist(a.x, a.y, b.x, b.y);
}
int main() {
double a = 1;
double b = 2;
double c = 3;
double d = 4;
cout << dist(a, b, c, d) << endl;
Point p{a, b};
Point q{c, d};
cout << dist(p, q) << endl;
} // main