domingo, 25 de março de 2012

C: Um exemplo de simplificação de expressão lógica

No outro dia vi uma expressão assim:

        if(((situacao == situacao_a) ||
            ((
situacao == situacao_b) && (strcmp(string,UMA_MACRO) == 0))) ||
            ((
situacao == situacao_c) ||
            ((
situacao == situacao_d) && (strcmp(string,UMA_MACRO) == 0))))
        {

                        /* ... */
        }


Este código acima está abaixo do ótimo, tanto em geração de código quanto em desempenho. Mas como otimizar?

Antes de continuar lendo, que tal você mesmo tentar fazer uma versão melhor dele? O artigo sobre avaliação incompleta pode ajudar.

sábado, 3 de março de 2012

C: Contagem de condições lógicas

Digamos que em um algoritmo é necessário que pelo menos 3 de 5 condições sejam verdadeiras para tomar uma ação. Como testar isto? Fazer um emaranhado de if? Pior, se somente 3 de 5 tem que ser verdadeiras? Fazer um emaranhado maior?

C: Avaliação incompleta

Existem duas formas de avaliação em expressões lógicas, a avaliação completa e a incompleta.

Por definição, no Pascal a avaliação sempre é completa (O Turbo Pascal tinha uma opção para mudar este comportamento.), e no C é incompleta.

O que é isto? Quais são as consequências? Como melhor aproveitar isto.

sexta-feira, 24 de fevereiro de 2012

C: Ser ou não ser - Boolean

No C não existe o tipo boolean, tal como existe em outras linguagens, mas existem operações lógicas. As operações lógicas são operações inteiras de baixo nível de precedência.

C: Explicando as bruxarias

A linguagem C permite uma economias de expressão, e outras linguagens podem ter seus truques também, então é aconselhável o uso de comentários explicando as "bruxarias" que você fez. Um exemplo pode ser visto abaixo:

Não há nada mais inseguro do que um procedimento problemático de segurança

Se você e/ou a empresa tem um procedimento de segurança que cause impedimentos inúteis, erros de conexão, muitas senhas etc, as pessoas ficam aborrecidas e tendem a não cumprir, e até contornar, os procedimentos de segurança.

Os procedimentos de segurança tem que fazer parte do dia a dia, mas não podem ser custosos e/ou penosos de serem seguidos, senão existirá uma tendência de serem abandonados.

Um exemplo é o mito da troca periódica de senha. Depois de um tempo a pessoa fica sem imaginação e começa a repetir senhas, trocar somente uma letra ou número da senha, usar senhas fáceis e óbvias, confundir senhas, esquecê-las etc. É isto que acontece com a mitológica segurança da troca frequente de senhas. Antes uma senha muito boa usada por muito tempo, em um ambiente seguro, do que trocas mensais de senha. Se a senha vazar, não importa se vai demorar 2 semanas para ser trocada, ou um ano, pois quem está afim de fazer um estrago, ou usá-la de forma errada, quase certamente fará no menor tempo possível, já prevendo que a senha logo será trocada.

C: Como compilar

Como compilar um programa em C? É uma dúvida simples, mas comum entre os iniciantes. A resposta varia conforme o sistema e o desenvolvedor do compilador, mas tem um básico que é comum nos Unix, e nos outros sistemas cujo compilador seja por linha de comando. E sobre este modo que aqui tratarei.

quinta-feira, 23 de fevereiro de 2012

C: Formas de armazenamento das variáveis

O C tem algumas formas de como uma variável será alocada. (Aqui se excluem as formas de alocação dinâmica, que deverá ser outro capítulo.) Estas formas são: auto, register, static e external.

quarta-feira, 22 de fevereiro de 2012

Processo x Programa Executável

"Alguém sabe a diferença entre um Processo e um Programa Executável?"

Esta foi a pergunta que um amigo, o Sergio Prallon, fez em uma turma de amigos para a qual ele ensinava C, a qual eu entrei de penetra. E eu respondi da seguinte forma:

quinta-feira, 16 de fevereiro de 2012

C x Java, um mito

No outro dia ouvi falar que os interpretadores Java estavam tão bons que os códigos escritos em Java rodavam quase tão rápido quanto os códigos escritos em C. Sinceramente eu duvido. Acho que o Java deve ter bons desenvolvedores C para escrever o interpretador e as bibliotecas. E acho que existem poucos programadores bons em C.

PS: Isto é uma hipótese complicada de se testar, mas que não pode ser facilmente descartada.

sábado, 4 de fevereiro de 2012

C: sizeof.c

Como forma de reconhecimento de um sistema, e de seu compilador C, este é um dos primeiros programas que executo em um sistema quando começo a mexer nele.

C: Dualidade char/int

Uma das definições para Byte é: "Byte a quantidade mínima de bits necessários para armazenar um caractere.". Memória, capacidade de armazenamento, tamanho de variáveis etc, são medidos em bytes, ou seus múltiplos (KB, MB etc).

Normalmente o Byte tem 8 bits, mas já li que houve uma exceção (um processador com o Byte de 9 bits).

O tipo char no C é este inteiro de um Byte, que pode ser usado para armazenar um número inteiro que caiba em um Byte, ou um caractere, e não é um tipo restritivo como outras linguagens de alto nível.

C: Modificadores de sinal e tamanho

A linguagem C tem basicamente quatro modificadores de tipo, dois em relação ao sinal, signed e unsigned, e dois relativo a tamanho da variável, short e long.

C: Tipos básicos de dados

O C tem alguns tipos básicos de dados, dos quais os outros se originam. Eles são: char, int, float, double. E tem modificadores de tipo: signed, unsigned, short e long. Todo o resto é derivado destes

