C++ is an object-oriented programming language that is widely supported on supercomputing platforms. Major portions of the LFM are written in C++ to take advantage of a library (P++) used to distribute LFM data for parallel computing.
This tutorial is designed to quickly bring Fortran developers up to speed on C++. It should prepare you to start working with A++ & P++ and introduce you to the coding style of the LFM.
control.C: An exceedingly fast tour through C++ Control Structures.
#include <iostream>
using namespace std;
void forLoop()
{
int array[5] = {1,2,3,4,5};
cout << +FUNCTION+ << endl;
for (int i=0; i < 10; i++){
cout << array[i] << "\t";
}
cout << endl;
}
void whileLoop()
{
int accountBalance = 100;
cout << +FUNCTION+ << endl;
int iterations = 0;
while (accountBalance > 0){
// Buy some stuff
accountBalance = accountBalance - 12;
iterations++;
}
cout << "It took " << iterations << " iterations to spend everything\!" << endl;
}
void conditionals()
{
cout << +FUNCTION+ << " (ie. \"if\", \"else\")" << endl;
float a;
cout << "Enter a number" << endl;
cin >> a;
if (a == 42){
cout << "Type this into Google: \"answer to life, the universe and everything\"." << endl;
}
else if (a != 42){
cout << "a is not 42." << endl;
}
else {
cout << "catch-all else statement." << endl;
}
}
int main ()
{
cout << "Select a control structure:" << endl;
cout << "1. for" << endl
<< "2. while" << endl
<< "3. if" << endl;
int controlSelection = 0;
cin >> controlSelection;
switch (controlSelection) {
case 1:
forLoop();
break;
case 2:
whileLoop();
break;
case 3:
conditionals();
default:
cout << "Did not understand control selection. Try again." << endl;
}
return 0;
}
functions.C; Learn about overloading, recurssion, inline, etc. at this C++ tutorial.
#include <iostream>
using namespace std;
void duplicate (int& a, int& b, int& c)
{
a*=2;
b*=2;
c*=2;
}
int main ()
{
int x=1, y=3, z=7;
cout << "Before duplication:" << endl;
cout << "x=" << x << ", y=" << y << ", z=" << z;
duplicate (x, y, z);
cout << "After duplication:" << endl;
cout << "x=" << x << ", y=" << y << ", z=" << z;
return 0;
}
arrays.C: Arrays as function parameters.
#include <iostream>
using namespace std;
void printarray (int arg[], int length) {
for (int n=0; n<length; n++)
cout << arg[n] << " ";
cout << "\n";
}
int main ()
{
int firstarray[] = {5, 10, 15};
int secondarray[] = {2, 4, 6, 8, 10};
printarray (firstarray,3);
printarray (secondarray,5);
return 0;
}
Implement a function to compute trapezoidal integration for
f(x) = sin(x)
The function prototype should look like:
float trapInt(int a, int b, int n);
Demonstrate that it works properly:
trapInt(0, 3.141592, 100)
should return a number close to 2.0.
This section was inspired by the cplusplus.com tutorial on pointers and Practical C++ Programming
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
float number = 42;
// "&" is the reference operator
float *number_ptr = &number;
cout << "Number = " << number << endl
<< "Number_ptr = " << number_ptr << endl
<< "*Number_ptr = " << *number_ptr << endl
<< "----" << endl;
// "*" is the dereference operator.
*number_ptr = 10;
cout << "Number = " << number << endl
<< "Number_ptr = " << number_ptr << endl
<< "*Number_ptr = " << *number_ptr << endl;
return 0;
}
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
float even[4] = {2.0, 4.0, 6.0, 8.0};
// Note I do not have a dereferencing operator!
float *even_ptr = even;
for (int i=0; i < 4; i++){
cout << "even[__ i __]: " << even[i] << "\t"
<< "even_ptr[__ i __]: " << even_ptr[i] << "\t"
<< "*even_ptr + " << i << ": " << *(even_ptr+i) << endl;
}
return 0;
}
What happens when we need to change the size of an array in a program?
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
cout << "Dynamically allocating an array of 2 elements" << endl;
int *array_ptr = new int[2];
array_ptr[0] = 1;
array_ptr[1] = 2;
cout << "Array contents:" << endl;
for (int i=0; i < 4; i++){
cout << array_ptr[i] << "\t";
}
cout << endl;
cout << "On second thought, we need an array of 4 elements. Deallocating memory..." << endl;
cout << "Array contents:" << endl;
for (int i=0; i < 4; i++){
cout << array_ptr[i] << "\t";
}
cout << endl;
cout << "... allocating a bigger array!" << endl;
delete [] array_ptr;
array_ptr = NULL;
array_ptr = new int[4];
array_ptr[0] = 1;
array_ptr[1] = 2;
array_ptr[2] = 3;
array_ptr[3] = 4;
cout << "Array contents:" << endl;
for (int i=0; i < 4; i++){
cout << array_ptr[i] << "\t";
}
cout << endl;
delete [] array_ptr;
return 0;
}
Warning: It's extremely easy to shoot yourself in the foot with dynamically-allocated memory!
Find more on the CPlusPlus.com tutorial on Dynamic Memory
Row vs column ordering (compare to Fortran)?
Write a program that asks the user to input the maximum number of intervals to use when computing Trapezoid integration for sin between 0 and pi. Store the results of trapezoid integration in an array for all values of n, n-1, n-2, ..., 1 intervals. Print the contents of this array to the user.
Definitions:
Data and functions can be
Learn more definitions at the cplusplus.com Classes I tutorial
#include <iostream>
#include <math.h>
class point
{
public:
// Constructor
point(const float &a, const float &b, const float &c) { x=a; y=b; z=c;};
float x,y,z;
};
float distance(const point &p1, const point &p2)
{
return sqrt( fabs(pow(p2.x - p1.x, 2) +
pow(p2.y - p1.y, 2) +
pow(p2.z - p1.z, 2) ));
}
int main(int argc, char **argv)
{
point origin(0, 0, 0);
point myPoint(2, 2, 2);
std::cout << "The distance is " << distance(myPoint, origin) << std::endl;
return 0;
}
Learn more at the Cplusplus.com "Classes 2" Tutorial.
point point::operator *(const float &scalar)
{
return point(x*scalar, y*scalar, z*scalar);
}
...
std::cout << "myPoint is " << myPoint.x << " " << myPoint.y << " " << myPoint.z << std::endl;
point p5 = myPoint*5;
std::cout << "myPoint*5 is " << p5.x << " " << p5.y << " " << P5.z << std::endl;
Advanced topic that does not appear to be extensively used by A++ & P++. However, the LFM has a few examples of derived classes:
Implement a vector class that can compute the dot product and cross product of two vectors.
No cheating!
#include <math.h>
#include <iostream>
using namespace std;
float trapInt(float a, float b, int n)
{
float dx = (b-a) / float(n) ;
float result = 0.0;
for (int i=0; i < n-1; i++){
float x0 = a+dx*float(i);
float x1 = a+dx*float(i+1);
result += dx*(sin(x1)+sin(x0));
}
return (result / 2.0);
}
int main(int argc, char **arv)
{
cout << "The Area is " << trapInt(0.0, 3.141592, 100) << endl;
return 0;
}
#include <iostream>
#include <math.h>
using namespace std;
class Vector
{
public:
float v0, v1, v2;
Vector(const float &v0, const float &v1, const float &v2);
float length() const;
Vector direction() const;
float dot(const Vector &inVector);
};
Vector::Vector(const float &v0, const float &v1, const float &v2)
{
this->v0 = v0;
this->v1 = v1;
this->v2 = v2;
}
float Vector::length() const
{
return sqrt( v0*v0 + v1*v1 + v2*v2 );
}
Vector Vector::direction() const
{
float vecLength = this->length();
float ihat = v0 / vecLength;
float jhat = v1 / vecLength;
float khat = v2 / vecLength;
return Vector(ihat, jhat, khat);
}
float Vector::dot(const Vector &inVector)
{
return ( inVector.v0 * v0 +
inVector.v1 * v1 +
inVector.v2 * v2 );
}
int main()
{
Vector test(2.0, 0.0, 0.0);
cout << "The vector is: " << test.v0 << " " << test.v1 << " " << test.v2 << endl;
cout << "Its length is: " << test.length() << endl;
Vector direction(1,1,1);
direction = test.direction();
cout << "Vector direction is " << direction.v0 << " " << direction.v1 << " " << direction.v2 << endl;
cout << "dot product with unit vector is " << test.dot(direction) << endl;
return 0;
}
Alternative implementation:
#include <iostream>
#include <math.h>
using namespace std;
class myVector
{
public:
// Constructor
myVector(const float &a, const float &b, const float &c) { x=a; y=b; z=c;};
float dot(const myVector &v);
myVector cross(const myVector &v);
float x,y,z;
};
float myVector::dot(const myVector &v)
{
return (x*v.x + y*v.y + z*v.z);
}
myVector myVector::cross(const myVector &v)
{
return myVector(y*v.z - v.y*z,
x*v.z - v.x*z,
x*v.y - v.y*x);
}
ostream &operator << (ostream &outs, const myVector &v)
{
outs << v.x << ", " << v.y << ", " << v.z << endl;
}
int main(int argc, char **argv)
{
myVector jhat(0, 1, 0);
myVector khat(0, 0, 1);
std::cout << "jxk = " << jhat.cross(khat) << std::endl;
std::cout << "j.k = " << jhat.dot(khat) << std::endl;
return 0;
}