Você está na página 1de 10

http://vidageek.

net/2007/07/19/yacp-yet-another-c-primer/

YACP (Yet Another C Primer)


Author: Jonas Abreu

Este o primeiro post de uma srie que tem por objetivo ensinar programao em C a algum que j tem noo do que programao, mas nunca programou. Programadores menos experientes tambm encontraro muito material til aqui. Esta srie est dividida em trs partes:
1. Apresentao e instalao de compiladores, bons editores de texto e um depurador. 2. Estrutura da linguagem de programao C. 3. Bibliotecas do padro ANSI C (ISO C 89) e ISO C 99.

A primeira parte, ir mostrar rapidamente como instalar o compilador GCC, os editores de texto GVim e Emacs e o depurador GDB. A segunda parte tratar de como a sintaxe de C estruturada e das palavras reservadas a linguagem. Introduzir o conceito de variveis, a estrutura de controle de fluxo de um programa, operaes com os temidos ponteiros (que so bem mais simples de usar do que as pessoas costumam pensar), manipulao de bits, funes e preprocessamento. A terceira parte vai funcionar como um guia de referncia para as funes dos padres ANSI e ISO C 99. Assim voc poder saber qual suporte C oferece para seus programadores.

Instalando o GCC
O GCC um dos melhores compiladores da linguagem C que existe. Boa parte do que foi adicionado ao padro ISO C 99 eram extenses apenas do GCC. Alm disso ele OpenSource. Nos exemplos vou usar o GCC, mas qualquer compilador ISO C 99 deve compilar os exemplos. Instalar o GCC em Linux bem simples. Provavelmente voc j possui ele instalado (sei apenas de uma verso do Ubuntu que no vinha com o GCC por padro). Para checar, abra um terminal e digite gcc version. Ele ir informar qual a verso do compilador. Se a shell devolver alguma mensagem de erro, instale o GCC com o seu gerenciador de pacotes (como so muitos, no vou entrar em detalhes). Em MacOS X, voc dever se cadastrar na Apple Developer Connection (ADC) e baixar o pacote xCode. O xCode vai instalar dezenas de programas, bibliotecas e frameworks em seu computador. Possui muita coisa realmente til e muita coisa intil. Ainda bem que voc pode escolher o que instalar. Em Windows, a melhor opo instalar o cygwin, que um emulador de Linux para Windows. Muito bom.

Instalando o depurador
O depurador que uso o GDB (GNU Debugger). Excelente depurador, poder ajudar muito a detectar algum erro em seus programas. Em Linux ele j deve estar instalado, caso contrrio siga o mesmo procedimento feito para o GCC.

Em MacOS X, o xCode j instala o GDB. Em Windows, o cygwin tambm j traz o GDB.

Instalando um editor de textos


Em Linux e MacOS X, o vim vem instalado por padro. Para instalar o Gvim use seu gerenciador de pacotes preferido ou acesse o site do Vim e faa o download. Para instalar em Windows, acesse o site do Vim e pegue o instalador. Alm do Vim, existe um outro bom editor chamado Emacs, criado por Richard Stallman. Para instalar o Emacs no Linux basta usar o seu gerenciador de pacotes (Portage, Synaptic, etc) e escolher a opo de instalar o Emacs. Caso sua distribuio no tenha um gerenciador de pacotes, entre no site do Emacs e faa o download. Para instalar no Windows, acesse o site do Emacs e pegue o pacote de arquivos pr-compilados. Ele no contm um instalador, mas basta extra-lo (ele um .zip) e executar o bin/runemacs.exe, voc pode deixar a pasta em qualquer lugar mas interessante deixar em um lugar fcil de lembrar (C:\ ou Arquivos de Programas).

YACP Condies Booleanas


Author: Jonas Abreu

Continuando o tutorial, vamos comear agora o feijo-com-arroz da programao. Programao nada mais do que controlar o fluxo de forma inteligente, para obter os resultados esperados. No prximo post vamos ver os dois controles mais simples, If e Else. Mas antes voc precisa saber o que

Condio Booleana e Operadores Booleanos


Uma condio booleana uma expresso (lembram de expresses numricas?) que resultam em um valor verdadeiro ou falso. Em C, como no existe um tipo booleano, a seguinte representao usada:
1. Se um nmero 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 no. Mas no apenas dessa forma que fazemos operaes booleanas. Existem outros operadores que servem para concatenar (ou modificar) condies booleanas. So os operadores booleanos. Os operadores mais comuns so:
1. Operador E (&&): Apenas diz que a expresso verdadeira se as duas condies ao lado dele forem verdadeiras; 2. Operador Ou inclusivo (||): Diz que uma expresso verdadeira se uma das duas condies for verdadeira; 3. Operador No (!): Diz que uma condio verdadeira se a condio 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 nmeros so verdadeiros) fica bem intuitivo:
verdadeiro E verdadeiro verdadeiro verdadeiro E falso falso (falso E falso) ou verdadeiro verdadeiro NO falso verdadeiro

