|
1592
|
Programación / Programación C/C++ / [C] Lista dinámica de funciones en C (emulando los delegados de .NET)
|
en: 20 Diciembre 2015, 01:38 am
|
Muy buenas. Pues la idea es hacer algo parecido a los delegados de C# pero con el C de toda la vida. Sobre una lista dinámica de diferentes funciones con la misma firma se puede hacer las siguientes operaciones: · Añadir funciones al final de la lista · Quitar la primera aparición de una función dada · Vaciar la lista de una tacada · Ejecutar todas las funciones de la lista de forma secuencial y con unos parámetros comunes dados en la llamada a la ejecución. En este programa se trabaja sobre una función que acepta un char* y no devuelve nada, pero se puede modificar fácilmente para trabajar con otras funciones. #include <stdio.h> #include <stdlib.h> typedef struct tdelegate { void (*func)(char*); struct tdelegate *next; } DELEGATE; int delegate_add(DELEGATE **pdelegate, void (*funcpointer)(char*)) { DELEGATE *newdelegate = malloc(sizeof(DELEGATE )); DELEGATE *aux = NULL; if(newdelegate == NULL) return 0; newdelegate->func = funcpointer; newdelegate->next = NULL; if(*pdelegate == NULL) *pdelegate = newdelegate; else { aux = *pdelegate; while(aux->next != NULL) aux = aux->next; aux->next = newdelegate; } return 1; } void delegate_exec(DELEGATE **pdelegate, char *str) { DELEGATE *actualdelegate = *pdelegate; while(actualdelegate != NULL) { actualdelegate->func(str); actualdelegate = actualdelegate->next; } } void delegate_del(DELEGATE **pdelegate, void (*funcpointer)(char*)) { DELEGATE *actualdelegate = *pdelegate; DELEGATE *aux = NULL; int found = 0; if(funcpointer == NULL || actualdelegate == NULL) return; if(actualdelegate->func == funcpointer) { aux = actualdelegate->next; actualdelegate = aux; } else { while(actualdelegate->next != NULL && !found) { if(actualdelegate->next->func == funcpointer) { found = 1; aux = actualdelegate->next->next; free(actualdelegate ->next ); actualdelegate->next = aux; } else actualdelegate = actualdelegate->next; } } } void delegate_free(DELEGATE **pdelegate) { DELEGATE *aux = NULL; if(*pdelegate == NULL) return; while(*pdelegate != NULL) { aux = (*pdelegate)->next; *pdelegate = aux; } } /* FUNCIONES DE PRUEBA */ void a(char *str) { } void b(char *str) { } void c(char *str) { } /* PROGRAMA DE PRUEBA */ int main() { DELEGATE *midelegado = NULL; delegate_add(&midelegado, &a); delegate_add(&midelegado, &b); delegate_add(&midelegado, &c); delegate_exec(&midelegado, "hola"); delegate_del(&midelegado, &b); delegate_exec(&midelegado, "adios"); delegate_free(&midelegado); midelegado = NULL; return 0; }
|
|
|
1593
|
Programación / Programación C/C++ / Re: Interpretar o compilar desde txt
|
en: 18 Diciembre 2015, 20:48 pm
|
Muy buenas. Supongo a que te refieres a que buscas algo como un intérprete de C++. Buscando un poco por internet he encontrado lo siguiente CLIN que es un intérprete de c++, en el sabor de CLAN. Si quieres algo más tradicional te puedes decantar por make, CMake, o algún IDE que usa esta tecnología. Tal vez te guste QT creator.
|
|
|
1596
|
Programación / Programación C/C++ / Re: Ayuda con una ordenacion de un array please? :P
|
en: 13 Diciembre 2015, 02:17 am
|
Muy buenas. Ahora que lo he visto, fallo mio. Siendo productoArray tu array de productos declarado como producto productoArray[pLength];
siendo pLength una constante numérica que marca el tamaño de tu array, la llamada a qsort debe ser así: qsort(productoArray , pLength , sizeof(producto ), comparar_producto );
No se si la funcion ordenarProducto debes incluirla obligatoriamente pero no te haría falta porque qsort hace todo el trabajo. Allí donde tengas ordenarProducto pones directamente qsort y tu array se debe ordenar directamente.
|
|
|
1597
|
Programación / Programación C/C++ / Re: tengo un problema conestructuras con arreglos !!!!
|
en: 12 Diciembre 2015, 22:25 pm
|
Muy buenas. #include<conio.h> // conio.h no es una libreria estandar y no funcionara en todos los compiladores. // ademas no usas ninguna de sus funciones. #include<stdio.h> #include <stdlib.h> struct matrix_x { int kick; int kick2; char nombre[10]; struct matrix_x *psiguiente; }; struct matrix_x *pprimero; struct matrix_x *pultimo; int i = 0; // Una variable global que no usas void insertar (int dato, char nombre[], int codigo) { struct matrix_x * paux; paux = (struct matrix_x *)malloc(sizeof(struct matrix_x )); if(paux == NULL) { printf("error en la memoria "); } else { paux->kick = dato; paux->kick2 = codigo; paux->nombre = nombre; // Debes los datos, no la direccion de los datos -> strncpy(paux->nombre, nombre, 10); paux->psiguiente = NULL; if (pprimero == NULL) { pprimero = paux; pultimo = paux; } else { pultimo->psiguiente = paux; pultimo = paux; } } i++; } void mostrar () { struct matrix_x *aux; aux = (struct matrix_x *)malloc(sizeof (struct matrix_x )); // Esta linea no la necesitas aux = pprimero; // pues aqui haces que aux apunte a pprimero abandonado la memoria apuntada anteriormente. Malo porque hay memoria asignada que no podras recuperar. int i = 0; // ocultas la variable i global while (aux != NULL){ printf ("\n dato___%d codigo___%d ",aux ->kick ,aux ->kick2 ); fflush(stdin ); // fflush espera un flujo de salida. Esto no funcionara en todos los compiladores o SS.OO. printf ("\n nombre %s",aux ->nombre ); fflush(stdin ); // otra vez el mal uso de fflush aux = aux->psiguiente; i++; // incrementas i local, pero no la usas } } int main() { int cx = 0; int dato, codigo; char nombre[10]; printf("Introduzca cero para continuar\n"); // while(dato != 0 && codigo != 0 && nombre != 0) { fflush(stdin ); // otra vez el mal uso de fflush printf ("dame dato_%d____",cx ); printf ("dame codigo_%d___",cx ); printf ("dame nombre _%d___",cx ); fflush(stdin ); // otra vez el mal uso de fflush scanf ("%s",&nombre [cx ] ); // varios fallos aquí -> scanf("%s", nombre); insertar(dato,nombre,codigo); cx=cx+1; // mas correcto usar ++cx. Por otra parte enganas al usuario, pues aunque insertar falle // al adquirir memoria con malloc y no introduzca el dato, incrementas cx sin que el dato // anterior se haya introducido, falseando asi el numero de datos introducidos. } mostrar(); printf ("has salido del programa"); // deberias incluir una función para liberar la memoria // que has adquirido con cada uno de los malloc en insertar. // main debe devolver un valor: el S.O. espera que devuelva 0 si el programa ha terminado con exito. }
|
|
|
1598
|
Programación / Programación C/C++ / Re: Ayuda con una ordenacion de un array please? :P
|
en: 12 Diciembre 2015, 21:23 pm
|
Muy buenas: Por lo pronto se me ocurre lo siguiente: Hacer una función que compare dos productos. int comparar_producto(const void *p1, const void *p2) { articulo *art1 = (articulo*) p1; articulo *art2 = (articulo*) p2; return strcmp(art1 ->nombre , art2 ->nombre ); }
Y finalmente usas la función qsort, de stdlib, para que te ordene ella sola el array. qsort(productoArray [], pLength , sizeof(producto ), comparar_producto );
|
|
|
1599
|
Programación / Programación C/C++ / Re: ¿Como cambiar un puntero de caracteres desde otra función?
|
en: 12 Diciembre 2015, 16:43 pm
|
Muy buenas.
Las constantes de cadena se guardan en una posición de memoria que C dedica para las constantes. Cuando asignas así una cadena a un puntero no varías una posición de memoria sino que apuntas a una zona de memoria que no va a cambiar en todo el programa.
Tu función recoge un puntero y por tanto podrías modificar en dicha función a lo que hay en esa zona de memoria que apunta el puntero, pero el puntero en sí, al ser una copia, aunque lo cambies dentro de la función, en main seguirás teniendo el valor original. Si quieres cambiarlo de la forma que quieres hacerlo pásalo con un puntero a puntero, entonces podrás cambiar hacia a donde apunta.
Una cosa a tener en cuenta: si lo haces de esta forma la cadena que dejes huérfana será un lastre: su memoria estará ocupada y el programa no la va a poder reclamar para darle otro uso, pero no podrás acceder a ella más pues habrás perdido su dirección al dar otro valor al puntero.
|
|
|
|
|
|
|