VidaGeek.net

Linux, Open-source, Programação e Produtividade

Archive for the ‘C’ Category

Cursos de verão do IME/USP reabrem inscrições

Uma boa notícia para quem ainda não sabe o que fazer no verão e gostaria de aprender algo ou se atualizar por um preço acessível: os cursos de verão do IME/USP reabriram inscrições para vagas remanescentes.

Há uma ampla gama de cursos relativos a Matemática e Estatística e também os de computação - tanto para iniciantes em programação quanto para aqueles que querem se atualizar aprendendo Java e Metodologias Ágeis.

Os cursos de Metodologias Ágeis contam alunos, ex-alunos e professores do IME membros da AgilCoop que, certamente, sabem muito bem do que estão falando. Ainda há vagas em ambos e, se você correr, pode conseguir descontos no curso introdutório - os primeiros 35 inscritos têm 40% de desconto!

Os de Java são ministrados por instrutores da Caelum graduandos e graduados pelo IME/USP, sem dúvida, com a excelência vista nos cursos na empresa e apreciada por diversos membros do GUJ (Grupo de Usuários de Java). As turmas de introdução à linguagem já estão lotadas, mas dois cursos ainda têm vagas:

Para quem está começando a programar há vagas em cursos de Introdução à Computação, ministradas na linguagem C, e para aqueles que já sabem o básico e querem aprender um pouco de análise de algoritmos e estruturas de dados, o curso de Tópicos de Programação pode ser uma boa idéia.

Você pode ver a lista toda de cursos disponíveis, horários e preços clicando aqui e você consegue as fichas de inscrição aqui.

Apesar de o site do IME/USP indicar que as inscrições terminaram em dezembro, elas foram reabertas ontem pelo fim da tarde! O site deve ser atualizado em breve. Novamente, se você ainda não fez planos para suas férias, vale a pena conferir e investir um pouco para aprender muito!

