Reputation: 4687
I just found out this code from a tutorial for matrix addition in c++ by reading the values from a file-
I wanted to ask what does #define does here? What is so special in it? And how is it different from separately declaring M and N as int or char in main?
code
#include <iostream>
#include <fstream>
using namespace std;
#define M 4
#define N 5
void matrixSum (int P[M][N], int Q[M][N], int R[M][N]);
void matrixSum (int P[M][N], int Q[M][N], int R[M][N]) {
for (int i=0; i<M; i++) // compute C[][]
for (int j=0; j<N; j++)
R[i][j] = P[i][j] + Q[i][j];
}
int main () {
ifstream f;
int A[M][N];
int B[M][N];
int C[M][N];
f.open("values"); // open file
for (int i=0; i<M; i++) // read A[][]
for (int j=0; j<N; j++)
f >> A[i][j];
for (int i=0; i<M; i++) // read B[][]
for (int j=0; j<N; j++)
f >> B[i][j];
matrixSum (A,B,C); // call to function
for (int i=0; i<M; i++) { // print C[][]
for (int j=0; j<N; j++)
cout << C[i][j] << " ";
cout << endl;
}
f.close();
}
Upvotes: 7
Views: 17960
Reputation: 19995
It is a preprocessor directive of the form
#define identifier token-sequence
The preprocessor runs before the compiler transforms your code for use in the compiler. The order is as follows:
So with the #define
you can have character manipulation (macro substitution).
Whenever M is seen 4 will be substituted.
The compiler will then see
void matrixSum (int P[4][5], int Q[4][5], int R[4][5]); // ..etc
The other way would be to use the const qualifier on a global variable.
In C, it would be
// Some fileA.c
const int M; // initialize
// Some fileB.c
const int M = 4; // defined
So I would say try to avoid when possible because macros are a form of text substitution, they do not obey scope and type rules.
Upvotes: 0
Reputation: 361252
As a side note, a more general solution would be this, using function template:
template<size_t M, size_t N>
void matrixSum (int (&P)[M][N], int (&Q)[M][N], int (&R)[M][N]);
template<size_t M, size_t N>
void matrixSum (int (&P)[M][N], int (&Q)[M][N], int (&R)[M][N])
{
for (int i=0; i<M; i++)
for (int j=0; j<N; j++)
R[i][j] = P[i][j] + Q[i][j];
}
int main ()
{
const int M = 4; //now in main!
const int N = 5;
ifstream f;
int A[M][N];
int B[M][N];
int C[M][N];
//same as before
}
I think this is better than using #define
, because using const
or enum
helps in debugging. A more detailed explanation is here:
C++ - enum vs. const vs. #define
Upvotes: 3
Reputation: 65599
#define and other commands beginning with # are commands run by the C preprocessor before compilation begins.
Specifically, #define tells the preprocessor that everywhere the token M occurs, the text "4" should be used in its place. You are correct in that using a normal variable definition is the preferred way of accomplishing the same functionality. The reason being the variable definition is processed by the compiler with the rest of the code and #defines involve a step before compilation. More complex #defines can lead to very difficult and confusing compiler errors. If something is wrong in the #define, the line that uses the #define lists the error (since the code was copy pasted there before compilation) not the line with the #define. Nevertheless, you'll see a lot of old C style code that defines constants with #defines.
Upvotes: 3
Reputation: 20314
The thought of const int M = 4;
and const int N = 5;
made the author shake in his boots because of the whopping 8 bytes of memory, so he used #define
instead.
Upvotes: 7