Skip to content

Instantly share code, notes, and snippets.

@colltoaction
Last active July 7, 2016 20:01
Show Gist options
  • Save colltoaction/cdf753222415b73d08e7c5cd45fe10fb to your computer and use it in GitHub Desktop.
Save colltoaction/cdf753222415b73d08e7c5cd45fe10fb to your computer and use it in GitHub Desktop.
Resumen de los temas de Taller I

Temas de Taller de Programación I (75.42)

Threads

pthread

  • int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
  • int pthread_join(pthread_t thread, void **retval);
  • int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
  • int pthread_mutex_destroy(pthread_mutex_t *mutex);
  • int pthread_mutex_lock(pthread_mutex_t *mutex);
  • int pthread_mutex_trylock(pthread_mutex_t *mutex);
  • int pthread_mutex_unlock(pthread_mutex_t *mutex);

Deadlock, Mutex

  • Existe un recurso compartido de forma no-compartible (Mutex)
  • Existe una dependencia mutua entre dos procesos/hilos (e.g. main hace lock y espera a pthread, y pthread hace lock en el mismo mutex, que estaba bloqueado)

Sintaxis y características de C++

Constructores

  • default: TIPO();
  • con valor de inicialización: TIPO(TIPO2 valor);
  • por copia: TIPO(const TIPO& valor);

Sobrecarga de operadores

  • friend std::ostream& operator << (std::ostream& os, const TIPO& elemento) ;
  • friend std::istream& operator >> (std::istream& is, TIPO& elemento) ;
  • TIPO& operator = (const TIPO& otro) ; siempre retorna *this por convención
  • TIPO operator + (const TIPO& otro) const;
  • bool operator > (const TIPO& otro) const;
  • operator TIPO () const; para convertir implícitamente
  • TIPO& operator ++ () ; prefix
  • TIPO operator ++ (int) ; postfix

Herencia

  • Simple / Múltiple
  • Pública / Protegida / Privada
  • Virtual <-- para salvar la de tipo diamante

Keywords

  • friend: si bien las funciones friend se declaran dentro de una clase, no son métodos de ella.
  • explicit: marca que un constructor con un solo parámetro no debe ser tomado implícitamente como constructor con valor de inicialización.
  • static:
    • como modificador de tipo storage duration, moviendo variables locales al data segment del programa.
    • como modificador de visibilidad, haciendo una variable global visible solo dentro de su translation unit (por default son extern).
    • como modificador de métodos de clases, para permitir accesos sin referir a ninguna instancia en particular.
  • const:
    • pospuesto a la declaración de un método, especifica que el mismo no modifica el estado interno del objeto.
    • antepuesto a un parámetro indica que no podrá ser modificado (por ejemplo, solo puede llamarse a métodos const).

Macros

  • __LINE__
  • __FILE__
  • __func__: > En C99 y C++11 se incluyó esta constante, que no es estrictamente una macro. Funciona como si inmediatamente después de la llave de la definición de la función se incluyera static const char __func__[] = "function-name";.

argc, argv

  • int main(int argc, char *argv[])
  • argv[0] es el nombre del programa

Funciones útiles

  • long int strtol (const char* str, char** endptr, int base);
  • double strtod (const char* str, char** endptr);
  • int snprintf(char* s, size_t n, const char* format, ...);

Ciclo de compilación (preprocesamiento, linking, etc.)

Nota: ver esto para más info.

