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);