Esta página está incompleta; podés ayudar completando el material. ====== Examen Final - 75.42. Taller de programación I ====== **Cátedra:** Veiga\\ **Fecha:** 2do Cuatrimestre 2007\\ **Día:** 12/02/2008\\ **Tema:** 2 ===== Enunciado ===== - **Indicar la salida** del siguiente programa: #include class Base { public: virtual void f1 (void) { cout << "B.f1" << endl; f3(); } void f2 (void) { cout << "B.f2" << endl; f3(); f1(); } static void f3 (void) { cout << "B.f3" << endl; } }; class Derivada : Base { public: void f1 (void) { cout << "D.f1" << endl; f3(); } virtual void f2 (void) { cout << "D.f2" << endl; f3(); f1(); } static void f3 (void) { cout << "D.f3" << endl; } }; void main (void) { Derivada* pD = new Derivada; Base* pB = (Base *) pD; pB->f1(); pB->f2(); pD->f1(); pD->f3(); } - **Implemente** la función **int parseint(char *s)** que devuelva el valor entero correspondiente al string recibido como parámetro. El string tendrá la forma cccccccc|nn, donde cccccccc será la secuencia de símbolos que representa un número en base nn, siendo nn un número decimal entre 2 y 8. {Aclaración: ANSI C} - ¿Qué significa la palabra clave **virtual**? ¿**Cómo** se usa? - Escriba un programa (desde la inicialización hasta la liberación de los recursos) que **reciba 300 bytes por el puerto 257 y, antes de cerrarse, los devuelva en orden inverso por el puerto 1122.** No considere errores de comunicaciones. {Aclaración: ignorar puerto 1122, devuelve los datos al mismo cliente.} - La clase **"Bytes"** encapsula un buffer de bytes. Sus atributos son **pBuffer** y **Largo**. Escriba la **declaración** de esta clase no olvidando: **Constructor default**, **constructor de copia**, **destructor**, **operadores** +, <<. Implemente el operador << de forma que imprima el contenido del buffer (byte a byte) en binario. - ¿Qué **áreas de memoria** (Ej: Code-Segment) conoce?. **Dé características** de cada una de ellas. - **Declare un puntero** a una función que recibe: una referencia a un arreglo (STL) de enteros largos no signados, una referencia a un caracter y un puntero a caracter con valor default NULL; y devuelve una referencia a una lista (STL) de enteros. - Describa el proceso de **linkedición**. - ¿Puede anteponerse la palabra **virtual** a un destructor? **Justifique.** - ¿Cual es la característica básica de **la programación orientada a EVENTOS**? Dé **un ejemplo en cualquier plataforma.** ===== Resolución ===== ==== Punto I ==== D.f1\\ D.f3\\ B.f2\\ B.f3\\ D.f1\\ D.f3\\ D.f1\\ D.f3\\ D.f3\\ ==== Punto II ==== #include #include #include int parseint(char *s){ char *strBase, *strNum; int num, base, pos=0; strBase = (char *) malloc(3*sizeof(char)); while (s[pos] != ':') pos++; strNum = (char *) malloc(pos*sizeof(char)); strcpy(strBase, &s[pos+1]); strncpy(strNum, s, pos); base = atoi(strBase); num = strtol(strNum, NULL, base); free(strBase); free(strNum); return num; } /* El main es solo para probarlo. */ int main(int argc, char *argv[]){ if (argc >1) printf("%s es %i\n", argv[1], parseint(argv[1])); else printf("Cantidad de parámetros incorrecta.\n"); return 0; } Otra forma: #include #include #include int parseint(char *s){ char *strBase, c[2]={'\0','\0'}; int num, base, pos=0, suma=0, i; strBase = (char *) malloc(3*sizeof(char)); while (s[pos] != ':') pos++; strcpy(strBase, &s[pos+1]); base = atoi(strBase); num = 1; for (i=(pos-1); i>=0;i--){ c[0] = s[i]; suma += (num *atoi(c)); num *=base; } free(strBase); return suma; } /* El main es solo para probarlo. */ int main(int argc, char *argv[]){ if (argc >1) printf("%s es %i\n", argv[1], parseint(argv[1])); else printf("Cantidad de parámetros incorrecta.\n"); return 0; } ==== Punto IV ==== No esta probado. #include #include #include #define PORT 257 #define CONEXIONES_EN_COLA 1 int main(int argc, char *argv[]){ char *buffer = (char *) malloc(301*sizeof(char)); struct sockaddr_in addr; int fd, fdnuevo, i; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); // Le hago el htonl por más que no es necesario ya que INADDR_ANY es 0, y 0 en big-endean o litle-endean es 0. memset(&addr.sin_zero, '\0', 8); // Creo el socket. fd = socket(AF_INET, SOCK_STREAM, 0); // Asocio el socket al puerto. bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr)); // Me pongo a escuchar y defino un máximo de CONEXIONES_EN_COLA conexiones esperando. listen(fd, CONEXIONES_EN_COLA); // Acepto una conexión. No guardo los datos de quien se conecta. Le paso dos punteros a NULL. fdnuevo = accept(fd, NULL, NULL); // Tengo en fdnuevo la conexión con el socket conectado. // Recibo los 300 bytes de una. recv(fdnuevo, buffer, 300, 0); // Envío los 300 bytes de a uno y comenzando por el último. for (i=299; i>=0; i--) send(fdnuevo, buffer[i], 1, 0); // Cierro ambos sockets. close(fd); close(fdnuevo); return 0; } ==== Punto V ==== class Bytes{ private: char *pBuffer; int Largo; public: Bytes(); // Constructor default. Bytes(const Bytes &b); // Constructor de copia. ~Bytes(); // Destructor. Bytes operator+ (const Bytes &b) const; // Operador +. friend std::ostream & operator<<(std::ostream & os, const Bytes &b); // Operador de salida estándar. }; void convertir(int num, int base, std::ostream &os){ if (num < base) os << num; else { convertir(num/base, base, os); os << num%base; } } std::ostream &operator<<(std::ostream & os, const Bytes &b){ for(int i=0; i ==== Punto VII ==== std::list & (*func)(std::array &refArray, char &refChar, char *ptrChar=NULL);