7

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();
}
peterh
  • 11,875
  • 18
  • 85
  • 108
Frustrated Coder
  • 4,417
  • 10
  • 31
  • 34
  • 2
    In C++ you would typically use something like `const int M = 4;` and `const int N = 5;` instead of using `#define`s because macros do not respect scope. While the code you posted is valid C++, it does not resemble modern C++. – In silico Mar 12 '11 at 20:12
  • Yeah, I am currently an undergraduate in 1st year so trying to learn as much as I can! – Frustrated Coder Mar 12 '11 at 20:21
  • Don't worry, it's good that you're asking questions about this. I assume you already have a C++ textbook that you're studying from. Otherwise, if you would like additional material, [we can recommend you some C++ books](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – In silico Mar 12 '11 at 20:26

4 Answers4

7

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.

Marlon
  • 19,924
  • 12
  • 70
  • 101
  • 1
    the compiler could be smart enough to not even use memory for these consts – Doug T. Mar 12 '11 at 20:17
  • 2
    Someone should tell the author that C++ compilers nowadays [can fold constants](http://en.wikipedia.org/wiki/Constant_folding). – In silico Mar 12 '11 at 20:17
  • This looks like C++ written by someone with lots of experience with C. There is no reason to declare all variables at the start of the function either. I suspect all of this is about habit, not trying to save memory. – André Caron Mar 12 '11 at 20:20
3

#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.

Doug T.
  • 64,223
  • 27
  • 138
  • 202
3

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

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
0

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:

  • Trigraph replacement
  • Line splicing
  • Macro definition and expansion

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.

phwd
  • 19,975
  • 5
  • 50
  • 78