/*****************************************************************************
 * 'main' illustrates the basic * and & operations. It gives an example of
 * a functions as parameters. C++ automatically converts function-valued
 * parameters to function pointers.
 * **************************************************************************/
#include<iostream>
#include<iomanip>
#include<stdexcept>

using std::cin; using std::cout;
using std::endl; using std::string;
using std::setw; using std::setprecision;
using std::streamsize; using std::domain_error;

float reciprocal(float x)
{
	if(x==0)
		throw domain_error(" division by zero ");
	return 1/x;
}
float square(float x)
{
	return x*x;
}
/*** Output a table of the values of f at -4, -3, -2, -1, 0, 1, 2, 3, 4 ***/
void table(float f(float))//This is automatically converted to a pointer to
			  //a function. 
			  //We could write(*f).
{
	float y;
	cout<<setw(3)<<"x"<<setw(8)<<"f(x)"<<endl;
	streamsize prec=cout.precision();
	for(float x=-4; x!=5;x++)
	{
		try
		{
			y=f(x);
			cout<<setprecision(3)<<setw(3)<<x<<setw(8)<<y<<endl;
		}
		catch (domain_error){}//suppress output for invalid x's 
	}
			
	cout<<setprecision(prec);
	return;
}
	

int main()
{
	int x=77;
	int *p;//This is a pointer to an int.
	p=&x;
	cout<<"x="<<x<<", and p is pointing to "<<*p<<endl;
	*p=88;
	cout<<"x="<<x<<", and p is pointing to "<<*p<<endl;
	table(&square);//The '&' is unnecessary.
	cout<<endl;
	table(reciprocal);// We omit the '&' here
	return 0;
}

	
