Inicialmente este blog foi criado para armazenar algumas dicas e links de UNIX/Linux, OpenVMS, linguagem C, Assembly, TCP/IP e nerdezas afins. No entanto devido ao autor ter abandonado o seu plano de ser um super hacker e dominar o mundo (devido esposa, família, filhos, trabalho), a partir de 2012 este blog tem um tipo de nerdeza mais light (Android, Linux, RetroPie (retrogames), produtividade, e por aí vai). Estas dicas raramente serão criações minhas.

Mostrando postagens com marcador C. Mostrar todas as postagens
Mostrando postagens com marcador C. Mostrar todas as postagens

quarta-feira, 8 de outubro de 2008

maneira Deitel de checar data

Essa é mais uma dica da série "como é que eu não tinha pensado nisso antes?". Trata-se de uma maneira super-simples de checar a validade de uma data. Vi isso no livro "Java: Como Programar", sexta edição, do Deitel. Aí vai...

- ano: pode ser qualquer inteiro não negativo.
- mês: inteiro dentro do intervalo [1,12].
- dia: aí vai o algoritmo em C, levando em consideração que o mês e ano são válidos.


int checarDia(int dia, int mes, int ano) {
   /* aqui está a simplicidade do algoritmo:
   * cada elemento deste array é o maior dia do mês cujo número
   * é o índice do elemento, exceto o elemento 0
   */
   int diaPorMes[] = { 0, 31, 28, 31, 30, 31, 30
   31, 31, 30, 31, 30, 31, 30 };

   /* veja que coisa mágica! */
   if(dia > 0 && dia <= diaPorMes[mes])
     return dia;

   /* cuidando do danadinho do ano bissexto */
   if(mes == 2 && dia == 29 && (ano % 400 == 0 || (ano % 4 == 0 && ano % 100 != 0)))
     return dia;

   /* se não for uma data válida, retornamos o dia primeiro */
     return 1;
}


Me lembro de um dia fazer um exercício de programação que pedia para validar se a data que o usuário entrou era válida, fiz o código usando switch-case e alguns ifs...

Ver essa solução usando um simples array chega a dar raiva! Raiva por não ter pensado nisso de primeira.

usando o qsort() do stdlib.h

O protótipo é o seguinte:


#include <stdlib.h>

void qsort(void *base, size_t nmemb, size_t size, int (*compare)(cont void *, const void*));


Criei uma função compara() para comparar dois inteiros:

int compara(int const *a, int const *b) {
    return *a - *b;
}


e usei o seguinte comando para ordenar um array de inteiros lista[] com 10 elementos.

qsort(lista, 10, sizeof(int), &compara);


Pronto! Agora lista já está ordenada.

quarta-feira, 2 de julho de 2008

indentando no vim

Essa eu vi em http://plutao.wordpress.com/2007/02/08/identando-o-codigo-no-vim/ e na verdade é uma citação.

Você já se deparou com um código todo mal identado? Como resolver esse problema no vim?

Selecione o bloco de texto e aperte = (igual) e o vim identa para você


Essa mudou minha vida! ;-)

sábado, 7 de junho de 2008

codigo para html

Dica retirada de http://www.ime.usp.br/~pf/algoritmos/apend/util.html.

Converter um código fonte em linguagem C, por exemplo, para html com syntax highlighting.


prompt$ enscript --highlight=c --color --language=html --output=arquivo.html arquivo.c

sexta-feira, 4 de abril de 2008

Projeto de Algoritmos

Achei esse conteúdo muito interessante para o estudo da disciplina Estrutura de Dados II: http://www.ime.usp.br/~pf/algoritmos/index.html.

O autor, Paulo Feofiloff, possui 2 características que eu aprecio muito: escreve todo código em C, e se preocupa com a elegância do código (indentação, comentários, etc.).

sexta-feira, 28 de março de 2008

Monitorando tempo de execução de uma função

Esse macete eu achei especialmente útil na hora de estudar o desempenho dos diversos algoritmos de ordenação. Aprendi no "Advanced Programming in the UNIX Environment" (Stevens e Rago), no Seção 8.16.

Vamos direto à prática, para detalhes é necessário consultar o livro e/ou as man pages.

Primeiro temos que criar a seguinte função para imprimir o tempo:


#include <unistd.h>

static void imprimetempo(clock_t tempo) {
    static long clktck = 0;

    if(clktck == 0)
        if((clktck = sysconf(_SC_CLK_TCK)) < 0)
            perror("sysconf");

    printf("%7.2f s", tempo / (double) clktck);
}


