2010-11-28 8 views
8

En el siguiente código:y operadora opcional en función de asignación de puntero

/* mylog.c */ 
#include <stdio.h> 
#include <stdlib.h> /* for atoi(3) */ 

int mylog10(int n) 
{ 
    int log = 0; 
    while (n > 0) 
    { 
     log++; 
     n /= 10; 
    } 
    return log; 
} 

int mylog2(int n) 
{ 
    int log = 0; 
    while (n > 0) 
    { 
     log++; 
     n >>= 1; 
    } 
    return log; 
} 

int main(int argc, const char* argv[]) 
{ 
    int (*logfunc)(int); /* function pointer */ 
    int n = 0, log; 

    if (argc > 1) 
    { 
     n = atoi(argv[1]); 
    } 

    logfunc = &mylog10; /* is unary '&' operator needed? */ 

    log = logfunc(n); 
    printf("%d\n", log); 
    return 0; 
} 

en la línea

logfunc = &mylog10; 

me he dado cuenta de que el unario & (dirección) del operador es opcional, y la el programa se compila y se ejecuta de la misma manera con o sin él (en Linux con GCC 4.2.4). ¿Por qué? ¿Es esto un problema específico del compilador, o quizás dos estándares de lenguaje diferentes aceptados por el compilador? Gracias.

+0

BTW- ¿significa esto que un puntero a la función "se comporta de la misma manera" como se comportaría una referencia a la función? – Kos

+0

@Kos: Puede parecer que se comporta de la misma manera en el nivel del código fuente, aunque la similitud es puramente superficial: la mecánica del lenguaje abstracto subyacente es bastante diferente. Sin embargo, si profundizas aún más y observas la mecánica a nivel de máquina, verás que parecen ser la misma otra vez. – AnT

Respuesta

13

Operador & es de hecho opcional cuando toma la dirección de una función en su contexto (asignándola a algo). No es específico del compilador, se sigue de la definición formal del lenguaje.

Simétricamente, el operador * es opcional al invocar la función a través de un puntero. En su ejemplo, puede invocar la función como (*logfunc)(n) o logfunc(n). Usaste el último, pero el primero también funcionaría.

14

Tiene la razón de que el & es opcional. Las funciones, como las matrices, se pueden convertir automáticamente en punteros. No es específico del compilador ni es el resultado de diferentes estándares de lenguaje. A partir de la norma, Sección 6.3.2.1, párrafo 4:

Un designador función es una expresión que tiene el tipo de función. Excepto cuando es el operando del operador sizeof o el unario operador &, un designador de función con el tipo de "función que devuelve tipo" se convierte en una expresión que tiene el tipo "puntero a función que devuelve un tipo".

+0

¿Vota por un descendente? Por qué ... –

+0

También fui votado negativamente, tengo una fuerte sospecha de que estos fueron votaciones rivales ... Aquí hay una compensación de mí –

+0

@Armen Tsirunyan: Las estadísticas de un "rival" no muestran suficientes votos hacia abajo para hacerlo el culpable. Lo que aparentemente me pone bajo sospecha :) ¡Pero no lo hice! Deben ser los votos a favor de algún troll. – AnT

7

Respondiendo en C++. Para C el mismo es

Presupuesto de estándar el C++ (4.3.1):

Un lvalue de tipo de función T puede ser convierte a un valor p de tipo “puntero a T.” El resultado es un puntero a la función.50)

Lo mismo para las matrices. (4.2.1)

Un lvalue o rvalue de tipo “array de N T” o “variedad de desconocido unido de T” se puede convertir en un valor p de tipo “puntero a T.” El resultado es un puntero al primer elemento de la matriz .

Pero, por favor, tenga en cuenta que se trata de conversiones y de ninguna manera es una función un puntero a la función o es una matriz un puntero. HTH

+0

Oh ... Supongo que uno de los puristas de C me votó negativamente ... –

5

de la norma (6.3.2.1/4):

un designador función es una expresión que tiene el tipo de función.Excepto cuando se es el operando del operador sizeof o la unario & operador, un designador función con tipo '' función de tipo regresar '' se convertido a una expresión que tiene tipo '' puntero a función que devuelve tipo ''.

Así que sí, omitiendo el & produce un puntero para funcionar de todos modos.

Cuestiones relacionadas