Os processadores de computadores só conhecem alguns tipos básicos de dados, como o Byte, que é um inteiro de 8 bits, praticamente todos os processadores conhecem o short, que é um inteiro de 16 bits, muitos conhecem inteiros de 32 bits, e alguns conhecem o inteiro de 64 bits. Muitos processadores conhecem o formato de ponto flutuante de 32 e de 64 bits. Para os processadores não existem strings, caracteres, structs etc.

Caracteres não fazem sentido para o processador. Este tipo de dados só faz sentido em algoritmos e, às vezes, em periféricos de entrada e saída. Uma controladora de vídeo em modo texto, tal como uma impressora, sabe que, se receber um certo byte para imprimir ,tem que desenhar uma matriz de pontos de uma certa forma. Strings fazem menos sentido ainda. Uma string é uma sequência de caracteres, que processador não passa de uma sequência de bytes, se muito.

O C age quase da mesma forma, tendo os mesmos tipos básicos, mesmo que o processador não tenha. Por exemplo, o long int é sempre de 32 bits (ou quase sempre, mas nunca vi uma exceção). Se o processador não tiver inteiro de 32 bits, o processador colocará códigos que emulam a existência dele. O mesmo acontece com o long long int, que é o inteiro muito longo, normalmente de 64 bits (também não conheço exceções), que só costuma existir nativamente em processadores de 64 bits. O tipo int costuma ser de 16 bits em máquinas de 8 e 16 bits, e 32 bits em máquinas de 32 e 64 bits. Portanto a linguagem C providencia não só um ambiente de programação comum entre diversas plataformas, como também um conjunto básico de tipos de variáveis constante independentes de plataformas.

segunda-feira, 30 de janeiro de 2012

Linguagem C

A linguagem de programação C é mal compreendida por muita gente, inclusive por alguns que programam nela. Alguns pensam nela como uma linguagem de alto nível, como Pascal, Java, PHP, BASIC (Visual Basic não é BASIC), Visual Basic etc, mas ela não é bem assim. Ela nasceu na Bell Labs, criada por Dennis Ritchie quando migravam o Unix para o PDP 11. Atualmente pode-se dizer que é a linguagem de programação mais importante do mundo.

O C não tem tipos tão fortes e limitados quanto as linguagens de alto nível. O C tem dualidades, tal como a dualidade ponteiro/array, de string/ponteiro/array, caractere/inteiro, tal como a Física tem a dualidade onda/partícula para as radiações eletromagnéticas. Estas dualidades confundem muito quem aprendeu a programar com linguagens de alto nível e especialmente quem não aprendeu linguagens de baixo nível, como Assembler. Este é um dos motivos que acho que todo programador tem que aprender Assembler, para ter uma ideia de como o computador interpreta as instruções, como são as instruções, o que são, e como o compilador gera código e otimiza os programas em alto nível. O C tem várias das facilidades interessantes de manipulação de dados que se tem no Assembler, mas apresentada da forma de alto nível, o que torna muito mais fácil escrever um programa em C do que em Assembler. É por isto que muitos autores falam que o C é uma linguagem de médio nível.

Entre muitos artigos que pretendo publicar neste blog, Uma boa parte será sobre esta maravilhosa, mas muitas vezes incompreendida, linguagem de programação. Não assumam como um curso básico de C, mas como um complemento ao aprendizado e um convite a discussões e estudos mais profundos.

Por que Mikronomicon

Eu tenho um blog de principalmente fotografia, mas já coloquei algumas coisas de programação nele, porém achei que era off-toppic.  Agora que estou trabalhando com programação resolvi fazer um blog de "nerfices".

Aqui pretendo falar principalmente de informática, de cosias de nerd, de desenvolvimento de softwares. Pretendo ensinar alguns truques que beiram a magia negra, à antiga arte quase perdida da programação consciente. Pretendo ensinar por que fazer algumas coisas de uma forma, e por que não de outra. Pretendo ensinar truques mágicos que podem ser centenas de vezes mais rápidos de executar do que as formas que a maioria dos programadores fazem. Em suma, um dos temas será sobre a magia mais obscura da programação de computadores.

Em busca de um nome acabei fazendo a pergunta no meu Facebook. Um amigo de longa data, o Roberto Assis, me deu uma resposta muito interessante: Micronomicon. A ideia é fazer um trocadilho com o Necronomicon, o livro imaginário criado pelo escritor H.P.Lovecraft em seus livros (ver aqui em Português e aqui em Inglês).  Mas o nome já estava em uso por um blog vazio (na data atual, 29/01/2012), então tive que usar Mikronomicon.

Sei que usar um nome baseado no nome criado pelo Lovecraft sem conhecer a obra dele chega a ser quase desrespeitoso. Posso estar cometendo uma grande gafe, por não entender o que realmente o Necronomicon significa, por não ter lido as obras dele. Posso estar deturpando o sentido. O meu conhecimento sobre o Necronomicon vem de outras fontes, principalmente da Wikipedia. Mas acho que o sentido do livro, e a sua suposta raridade, foram o que mais me chamaram a atenção.

O Necronomicon seria, pelo que eu li, um livro praticamente perdido, com poucos exemplares sobreviventes, e ainda por cima proibido, ensinando uma arte perdida, muito pouco conhecida, chegando a ser muito perigosa. É neste sentido que uso como origem do nome deste blog.

Tal como dizem sobre o Necronomicon original, a leitura pode levar à loucura e à morte. Portanto, leiam o conteúdo deste blog por sua conta e risco, e não me responsabilizo pelas consequências.