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);
- 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)
- default:
TIPO();
- con valor de inicialización:
TIPO(TIPO2 valor);
- por copia:
TIPO(const TIPO& valor);
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ónTIPO operator + (const TIPO& otro) const;
bool operator > (const TIPO& otro) const;
operator TIPO () const;
para convertir implícitamenteTIPO& operator ++ () ;
prefixTIPO operator ++ (int) ;
postfix
- Simple / Múltiple
- Pública / Protegida / Privada
- Virtual <-- para salvar la de tipo diamante
friend
: si bien las funcionesfriend
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.
- como modificador de tipo
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).
__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 incluyerastatic const char __func__[] = "function-name";
.
int main(int argc, char *argv[])
argv[0]
es el nombre del programa
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, ...);
Nota: ver esto para más info.
- Compilación condicional (e.g. #if, #ifdef)
- Header guards (#ifndef, #define, #endif)
- Expansión de macros
- Inclusión de archivos (#include)
- Convierte el código preprocesado a un archivo objeto
- Pueden existir símbolos declarados pero sin definir (serán linkeados luego)
- 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)
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)'
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 {};
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);
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);
- Óvalo ocupando toda la ventana:
- 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);
- Rectángulo que ocupe el primer cuadrante de la ventana:
- Para dibujar finalmente el path que se haya trazado:
cr->stroke();
- Para rellenar con un color el path que se haya trazado:
cr->fill();
- 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)
for (std::TIPO<int>::iterator it = myiterable.begin(); it != myiterable.end(); ++it) {
// *it para obtener el elemento
}
bind
vsconnect
: mismos parámetros, pero bind es para un server que va a aceptar conexiones y connect para conectarse a otro servidor.send
yrecv
: 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; };
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);
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);
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 beSEEK_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)
- 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.