Vous êtes sur la page 1sur 16

Introducao `a Computacao Cientca em C

Monica Bahiana
Departamento de Fsica dos Solidos
Instituto de Fsica
Universidade Federal do Rio de Janeiro
Captulo 1
Conhecimentos basicos
1.1 A comunicacao com o computador
O objetivo do programador e escrever um conjunto de instrucoes numa linguagem que e muito semelhante
`a usada entre seres humanos, mas usando regras de formatacao pre-denidas, que possam ser traduzidas
e passadas a uma unidade de processamento, ou CPU (Central Processing Unit), que nalmente sera a
responsavel pela execucao. O conjunto de regras e semelhante ao existente nas lnguas em geral, envolvem
denicoes de smbolos, ortograa e sintaxe. Cada conjunto de regras dene uma linguagem de programacao.
Existem muitas linguagens e, dependendo do objetivo do programador, uma pode ser mais conveniente do
que a outra. O que todas tem em comum e que no m da linha esta um processador que deve ser capaz
de executar as instrucoes, entao nosso primeiro passo e entender, minimamente, como e feita a comunicacao
com o processador. No caso da linguagem C isso e especialmente importante, porque estaremos lidando com
enderecos de memoria explicitamente. Nosso foco serao as aplicacoes que envolvem operacoes matematicas,
entao a representacao numerica sera enfatizada.
Todas as instrucoes passadas a um processador, assim como todos os dados necessarios para a execucao
de uma tarefa, serao, em algum ponto, mapeadas numa seq uencia de 0s e 1s. Isso porque os dispositivos
que armazenam essas instrucoes sao compostos de elementos que podem ter apenas dois estados, que sao
associados aos dois algarismos. Isso dene a unidade fundamental de memoria, ou de informacao, um bit. A
palavra bit em ingles signica um pedaco muito pequeno. Em geral nos referimos a grupos de 8 bits, que sao
chamados bytes. A esses dispositivos de armazenamento chamamos genericamente de memoria. Em um
computador tpico existem diversos tipos de memoria, em geral baseadas em semicondutores ou materiais
magneticos. As caractersticas dessas memorias compreendem: capacidade de armazenamento, rapidez para
troca de informacao, estabilidade e custo.
Para a programacao o maior interesse esta nas memorias de acesso aleatorio, ou RAM (Random Access
Memory), que sao em geral semicondutoras. A designacao acesso aleatorio, refere-se ao fato de que pode-se
retirar informacao armazenada em qualquer posicao de forma independente. O oposto disso e a memoria
seq uencial (por exemplo um dispositivo de armazenamento tipo ta cassete), no qual toda a parte anterior
deve ser percorrida para se chegar a um determinado ponto. Para entender como funciona a RAM podemos
imagina-la como uma matriz de celulas. Associados a cada celula de memoria existem dois itens: o conte udo
da celula e o seu endereco, ou seja a sua posicao na matriz. Cada vez que a CPU necessita de uma
determinada informacao contida na RAM, deve colocar o endereco referente `a localizacao da informacao
desejada no transportador de enderecos ou address bus, e esperar ate que o transportador de dados, ou
data bus, traga o conte udo da localiza cao especicada, que e entao copiado para os registros (que sao
memorias na CPU). As operacoes sao efetuadas entre os conte udos dos registros. Na verdade existem nveis
intermediarios entre os registros e a RAM, que sao os nveis cache. A memoria cache e um um reservatorio
pequeno mas de rapido acesso, que permite que a CPU trabalhe de forma contnua, sem ter que esperar
por dados vindos da RAM. Os dados sao extrados da RAM em grupos de 4 ou 8 bytes (32 ou 64 bits)
de cada vez. O tempo tpico de uma troca de dados entre a RAM e a CPU e 90 ns (90 10
9
s), o que
e muito comparado com o tempo tpico de um ciclo de um processador. Por exemplo, um processador de
1 GHz (10
9
Hz) tem um ciclo de 1 ns, por isso as memorias cache sao necessarias. A gura 1.1 mostra o
1
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 2
esquema basico das diversas memorias em um computador caseiro tpico. Os detalhes de como e feita essa
Figura 1.1: Esquema de organizacao de memoria em um computador tpico.
troca de informacao, de como estao relacionadas as diversas memorias, e de como e o funcionamento de
um processador sao muito interessantes, mas estao fora do nosso objetivo. A pagina da Intel traz diversas
informacoes sobre todos os seus processadores, com disponibilidade de documentacao para download [1], mas
o conte udo dos manuais e extremamente tecnico. Uma versao mais amigavel pode ser encontrada no classico
The Winn Rosch Hardware Bible [2], atualmente ja na sexta edicao. Tambem ha diversos sites que trazem
informacao a esse respeito [3, 4]. O importante neste momento e entender dois conceitos:
1. Toda a informacao devera ser representada, na sua forma nal, por uma seq uencia nita de 0s e 1s.
2. Para que nossas instrucoes sejam executadas pela CPU e preciso que a mesma tenha acesso ao endereco
de armazenamento dos dados necessarios na RAM.
1.2 Representacao binaria de n umeros inteiros, reais e caracteres
Vamos iniciar pelo caso mais simples, n umeros inteiros positivos. Estamos acostumados a trabalhar com
a base decimal que tem 10 algarismos. Quando escrevemos um n umero inteiro nessa base, estamos nos
referindo `as potencias de 10 existentes nele. Por exemplo
2367 = 7 10
0
+ 6 10
1
+ 3 10
2
+ 2 10
3
.
Na base binaria temos apenas dois algarismos, 0 e 1, que devem informar sobre as potencias de 2 existentes
no n umero. Por exemplo
11001 = 1 2
0
+ 0 2
1
+ 0 2
2
+ 1 2
3
+ 1 2
4
.
O n umero 11001 na base binaria vale 25 na base decimal. Para passar um n umero decimal para a base
binaria, usamos a divisao seq uencial por 2. Por exemplo, para o n umero 43, temos
43 = 2 21 + 1 2
0
(1.1)
= 2 (2 10 + 1 2
0
) + 1 2
0
= 2
2
10 + 1 2
1
+ 1 2
0
= 2
2
(2 5 + 0 2
0
) + 1 2
1
+ 1 2
0
= 2
3
5 + 0 2
2
+ 1 2
1
+ 1 2
0
= 2
3
(2 2 + 1 2
0
) + 0 2
2
+ 1 2
1
+ 1 2
0
= 2
4
2 + 1 2
3
+ 0 2
2
+ 1 2
1
+ 1 2
0
= 2
4
(2 1 + 0 2
0
) + 1 2
3
+ 0 2
2
+ 1 2
1
+ 1 2
0
= 1 2
5
+ 0 2
4
+ 1 2
3
+ 0 2
2
+ 1 2
1
+ 1 2
0
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 3
Assim, numa representacao de 8 bits (8 algarismos), 43 = 00101011. Note que os 0s e 1s vieram dos restos
das divisoes por 2.
O valor maximo dos n umeros que podemos usar nos calculos ca limitado pelo n umero de bits usados
para representa-los. Suponha que num determinado computador, os n umeros inteiros sao armazenados em 1
byte. Como 1 byte = 8 bits, isso signica que poderemos representar n umeros com seq uencias de 8 algarismos
correspondendo `a presenca das potencias de 2
0
a 2
7
. O maior n umero que poderemos escrever, neste caso e
11111111 = 1 2
0
+ 1 2
1
+ 1 2
2
+ 1 2
3
+ 1 2
4
+ 1 2
5
+ 1 2
6
+ 1 2
7
,
que e 255 na base 10. Os n umeros menores que 255 terao os bits desnecessarios preenchidos por 0s. Note
que as opera coes de multiplicar e dividir por 2 signicam deslocar para a esquerda e direita, respectivamente,
os bits de um n umero, preenchendo os novos bits com 0. Exemplo com 4 bits: 2 = 0010, 4 = 0100, 8 = 1000.
Para que um inteiro com sinal seja gravado nos mesmos 8 bits, teremos que usar um bit para o sinal,
por exemplo 1 se for um n umero negativo e 0 se for positivo. Restam, assim, 7 bits para a representacao do
valor do n umero. Neste caso, poderamos ter n umeros entre -127 e 127 na base 10.
A base hexadecimal tambem e muito usada, porque permite escrever n umeros grandes com poucos alga-
rismos. Os enderecos de memoria em geral sao escritos nessa base. Neste caso precisamos de 16 algarismos,
que sao os algarismos 0-9, mais as letras A, B, C, D, E e F, valendo 10, 11, 12, 13, 14 e 15 respectivamente.
O n umero 2367 na base 10, ca escrito como 93F, 11001 na base binaria ca 19 na hexadecimal.
A representacao de caracteres e equivalente `a dos inteiros sem sinal. As letras (mai usculas e min usculas)
e outros caracteres, tais como ponto, vrgula, nova linha, tabulacao, sao associados a um inteiro sem sinal
de 1 byte, formando a conhecida tabela ASCII (American Standard Code for Information Interchange). De
acordo com essa tabela, a letra a vale 097, A vale 065, o smbolo # vale 035, e assim por diante. A tabela
completa esta no Apendice A.
A representacao dos n umeros reais e bem mais complicada. Na verdade o computador so entende n umeros
inteiros, entao o n umero real deve ser representado a partir de n umeros inteiros, na forma
s M B
E
, (1.2)
onde s e o bit referente ao sinal do n umero, M e a mantissa, B a base (2 em geral), e E e o expoente. Por
exemplo, um real de 4 bytes, ou 32 bits, e tipicamente escrito com 1 bit para o sinal, 23 para a mantissa e 8
para o expoente. Sua representacao na memoria sera uma seq uencia de 32 bits, com a convencao: o primeiro
(mais `a esquerda) e o sinal, os 8 proximos o valor do expoente (vamos supor que a base seja binaria), e os 23
seguintes a mantissa. Para que nao seja necessaria a reserva de um bit de sinal para o expoente, o n umero
todo e multiplicado por um valor na forma B
E
, e os 8 bits do expoente passam a representar um inteiro
sem sinal, que podera ir de 0 a 255. Para um dado valor de E muitas denicoes de mantissa e expoente sao
possveis. Vamos ver um exemplo, algumas representacoes do n umero real 3.0 (= 2
0
+ 2
1
), para B = 2 e
E = 151. O bit de sinal e denido como 0 para n umeros positivos e 1, para negativos.
bit de sinal expoente com 8 bits mantissa com 23 bits
0 10010111 00000000000000000000011
0 10000110 00000000001100000000000
0 10000010 11000000000000000000000
Tabela 1.1: Possveis representacoes do um n umero real 3.0 com 4 bytes. Os 32 bits estao divididos em 1
bit para sinal, 8 para expoente e 23 para mantissa. O n umero foi multiplicado por 2
151
. Na primeira linha
temos (2
1
+ 2
0
) 2
151
, na segunda, (2
12
+ 2
11
) 2
140
, e na terceira, (2
22
+ 2
21
) 2
130
Para obter a melhor precisao possvel, sempre e escolhida a representacao com os bits da mantissa
deslocados ao maximo para a esquerda, no caso das representacoes apresentadas na tabela 1.1, a terceira
seria preferida. A tabela 1.2 mostra outros exemplos, analise-os e entenda como as representacoes foram
obtidas.
A aritmetica entre n umeros reais e problematica por causa do n umero nito de bits da mantissa. Veja
o que ocorre se realizamos a operacao 3 + 10
7
. Para efetuar a operacao temos que igualar os expoentes.
O expoente de 10
7
e 105, para torna-lo 130 temos que compensar, dividindo a mantissa por 2
25
, o que
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 4
n umero bit de sinal expoente com 8 bits mantissa com 23 bits
1/2 1 10000000 10000000000000000000000
3 0 1000010 11000000000000000000000
1/4 0 01111111 10000000000000000000000
10
7
0 01101001 11010110101111111001010
Tabela 1.2: Representacao de um n umero real com 4 bytes. Os 32 bits estao divididos em 1 bit para sinal,
8 para expoente e 23 para mantissa.
signica deslocar os bits da mantissa 25 casas para a direita, e preencher os bits `a esquerda com zero. Como
so temos 23 bits, a mantissa ca nula, ou seja 10
7
transforma-se em zero nessa operacao. Este e um exemplo
extremo, mas casos em que varios bits sao perdidos para essa compensacao de mantissa sao muito comuns,
e e uma causa seria de perda de precisao em calculos numericos. Como em geral nao se pode deixar de
usar n umeros reais, deve-se ter muito cuidado com esse tipo de problema e tentar evitar situacoes como o
exemplo acima.
1.3 Ordens de grandeza
Bytes(8 bits)
0.1 bytes: Uma decisao binaria.
1 byte: Um caracter.
10 bytes: Uma palavra.
100 bytes: Uma frase.
Kilobyte (10
3
bytes)
1 Kilobyte: Uma estoria muito curta.
2 Kilobytes: Uma pagina datilografada.
10 Kilobytes: Uma pagina de enciclopedia.
50 Kilobytes: A imagem de uma pagina de documento, comprimida.
100 Kilobytes: Uma foto com baixa resolucao. A RAM dos computadores caseiros por volta de
1985.
Megabyte (10
6
bytes)
1 Megabyte: Um romance pequeno. Um disquete.
2 Megabytes: Uma foto de alta resolucao. Kernigham & Ritchie versao DJVU.
5 Megabytes: A obra completa de Shakespeare. 30 segundos de vdeo com qualidade TV. Um
arquivo MP3 de m usica popular, delidade media.
10 Megabytes: Um minuto de som de alta delidade. Um raio-X digital do torax. A RAM dos
computadores caseiros em 1990.
50 Megabytes: Um mamograma digital. Um disco rgido caseiro (muito grande!) em 1987.
100 Megabytes: 1 metro de livros numa estante.
500 Megabytes: Um CD-ROM.
Gigabyte (10
9
bytes)
1 Gigabyte: A cacamba de uma pickup cheia de papel datilografado. O som de uma sinfonia
gravada em alta delidade. Um lme com qualidade TV.
2 Gigabytes: 20 metros de livros numa estante.
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 5
10 Gigabytes: A pasta com as m usicas eletronicas da minha lha. (Paula, voce tem que limpar
esse disco!)
20 Gigabytes: Uma boa colecao de obras de m usica classica.
50 Gigabytes: Um piso inteiro coberto de livros.
100 Gigabytes: Um piso inteiro coberto de revistas cientcas.
1.4 Primeiro programa
A unica maneira de se aprender uma nova linguagem e escrevendo programas com ela, entao, antes de
continuarmos, vamos logo escrever e executar nosso primeiro programa em C. O programa deve instruir a
CPU a escrever na tela de seu monitor a frase
oi, mundo
Em C, um possvel codigo para executar essa tafera e:
#include <stdio.h>
void main(void)
{
printf("oi, mundo\n");
}
Use um editor qualquer (ex: gedit, emacs, vi) para escrever o texto acima, e salve-o com o nome (por
exemplo) oi.c. Abra uma janela terminal, va para o diretorio onde esta o arquivo oi.c, e crie o arquivo
binario que executara seu programa, com o comando:
gcc -o oi oi.c
Aqui, gcc invoca compilador C com a op cao o (as opcoes aparecem sempre na forma -opcao) que signica
que o arquivo executavel tera o nome especicado a seguir ( oi, no caso), em vez do nome default a.out. Se
tudo correu bem voce devera ter no seu diretorio os arquivos oi.o e oi, alem do oi.c original. Dependendo
de como voce deniu o comando ls voce vera um * ao lado do nome do executavel, ou o vera em uma cor
diferente. Para executar o programa de o (agora) comando ./oi. Na sua tela aparecera
oi, mundo
Agora algumas explicacoes sobre o codigo propriamente dito. Um codigo em C, de qualquer tamanho que
seja, consiste de funcoes e variaveis. Uma funcao contem expressoes que especicam as operacoes que
devem ser realizadas, usando as variaveis declaradas nela. Uma funcao em geral contem outras funcoes,
e a comunicacao entre funcoes se da pelo argumento, e pelo resultado do calculo da funcao chamada. No
nosso exemplo temos a funcao de nome main (que signica principal em ingles), chamando a funcao printf.
Normalmente voce tem a liberdade de escolher qualquer nome para as funcoes, mas main e especial - seu
programa comeca a execucao no incio de main. Isso signica que todo programa deve ter uma funcao main
em alguma parte. A expressao void main(void) indica que main e do tipo void, vazio em ingles, e tem uma
lista de argumentos tambem vazia. Veremos no Captulo ?? o que isso signica. O par de chaves , { }, dene
os limites do bloco que contem as instru coes da funcao. Embora possamos iniciar as linhas em qualquer
coluna, costuma-se recuar de um espaco de tabulacao cada vez que um bloco e iniciado. A chave que fecha
um bloco deve car alinhada com a que abre. Um codigo em geral tem varios blocos, inclusive aninhados,
se esses alinhamentos sao mantidos, ca muito mais facil de ler e entender o codigo. Para o compilador nao
faz diferen ca, mas para o ser humano faz muita!
A funcao printf e chamada para escrever a seq uencia de caracteres indicada entre aspas, na tela. Esta
e uma das funcoes de entrada e sada de dados, denida na biblioteca padrao.
A primeira linha do codigo,
#include <stdio.h>
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 6
faz com que o compilador inclua informacao sobre a biblioteca padrao (standard) para input/output (entrada
ou sada de informacao, ou I/O, de forma abreviada); esta linha aparece no comeco de varios codigos em C,
sempre que for preciso usar as funcoes para leitura ou sada de dados. No Captulo ?? veremos mais detalhes
sobre esse assunto.
Os parenteses apos a chamada da funcao envolvem a lista de argumentos. Neste exemplo, main e denida
como uma funcao que nao precisa de argumentos, por isso apresenta uma lista vazia (void). A funcao main
contem apenas uma expressao,
printf("oi, mundo\n");
onde o sinal ; determina o nal do comando. Por sua vez, printf e uma funcao com o argumento
"oi, mundo\n". printf e uma funcao cuja tarefa e imprimir dados de sada, que neste caso sao a cadeia de
caracteres entre aspas, no standard output, que aqui e o terminal. A seq uencia \n e a notacao para caracter
linha nova que, quando impresso, avanca a sada para a margem esquerda da linha seguinte. Se voce nao
coloca o \n (experimente!) a proxima sada se dara na mesma linha anterior.
1.5 Tipos de variaveis em C
Na linguagem C precisamos especicar o tipo de todas as variaveis. No incio de cada bloco de codigo sao
feitas as declaracoes de variaveis, que sao expressoes que denem o nome e o tipo das variaveis que serao
usadas. Na escolha dos nomes de variaveis as letras min usculas sao diferenciadas das mai usculas, os nomes
podem conter letras e n umeros, mas devem iniciar por uma letra. O uso de letras min usculas e uma tradicao
em C. Alguns exemplos de declaracoes sao
float x, y, a;
int q, p;
char n, r;
Aqui, x, y e a sao variaveis reais (oating point), p e q sao inteiras (integer) e n e r caracteres (characters.
Essas expressoes tem o efeito de solicitar que sejam reservados espacos de memoria com o tamanho e estrutura
especcos de cada tipo, e associa-los aos nomes que escolhemos. O valor inicial das variaveis em geral e
algum lixo, essencialmente o conte udo que ja existia naquela posicao de memoria.
Outros tipos tambem muito usados sao double, para n umeros reais com o dobro de bits do que float,
e long para n umeros inteiros com mais bits do que int.
O n umero de bytes reservado para cada tipo de variavel depende de cada computador. Podemos descobrir
esses valores com o uso do operador sizeof. Veja o codigo de sizes.c abaixo.
#include <stdio.h>
void main(void)
{
printf("um inteiro tem %d bytes\n",sizeof(int));
printf("um inteiro longo tem %d bytes\n",sizeof(long));
printf("um inteiro curto tem %d bytes\n",sizeof(short));
printf("um real tem %d bytes\n",sizeof(float));
printf("um real duplo tem %d bytes\n",sizeof(double));
printf("um caracter tem %d bytes\n",sizeof(char));
}
Neste exemplo estamos usando a funcao printf com dois argumentos, separados por vrgulas. O primeiro
e uma seq uencia de caracteres, e o segundo um n umero inteiro, resultante da operacao de sizeof sobre os
varios tipos de variavel. O n umero inteiro sera substitudo na posicao indicada por %, e escrito na tela
com o formato especicado, d no caso, que e um formato default para entrada e sada de valores inteiros.
Veremos mais sobre isso no Captulo 2.
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 7
1.6 Operacoes aritmeticas simples
Os operadores aritmeticos binarios
a
sao +, -, *, / e %, eles denem soma, subtracao, multiplicacao, divisao
e resto, respectivamente. O signicado dos quatro primeiros e obvio. O operador % da como resultado o
resto da divisao de dois n umeros. O smbolo = e usado para atribuir valores a variaveis. Veja o exemplo
abaixo,onde um fragmento de codigo e destacado.
float x, a; Sao reservados blocos de memoria para x e a.
a = 2.0; O valor 2.0 e armazenado no espaco associado a a.
x = 10.5;O valor 10.5 e armazenado no espaco associado a x.
x = a*x; O valor armazenado no espaco associado a x e trocado para 21.0.
Numa expressao composta de varias operacoes aritmeticas a ordem com que as mesmas sao executadas
depende da precedencia dos operadores. *, / e % tem a mesma precedencia, e tem precedencia sobre as
opera coes + e . No caso de operacoes com mesma precedencia, a execucao e feita da esquerda para a
direita. Por exemplo,
float x,y;
x = 1.0;
y = 1./x+1.0;
A opera cao 1./x sera realizada primeiro, e o valor de y sera 2.0. Se quisermos que a divisao seja feita por
x+1.0, entao podemos forcar a precedencia usando parenteses. Por exemplo, se escrevemos
float x,y;
x = 1.0;
y = 1./(x+1.0);
o valor de y sera 0.5.
Operacoes entre variaveis de tipo diferente
Se um operador atua entre operandos de tipos diferentes, o operando de tipo mais restrito sera promovido
ao tipo menos restrito, e o resultado sera desse tipo. Por exemplo, na operacao a+x, se a e int e x e float,
primeiro a sera promovido a float, e depois somado a x. O resultado sera float. Se esse resultado e
atribudo a uma variavel, o tipo dela sera usado como cast. No exemplo que acabamos de ver, se fazemos o
resultado float ser atribudo a uma variavel int, a parte decimal sera truncada. Veja outro exemplo:
float x,y;
int a,b;
x = 2.0;
a = 1;
y = a/x;
b = a/x;
Neste caso y vale 0.5 e b, 0. Note que essa truncagem, misturada a descuido com relacao `a precedencia pode
gerar muitos desastres. Observe o exemplo abaixo, e tente entender o que sera escrito na tela.
//intfloat.c
#include <stdio.h>
void main(void)
{
int a, b, c;
float cf, bf;
a
Operadores binarios requerem dois operandos, operadores unarios, apenas um
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 8
a = 2;
b = 3.99;
bf = 3.99;
printf("a = %d b = %d \n", a, b);
c = a/b; //c = 0
printf("c = %d\n", c);
c = c+2; //c = 2
printf("c = %d\n", c);
cf = c/3; //cf = 0
printf("cf = %f\n", cf);
cf = c/3.0; //cf = 0.6666667
printf("cf = %f\n", cf);
cf = a/bf; //cf = 0.501253
printf("cf = %f\n", cf);
cf = a/b*a; //cf = 0.00000
printf("cf = %f\n", cf);
cf = a*a/b; //cf = 1.00000
printf("cf = %f\n", cf);
}
Neste exemplo ha dois novos elementos: o formato %f para escrever n umeros do tipo float, e o smbolo //
que faz com que o resto da linha seja ignorado pelo compilador.

E uma otima forma de se colocar comentarios
e explica coes que tornem o codigo mais compreensvel.
Finalmente pode-se alterar o tipo de uma variavel ou expressao com um operador unario de cast, que
signica molde em ingles. A operacao tem a forma (tipo) express~ao. Por xemplo, se x e y sao float,
(int)(x+y) e do tipo int. O efeito e o mesmo da atribuicao a uma variavel do tipo desejado, mas deixa
mais claro qual a conversao pretendida.
1.7 Entrada de n umeros pelo teclado
A biblioteca padrao tem diversas funcoes para que valores digitados durante a execucao sejam usados pelo
programa. Aqui vamos ver uma delas, a scanf, diretamente num exemplo, um progama que pede que se
entre com dois n umeros, calcula a soma deles e escreve na tela o resultado.
//lenum.c
#include <stdio.h>
void main(void)
{
float a, b, soma;
printf("Digite os valores de a e b\n");
scanf("%f %f",&a, &b);
soma = a + b;
printf(" A soma e %f\n",soma);
}
O primeiro argumento de scanf e uma seq uencia de caracteres que dene quantos valores serao lidos, e de
que tipo sao, e depois da vrgula, a lista com os enderecos das variaveis que terao seus valores atribudos.
O operador unario & da o endereco de memoria de uma determinada variavel, a funcao scanf precisa dessa
informacao para funcionar. Assim como printf, a lista de formatos sera casada com a lista depois da vrgula.
Espa cos em branco, tabs e caracteres de nova linha sao ignorados na leitura. scanf segue buscando valores
para satisfazer sua lista de formatos. Se estamos entrando dados pelo teclado, isso signica que seu programa
cara esperando a digitacao de tantos dados quantos forem especicados na lista de formatos.
As principais fontes de erro no uso de scanf sao: colocar o nome da variavel e nao seu endereco, ter listas
de formatos incompatvel com a lista de enderecos, seja por n umero de campos seja por tipo de variavel.
Esses erros em geral nao sao detectados na compilacao.
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 9
1.8 Entrada e sada de caracteres
A entrada de caracteres pelo teclado pode ser feita com scanf usando o formato %c ou %1s. Na primeira
forma os espacos em branco nao sao ignorados. A sada pode ser feita com printf usando o formato %c.
Segue um exemplo de seu uso.
#include <stdio.h>
// lechar.c
void main(void)
{
char a, b;
float x,y,soma;
printf("Digite os valores de x e y\n");
scanf("%f %f",&x, &y);
soma = x+y;
printf(" A soma e %f\n",soma);
printf("Digite duas letras\n");
scanf("%1s %1s",&a, &b);
printf(" As letras digitadas sao %c e %c \n",a,b);
}
Modique o codigo colocando scanf("%c %c",&a, &b); no lugar de scanf("%1 s %1 s",&a, &b); e veja
que o enter que segue a leitura dos dados numericos acaba sendo lido erradamente.
Os caracteres podem ser acessado pelo seu valor na tabela ASCII, ou diretamente pelo caracter. Veja
como:
// ascii.c
#include <stdio.h>
void main(void)
{
char c;
c = &;
printf("\n a letra e %c e seu valor ASCII e %d\n\n",c,c);
c = 64;
printf("\n a letra e %c e seu valor ASCII e %d\n\n",c,c);
}
1.9 Exerccios
1. O comando man em Linux refere-se a manual, ele da informacoes sobre comandos de uma forma geral.
Procure mais informacao sobre o compilador gcc usando o comando man gcc. Verique as opcoes de
otimizacao.
2. (a) Suponha que voce tenha 1 byte para representar os n umeros inteiros. Escreva os n umeros abaixo
na forma binaria, usando todos os algarismos disponveis.
i. 9
ii. 18
iii. 36
iv. 137
v. 321
(b) Os n umeros abaixo foram escritos na base hexadecimal, passe-os para a base decimal.
CAP

ITULO 1. CONHECIMENTOS B

ASICOS 10
i. 45F7
ii. FFCC0
iii. CCF99
iv. ABCD
(c) Escreva os n umeros reais abaixo na base binaria, usando a forma 1.2, assim como foi feito na
tabela 1.2.
i. -10
ii. 1/8
iii. 5
3. Fa ca alguns testes com o programa oi.c.
(a) Modique-o para que escreva outra frase. Salve o arquivo com outro nome, compile e execute.
(b) Compile sem a opcao -o e verique a criacao de um executavel de nome a.out.
(c) Elimine o ; do nal da linha, compile e veja que tipo de mensagem de erro aparece.
(d) Recoloque o ;. Agora elimine o # include <stdio.h> compile e veja que tipo de mensagem de
erro aparece.
4. Use um editor para escrever o codigo que calcula os tamanhos de variaveis, usando o operador sizeof.
Salve o arquivo com o nome qualquer com a extensao .c (ex:sizes.c). Compile-o e execute-o. Registre
o tamanhos retornados.
5. Indique o que esta errado no codigo abaixo:
#include <stdio.h>
void main(void)
{
int a, b;
double x, y;
x = 2*y;
scanf("%f",&y);
printf("x = %f\n",x);
printf("entre com os valores de a e b\n")
scanf("%f %d",a,b);
x = (float)a/b;
}
6. Escreva o codigo de um programa que
(a) Pede o valor de um angulo em graus, pelo teclado, calcula e escreve na tela seu valor em radianos.
(b) Pede o valor de uma temperatura em graus Celsius, pelo teclado, calcula e escreve na tela seu
valor em Farenheit.
Apendice A
Tabela ASCII
ASCII (The American Standard Code for Information Interchange) e um padrao de representacao de car-
acteres proposto pelo ANSI (American National Standards Institute) em 1963 e nalizado em 1968, com
o objetivo de padronizar dados entre diversos equipamentos de processamento de dados. Os 32 primeiros
smbolos sao caracteres de controle, e tem pouco interesse para nos. Os seguintes referem-se aos algarismos,
letras mai usculas e min usculas e varias pontuacoes,
O nome ASCII, pronunciado como asqui e usado muitas vezes quando queremos qualicar um documento
sem qualquer formatacao, e portanto compatvel com qualquer software. A lngua portuguesa requer que
usemos diversos smbolos que nao fazem parte da tabela ASCII, sao todos os caracteres acentuados e a
cedilha, isso faz varios textos de e-mails quem ilegveis para quem os le. Para garantir que tudo o que voce
escreve sera lido exatamten do esmo jeito, independente do comptuador ou do software usado, retrinja-se
aos sm bolos da tabela ASCII. Alem da portabilidade, voce estara gerando arquivos menores, ja que cada
caracter estara ocupando apenas 1 byte de memoria.
Existe uma tabela ASII estendida, com mais 128 smbolos, mas nao e padronizada e nao e lida por
diversos aplicativos.
11
AP

ENDICE A. TABELA ASCII 12


Decimal Octal Hex Binario Valor Descricao
000 000 000 00000000 NUL (Null char.)
001 001 001 00000001 SOH (Start of Header)
002 002 002 00000010 STX (Start of Text)
003 003 003 00000011 ETX (End of Text)
004 004 004 00000100 EOT (End of Transmission)
005 005 005 00000101 ENQ (Enquiry)
006 006 006 00000110 ACK (Acknowledgment)
007 007 007 00000111 BEL (Bell)
008 010 008 00001000 BS (Backspace)
009 011 009 00001001 HT (Horizontal Tab)
010 012 00A 00001010 LF (Line Feed)
011 013 00B 00001011 VT (Vertical Tab)
012 014 00C 00001100 FF (Form Feed)
013 015 00D 00001101 CR (Carriage Return)
014 016 00E 00001110 SO (Shift Out)
015 017 00F 00001111 SI (Shift In)
016 020 010 00010000 DLE (Data Link Escape)
017 021 011 00010001 DC1 (XON) (Device Control 1)
018 022 012 00010010 DC2 (Device Control 2)
019 023 013 00010011 DC3 (XOFF) (Device Control 3)
020 024 014 00010100 DC4 (Device Control 4)
021 025 015 00010101 NAK (Negative Acknowledgement)
022 026 016 00010110 SYN (Synchronous Idle)
023 027 017 00010111 ETB (End of Trans. Block)
024 030 018 00011000 CAN (Cancel)
025 031 019 00011001 EM (End of Medium)
026 032 01A 00011010 SUB (Substitute)
027 033 01B 00011011 ESC (Escape)
028 034 01C 00011100 FS (File Separator)
029 035 01D 00011101 GS (Group Separator)
030 036 01E 00011110 RS (Request to Send)(Record Separator)
031 037 01F 00011111 US (Unit Separator)
032 040 020 00100000 SP (Space)
AP

ENDICE A. TABELA ASCII 13


Decimal Octal Hex Binario Valor Descricao
033 041 021 00100001 ! (exclamation mark)
034 042 022 00100010 (double quote)
035 043 023 00100011 # (number sign)
036 044 024 00100100 $ (dollar sign)
037 045 025 00100101 % (percent)
038 046 026 00100110 & (ampersand)
039 047 027 00100111 (single quote)
040 050 028 00101000 ( (left/opening parenthesis)
041 051 029 00101001 ) (right/closing parenthesis)
042 052 02A 00101010 * (asterisk)
043 053 02B 00101011 + (plus)
044 054 02C 00101100 , (comma)
045 055 02D 00101101 - (minus or dash)
046 056 02E 00101110 . (dot)
047 057 02F 00101111 / (forward slash)
048 060 030 00110000 0
049 061 031 00110001 1
050 062 032 00110010 2
051 063 033 00110011 3
052 064 034 00110100 4
053 065 035 00110101 5
054 066 036 00110110 6
055 067 037 00110111 7
056 070 038 00111000 8
057 071 039 00111001 9
058 072 03A 00111010 : (colon)
059 073 03B 00111011 ; (semi-colon)
060 074 03C 00111100 > (less than)
061 075 03D 00111101 = (equal sign)
062 076 03E 00111110 > (greater than)
063 077 03F 00111111 ? (question mark)
064 100 040 01000000 @ (AT symbol)
065 101 041 01000001 A
066 102 042 01000010 B
067 103 043 01000011 C
068 104 044 01000100 D
069 105 045 01000101 E
070 106 046 01000110 F
071 107 047 01000111 G
072 110 048 01001000 H
073 111 049 01001001 I
074 112 04A 01001010 J
075 113 04B 01001011 K
076 114 04C 01001100 L
077 115 04D 01001101 M
078 116 04E 01001110 N
079 117 04F 01001111 O
080 120 050 01010000 P
081 121 051 01010001 Q
082 122 052 01010010 R
083 123 053 01010011 S
084 124 054 01010100 T
085 125 055 01010101 U
086 126 056 01010110 V
087 127 057 01010111 W
088 130 058 01011000 X
089 131 059 01011001 Y
090 132 05A 01011010 Z
AP

ENDICE A. TABELA ASCII 14


Decimal Octal Hex Binario Valor Descricao
091 133 05B 01011011 [ (left/opening bracket)
092 134 05C 01011100 \ (back slash)
093 135 05D 01011101 ] (right/closing bracket)
094 136 05E 01011110 ^ (caret/cirumex)
095 137 05F 01011111 (underscore)
096 140 060 01100000
097 141 061 01100001 a
098 142 062 01100010 b
099 143 063 01100011 c
100 144 064 01100100 d
101 145 065 01100101 e
102 146 066 01100110 f
103 147 067 01100111 g
104 150 068 01101000 h
105 151 069 01101001 i
106 152 06A 01101010 j
107 153 06B 01101011 k
108 154 06C 01101100 l
109 155 06D 01101101 m
110 156 06E 01101110 n
111 157 06F 01101111 o
112 160 070 01110000 p
113 161 071 01110001 q
114 162 072 01110010 r
115 163 073 01110011 s
116 164 074 01110100 t
117 165 075 01110101 u
118 166 076 01110110 v
119 167 077 01110111 w
120 170 078 01111000 x
121 171 079 01111001 y
122 172 07A 01111010 z
123 173 07B 01111011 { (left/opening brace)
124 174 07C 01111100 | (vertical bar)
125 175 07D 01111101 } (right/closing brace)
126 176 07E 01111110 ~ (tilde)
127 177 07F 01111111 DEL (delete)
Bibliograa
[1] Intel Coporporation. IA-32 Intel Architecture Software Developers Manual.
http://support.intel.com/design/Pentium4/documentation.htm, 2004.
[2] Winn L. Rosch. The Winn L. Rosch Hardware Bible (6th Edition). Que, 2003.
[3] http://computer.howstuworks.com/computer-memory.htm.
[4] http://arstechnica.com/paedia/r/ram guide/ram guide.part1-1.html.
15

Vous aimerez peut-être aussi