Tengo que declarar un array de punteros a funciones como:

extern void function1(void);
extern void function2(void);
...

void (*MESSAGE_HANDLERS[])(void) = {
   function1,
   function2,
   ...
};

Sin embargo, quiero que el la matriz para ser declarado como constantes, tanto de los datos en la matriz y el puntero a los datos. Por desgracia, no recuerdo dónde colocar la const de la palabra clave(s).

Estoy suponiendo que el actual puntero, MESSAGE_HANDLERS en este caso, ya es constante porque se declara como una matriz. En el otherhand, no los punteros de función dentro de la matriz de cambios en tiempo de ejecución si se declara tal como se muestra?

5 Comentarios

  1. 57

    No es una técnica para recordar cómo construir este tipo. Primero intente leer punteros a partir de su nombre y se lee de derecha a izquierda.

    Cómo declarar que cosas sin ayuda?

    Matrices

    T t[5];

    es un matriz de 5 T. Para hacer T un tipo de función, se escribe el tipo de devolución a la izquierda, y los parámetros a la derecha:

    void t[5](void);

    sería ser un matriz de 5 funciones devuelven void y que no toman parámetros. Pero las funciones en sí misma no puede ser metido en matrices! No son objetos. Sólo los punteros a los mismos.

    Lo que acerca de

    void * t[5](void);

    Que aún está equivocado, ya que acaba de cambiar el tipo de devolución a ser un puntero a void. Usted tiene que usar paréntesis:

    void (*t[5])(void);

    y esto realmente va a funcionar. t es una matriz de 5 punteros a funciones que devuelven void y que no toman parámetros.

    Genial! ¿Qué acerca de una matriz de punteros a arras? Que es muy similar. El tipo de elemento aparece en la izquierda, y la dimensión de la derecha. De nuevo, los paréntesis son necesarios porque de lo contrario la matriz se convertiría en una matriz multidimensional de punteros de entero:

    int (*t[5])[3];

    Que es! Un matriz de 5 punteros a arrays de 3 int.

    Lo que acerca de las funciones?

    Lo que hemos aprendido es cierto acerca de las funciones. Vamos a declarar una función que recibe un int y devuelve un puntero a otra función no toma ningún parámetro y devuelve void:

    void (*f(int))(void);

    necesitamos paréntesis de nuevo por la misma razón que el anterior. Ahora pudiéramos llamar, y llamar a la función devuelto señaló de nuevo.

    f(10)();

    Devolver un puntero a función que devuelve otro puntero a función

    Lo que acerca de esto?

    f(10)(true)(3.4);

    ? En otras palabras, ¿cómo sería un función de tomar int devuelve un puntero a una función que recibe bool devolver un puntero a una función que recibe doble y devuelve void sería así? La respuesta es que acaba de nido de ellos:

    void (*(*f(int))(bool))(double);

    Usted podría hacer así un sinfín de veces. De hecho, usted también puede devolver un puntero a una matriz de la misma manera que un puntero a una función:

    int (*(*f(int))(bool))[3];

    Este es un función de tomar int devuelve un puntero a una función que recibe bool devolver un puntero a una matriz de 3 int

    , ¿Qué tiene que ver con la const?

    Ahora que el explicado anteriormente cómo construir complexer los tipos de los tipos fundamentales, usted puede poner const de los lugares en donde usted ahora sabe a donde pertenecen. Simplemente tenga en cuenta:

    T c * c * c ... * c name;

    La T es el tipo básico que nos terminan apuntando en la final. El c significa ya sea constante o no constante. Por ejemplo

    int const * const * name;

    declarará nombre, para el tipo de puntero a un puntero constante a una constante int. Usted puede cambiar name, pero no puede cambiar *name, que sería de tipo

    int const * const

    y ni **name, que sería de tipo

    int const

    Vamos a aplicar esto a un puntero a función de arriba:

    void (* const t[5])(void);

    Esto en realidad podría declarar la matriz para contener constante de los punteros. Así que después de crear e inicializar) la matriz, la punteros son const, porque el const apareció después de la estrella. Tenga en cuenta que no podemos poner un const antes de que la estrella en este caso, ya que no hay punteros a constantes funciones. Funciones simplemente no puede ser constante ya que no tendría sentido. Así que el siguiente no es válido:

    void (const * t[5])(void);

    Conclusión

    El C++ y C forma de declarar funciones y matrices en realidad en realidad es un poco confuso. Usted tiene que conseguir su cabeza alrededor de la primera, pero si usted entiende esto, usted puede escribir muy compacto declaraciones de función de usarlo.

    • lo siento compañero. inicialmente, tenía const, pero de alguna manera me lo quitaron. ahora de nuevo, me la extendió a explicar en más detalle.
    • Gracias! Esta es una gran explicación.
  2. 15

    cdecl dice:

    cdecl> explain void (* const foo[])(void)
    declare foo as array of const pointer to function (void) returning void

    Es lo que usted necesita?

    • Sí, eso es exactamente lo que necesitaba. Yo no era consciente de la cdecl (y c++decl) programas. Gracias por la sugerencia.
    • cdecl es excelente. Gracias por llegar en el conocimiento.
    • FYI, cdecl está ahora en línea: cdecl.org
  3. 15

    En situaciones como esta, hacer un typedef a nombre de la función de la firma, que hace que sea mucho más sencillo:

    typedef void MESSAGE_HANDLER(void);

    con que en su lugar, debería ser justo:

    MESSAGE_HANDLER * const handlers[] = { function1, function2 };

    Para obtener el contenido real de la constante de matriz.

    EDITAR: se Quitó el puntero parte de la typedef, este es realmente el mejor (en vivo y aprender).

    • No estoy seguro, pero probablemente debe colocar la palabra clave const después de MASSAGE_HANDLER. De todos modos, esta respuesta debe ser mayor, typedefs son el camino para evitar la confusión!
    • const y const T son los mismos (donde T es un identificador que los identificadores de un tipo). Tienes razón que T const se considera más coherente por muchos.
    • Tenga en cuenta que muchas personas consideran puntero typedefs a ser algo obfuscatory; no es necesario incluir el puntero en el typedef aquí, por ejemplo,typedef void Handler(void); Handler func1, func2; Handler * const handlers[] = { func1, func2 }; .
  4. 1

    Con VisualStudio 2008, me sale:

    void (* const MESSAGE_HANDLERS[])(void) = {
       NULL,
       NULL
    };
    
    int main ()
    {
        /* Gives error 
            '=' : left operand must be l-value
        */
        MESSAGE_HANDLERS = NULL;
    
        /* Gives error 
            l-value specifies const object
        */
        MESSAGE_HANDLERS[0] = NULL;
    }
  5. 1

    No estoy seguro de si esto va a funcionar en ‘C’. no funciona en ‘C++’:

    • Definir primero MESSAGE_HANDLERS como un tipo:

      typedef void (*MESSAGE_HANDLER)();

    • A continuación, utilice la definición de tipo para declarar la matriz de una constante:

      MESSAGE_HANDLER const handlers[] = {function1, function2};

    El truco está en la typedef, si usted puede hacer el mismo semánticamente en ‘C’, se debe trabajar demasiado.

    • ¿Esto no es declarar un array de punteros a const funciones?

Dejar respuesta

Please enter your comment!
Please enter your name here