Posts Relacionados:

  • Cursos de verão no IME-USP
  • Pós graduação em TV digital
  • FLISOL terá sede no IME/USP
  • Palestra da Mozilla no IME/USP
  • VidaGeek.net agora também é Fórum!
  • Que curso eu faço?
  • FISL 9.0: Introducing Google Summer of Code
  • Acompanhe-nos por RSS, por Email ou via Twitter.
    Veja como ter um desconto no Dreamhost: um excelente servidor web.

  • 2 Comments
  • Filed under: C, Java, News, Programacao
  • Aplicações portáveis em C/C++

    Um requisito cada vez mais importante hoje em dia para uma aplicação é a portabilidade. Com cada vez mais sistemas diferentes no mercado, com configurações e necessidades específicas, fica mais difícil atingir esse objetivo.

    Em Java, essa preocupação não é necessária, já que a máquina virtual é sempre a mesma (na verdade, quase sempre… algumas têm funcionalidades a mais). Mas em linguagens compiladas para código de máquina, como C e C++, a tarefa fica mais difícil.

    Felizmente há diversas ferramentas e truques que podem ser utilizados para atingir esse objetivo mais facilmente. É possível fazer aplicações portáveis em C e C++ sem o uso dessas ferramentas, mas é mais fácil utilizarmos o que já está pronto. As duas principais ferramentas que fazem esse papel são o autoconf e o CMake. Não tenho muita experiência com o autoconf, mas já utilizei o CMake numa aplicação que utilizava as bibliotecas GTK+ (Gimp ToolKit) e VTK (Visualization ToolKit). Ambas as bibliotecas estão disponíveis para mais de um sistema operacional, e meu objetivo era fazer com que meu programa funcionasse tanto em Windows como em Linux. Utilizando o CMake, não foi necessária nenhuma alteração na aplicação para fazê-la funcionar em ambos os sistemas.

    A função dessas ferramentas é assegurar que as dependências do seu programa (bibliotecas, formato de dados) estão satisfeitas e gerar instruções para uma ferramenta de compilação (Make, Visual Studio) saber como chamar o compilador para compilar seu programa, afinal os compiladores mudam de sistema para sistema, e mesmo as opções de compilação de um mesmo compilador mudam.

    Então, se você for escrever uma aplicação um pouco mais complexa do que um “Hello world”, vale a pena investir um tempinho para escrever um arquivo de configuração para usar uma dessas ferramentas!

    Posts Relacionados:

  • Uma gem para testar aplicações que se comunicam com a Internet
  • Guia Linux - Parte III: Programação
  • Acompanhe-nos por RSS, por Email ou via Twitter.
    Veja como ter um desconto no Dreamhost: um excelente servidor web.

  • 3 Comments
  • Filed under: C, Dicas, Linux, Programacao
  • YACP - Condições Booleanas

    Continuando o tutorial, vamos começar agora o feijão-com-arroz da programação. Programação nada mais é do que controlar o fluxo de forma inteligente, para obter os resultados esperados. No próximo post vamos ver os dois controles mais simples, If e Else. Mas antes você precisa saber o que é

    Condição Booleana e Operadores Booleanos

    Uma condição booleana é uma expressão (lembram de expressões numéricas?) que resultam em um valor verdadeiro ou falso. Em C, como não existe um tipo booleano, a seguinte representação é usada:

    1. Se um número é diferente de 0, ele é considerado um valor verdadeiro;
    2. Se é igual a zero, é falso.

    Isso significa que 3 + 2 é verdadeiro em C, mas 4 - 4 não.

    Mas não é apenas dessa forma que fazemos operações booleanas. Existem outros operadores que servem para concatenar (ou modificar) condições booleanas. São os operadores booleanos.

    Os operadores mais comuns são:

    1. Operador “E” (&&): Apenas diz que a expressão é verdadeira se as duas condições ao lado dele forem verdadeiras;
    2. Operador “Ou” inclusivo (||): Diz que uma expressão é verdadeira se uma das duas condições for verdadeira;
    3. Operador “Não” (!): Diz que uma condição é verdadeira se a condição à qual ele é aplicado for falsa e vice-versa.

    Chega de teoria. Basicamente o que acontece é o seguinte:

    
    2+3 && 5 é verdadeiro
    2+3 && 0 é falso
    2+3 && 4 é verdadeiro
    2+3 || 0 é verdadeiro
    2+3 || 1 é verdadeiro
    2-2 || 1-1 é falso
    !0 é verdadeiro
    !1234567 é falso
    (0 && 0) || 1 é verdadeiro
    

    Notem que se você ler o que está escrito (sabendo que 0 é falso e os outros números são verdadeiros) fica bem intuitivo:

    
    verdadeiro E verdadeiro é verdadeiro
    verdadeiro E falso é falso
    (falso E falso) ou verdadeiro é verdadeiro
    NÃO falso é verdadeiro
    

    Certo… tirando o último exemplo não é tão intuitivo assim mas você se acostuma.

    Se você fizer todas as comparações possíveis usando duas condições e um operador você chega as seguintes tabelas:

    Operador E (&&)
    && verdadeiro falso
    verdadeiro verdadeiro falso
    falso falso falso
    Operador Ou (||)
    || verdadeiro falso
    verdadeiro verdadeiro verdadeiro
    falso verdadeiro falso
    Operador Não (!)
    ! verdadeiro falso
    falso verdadeiro

    Existe um outro operador, chamado Ou Exclusivo. As expressões formadas por ele são verdadeiras se uma única condição (das duas em volta dele) for verdadeira. Se as duas forem verdadeiras ou falsas a expressão é falsa. Ele não costuma ser muito utilizado (só usei ele pra criptografia e mesmo assim era um operador um pouquinho diferente.

    Posts Relacionados:

  • Dia C - Tuning
  • TRUE & TRUE == FALSE ?
  • YACP - Variáveis e Tipos Primitivos
  • YACP - Aprendendo a usar suas ferramentas
  • YACP (Yet Another C Primer)
  • YACP - Definindo seus próprios tipos
  • Acompanhe-nos por RSS, por Email ou via Twitter.
    Veja como ter um desconto no Dreamhost: um excelente servidor web.

    YACP - Definindo seus próprios tipos

    C possui suporte a definição de novos tipos, o que torna o código muitas vezes mais legível e conciso. É possível criar esses novos tipos com typedef, struct, enum e union.

    Typedef

    Typedef serve para você mudar o nome de um tipo. Parece meio inútil mas na verdade ajuda muito com a semântica do código. Por exemplo, você decide que precisa de um tipo para guardar dinheiro. Float não serve, porque pode dar erros de precisão (faça o teste com R$0.30 . É uma dízima periódica em binário e pode gerar resultados estranhos). Então você percebe que se guardar o dinheiro contando os centavos (1 real = 100 centavos) você não vai ter problemas de precisão, pois você sabe que os postos de gasolina não podem colocar aquele terceiro digito depois da vírgula, pois não existe milésimo de real.

    Então você vai lá e declara dinheiro como int. Pronto. Seu sistema funciona e você fica feliz, mas chamar seu dinheiro de int é meio feio e não faz muito sentido semanticamente. Como resolver isso? Você cria um novo tipo chamado dinheiro com o typedef:

    typedef int dinheiro;/*cria o tipo dinheiro*/

    dinheiro d;
    /*não tem a ver com a definição do tipo.*/
    /*Coloquei só pra exemplificar*/

    Agora você armazena seu dinheiro em um tipo dinheiro. Muito mais legível, certo?

    Struct

    Struct é uma forma de você agrupar diversos tipos dentro de um único, e acessá-los de forma individual. Na minha opinião é o recurso mais poderoso para definição de novos tipos. É muito bom para juntar informações relevantes e colocá-las em um único lugar de facil manipulação.

    struct nome_struct {
    tipo1 nome1;
    tipo2 nome2;
    .
    .
    .
    tipoN nomeN;
    }


    Para acessar qualquer tipo que esteja dentro da struct, use o operador “.”:

    Minhastruct.nome1;


    E você usa como uma variável qualquer. Simples, não? Nem tanto. A sintaxe de declaração de uma variavel do tipo struct é meio chata. Você precisa dizer que aquilo é uma struct:

    struct nome_struct minhaStruct;


    É aqui que entra a verdadeira mágica do typedef. Bem agora que você estava quase acreditando que a melhor utilidade do typedef é mudar o nome de um tipo primitivo.

    Se você criar um tipo para representar “struct nome_struct”, fica bem mais fácil de declarar:

    typedef struct nome_struct novo_nome;


    Geralmente isso já é feito quando declaramos a struct:

    typedef struct nome_meio_inutil {
    tipo1 nome1;
    .
    .
    .
    tipoN nomeN;
    } nome_real;


    O resto é igual, mas você usa o nome real pra declarar.

    typedef struct _retangulo {
    double lado;
    double altura;
    } retangulo;

    retangulo r;
    double area;

    r.lado = 4.0;
    r.altura = 3.1415;
    area = r.lado * r.altura;

    Enum

    Enum cria um tipo que pode apenas receber valores específicados durante a sua criação. Por exemplo:

    enum {janeiro,
    fevereiro,
    marco,
    abril,
    maio,
    junho,
    julho,
    agosto,
    setembro,
    outubro,
    novembro,
    dezembro
    };


    Mas como isso funciona? Cada posição recebe um valor (a partir de 0 e incrementando para cada posição) e se você colocar um valor que seja diferente desses o compilador gera um erro (ou talvez um warning). O problema é que esse nosso tipo não tem nome e sempre que você for usar você precisa colocar toda essa linha de código para declarar uma variavel:

    enum {janeiro,
    fevereiro,
    marco,
    abril,
    maio,
    junho,
    julho,
    agosto,
    setembro,
    outubro,
    novembro,
    dezembro
    } meses;


    Novamente somos salvos pelo typedef:

    typedef enum {
    janeiro,
    fevereiro,
    marco,
    abril,
    maio,
    junho,
    julho,
    agosto,
    setembro,
    outubro,
    novembro,
    dezembro
    } mes;

    mes m = 8;/*setembro*/

    m = m + 1;/*outubro*/

    m = novembro;/*10*/

    A parte mais legal é que aumenta a legibilidade do código, pois é muito mais elegante você verificar se o mês é janeiro do que verificar se ele é 0.

    Também é possível mudar o valor inicial do enum, atribuindo para o primeiro elemento um valor inteiro:

    typedef enum {
    algo=1800,
    sim,
    nao,
    sou,
    muito
    } criativo;

    criativo c;

    c = algo;
    c = c + 1;/*sim*/
    c = muito;/*1804*/

    Union

    Union é uma forma de você colocar diversos tipos em uma única variável. Um conceito interessante, mas que eu não vejo ser usado com muita frequência (Usei apenas uma vez e poderia ter feito de uma forma que evitasse isso). A sintaxe de declaração é bem semelhante à struct:

    typedef union nome_meio_inutil {
    int i;
    float f;
    char c;
    }minha_union;

    minha_union m;

    Já declarei com o typedef, mas se não tivesse feito isso, teria que escrever union antes da declaração, como acontece com struct.

    Para utilizar, é basicamente como o struct. Possui apenas uma diferença (fundamental). Ela guarda apenas um dos valores por vez. Portanto, se você armazenar algo em m.i e depois em m.f, o valor de m.i será sobrescrito.

    minha_union m;
    m.i = 10;
    m.f = 9.0;/*O valor de m.i foi sobrescrito*/


    E cuidado com a leitura dos valores. Se você gravar em m.f e ler com m.i, você receberá um valor que não apresenta sentido, pois o union não faz conversão entre os tipos que você coloca nele.

    minha_union m;
    m.f = 11.5;
    printf("%d\n", m.i);/*vai imprimir algum valor estranho*/


    A única vez que usei essa estrutura foi quando estava fazendo um leitor de arquivos .ini . Convencionei que poderiam existir apenas 3 tipos dentro do ini (string, inteiro e float) e criei um union para representar isso. Mesmo assim ainda precisava de 2 bits pra armazenar qual tipo eu tinha lido, porque o union não mantém essa informação.

    Posts Relacionados:

  • YACP - Variáveis e Tipos Primitivos
  • Linguagens de programação - C++
  • Groupware
  • YACP - Condições Booleanas
  • YACP (Yet Another C Primer)
  • Economizando com Software Livre
  • Dia C - Usando testes para o desenvolvimento
  • Acompanhe-nos por RSS, por Email ou via Twitter.
    Veja como ter um desconto no Dreamhost: um excelente servidor web.