2010-11-19 6 views
27

¿Pueden las estructuras contener funciones?Funciones en la estructura

+0

Pueden, pero no hay una ventaja inherente en la programación habitual de C. En C, todas las funciones se encuentran en el espacio global de todos modos, por lo que no obtendrá información ocultando las mismas en una función. El ejemplo de paxdiablo es una forma de organizar las funciones en una estructura, pero debe ver que tiene que eliminar la referencia de cada una de ellas para usarla. La estructura organizativa estándar de C es el archivo, con las interfaces en el encabezado y las implementaciones en el origen. Así es como se hace libc y así es como casi todas las bibliotecas C están listas. –

Respuesta

33

No, pero pueden contener función punteros.

Si su intención es hacer algún tipo de polimorfismo en C, entonces sí, se puede hacer:

typedef struct { 
    int (*open)(void *self, char *fspec); 
    int (*close)(void *self); 
    int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz); 
    int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz); 
    // And data goes here. 
} tCommClass; 

El typedef anterior era para una estructura que creé para una biblioteca general de comunicaciones de propósito. Con el fin de inicializar la variable, sería:

tCommClass *makeCommTcp (void) { 
    tCommClass *comm = malloc (sizeof (tCommClass)); 
    if (comm != NULL) { 
     comm->open = &tcpOpen; 
     comm->close = &tcpOpen; 
     comm->read = &tcpOpen; 
     comm->write = &tcpWrite; 
    } 
    return comm; 
} 

tCommClass *makeCommSna (void) { 
    tCommClass *comm = malloc (sizeof (tCommClass)); 
    if (comm != NULL) { 
     comm->open = &snaOpen; 
     comm->close = &snaOpen; 
     comm->read = &snaOpen; 
     comm->write = &snaWrite; 
    } 
    return comm; 
} 

tCommClass *commTcp = makeCommTcp(); 
tCommClass *commSna = makeCommSna(); 

Luego, para llamar a las funciones, algo así como:

// Pass commTcp as first params so we have a self/this variable 
// for accessing other functions and data area of object. 
int stat = (commTcp->open)(commTcp, "bigiron.box.com:5000"); 

De esta manera, un solo tipo podría ser utilizado para TCP, SNA, RS232 o incluso pidgeons portadores, con exactamente la misma interfaz.

+1

¿Esta es también una de las estructuras y clases b/w de diferencia? Porque a partir de ahora sé que la diferencia es que struct tiene público por defecto y la clase es privada por defecto – JoshMachine

+0

@Josh, creo que tienes razón acerca de que público/privado es la única diferencia entre struct/union en C++. Esta pregunta fue sobre C. Sospecho que las funciones _se_ están permitidas en C++ ya que 'struct xyz {int fn (void); } a; 'funcionó bien en g ++. – paxdiablo

+0

Oh, claro, no vi la etiqueta C. +1 para despejar la duda! – JoshMachine

5

editar aclarado ambigüedad con el uso de los datos de los tipos de datos "

No en C. struct tipos sólo pueden contener.

De la sección 6.7.2.1 del estándar ISO C99.

Una estructura o unión no contendrán un miembro con incompleta o función de tipo (por lo tanto, una estructura no deberá contener una instancia de sí mismo, pero puede contener un puntero a una instancia de sí mismo), excepto que el último miembro de una estructura con más de un miembro con nombre puede tener un tipo de matriz incompleto; dicha estructura (y cualquier unión que contenga, posiblemente recursivamente, un miembro que sea tal estructura) no deberá ser un miembro de una estructura o un elemento de una matriz.

+0

+1 para señalar el estándar – Jay

+0

"contener tipos de datos" es peligrosamente ambiguo (al menos para un usuario de C++, donde pueden declarar tipos) - "contener datos" parece más preciso. Todo quedó claro en el estándar, aunque ... :-). –

0

En C, las estructuras pueden contener valores de datos y no los punteros de función. No permitido en C. pero el siguiente funciona literalmente bien cuando se lo marca con gcc.

enter code here 

#include <stdio.h> 

