|
Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.
Mensajes - Rombus
26
« en: Viernes 17 de Octubre de 2008, 21:50 »
ah! por eso no lo habia visto jeje
uso C
al doble puntero entonces
saludos!
27
« en: Viernes 17 de Octubre de 2008, 18:28 »
ah, con eso te referias a "pasado como referencia a puntero"? nunca habia visto algo asi :O la implementacion quedaria igual? o deberia cambiarla como si fuera doble puntero, osea asi: void qDestroy(queue_t *&queue){ (*queue) = NULL; }
28
« en: Viernes 17 de Octubre de 2008, 16:35 »
ah!.. lo q dices es q deberia ser void qDestroy(queue_t **queue)
para q tenga sentido la asignacion?
29
« en: Viernes 17 de Octubre de 2008, 05:00 »
me parece perfecto q me hagas esas preguntas hay otra que capaz te interese (si es que no lo habias entendido) que es esta: (*prom)= (float)sum / (float)p;
primero q nada *prom entre parentesis para indicarle que quieres asignar el resultado del promedio en lo q tiene la direccion a la q apuntas, y no en el lugar donde dice a q direccion apuntar. Luego casteo tanto sum y p a (float). Supongamos este codigo: int a = 5, b = 2; float c; c = a / b
el resultado guardado en c seria 2.0000000, cuando lo logico hubiera sido un 2.5000000 entonces piensas "claro debo castear el resultado de a / b a float pq son enteros, el codigo quedaria asi: int a = 5, b = 2; float c; c = (float)(a / b)
y el resultado obtenido seria el mismo q antes! :O pq el resultado de dividir el entero 5 con el entero 2 es 2 casteado a float es 2.0000000 por eso debes hacer un: int a = 5, b = 2; float c; c = (float)a / (float)b
la funcion main es una funcion como cualquier otra (con algunas particularidades) osea puede ser tanto void como int, como cualquier funcion... pero si es int debe devolver algo, un int presisamente, yo lo cambie a int main (void) y el return 0 pq uso linux y en mi compilador me tira un warning, lo q no significa q de la otra forma este mal. el (void) significa que esa funcion no recibe parametros y borre la conio.h y los clrscr() pq al usar linux no tengo la conio.h de borland, y el getch() se puede reemplazar por el getchar() de stdio.h q es ANSI. una funcion solo puede devolver mediante el return un solo valor por lo que hacer lo q quieres es medio dificil. lo q puedes hacer es devolver un arreglo donde cada posicion tenga un dato, pero el arreglo tiene todos los elementos de un mismo tipo asique no podrias devolver dos ints y un float si tienes mas dudas solo pregunta >
30
« en: Viernes 17 de Octubre de 2008, 04:22 »
odio q usen la conio.h para hacer getch() y clrscr()
31
« en: Viernes 17 de Octubre de 2008, 04:15 »
oka a q te refieres con la linea 36 para q es ese puntero aumentado, bah.. para q deberia ser, pq no esta usado, al igual q el vector v fijate q en la funcion ingreso al final haces: *prom=(sum/p); sum es una variable por parametro, y cuando la pasas pasas basura pq prom no esta inicializada, y dentro de la funcion haces sum=sum+matriz1 [j]; osea a basura le dejo basura + matriz[j] XDXD
ah! ya entendi para q haces *k++, pero la forma en q lo haces es incorrecta *k++ le suma uno a el puntero k y dsp hace * y lo q quieres no es sumarle uno a la direccion donde apunta K sino al valor de dentro entonces debes hacer
otro error es el de no inicializar p en 0 p vale basura, asique basura ++ XD ten cuidado con las no inicializaciones de las variables #include<stdio.h> void ingreso(int matriz1[10][10], int matriz2[10][10], int m, int n,int sum,int *k,float *prom); int main(void){ int m1[10][10],m2[10][10],/*v[20],*/m,n,sum = 0,k=0; float prom=0; printf("ingrese el tama¤o de la matrizn"); //sum vale basura ingreso(m1,m2,m,n,sum,&k,&prom); printf("la cantidad de n no multiplos son %dn",k ); printf("el promedio es %fn",prom ); return 0; } void ingreso(int matriz1[10][10], int matriz2[10][10], int m, int n,int sum,int *k,float *prom){ int i,j,p = 0; for(i=0;i<m;i++){ for(j=0;j<n;j++){ printf("ingrese los numeros a la matrizn"); scanf("%d",&matriz1 [i ][j ]); } } for(i=0;i<m;i++){ for(j=0;j<n;j++){ if(matriz1[i][j]%7==0){ matriz2[i][j]=matriz1[i][j]; } } } for(i=0;i<m;i++){ for(j=0;j<n;j++){ if(matriz1[i][j]%7!=0){ sum +=matriz1[i][j]; (*k)++; p++; } } } (*prom)= (float)sum / (float)p; }
32
« en: Viernes 17 de Octubre de 2008, 03:56 »
tengo que devolver los 2 valores en el main principal y no por funcion osea , 1 puntero y el otro por return. estem... devolver dos valores en el main? o devolverlos de una funcion al main?
33
« en: Jueves 16 de Octubre de 2008, 20:08 »
uhhhh! el_uni muchas gracias!!! ese error me estaba limando la cabeza, lo peor de todo es que hice un stack generico (el que adjunte mas arriba) y lo tube en cuenta a eso, despues ayude a un amigo a hacer uno y no andubo, lo revise y era por ese mismo error, nunca se me hubiera ocurrido buscarlo en esta, ya estaba muy saturado XD y agregue tambien el queue = NULL; en la qDestroy, esta bueno, en teoria evitas fallos de segmentacion, ya que en una condicion como esta al haber hecho el queue = NULL no entraria gracias nuevamente!! saludos
34
« en: Jueves 16 de Octubre de 2008, 16:01 »
q copado, la idea de un programa q haga diagramas de flujo a partir de codigo me parecia media utopica.
habria q hacer uno al revez. de diagrama de flujo a C xD
35
« en: Jueves 16 de Octubre de 2008, 15:12 »
jaja, si leer codigo ageno es todo un tema XD ta dificil el problema :S buenisimo! me gustaria ver el vector generico si no te es molestia espero tus comentarios
36
« en: Jueves 16 de Octubre de 2008, 14:54 »
claro, es parcticamente lo mismo no? si tu haces: c->datos+((c->primero+c->usados++)%c->tam
y el mio es: (queue->cola->elementos))+(queue->cola->tail % queue->cola->size)
el codigo esta todo completo y listo para compilar, hay un par de printf's como dije mas arriba que me dan valores re confusos seguro si comparas tu cola generica con la mia vas a descubrir el error facilmente, habiendolo implementado igual : D en internet no hay nada de documentacion con colas implementadas asi :S, por lo menos yo no encontre saludos!
37
« en: Jueves 16 de Octubre de 2008, 14:26 »
"atraves del codigo en c++ haga el diagrama de flujo"
esos programas hacen eso?
o uno tiene que hacer los diagramas?
para hacer diagramas yo uso el Dia, no se si esta para windows, pero es re util pq soporta miles de diagramas, ERD, modelo Relaciona, Diagrama de Flujo, Automatas Finitos, etc..
saludos
38
« en: Jueves 16 de Octubre de 2008, 14:21 »
hola el_uni! gracias por tomarte el tiepo para leer mi problema. es interesante tu pregunta ya que en la implementacion que estoy realizando el head y el tail no son la posicion del ultimo y el primer elemento, sino que son la cantidad de puts y la cantidad de gets respectivamente. esto me da la libertad de hacer una cola circular tan sencillamente como con esta instruccion: memcpy( ((char *)(queue ->cola ->elementos ))+(queue ->cola ->tail % queue ->cola ->size ), valor , queue ->sizeTipo );
capaz se ve mejor de esta manera: queue->cola->elementos[queue->cola->tail % queue->cola->size]
vi investigando en internet gente que realiza colas que son simplemente listas ligadas que ademas tienen un head y tail, esta bueno eso... pero queria que me ande con esta metodologia. aparte hice el stack generico (lo dejo adjunto por si a alguien le interesa ) y no tube mayores problemas. le di muchas vueltas, sinceramente no se donde esta el error, seguramente es algun problema como dijo moskito, algun puntero algun cast. espero que me puedan ayudar saludos!
39
« en: Martes 14 de Octubre de 2008, 15:39 »
uh buenisimo! gracias moskito, espero tu respuesta
40
« en: Lunes 13 de Octubre de 2008, 19:32 »
si la verdad... voy a ver si me puedo poner en contacto para que lo corrigan gracias por las respuestas!
41
« en: Lunes 13 de Octubre de 2008, 19:20 »
hola moskito! gracias por responder la cola generica que hice anda bien, pero no anda como deberia andar, bah... mejor dicho, no anda como yo quiero que ande. estube probando mas formas y termine creo con el mismo codigo pero con un par de printf's que meustran cosas que sinceramente no entiendo que son. hice esta prueba: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define FALSE 0 #define TRUE !FALSE typedef char boolean; //Cola propiamente dicha typedef struct{ void *elementos; int size; int head, //Cantidad de puts(); tail; //Cantidad de Gets(); }cola_t; //Estructura Administrativa typedef struct{ cola_t *cola; int sizeTipo; }queue_t; queue_t *qCreate(int size, int sizeTipo){ queue_t *queue = (queue_t *)malloc(sizeof(queue_t )); queue ->cola = (cola_t *)malloc(sizeof(cola_t )); queue->sizeTipo = sizeTipo; queue ->cola ->elementos = (void *)malloc(sizeTipo * size ); assert(queue ->cola ->elementos ); queue->cola->size = size; queue->cola->head = queue->cola->tail = 0; return queue; } void qDestroy(queue_t *queue){ } int qFull(queue_t *queue){ if(queue && queue->cola) //Si tengo queue return ((queue->cola->tail - queue->cola->head) == queue->cola->size); return -1; //No hay cola, devuelvo -1 } int qEmpty(queue_t *queue){ if(queue && queue->cola) //si tengo queue return (queue->cola->tail == queue->cola->head); return -1; //No hay cola } boolean qPut(queue_t *queue, void *valor){ if(qFull(queue)) return FALSE; //Esta llena y no puedo ingresar nada memcpy( ((char *)(queue ->cola ->elementos ))+(queue ->cola ->tail % queue ->cola ->size ), valor , queue ->sizeTipo ); valor = (void *)valor; printf("Guardado: %dn",*( ((char*)(queue ->cola ->elementos ))+(queue ->cola ->tail )) ); //printf(" ingresado en: %dn",queue->cola->tail % queue->cola->size); queue->cola->tail++; return TRUE; } boolean qGet(queue_t *queue, void *valor){ if(qEmpty(queue)) return FALSE; //Esta vacia y no puedo ingresar nada /* * Resuelvo el problema de q los * indices crezcan hacia el infinito */ if(queue->cola->head > queue->cola->size){ queue->cola->head %= queue->cola->size; queue->cola->tail %= queue->cola->size; } memcpy(valor ,((char *)(queue ->cola ->elementos ))+(queue ->cola ->head % queue ->cola ->size ), queue ->sizeTipo ); printf("Removido: %dn",*((char *)(queue ->cola ->elementos ))+(queue ->cola ->head % queue ->cola ->size )); //printf("en exa: %0xn",valor); //printf(" removido de: %dn",queue->cola->head % queue->cola->size); queue->cola->head++; return TRUE; } int main(void){ queue_t *queue; int a = 15, b = 22, c,d; queue = qCreate(5,sizeof(int)); qPut (queue,(void *)&a); qPut (queue,(void *)&b); qGet(queue,(void *)&c); qGet(queue,(void *)&d); printf("El primer valor que extraje fue : %dn",c ); printf("Ese mismo valor mostrado antes pero casteado a (char) : %dn",(char)c ); printf("el segundo valor que extraje fue: %dn",d ); qDestroy(queue); return 0; }
Descripcion de lo que obtengopuse printf's en la funcion qPut para ver que los valores insertados en la pila sea correctos y descartar la posibilidad de la carga de valores erroneos. el resultado de esos printf's en mi prueba fueron los correctos 15 y 22 como le dije q lo haga despues puse printf's en la qGet para ver si lo que remuevo es correcto, y obtengo 15 y 16, osea, el primer valor es correcto, yo ingrese 15 y removi 15, pero el segundo valor es incorrecto, yo ingrese 22 como segundo valor pero remuevo 16 :S. y finalmente puse printf's en el main de la variable que agarra los valores que remueve la qGet y obtengo esto: 5647 y 22, osea al revez que antes, el primer valor es erroneo (esperaba un 15), y el segundo valor es correcto. por alguna razon, se me ocurrio castear la variable donde guardo el valor que saca el qGet a char (solo la primera vez q imprime, ya que la segunda vez obtengo el resultado esperado) y magicamente andubo! el problema es que no entiendo que es lo q pasa, deberia darme los valores correctos sin tener que hacer el cast. no parece muy generico el hecho de tener que adivinar a q variable hacerle el cast y a cual no :S espero que me puedas ayudar gracias!
42
« en: Lunes 13 de Octubre de 2008, 02:08 »
esta acà: http://www.conclase.net/c/librerias/fun ... fun=memcpyyo le agregue un par de cosas para ver si funcionaba, pero el codigo en si es el mismo. carece de la asignacion. habia otro tambien q me daba error... ahora no me acuerdo cual era. si, tiene sentido pensar q no ande en ningun lado, pq estas asignando algo a ul lugar de memoria que es basura. habria que mandarles un mail o comunicarse de alguna forma para que lo arreglen los de c con clase, que tiene toda la onda esa pag XD
43
« en: Domingo 12 de Octubre de 2008, 23:18 »
ahh!!
y sigo con el problema de asignarle cosas a memoria no definida XD
che, pero que mal los de C con clase al poner ese codigo.
o en otros compiladores anda?
gracias por las respuestas!!
44
« en: Domingo 12 de Octubre de 2008, 04:43 »
Hola gente! estube aberiguando sobre la funcion memcpy, ya que siempre tengo problemas de fallos de segmentacion y encontre un codigo de ejemplo en la pagina de c con clase. el codigo es el siguiente: #include <stdio.h> #include <string.h> #define LEN1 7 #define LEN2 5 int main(void){ char a[LEN1] = "abcdefg"; char *ptr; int i; for(i=0; i<LEN1; i++) printf( "a[%d]=%c ", i , a [i ] ); for(i=0; i<LEN2; i++) printf( "ptr[%d]=%c ", i , ptr [i ] ); return 0; }
deberia de andar, ya que parece bastante razonable y a parte esta en c con clase que es una pagina bastante confiable... el problema es que en mi gcc desde ubuntu me tira un segmentation fault en el memcpy alguien sabe a q se debe esto? gracias de antemano!
45
« en: Viernes 10 de Octubre de 2008, 16:49 »
Hola gente! estoy realizando la implementacion de estructuras de datos genericas, la de pila ya la tengo y no tube mayores problemas, pero cuando llegue a la de cola se me complico un poco. bien este es mi codigo, esta completo asi se puede pegar a un compilador o algun lugar donde se pueda leer mejor: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define FALSE 0 #define TRUE !FALSE typedef char boolean; //Cola propiamente dicha typedef struct{ void *elementos; int size; int head, //Cantidad de puts(); tail; //Cantidad de Gets(); }cola_t; //Estructura Administrativa typedef struct{ cola_t *cola; int sizeTipo; }queue_t; queue_t *qCreate(int size, int sizeTipo){ queue_t *queue = (queue_t *)malloc(sizeof(queue_t )); queue ->cola = (cola_t *)malloc(sizeof(cola_t )); queue->sizeTipo = sizeTipo; queue ->cola ->elementos = (void *)malloc(sizeTipo * size ); assert(queue ->cola ->elementos ); queue->cola->size = size; queue->cola->head = queue->cola->tail = 0; return queue; } void qDestroy(queue_t *queue){ } int qFull(queue_t *queue){ if(queue && queue->cola) //Si tengo queue return ((queue->cola->tail - queue->cola->head) == queue->cola->size); return -1; //No hay cola, devuelvo -1 } int qEmpty(queue_t *queue){ if(queue && queue->cola) //si tengo queue return (queue->cola->tail == queue->cola->head); return -1; //No hay cola } boolean qPut(queue_t *queue, void *valor){ if(qFull(queue)) return FALSE; //Esta llena y no puedo ingresar nada memcpy( (char *)(queue ->cola ->elementos )+(queue ->cola ->tail % queue ->cola ->size ), valor , queue ->sizeTipo ); printf("Guardado: %dn",*(char *)((queue ->cola ->elementos )+(queue ->cola ->tail ))); //printf(" ingresado en: %dn",queue->cola->tail % queue->cola->size); queue->cola->tail++; return TRUE; } boolean qGet(queue_t *queue, void *valor){ if(qEmpty(queue)) return FALSE; //Esta vacia y no puedo ingresar nada /* * Resuelvo el problema de q los * indices crezcan hacia el infinito */ if(queue->cola->head > queue->cola->size){ queue->cola->head %= queue->cola->size; queue->cola->tail %= queue->cola->size; } memcpy(valor ,(void*)(queue ->cola ->elementos )+(queue ->cola ->head % queue ->cola ->size ), queue ->sizeTipo ); printf("Removido: %dn",*(int *)valor ); //printf(" removido de: %dn",queue->cola->head % queue->cola->size); queue->cola->head++; return TRUE; } int main(void){ queue_t *queue; int a = 3, b = 2, c,d; queue = qCreate(5,sizeof(int)); qPut (queue,(void *)&a); qPut (queue,(void *)&b); qGet(queue,(void *)&c); qGet(queue,(void *)&d); printf("Extraje en el main: %dn",(char)c ); printf("Extraje en el main: %dn",d ); qDestroy(queue); return 0; }
mi problema es la parte de qGet(), osea, extraer elementos de la cola.A simple vista no puedo encontrarle el error, pero de tantas pruebas que realice, me di cuenta que si casteo la variable donde guarde el valor removido de la cola a char, el resultado que obtengo es el esperado (linea 103). Pero sinceramente no entiendo porque pasa esto, ni como hacer para que no haga falta hacer ese casteo a char. ¿tendra algo que ver con el hecho de que en la funcion qPut donde esta el memcpy lo castie a (char *) ? (linea59), aunque probe en no castearlo y dejarlo void * pero me tira un error de compilacion, desreferenciando puntero void.
46
« en: Viernes 10 de Octubre de 2008, 15:54 »
Gracias diego.martinez!, la directiva #ifndef al parecer es muy amplia XD Malik, me explico mejor : supongamos que quieres crear una libreria que sume numeros, es muy probable que debas incluir la libreria math.h (muy probalbe no, seguro la incluyes), entonces desde tu programa incluyes la stdio.h y la math.h pq tambien quieres realizar algunas operaciones matematicas. si despues de haber hecho #include <math.h> haces el include de tu libreria, que tambien llama a la math.h sin haberlo premeditado obtendras un error de redefinicion, osea, el compilador te dira que tienes dos funciones con el mismo nombre, algo que es incorrecto. en cambio si en tu libreria contemplas ese caso preguntando si ya esta incluida la math.h no la incluis, sino si la incluyes. evitando ese problema. espero haberme explicado saludos!
47
« en: Jueves 9 de Octubre de 2008, 20:40 »
Hola gente! estoy intentando hacer algo semejante a una libreria. y averiguando me entere que con esto: #ifndef _stdio_h #include <stdio.h> #endif #ifndef _stdlib_h #include <stdlib.h> #endif #ifndef _string_h #include <string.h> #endif #ifndef _assert_h #include <assert.h> #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE !FALSE #endif
evito problemas del tipo "redefinicion de tal cosa", tanto en inclusiones de librerias como de macros. Existe alguna forma de hacer lo mismo pero contemplando los typedefs?si el typedef de boolean no esta typedef char boolean; fin si
gracias por su tiempo!
48
« en: Jueves 9 de Octubre de 2008, 19:33 »
esa! ahi quedó era ese (basicamente) mi problema, como la invocaba a la funcion no le estaba pasando la direccion de memoria. aca tengo el codigo para probarlo que quedo andando: #include <stdio.h> /* * Servicios de Pila: * * pilaAdm_t *stackCreate(int size, int sizeTipo); * * void stackDestroy(stack_t *pila); * * boolean push(pilaAdm_t *stack, void *elemento); * * boolean pop(pilaAdm_t *stack, void *elemento); * * stackEmpty(pila); * * stackFull(pila); * */ #ifndef _stdio_h #include <stdio.h> #endif #ifndef _stdlib_h #include <stdlib.h> #endif #ifndef _string_h #include <string.h> #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE !FALSE #endif #define stackEmpty(pila) pila->head == 0 #define stackFull(pila) pila->head == pila->size typedef char boolean; typedef struct{ void *elementos; int size; int head; }pila_t; typedef struct{ pila_t *pila; int sizeTipo; }pilaAdm_t; pilaAdm_t *stackCreate(int size, int sizeTipo); void stackDestroy(pilaAdm_t *pila); boolean push(pilaAdm_t *stack, void *elemento); boolean pop(pilaAdm_t *stack, void *elemento); pilaAdm_t *stackCreate(int size, int sizeTipo){ pilaAdm_t *stack = (pilaAdm_t *) malloc (sizeof(pilaAdm_t )); stack ->pila = (pila_t *) malloc (sizeof(pila_t )); stack ->pila ->elementos = (void *) malloc (sizeTipo * size ); stack->pila->size = size; stack->pila->head = 0; stack->sizeTipo = sizeTipo; return stack; } void stackDestroy(pilaAdm_t *stack){ free(stack ->pila ->elementos ); } boolean push(pilaAdm_t *stack, void *elemento){ if(!stack->pila || stackFull(stack->pila)) return FALSE; //si no hay pila o esta esta llena no puedo insertar memcpy((char *)stack ->pila ->elementos + (stack ->sizeTipo * stack ->pila ->head ++), elemento ,stack ->sizeTipo ); return TRUE; } boolean pop(pilaAdm_t *stack, void *elemento){ if(!stack->pila || stackEmpty(stack->pila)) return FALSE; //Si no tengo pila, o si esta vacia no puedo hacer pop stack->pila->head--; //memcpy(elemento, (void *)(((char *)stack->pila->elementos) + (stack->sizeTipo * stack->pila->head)), stack->sizeTipo); memcpy(elemento , stack ->pila ->elementos + (stack ->sizeTipo * stack ->pila ->head ), stack ->sizeTipo ); return TRUE; } int main(void){ pilaAdm_t *stack; int i,a, n = 5; stack = stackCreate(n,sizeof(int)); for(i=0; i< 5; i++) push(stack,(void *)&i); for(i=0; i<5; i++){ pop(stack,(void *)&a); } return 0; }
mi idea es meterlo en un archivo stack.c asi lo puedo incluir en mis programas muchas gracias Eternal idol, no hay nada peor que bloquearse con algo y no poder salir de ahi!
49
« en: Jueves 9 de Octubre de 2008, 19:02 »
jaja en esta funcion tambien me tira un segmentation fault boolean push(pilaAdm_t *stack, void *elemento){ if(!stack->pila || stackFull(stack->pila)) return FALSE; //si no hay pila o esta está llena no puedo insertar memcpy(stack ->pila ->elementos + (stack ->sizeTipo * stack ->pila ->head ++), elemento , stack ->sizeTipo ); return TRUE; }
en la parte del memcpy, pero no entiendo porque, lo que deberia hacer es copiar elemento, en (posicion 0 de la pila + (size veces por el tipo de dato a guardar)) y el peso del dato a guardar es sizeTipo. es porque no castiee el stack->pila->elementos de void * a char * y capaz por eso no me permite hacer la aritmetica de punteros? aunque intente castearlo y tampoco anda :S saludos!
50
« en: Jueves 9 de Octubre de 2008, 18:42 »
:O! tenes razon! pilaAdm_t *stackCreate(int size, int sizeTipo){ pilaAdm_t *stack = (pilaAdm_t *) malloc (sizeof(pilaAdm_t )); pila_t *pilaPmd = (pila_t *) malloc (sizeof(pila_t )); stack->pila = pilaPmd; stack ->pila ->elementos = (void *) malloc (sizeTipo * size ); stack->pila->size = size; stack->pila->head = 0; stack->sizeTipo = sizeTipo; return stack; }
excelente!, gracias Eternal Idol, no lo podia ver ahora me tira el mismo error pero con las instrucciones de push y pop, pero seguro se deben a algo por el estilo de mi error anterior, ahora las veo. saludos!
|
|
|