132 votos

MIN y MAX en C

¿Donde son MIN y MAX definidos en C, si en todos?

¿Cuál es la mejor manera de implementar estos, como genéricamente y tipo de seguro como sea posible. (Compilador extensiones/builtins para los compiladores preferidos.)

179voto

David Titarenco Puntos 17148

¿Dónde están MIN y MAX se define en C, si a todos?

Ellos no están.

¿Cuál es la mejor forma de implementar estos, de forma genérica y tipo de seguro como sea posible (compilador extensiones/builtins de los principales compiladores de preferencia).

Como funciones. Yo no uso macros como #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)), especialmente si usted planea implementar el código. Escribir su propia, usar algo como estándar fmax o fmin, o solución de la macro utilizando GCC typeof (se obtiene typesafety de bonificación):

 #define max(a,b) \
   ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
     _a > _b ? _a : _b; })

Todo el mundo dice : "oh, yo sé acerca de la doble evaluación, no hay problema" y un par de meses en el camino, tendrás la depuración de las más tontas de problemas por horas en extremo.

Edit: nota : el uso de __typeof__ en lugar de typeof:

Si usted está escribiendo un archivo de cabecera que debe trabajar cuando se incluye en la norma ISO C programas, escribir __typeof__ lugar de typeof.

52voto

Mikel Puntos 10000

También dispone en la libc de GNU (Linux) y FreeBSD versiones de sys/parm.h, y tiene la definición proporcionada por dreamlax.


En Debian:

$ uname -sr
Linux 2.6.11

$ cat /etc/debian_version
5.0.2

$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

$ head -n 2 /usr/include/sys/param.h | grep GNU
This file is part of the GNU C Library.

En FreeBSD:

$ uname -sr
FreeBSD 5.5-STABLE

$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

La fuente de los repositorios están aquí:

32voto

dan04 Puntos 33306

Hay un std::min y std::max en C++, pero que yo sepa, no hay ningún equivalente en la biblioteca estándar de C. Se les pueden definir usted mismo con macros como

#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))

Pero esto causa problemas si escribes algo como MAX(++a, ++b) .

10voto

dreamlax Puntos 47152

No creo que ellos se han estandarizado las macros. Hay estandarizados de las funciones de punto flotante ya, fmax y fmin (y fmaxf para la flota, y fmaxl para los de largo dobles).

Usted puede aplicar, ya que las macros como el tiempo que son conscientes de los problemas de efectos secundarios/doble-evaluación.

#define MAX(a,b) ((a) > (b) ? a : b)
#define MIN(a,b) ((a) < (b) ? a : b)

En la mayoría de los casos, puede dejar que el compilador para determinar lo que estamos tratando de hacer y optimizar de la mejor manera que puede. Mientras esto causa problemas cuando se utiliza como MAX(i++, j++), dudo que hay mucha necesidad en la comprobación de la máxima de incrementa los valores de una sola vez. Incremento en primer lugar, a continuación, comprobar.

9voto

Matt Joiner Puntos 29194

Escribí esta versión que funciona para MSVC, GCC, C y C++.

#if defined(__cplusplus) && !defined(__GNUC__)
#   include <algorithm>
#   define MIN std::min
#   define MAX std::max
//#   define TMIN(T, a, b) std::min<T>(a, b)
//#   define TMAX(T, a, b) std::max<T>(a, b)
#else
#       define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \
                ({ \
                        decltype(lexpr) lvar = (lexpr); \
                        decltype(rexpr) rvar = (rexpr); \
                        lvar binoper rvar ? lvar : rvar; \
                })
#       define _CHOOSE_VAR2(prefix, unique) prefix##unique
#       define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique)
#       define _CHOOSE(binoper, lexpr, rexpr) \
                _CHOOSE2( \
                        binoper, \
                        lexpr, _CHOOSE_VAR(_left, __COUNTER__), \
                        rexpr, _CHOOSE_VAR(_right, __COUNTER__) \
                )
#       define MIN(a, b) _CHOOSE(<, a, b)
#       define MAX(a, b) _CHOOSE(>, a, b)
#endif

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X