struct st_func_ptr{ 
     int data; 
     int (*callback)(); 
}; 

int cb(){ 
     printf(" Inside the call back \n"); 
     return 0; 
} 

int main() { 
     struct st_func_ptr sfp = {10, cb}; 

     printf("return value = %d \n",sfp.callback()); 

     printf(" Inside main\n"); 
     return 0; 
} 

Por lo tanto, estoy confundido ...

+1

¿Quién dice que no puede tener punteros de función en una estructura en 'C'? – detly

+2

Sí, parece que estás mezclando cosas. Los punteros de función están permitidos, las funciones en sí mismas no. –

+0

devolución de llamada es un puntero a función con 0 parámetros que devuelven int. C le permitirá asignar a la devolución de llamada por referencia cualquier función que coincida con que funcione la firma. El uso de la lista de inicialización es lo nuevo y especial aquí. La sentencia printf es válida C, pero no es un buen estilo. Es confuso en cuanto a las intenciones y si lo viste muy lejos de la definición de estructura, podrías quedarte perplejo de lo que era y tener que ir a cazar. –

0

Está bien. En el código del kernel de Linux, encontrará que muchas estructuras contienen funciones. tales como:

/* 


* The type of device, "struct device" is embedded in. A class 
* or bus can contain devices of different types 
* like "partitions" and "disks", "mouse" and "event". 
* This identifies the device type and carries type-specific 
* information, equivalent to the kobj_type of a kobject. 
* If "name" is specified, the uevent will contain it in 
* the DEVTYPE variable. 
*/ 
struct device_type { 
     const char *name; 
     struct attribute_group **groups; 
     int (*uevent)(struct device *dev, struct kobj_uevent_env *env); 
     void (*release)(struct device *dev); 
     int (*suspend)(struct device * dev, pm_message_t state); 
     int (*resume)(struct device * dev); 
}; 
+0

Bueno, son indicadores de las funciones, más o menos lo mismo, excepto que requiere un cierto esfuerzo inicializarlos, existe el riesgo de intentar usarlos cuando son NULOS o no válidos, y se pueden cambiar en tiempo de ejecución. .. –

0

Sí, es posible declarar una función y no se permite la definición de función y que debe ser el puntero de función.

Se basa en la estructura etiquetada C99.

Lokesh V

0

Se puede, pero no hay ninguna ventaja inherente a la programación habitual C.

En C, todas las funciones se encuentran en el espacio global de todos modos, por lo que no se oculta la información metiéndolas en una función.El ejemplo de paxdiablo es una forma de organizar las funciones en una estructura, pero debe ver que tiene que eliminar la referencia de cada una de ellas para usarla.

La estructura organizativa estándar de C es el archivo, con las interfaces en el encabezado y las implementaciones en la fuente.

Así es como se hace libc y así es como casi todas las bibliotecas C están listas.

Los compiladores Moder C le permiten definir e implementar funciones en el mismo archivo fuente, e incluso implementar funciones estáticas en archivos de encabezado. Desafortunadamente, esto genera cierta confusión en cuanto a qué es lo que pasa, y usted puede obtener soluciones inusuales como funciones de integración en estructuras, programas de fuente única sin encabezados, etc. Pierde la ventaja de separar la interfaz de la implementación de esa manera.

0

No You Can not. Structure no puede contener una declaración de una función, pero pueden contener la definición de una función. La estructura solo puede contener tipos de datos, punteros, indicadores para diferentes funciones. Puede hacer un puntero a una función y luego acceder desde la estructura.

#include<iostream> 
#include<cstring> 
using namespace std; 

struct full_name 
{ 
    char *fname; 
    char *lname; 
    void (*show)(char *,char*); 
}; 

void show(char *a1,char * a2) 
{ 
    cout<<a1<<"-"<<a2<<endl; 
} 

int main() 
{ 

struct full_name loki; 
loki.fname="Mohit"; 
loki.lname="Dabas"; 
loki.show=show; 
loki.show(loki.fname,loki.lname); 


return 0; 

} 
Cuestiones relacionadas