E para que esta função seja útil temos que chamá-la de maneira análoga ao exemplo abaixo:


#include <sys/times.h>

int main() {
    clock_t ini, fim;
    .
    .
    .
    ini = times(NULL);
    funcao_que_quero_ver_quanto_tempo_leva(argumentos);
    fim = times(NULL);

    printf("Tempo que levou: ");
    imprimetempo(fim - ini);
    .
    .
    .
    return 0;
}

segunda-feira, 3 de março de 2008

gerando números aleatórios

Essa eu aprendi no Programming in C - UNIX System Calls and Subroutines using C. Trata-se de uma gambiarra para gerar números aleatórios.

Abaixo uma função que gera n números aleatórios de zero a nove e guarda no vetor V passado a função como parâmetro:


#include <stdlib.h>
#include <time.h>

#define MAIOR 10


void geranumeros(int V[], int n) {
    srand((unsigned int) time(NULL));
    while(n > 0)
        V[--n] = rand() % MAIOR;
}


Achei isso especialmente útil na hora de testar os algoritmos de ordenação ensinados na disciplina de Estrutura de Dados II.

quinta-feira, 6 de setembro de 2007

programacao em C para unix

Material clássico sobre programação em C para UNIX. Tem material sobre IPC, Threads e RPC. Aí está o link: http://www.cs.cf.ac.uk/Dave/C/

domingo, 5 de agosto de 2007

Insecure Programming by example

Ótimos exercícios para exploração de programas inseguros:

stack smashing protection e outros

Documentos a serem lidos.
 
stack-smashing protection (wikipedia):
 
defeating compiler-level buffer overflow protection: http://www.usenix.org/publications/login/2005-06/pdfs/alexander0506.pdf
 
four different tricks to bypass stackshield and stackguard protection: http://www.coresecurity.com/index.php5?module=ContentMod&action=item&id=1146

quarta-feira, 18 de julho de 2007

Compilar com gcc sem otimização

Parâmetro para o gcc muito útil para estudar Stack Overflow com o texto do aleph1 (ou qualquer outro destes textos que ensinam como "smash the stack for fun and profit").
$ gcc -mpreferred-stack-boundary=2 prog.c -o prog
Macete aprendido no livro The Shellcoder's Handbook.

domingo, 8 de julho de 2007

Editando programas em C com vim

O vim é o meu editor favorito. E para programar em C é o melhor que já usei. Aqui vai alguns macetes úteis que foram retirados do C editing with VIM HOWTO.


1. Movendo-se pelo texto

{ - volta um parágrafo
} - avança um parágrafo
][ - avança para o próximo } que estiver na primeira coluna
[] - volta para o mais próximo } que estiver na primeira coluna
% - alterna o (, {, ou [ que casa com seu respectivo ), }, ou ].



2. Saltando para posições aleatórias

+ ctags:
Resumo:
ctags *.c - cria o arquivo tags a ser usado pelo vim
CTRL+] - pula para a declaração do identificador (função ou var)
CTRL+T - pula para a posição que estava quando chamou CTRL+]

Descrição:
Primeiro deve-se usar o programa ctags nos arquivos .c para então
chamar o vim. Por exemplo:

[prompt]$ ctags *.c

Este comando criará um arquivo chamado tags no diretório corrente.
Agora quando chamar o vim basta teclar CTRL+] para ir para a declaração de
um identificador, e CTRL+T para voltar de onde chamou.


+ marcadores:
m' - marca uma posição
'' - vai para a posição marcada
m? - marca a posição ? que pode ser A-Z e a-z
'? - vai para a posição marcada com ?



3. Auto-completando palavras
CTRL+P - procura a palavra e mostra as opções (inclusive nos includes)
CTRL+N - idem acima só que no sentido contrário



4. Auto-formatação
:set textwidth=75 - texto com 75 colunas
:set cindent - indentação automática



5. Corrigindo rapidamente
:set makeprg=make\ %:r - configura :make para 'make arquivo_sem_extensao'
:make - executa o que está configurado em makeprg
:cn e :cN - vai para o erro (n vai, N volta)



6. Outros itens adicionados por mim
:map <F9> :w<CR>:make<CR> - <F9> salva e compila
:map <F10> :w<CR>:make<CR>:!./%:r - <F10> salva, compila e espera argumentos

tags