Certo tirando o ltimo exemplo no to intuitivo assim mas voc se acostuma. Se voc fizer todas as comparaes possveis usando duas condies e um operador voc chega as seguintes tabelas: Operador E (&&) && verdadeiro falso Operador Ou (||) || verdadeiro falso Operador No (!) ! verdadeiro falso falso verdadeiro verdadeiro falso verdadeiro verdadeiro verdadeiro falso verdadeiro falso verdadeiro falso falso falso

Existe um outro operador, chamado Ou Exclusivo. As expresses formadas por ele so verdadeiras se uma nica condio (das duas em volta dele) for verdadeira. Se as duas forem verdadeiras ou falsas a expresso falsa. Ele no costuma ser muito utilizado (s usei ele pra criptografia e mesmo assim era um operador um pouquinho diferente

YACP Aprendendo a usar suas ferramentas


Author: Jonas Abreu

25

JUL

Agora que voc j instalou seu compilador, editor de texto favorito e depurador, nada como algumas dicas de como us-los.

Usando o GCC

Para compilar um programa, abra um terminal (Linux: [xgk]term, rxvt, etc; MacOS X: Terminal, DashBoard Shell, etc; Windows: cygwin). No terminal digite a seguinte linha: gcc -Wall -pedantic -std=c99 -g seu_arquivo.c -o arquivo_de_saida Lembre de trocar seu_arquivo.c pelo arquivo que voc quer compilar e arquivo_de_saida pelo nome que voc quer dar para o seu executvel. A flag Wall serve para que o compilador gere o maior nmero possvel de avisos de coisas que podem estar erradas no seu programa. Std=c99 para ele compilar usando ISO C 99 como padro e pedantic para ele forar o padro de compilao (se no usar, ele pode deixar passar algum cdigo que no seja ISO C 99). G para que ele gere marcaes para o depurador, facilitando o processo de depurao mais tarde.

Rodando seu programa


Em Linux, Windows e MacOS X, digite: ./nome_do_seu_programa

Usando o GDB
Para rodar o GDB, digite: gdb nome_do_seu_programa O GDB possui diversos comandos internos:

r Roda o seu programa dentro do gdb b [nome_funcao|linha do programa] Pausa a execuo do programa (breakpoint) quando a funo nome_funo for chamada ou quando o programa for executar o comando que est na linha indicada n Executa a prxima linha do seu programa c Continua a execuo at que um breakpoint seja atingido

Existem vrios outros mas esses devem ser os mais usados.

Usando o GVim
O Vim possui vrios modos de utilizao. Vamos nos focar no modo de comando (padro) e de insero. No modo de comando no aparece nada escrito no canto inferior esquerdo da tela (a no ser mensagens de erro em vermelho. Voc vai notar.) Neste modo possvel salvar seu arquivo, abrir um novo, fechar o Vim, etc. Aqui vo alguns dos comandos mais usados:

:sav nome_arquivo Salva o arquivo atual em nome_arquivo :w Escreve o arquivo atual :q Fecha o Vim :x Escreve o arquivo e fecha o Vim :e nome_arquivo Abre o arquivo nome_arquivo (cria um novo se no existir arquivo com o nome a Muda para o modo de insero (no tem : antes do a) u (no modo de comando) desfazer :syn on Ativa o modo de colorao (muito til quando programando) :set ai Ativa a autoindentao :set cindent Ativa o modo de indentao para C :set nu Coloca numerao nas linhas do seu programa

:set ruler Coloca indicador de linha e coluna de inde o cursor est :set keymap=accents Se seu teclado no estiver bem configurado, no Vim ele colocar acentos :set noexpandtab (Veja os comentrios)

Os ltimos 6 comandos podem ser colocados em um arquivo especial chamado .vimrc (_vimrc no Vim para Windows e .vimrc no cygwin). Esse arquivo possui comandos que sero executados sempre que voc abrir o Vim/GVim. Assim no necessrio digit-los toda vez que for programar. Este arquivo costuma se localizar na sua home. O modo de insero serve para voc modificar o texto do arquivo. Para voltar para o modo de comando aperte Esc.

Usando o Emacs
J o emacs possui apenas um modo e uso. Insero. Isso significa que voc no precisa fazer nada antes de comear a digitar seu programa. Aqui vo alguns comandos teis (embora voc possa fazer tudo com o menu):

ctrl-x+ctrl-f abre um arquivo ctrl-x+ctrl-s salva o arquivo ctrl-x+ctrl-c sai do emacs ctrl-espao seleciona texto alt-w copia texto selecionado ctrl-w recorta texto selecionado ctrl-y cola o texto previamente copiado ctrl-_ desfazer

YACP Variveis e Tipos Primitivos


Author: Jonas Abreu

30
Variveis

JUL

Em C, uma varivel pode ser visto de forma semelhante a que vista em matemtica. Ela um lugar para voc colocar valores. A diferena que um conceito mais restrito. Cada varivel possui um tipo e apenas valores desse tipo podem ser colocados dentro da varivel. A varivel tambm possui limitaes. Por exemplo, voc no pode colocar um nmero real dentro de uma varivel inteira. Se voc fizer isso, o compilador poder gerar um aviso, erro ou far algum malabarismo para conseguir colocar dentro da varivel. No caso, ele pegar apenas a arte inteira do nmero real. Alm disso, as variveis possuem um valor mximo e mnimo que pode ser colocado dentro delas. Qualquer valor entre esses dois extremos (inclusive) pode ser atribudo (colocado) a varivel. Um valor fora desse limites geralmente ir produzir resultados estranhos, como uma multiplicao entre dois nmeros positivos gerando um nmero negativo.

Tipos Primitivos
C possui diversos tipos de varivel que j vem definidos e que voc pode usar para compor outros. Esses so os tipos primitivos. Aqui vai uma tabela com os principais tipos primitivos e seus valores mximos e mnimos:

Tipo

Equivalente Armazena o cdigo de um caractere Armazena um inteiro Armazena um inteiro Nmero real com preciso simples Nmero real com dupla preciso

Valor Mximo

Valor Mnimo

Nmero de bytes em geral(processador de 32 bits) 1 4 4 4 8

char int long float double

127 2147483647 2147483647 ??? ???

-128 -2147483648 -2147483648 ??? ???

Alm dos tipos primitivos, existem modificadores para o tamanho desses tipos: Modificador short long unsigned signed Efeito Reduz pela metade o nmero de bytes do tipo primitivo Dobra o nmero de bytes do tipo primitivo Define que o tipo apenas representar valores positivos Define que o tipo representar valores positivos e negativos

Usando Variveis
Em C, para se utilizar uma varivel, necessrio declar-la antes. Para isso, voc deve tambm indicar de qual tipo que ela seja. A sintaxe basicamente: tipo nome_da_variavel; Alguns exemplos: int i; long long inteiro_bem_longo; float pontoFlutuante; double pontoFlutuante2; long double CaSeSeNsItIvE; short int podemosUsarVariosCaracteresNoNomeDaVariavel; Em C, nomes (de qualquer coisa) podem possuir muitos caracteres (no pude encontrar um valor mximo, mas meus testes mostraram que at 10765 caracteres funciona), desde que no sejam comeados por nmeros (podem possuir nmeros a partir do segundo caractere, mesmo que seja entre caracteres) ou operadores. Tambm no permitido dar nomes iguais, mesmo que seja para coisas diferentes.

YACP Definindo seus prprios tipos


Author: Jonas Abreu

15

AUG

C possui suporte a definio de novos tipos, o que torna o cdigo muitas vezes mais legvel e conciso. possvel criar esses novos tipos com typedef, struct, enum e union.

Typedef
Typedef serve para voc mudar o nome de um tipo. Parece meio intil mas na verdade ajuda muito com a semntica do cdigo. Por exemplo, voc decide que precisa de um tipo para guardar dinheiro. Float no serve, porque pode dar erros de preciso (faa o teste com R$0.30 . uma dzima peridica em binrio e pode gerar resultados estranhos). Ento voc percebe que se guardar o dinheiro contando os centavos (1 real = 100 centavos) voc no vai ter problemas de preciso, pois voc sabe que os postos de gasolina no podem colocar aquele terceiro digito depois da vrgula, pois no existe milsimo de real. Ento 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 no 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; /*no tem a ver com a definio do tipo.*/ /*Coloquei s pra exemplificar*/ Agora voc armazena seu dinheiro em um tipo dinheiro. Muito mais legvel, certo?

Struct
Struct uma forma de voc agrupar diversos tipos dentro de um nico, e acess-los de forma individual. Na minha opinio o recurso mais poderoso para definio de novos tipos. muito bom para juntar informaes relevantes e coloc-las em um nico lugar de facil manipulao. 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 varivel qualquer. Simples, no? Nem tanto. A sintaxe de declarao de uma variavel do tipo struct meio chata. Voc precisa dizer que aquilo uma struct: struct nome_struct minhaStruct;

aqui que entra a verdadeira mgica 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 fcil 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 especficados durante a sua criao. Por exemplo: enum {janeiro, fevereiro, marco, abril, maio, junho, julho, agosto, setembro, outubro, novembro, dezembro };

Mas como isso funciona? Cada posio recebe um valor (a partir de 0 e incrementando para cada posio) 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 no tem nome e sempre que voc for usar voc precisa colocar toda essa linha de cdigo 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 cdigo, pois muito mais elegante voc verificar se o ms janeiro do que verificar se ele 0. Tambm possvel 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 varivel. Um conceito interessante, mas que eu no vejo ser usado com muita frequncia (Usei apenas uma vez e poderia ter feito de uma forma que evitasse isso). A sintaxe de declarao 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 no tivesse feito isso, teria que escrever union antes da declarao, como acontece com struct. Para utilizar, basicamente como o struct. Possui apenas uma diferena (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 no apresenta sentido, pois o union no faz converso entre os tipos que voc coloca nele. minha_union m; m.f = 11.5; printf("%d\n", m.i);/*vai imprimir algum valor estranho*/

Você também pode gostar