Preprocesador

  • Compilación condicional (e.g. #if, #ifdef)
  • Header guards (#ifndef, #define, #endif)
  • Expansión de macros
  • Inclusión de archivos (#include)

Compilador

  • Convierte el código preprocesado a un archivo objeto
  • Pueden existir símbolos declarados pero sin definir (serán linkeados luego)

Linkedición

  • Toma los archivos objeto y los convierte en una biblioteca o ejecutable (producto final)
  • Reemplaza las referencias sin definir con las direcciones correctas (obtenidas de otros archivos objeto o bibliotecas del sistema)

Ambigüedades

int i = sqrt(4)
error C2668: 'sqrt' : ambiguous call to overloaded function
       could be 'long double sqrt(long double)'
       or       'float sqrt(float)'
       or       'double sqrt(double)'

Declaración / Definición

A declaration introduces an identifier and describes its type, be it a type, object, or function. A declaration is what the compiler needs to accept references to that identifier. These are declarations:

extern int bar;
extern int g(int, int);
double f(int, double); // extern can be omitted for function declarations
class foo; // no extern allowed for type declarations

A definition actually instantiates/implements this identifier. It's what the linker needs in order to link references to those entities. These are definitions corresponding to the above declarations:

int bar;
int g(int lhs, int rhs) {return lhs*rhs;}
double f(int i, double d) {return i+d;}
class foo {};

Interfaces gráficas

GTK

Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
Gtk::Window window;
Gtk::ListBox element;
Gtk::ListBoxRow row;
row.add_label("Row");
element.append(row);
window.add(element);
return app->run(window);

Cairo

Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
Gtk::Window window;
MiDrawingArea element;
window.add(element);
return app->run(window);

// MiDrawingArea hereda de Gtk::DrawingArea.
// Implementa bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) para dibujar usando Cairo
  • Escalar el lienzo a 0-1: cr->scale(get_allocation().get_width(), get_allocation().get_height());
  • Cambiar el color a azul: cr->set_source_rgba(0, 0, 1.0, 1);
  • Trazar arco: void Cairo::Context::arc(double xc, double yc, double radius, double angle1, double angle2);
    • Óvalo ocupando toda la ventana: cr->arc(0.5, 0.5, 0.5, 0, 2 * M_PI);
  • Cerrar trazo (e.g. para medio círculo): cr->close_path();
  • Trazar línea al centro de la ventana: cr->line_to(0.5, 0.5);
  • Trazar un rectángulo: void Cairo::Context::rectangle(double x, double y, double width, double height);
    • Rectángulo que ocupe el primer cuadrante de la ventana: cr->rectangle(0.5, 0, 0.5, 0.5);
  • Para dibujar finalmente el path que se haya trazado: cr->stroke();
  • Para rellenar con un color el path que se haya trazado: cr->fill();

STL

Estructuras de datos y adaptadores

  • Lista enlazada (list)
  • Cola de doble entrada (deque)
  • Cola (queue, es un adaptador sobre deque o list)
  • Pila (stack, es un adaptador sobre deque, list o vector)

Iteradores

for (std::TIPO<int>::iterator it = myiterable.begin(); it != myiterable.end(); ++it) {
  // *it para obtener el elemento
}

Sockets

Funciones y estructuras necesarias

  • bind vs connect: mismos parámetros, pero bind es para un server que va a aceptar conexiones y connect para conectarse a otro servidor.
  • send y recv: dos caras de una misma moneda, ya que deben ser parejos la cantidad de cosas enviadas y recibidas en el servidor y el cliente.
  • int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
  • void freeaddrinfo(struct addrinfo *res);
  • int socket(int domain, int type, int protocol);
  • int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • int listen(int sockfd, int backlog);
  • int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
  • ssize_t send(int sockfd, const void *buf, size_t len, int flags);
  • ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  • int shutdown(int sockfd, int how);
  • int close(int fd);
  • struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; socklen_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; };

TCP Server

socket + bind + listen + accept + send/recv

struct addrinfo hints;
struct addrinfo* results;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_STREAM; // TCP
hints.ai_flags = AI_PASSIVE; // Server
getaddrinfo("localhost", "8080", &hints, &results);
int skt = socket(results->ai_family, results->ai_socktype, results->ai_protocol);
bind(skt, results->ai_addr, results->ai_addrlen);
listen(skt, 20);
int peer = accept(skt, NULL, NULL);
char buf[5];
recv(peer, buf, 5, MSG_NOSIGNAL);
send(peer, "chau", 5, MSG_NOSIGNAL);
assert(strcmp("hola", buf) == 0);
freeaddrinfo(results);
shutdown(peer, SHUT_RDRW);
close(peer);
shutdown(skt, SHUT_RDRW);
close(skt);

TCP Client

socket + connect + send/recv

struct addrinfo hints;
struct addrinfo* results;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_STREAM; // TCP
//hints.ai_flags = 0; // Not set for client
getaddrinfo("localhost", "8080", &hints, &results);
int skt = socket(results->ai_family, results->ai_socktype, results->ai_protocol);
connect(skt, results->ai_addr, results->ai_addrlen);
send(peer, "hola", 5, MSG_NOSIGNAL);
char buf[5];
recv(peer, buf, 5, MSG_NOSIGNAL);
assert(strcmp("chau", buf) == 0);
freeaddrinfo(results);
shutdown(skt, SHUT_RDRW);
close(skt);

Procesamiento de archivos

Funciones

  • FILE* fopen(const char* filename, const char* mode);
  • int fclose(FILE* stream);
  • int fgetc(FILE* stream);
  • int fputc(int character, FILE* stream);
  • int feof(FILE* stream);
  • int fseek(FILE* stream, long int offset, int origin);
    • For streams open in binary mode, the new position is defined by adding offset to a reference position specified by origin.
    • For streams open in text mode, offset shall either be zero or a value returned by a previous call to ftell, and origin shall necessarily be SEEK_SET.
  • long int ftell(FILE* stream);
    • For binary streams, this is the number of bytes from the beginning of the file.
    • For text streams, the numerical value may not be meaningful but can still be used to restore the position to the same position later using fseek.
  • int truncate(const char *path, off_t length);
  • stdin (es un file pointer, no una función)

Estrategia de edición in-place

  • Para archivos que se acortan, alcanza con llevar dos índices, para lectura y escritura, y un contador de caracteres. Luego llamar a truncate.
  • Para archivos que se agrandan, se necesita hacer dos pasadas. La primera cuenta los caracteres finales, setea seek_lectura en el último caracter válido, y hace un truncate (para agrandar). Luego con dos índices se va escribiendo el archivo en sentido inverso.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment