Using counters has some advantages in terms of logical meaning. It also shows improved robustness in some cases: there are places where the fact that counters are terminated properly is important. For example, try
\documentclass{article}
\begin{document}
\newcounter{demo}
\setcounter{demo}{10}
\newcounter{minnumber}
\setcounter{minnumber}{1}
\ifnum\value{demo}>\value{minnumber}11 correct\else oops\fi
\end{document}
versus
\documentclass{article}
\begin{document}
\newcommand*\demo{10}
\newcommand*\minnumber{1}
\ifnum\demo>\minnumber 11 correct\else oops\fi
\end{document}
This happens because a number stored in a macro can be 'partial', and so TeX will keep looking for the end of the number after the macro. This does not happen with counters, which TeX considers as 'complete'.
One thing to watch is that LaTeX counters are always set globally:
\documentclass{article}
\begin{document}
\newcounter{demo}
\begingroup
\setcounter{demo}{10}
\endgroup
\the\value{demo}
\end{document}
This effect also means that the performance (speed of execution) with counters may be better than with macros.
If you want a local value, either use a macro or use the plain TeX count register type:
\documentclass{article}
\begin{document}
\newcount\demo
\begingroup
\demo10\relax
\endgroup
\the\demo
\end{document}
(TeX count registers have a different syntax to LaTeX counters, as you can see.)
\ifnum\demo>\minnumber\relax 11 correct\else oops\fiin the second example will make things right, right? Is that what you meant with "a number stored in a macro can be 'partial'"? – Gonzalo Medina Jun 17 '11 at 02:36\relaxhere, although in some cases this may not be desirable (it will not 'disappear' in an\edef). When TeX inserts a macro, it simply replaces the macro name with the contents. So\demo 1is turned into101by TeX: TeX does not stop looking for digits just because it's expanded\demo. On the other hand, TeX does not expand counters but uses them directly as values. – Joseph Wright Jun 17 '11 at 06:12