The following two codes are doing the same thing:
It calculates probabilities of the sum of faces when they rolled together. For example, when we rolled two dices, the sum of the faces could be in the range of 2 and 12, and then calculate the probabilities of the sum f faces for each trial.
C version:
#include <stdio.h> #include <stdlib.h> #include <time.h> #define FACES 6 #define NDICE 3 #define OUTCOME_ARRAY_SIZE (FACES * NDICE + 1) #define RANDOM_FACE (rand() % FACES + 1) int main() { int i, j, index, trials; int outcome[OUTCOME_ARRAY_SIZE] = {0}; srand(clock()); printf("\nEnter the number of trials\n"); scanf("%d", &trials); for(i = 0; i < trials; ++i) { index = 0; for(j = 0; j < NDICE; ++j) { index += RANDOM_FACE; } outcome[index]++; } for(i = NDICE; i < OUTCOME_ARRAY_SIZE; ++i) printf("sum of faces = %d probability = %lf\n", i, (double)(outcome[i])/trials); return 0; }
C++ version:
#include <iostream> #include <cstdlib> #include <ctime> using namespace std; const int FACES = 6; const int NDICE = 3; const int OUTCOME_ARRAY_SIZE = FACES*NDICE + 1; inline int randomFace() { return rand() % FACES + 1; } int main() { srand(clock()); cout << "\nEnter the number of trials\n"; int trials; cin >> trials; int* outcome = new int[OUTCOME_ARRAY_SIZE]; for(int i = 0; i < trials; ++i) { int index = 0; for(int j = 0; j < NDICE; ++j) { index += randomFace(); } outcome[index]++; } for(int i = NDICE; i < OUTCOME_ARRAY_SIZE; ++i) cout << "sum of faces = " << i << " probability = " << static_cast<double>(outcome[i])/trials << endl; delete outcome; return 0; }
These two codes illustrate the basic difference between C and C++ codes:
In C, by default, a parameter is passed by value. When the parameter is passed, the function copies the value and use the value locally. So, even though we can modified the value within the function, it only changes the value of the copy. Therefore, in C, we pass the address, and dereference the value and modifies the value that pointed by the pointer.
C version:
#include <stdio.h> void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } void swap_double(double *a, double *b) { double temp = *a; *a = *b; *b = temp; } int main() { int i1= 1, i2 = 2; double d1 = 1.1, d2 = 2.2; printf("i1=%d i2=%d\n", i1, i2); swap(&i1, &i2); printf("i1=%d i2=%d\n", i1, i2); printf("d1=%lf d2=%lf\n", d1, d2); swap_double(&d1, &d2); printf("d1=%lf d2=%lf\n", d1, d2); return 0; }
C++ version:
#include <iostream> using namespace std; void swap(int &a, int &b) { int temp = a; a = b; b = temp; } void swap(double &a, double &b) { double temp = a; a = b; b = temp; } int main() { int i1= 1, i2 = 2; double d1 = 1.1, d2 = 2.2; cout << "i1=" << i1 << " i2=" << i2 << endl; swap(i1, i2); cout << "i1=" << i1 << " i2=" << i2 << endl; cout << "d1=" << d1 << " d2=" << d2 << endl; swap(d1, d2); cout << "d1=" << d1 << " d2=" << d2 << endl; return 0; }
As we can see from the two codes, C++ version is much simpler:
Simply put, generic in C++ means using templates.
We can easily convert the C++ code for swap() using meta variable T, then it will be substituted by the proper data type such as int or double during compile time. The compiler uses a routine that matches the signature to infer what the code should use:
template <typename T> void swap(T &a, T &b) { T temp = a; a = b; b = temp; }