int area(int length, int width){
return length*width;
}
int framed_area(int x, int y){
return area(x-2,y-2);
}
int main() {
int x=-1;
int y=2;
int z=4;
int area1=area(x,y);
int area2=framed_area(1,z);
int area3=framed_area(y,z);
double ratio=double(area1)/area3;// double division!
return 0;
}
Find (possible) errors.
if(x<=0) error("non-positive x");
if(y<=0) error("non-positive x");
We will see what the error function means later.
int framed_area(int x, int y){
constexpr int frame_width=2;
if( x-frame_width<=0 || y-frame_width<=0 ){
error("error called by framed_area()");
}// Error handling
return area(x-frame_width,y-frame_width);
}
int area(int length, int width){
// Error handling
return length*width;
}
inline void error(const string& s)
{
throw runtime_error(s);
}
If a function finds an error that it cannot handle, it does not return normally, instead it throws an exception.
try{
// Something wrong! Throw an exception.
}
catch(Exception-type1 & e ){
// Do something
}
catch(Exception-type2 & e ){
// Do something
}
...
#include <string> // for string
#include <stdexcept> // for exception, runtime_error, out_of_range
#include <iostream> // for cout
using namespace std;
int area(int length, int width){
if(length<=0 || width<=0){
throw runtime_error("Non positive area length="+to_string(length)+" width="+to_string(width));
}
return length*width;
}
int framed_area(int x, int y){
return area(x-2,y-2);
}
int main() {
int x=-1;
int y=2;
int z=4;
try{
int area1=area(x,y);
int area2=framed_area(1,z);
int area3=framed_area(y,z);
double ratio=double(area1)/area3;// double division!
}
catch(runtime_error & e){
cout<<e.what();
}
return 0;
}
Someone uses cerr instead of cout to report an error.
void f(int x){ //f:global, x: local
int z=x+7; //z:local
}
void g(int x){ //g: global, x: local
int f=x+2; //f: local
return 2*f;
}
Make a max and abs(absolute value) function.
int max(int a, int b);
int abs(int a);
$$abs(x)=|x|$$
class Hello{
private:
vector<int> v; // v: class scope
public:
int largest()// As absolute values
{
int r=0; //r:local
for(int i=0;i<v.size();i++){ //i: for-statment scope
r=max(r, abs(v[i]));
}
return r;
}
// No r here.
};
//No v here
int x;// global x
int y;// global y
int f(){
int x; //x: local, hide global x
x=7;
{
int x=y;//local x, hide the previous local x
++x;
}
++x;
return x;
}
void f(){
void g(){
}
}
Nested function is not legal in c++ (except lambda).
double f(int a, int b);
double f(int a, int b){return a*b;}
void g(int a);
void
means "does not return a value".
Here name a,b
are not important when you implement.
my_find
searches for s in vs starting at hint
int my_find( vector<string> vs, string s, int hint){
if(hint < 0|| hint > vs.size()) hint=0;
for(int i=hint;i<vs.size();++i)
if(vs[i]==0) return i;
if(hint > 0){ //Check before hint.
for(int i=hint;i vs.size();++i)
if(vs[i]==0) return i;
}
return -1; //Not found.
}
If you just do not want to use a hint, we leave 3rd argument as unnamed.
int my_find( vector<string> vs, string s, int){
for(int i=-;i<vs.size();++i)
if(vs[i]==0) return i;
return -1; //Not found.
}
vector<double> v {1,2,3,4,5};
print(v);
// (1,2,3,4,5)
void print(const vector<double> & v)
What is benefit here?
Make a swap function which swaps two int values.
int a=2, b=3;
swap(a,b);
//a=3, b=2