Professional Documents
Culture Documents
Fundamentos de
Linguagem C
ou
Tudo que voc precisa saber sobre C para no passar vergonha!
Suplentes
Diretoria SENAI - SR
Diretor Regional
Jos Zorta
Diretor Tcnico
Paulo Fernando Presser
Diretor Administrativo e Financeiro
Adalberto Luiz Lenhard
5
Apresentao
Adalberto A. Dornelles F.
1. Fundamentos da Linguagem C
1.1
Linguagens de Programao
Exemplos de cdigos.
10 input num
20 for n = 1 to 10 step 1
30 let tab = num * n
40 print chr$ (tab)
50 next n
Exemplo: trecho do mesmo programa escrito em linguagem Fortran:
read (num);
do 1 n = 1:10
tab = num * n
write(tab)
10 continue
Exemplo: trecho do mesmo programa escrito em linguagem Assembly para INTEL 8088:
MOV CX,0
IN
AX,PORTA
MOV DX,AX
LABEL:
INC CX
MOV AX,DX
MUL CX
OUT AX, PORTA
CMP CX,10
JNE LABEL
1.1.2
Linguagens de alto nvel: So linguagens voltadas para o ser humano. Em geral utilizam sintaxe
estruturada tornando seu cdigo mais legvel. Necessitam de compiladores ou interpretadores para gerar
instrues do microprocessador. Interpretadores fazem a interpretao de cada instruo do programa
fonte executando-a dentro de um ambiente de programao, Basic e AutoLISP por exemplo.
Compiladores fazem a traduo de todas as instrues do programa fonte gerando um programa
executvel. Estes programas executveis (*.exe) podem ser executados fora dos ambientes de
programao, C e Pascal por exemplo. As linguagens de alto nvel podem se distinguir quanto a sua
aplicao em genricas como C, Pascal e Basic ou especficas como Fortran (clculo matemtico),
GPSS (simulao), LISP (inteligncia artificial) ou CLIPPER (banco de dados).
Vantagens: Por serem compiladas ou interpretadas, tem maior portabilidade podendo ser
executados em varias plataformas com pouqussimas modificaes. Em geral, a programao torna-se
mais fcil por causa do maior ou menor grau de estruturao de suas linguagens.
Desvantagens: Em geral, as rotinas geradas (em linguagem de maquina) so mais genricas e
portanto mais complexas e por isso so mais lentas e ocupam mais memria.
1.2
Linguagem C
A linguagem C uma linguagem de alto nvel, genrica. Foi desenvolvida por programadores
para programadores tendo como meta caractersticas de flexibilidade e portabilidade. O C uma
linguagem que nasceu juntamente com o advento da teoria de linguagem estruturada e do computador
pessoal. Assim tornou-se rapidamente uma linguagem popular entre os programadores. O C foi usado
para desenvolver o sistema operacional UNIX, e hoje esta sendo usada para desenvolver novas
linguagens, entre elas a linguagem C++ e Java.
1.2.1
Caractersticas do C
O C compartilha recursos tanto de alto quanto de baixo nvel, pois permite acesso e programao
direta do microprocessador. Com isto, rotinas cuja dependncia do tempo crtica, podem ser
facilmente implementadas usando instrues em Assembly. Por esta razo o
C a linguagem
Histrico
1970: Denis Ritchie desenha uma linguagem a partir do BCPL nos laboratrios da Bell Telephones, Inc.
Chama a linguagem de B.
1978: Brian Kerningham junta-se a Ritchie para aprimorar a linguagem. A nova verso chama-se C.
Pelas suas caractersticas de portabilidade e estruturao j se torna popular entre os
programadores.
~1980: A linguagem padronizada pelo American National Standard Institute: surge o ANSI C.
~1990: A Borland International Co, fabricante de compiladores profissionais escolhe o C e o Pascal
como linguagens de trabalho para o seu Integrated Development Enviroment (Ambiente Integrado
de Desenvolvimento): surge o Turbo C.
~1992: O C se torna ponto de concordncia entre tericos do desenvolvimento da teoria de Object
Oriented Programming (programao orientada a objetos): surge o C++.
1.3
Estrutura de um programa em C
Conjunto de caracteres
Comentrios
Em C, comentrios podem ser escritos em qualquer lugar do texto para facilitar a interpretao do
algoritmo. Para que o comentrio seja identificado como tal, ele deve ter um /* antes e um */ depois.
Observe que no exemplo e0101.cpp todo o cabealho esta dentro de um comentrio.
Exemplo:
/* esta e uma linha de comentrio em C */
Observao: O C++ permite que comentrios sejam escritos de outra forma: colocando um //
em uma linha, o compilador entender que tudo que estiver a direita do smbolo um comentrio.
Observe no programa exemplo e0101.cpp as linhas de comentrios colocadas a direita dos comandos.
Exemplo:
// este e um comentrio valido apenas em C++
1.3.3
Diretivas de Compilao
Declarao de variveis
Em C, como na maioria das linguagens, as variveis devem ser declaradas no inicio do programa.
Estas variveis podem ser de vrios tipos: int (inteiro), float (real de simples preciso) e outras que
sero vistas no capitulo 2. No exemplo acima num, raiz, inf e sup so declaradas como variveis
reais, enquanto i declarada como uma varivel inteira.
11
1.3.5
Estruturas de controle
Linguagem C
se condio
if(condio){
ento bloco 1
seno bloco 2
bloco 1;
}else{
fim se
bloco 2;
};
Estrutura de Repetio: Permite executar repetidamente um bloco de instrues ate que uma
condio de controle seja satisfeita.
Pseudo-linguagem
Linguagem C
faa
do{
bloco
at condio
bloco;
}while(condio);
2. Constantes e Variveis
12
Neste capitulo veremos como os dados constantes e variveis so manipulados pela linguagem C.
O que so constantes inteiras, reais, caracteres e strings. Quais so as regras de atribuio de nomes a
variveis e quais so os tipos de dados que O C pode manipular. Veremos tambm como so declaradas
as variveis e as constantes simblicas usadas em um programa.
2.1
Constantes
O C possui quatro tipos bsicos de constantes: inteiras, de ponto flutuante, caracteres e strings.
Constantes inteiras e de ponto flutuante representam nmeros de um modo geral. Caracteres e strings
representam letras e agrupamentos de letras (palavras).
2.1.1
Constantes inteiras
Uma constante inteira um nmero de valor inteiro. De uma forma geral, constantes inteiras so
seqncias de dgitos que representam nmeros inteiros. Nmeros inteiros podem ser escritos no formato
decimal (base 10), hexadecimal (base 16) ou octal (base 8).
Uma constante inteira decimal formada por uma seqncia de dgitos decimais: 0, 1, 2,
3, 4, 5, 6, 7, 8, 9. Se a constante tiver dois ou mais dgitos, o primeiro no pode ser 0. Na
verdade, pode ser 0 mas o compilador considerar esta constante como octal e no decimal.
Exemplo: A seguir so mostradas algumas constantes inteiras decimais vlidas.
0
-45
26338
-7575
1010
(ponto)
1,2
(vrgula)
045
212-22-33
(caracter ilegal: -)
Uma constante inteira hexadecimal formada por uma seqncia de dgitos decimais: 0, 1,
2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F (ou a, b, c, d, e). Uma constante
hexadecimal deve comear por 0x. Neste caso, os dgitos hexadecimais podem ser minsculos ou
maisculos.
Exemplo: A seguir so mostrados algumas constantes inteiras hexadecimais vlidas.
0x0
0x3
0x4f5a
0x2FFE
OxABCD
0xAaFf
0x3.
(ponto)
0x1,e
(vrgula)
0x ff
(espao)
FFEE
0Xfg34
(caracter ilegal: g)
Uma constante inteira octal formada por uma seqncia de dgitos octais: 0, 1, 2, 3, 4,
5, 6, 7. A constante octal deve ter o primeiro digito 0 para que o compilador a identifique como tal
Exemplo: A seguir so mostrados algumas constantes octais vlidas.
00
-03
045
02633
07575
-0101
(ponto)
01,2
(vrgula)
0 4
(espao)
45
01784
(caracter ilegal: 8)
2.1.2
Nmeros reais (no inteiros) so representados em base 10, por nmeros com um ponto decimal e
(opcionalmente) um expoente. Um nmero ponto flutuante deve ter um ponto decimal que no pode ser
substitudo por uma vrgula. Um nmero de ponto flutuante pode ser escrito em notao cientfica. Neste
caso o x10 substitudo por e ou E. O nmero 1.23e4 representa 1.23 x 104 ou 12300.
Exemplo: Nmeros de ponto flutuante vlidos.
0.234
125.65
.93
1.23e-9
-1.e2
10.6e18
-.853E+67
+3.14e+2
31.4e1
.314E+3
314e0
Constantes caracteres
Uma constante caracter uma letra ou smbolo colocado entre aspas simples.
Exemplo: Abaixo esto representados algumas constantes caracteres.
a
&
14
valor 65. Os valores numricos dos caracteres esto padronizados em uma tabela chamada de American
Standard Code for Information Interchange Table ou simplesmente tabela ASCII. Veja apndice B.
Certos codigos de controle da tabela ASCII (como o line feed) ou caracteres especiaiss (como ')
possuem representao especial no C. Esta representacao chama-se seqncia de escape representada por
uma barra invertida (\) e um caracter. Sequencias de escape so interpretadas como caracteres simples.
Abaixo segue uma lista das principais sequencias de escape usadas no C.
Controle/Caracter
Sequencia de escape
Valor ASCII
nulo (null)
\0
00
campainha (bell)
\a
07
retrocesso (backspace)
\b
08
tabulacao horizontal
\t
09
\n
10
tabulacao vertical
\v
11
\f
12
\r
13
aspas (")
\"
34
apostrofo (')
\'
39
interrogacao (?)
\?
63
\\
92
2.1.4
Constantes strings
Uma constante string consiste de um conjunto de caracteres colocados entre aspas duplas.
Embora as instrues do C usem apenas os caracteres do conjunto padro ASCII, as constantes caracter e
string podem conter caracteres do conjunto estendido ASCII: , , , , ...
Exemplo: Abaixo seguem algumas constantes strings vlidas.
Oba!
Caxias do Sul
A resposta :
Joo Carlos da Silveira
a
isto uma string
2.2
Identificadores
Identificadores so os nomes das variveis e funes usadas no programa. Por exemplo raiz e
MAX so nomes de variveis utilizadas no programa e0101.cpp.
2.2.1
Regras de sintaxe
15
O resto do identificador deve conter apenas letras, underscores ou dgitos (0 - 9). No pode
conter outros caracteres. Em C, os identificadores podem ter at 32 caracteres.
Em C, letras maisculas so diferentes de letras minsculas: Por exemplo: MAX, max, Max
so nomes diferentes para o compilador. Esta propriedade chamada de case sensibility.
Exemplo: os nomes abaixo so vlidos:
abc, y24, VetorPontosMovimentoRobo, nota_1, TAM_MAX.
Exemplo: os nomes abaixo no so vlidos:
3dia, vetor-1, pao&leite, iterao.
2.2.2
Palavras reservadas
Existem certos nomes que no podem ser usados como identificadores. So chamadas as
palavras reservadas e so de uso restrito da linguagem C (comandos, estruturas, declaraes, etc.). O
conjunto de palavras reservadas usadas em C o seguinte:
asm
auto
break
case
cdecl
char
class
const
continue
_cs
default
delete
do
double
_ds
else
enum
_es
extern
_export
far
_fastcall
float
for
friend
goto
huge
if
inline
int
interrupt
_loadds
long
near
new
operator
pascal
private
protected
public
register
return
_saveregs
_seg
short
signed
sizeof
_ss
static
struct
switch
template
this
typedef
union
unsigned
virtual
void
volatile
while
2.3
Tipos de dados
Em C, como na maioria das linguagens, os dados so divididos tipos: inteiro, real, caracter, etc.
Esta diviso se deve basicamente ao nmero de bytes reservados para cada dado. Cada tipo de dado
possui um intervalo de valores permitidos.
2.3.1
16
Tipos bsicos
Abaixo segue uma lista dos tipos bsicos de dados permitidos em C. Os tipos char e int so
inteiros e os tipos float e double so de ponto flutuante.
Tipo
Tamanho
char
1 byte
int
2 bytes
-32768 a 32767
float
4 bytes
3.4e-38 a 3.4e38
double
8 bytes
1.7e-308 a 1.7e308
2.3.2
Intervalo
-128 a 127
Uso
nmero muito pequeno e caracter ASCII
Declarao de variveis
Para que se possa usar uma varivel em um programa, necessrio fazer uma declarao de
varivel antes. A declarao de variveis simplesmente informa ao processador quais so os nomes
utilizados para armazenar dados variveis e quais so os tipos usados. Deste modo o processador pode
alocar (reservar) o espao necessrio na memria para a manipulao destas variveis. possvel declarar
mais de uma varivel ao mesmo tempo, basta separ-las por vrgulas (,).
Sintaxe: A sintaxe para declarao de variveis a seguinte:
tipo variavel_1 [, variavel_2, ...] ;
Onde tipo o tipo de dado e variavel_1 o nome da varivel a ser declarada. Se houver
mais de uma varivel, seus nomes so separados por vrgulas.
Exemplo: Declarao das variveis:
int i;
int x,y,z;
char letra;
float nota_1,nota_2,media;
double num;
No exemplo acima, i, x, y e z foram declaradas variveis inteiras. Assim elas podem armazenar
valores inteiros de -32768 at 32767. Do mesmo modo letra foi declarada como varivel caracter
podendo receber valores de -128 at 127 ou caracteres do conjunto padro ASCII. As variveis nota_1,
nota_2 e media foram declaradas como ponto flutuante tipo float e num como ponto flutuante tipo
double.
A declarao de variveis feita, em geral, dentro de uma rotina. Por exemplo, a rotina principal
main(). Deste modo se diz que est se fazendo uma declarao de variveis locais. Variveis locais
podem ser referenciadas apenas dentro da rotina dentro da qual foi declarada, neste caso a rotina
main().
17
// declaracao de variaveis
raio = 2.5;
rea = 3.14 * raio * raio;
}
No exemplo acima, as variveis area e raio foram declaradas como variveis locais tipo
float. Assim o processador faz a alocao de dois espaos (endereos) de 4 bytes cada para armazenar
as informaes, um para cada varivel. Na terceira linha, o processador coloca no endereo alocado para
raio o valor 2.5. Depois, na quarta linha, o processador coloca o resultado da conta (19.625) no
endereo de rea.
possvel fazer a declarao de variveis fora de uma rotina. Neste caso diz-se que se fez a
declarao de variveis globais. O uso de variveis globais explicado na sesso ?.?.
2.3.3
Tipos modificados
Alm dos tipos de dados citados acima existem outros tipos de dados ditos modificados. Em C
existem dois modificadores: o modificador long e o modificador unsigned. Tipicamente o
modificador long aumenta o nmero de bytes usados para o registro do nmero. Por conseqncia o
intervalo de validade do nmero fica aumentado significativamente. O modificador unsigned, usado
somente em inteiros, permite que um bit usado para guardar o sinal do nmero seja usado para guardar o
valor do nmero. Em conseqncia disto o intervalo do nmero fica dobrado, porm somente permite o
uso de nmeros positivos.
Tipo
Tamanho (bytes)
Intervalo
unsigned char
0 a 255
unsigned int
0 a 65 535
long int
long double
2.3.4
10
3.4e-4932 a 1.1e4932
Strings.
Uma string um conjunto ordenado de caracteres que pode ser armazenado sob forma de um
vetor um ponteiro. Estas estruturas de dados sero vistas em detalhe nos capitulo ? e ?. Por enquanto, nos
basta saber como declarar e armazenar um conjunto caracter em uma varivel.
18
Sintaxe: Para declararmos uma varivel para receber um conjunto caracter devemos escrever:
char* var;
Exemplo: No exemplo seguinte a varivel nome foi declarada como conjunto caracter e em
seguida recebe uma constante string.
char* nome;
nome = "Joo Carlos de Oliveira Andrade";
2.3.5
Inicializao de variveis.
Quando se faz a declarao de uma varivel est se determinando que tipo de dado ela vai
receber. possvel, em C, declarar uma varivel e j armazenar nela um valor inicial. Chamamos este
procedimento de inicializao de uma varivel.
Sintaxe: A sintaxe para a inicializao de variveis :
tipo var_1 = valor_1 [, var_2 = valor_2, ...] ;
Onde tipo o tipo de dado, var_1 o nome da varivel a ser inicializada e valor_1 o
valor inicial da varivel.
Exemplo: Inicializao de variveis:
int i = 0, j = 100;
float num = 13.5;
char* titulo = " Programa Teste ";
No exemplo acima, i e j foram declaradas variveis tipo int. O valor inicial de i 0 e o de j
100. Do mesmo modo num foi declarada como varivel float com valor inicial de 13.5. Tambem a
variavel titulo foi declarada como um conjunto caracter e recebeu como conteudo inicial a string "
Programa Teste ".
2.3.6
Algumas vezes queremos, momentaneamente, modificar o tipo de dado representado por uma
varivel, isto , queremos que o dado seja apresentado em um tipo diferente do qual a varivel foi
inicialmente
declarada.
Por
exemplo:
declaramos
uma
varivel
como
int
queremos,
momentaneamente, que seu contedo seja apresentado como float. Este procedimento chamado de
converso de tipo ou casting (moldagem, em ingls).
Sintaxe: A sintaxe da instruo de converso de tipo :
(tipo) varivel
19
onde tipo o nome do tipo ao qual queremos converter o dado armazenado em varivel.
Exemplo: observe a converso de tipo feita no exemplo abaixo:
int num;
float valor = 13.0;
num = (int)valor % 2;
No exemplo acima a varivel valor foi declarada inicialmente como sendo do tipo float
recebendo o valor inicial 13.0. Logo em seguida o contedo de valor convertido para o tipo int para
realizar a operao mdulo (%) com o inteiro 2. Aqui a converso necessria pois a operao mdulo
somente pode ser feita com inteiros. importante salientar que a converso de tipo feita com o dado
armazenado em uma varivel mas a varivel continua tendo o seu tipo original. No exemplo acima a
varivel valor e os dados nela armazenados continuam sendo do tipo float aps a converso.
Veremos na seo 3.1 uma explicao mais detalhada do uso da converso de tipos.
2.4.1
3.14159
#define ON
#define OFF 0
#define ENDERECO 0x378
20
void main(){
...
No exemplo acima, definimos PI como 3.14159. Isto significa que todas as ocorrncias do
texto PI ser trocado por 3.14159. Assim se escrevemos uma instruo:
rea = PI * raio * raio;
o compilador vai interpretar esta instruo como se fosse escrita assim:
rea = 3.14159 * raio * raio;
Poderamos escrever estas instrues assim:
float pi = 3.14159;
rea = pi * rea * rea;
porm este tipo de instruo tem duas desvantagens: Primeiro, reserva 4 bytes de memria
desnecessariamente. Segundo, esta instruo executada mais lentamente pois o processador precisa
acessar a memria para verificar qual o valor de pi.
Observe tambm que no exemplo definimos os nomes simblicos com letras maisculas. Isto no
necessrio, podemos perfeitamente definir nomes simblicos usando letras minsculas, porm faz parte
do jargo dos programadores C usar letras maisculas para definir constantes simblicas.
O uso da diretiva #define no se restringe apenas ao apresentado acima, podemos us-la para
definir macro instrues. No veremos o uso de macros neste texto, procure mais detalhes na
bibliografia recomendada.
2.4.2
Constantes pr-definidas
Constante
Valor
Significado
math.h
M_PI
3.14159...
math.h
M_PI_2
1.57079...
/2
math.h
M_PI_4
0,78539...
/4
math.h
M_1_PI
0,31830...
1/
math.h
M_SQRT2
1,41421...
conio.h
BLACK
conio.h
BLUE
conio.h
GREEN
conio.h
CYAN
conio.h
RED
conio.h
MAGENTA
limits.h
INT_MAX
32767
limits.h
INT_MIN
-32768
Cada uma das constantes acima esta definida em uma biblioteca. Uma biblioteca, em C, um
arquivo pr-compilado chamado arquivo header (cabealho, em ingls). Em cada biblioteca esto
agrupadas constantes e funes semelhantes (veja seo 3.7.2). Por exemplo, constantes e funes
matemticas esto guardadas na biblioteca math.h (mathematical functions), constantes e funes de
manipulao teclado e monitor esto guardadas na biblioteca conio.h (console input and output). Para
que se possa usar a constante simblica em um programa preciso incluir a biblioteca na compilao do
programa.
Sintaxe: A sintaxe de incluso de bibliotecas a seguinte:
#include <nome_bib>
onde nome_bib o nome da biblioteca que se deseja incluir. Esta instruo deve ser escrita
antes do programa principal.
Exemplo: O programa abaixo usa a constante predefinida M_PI para calcular a rea de um disco
circular.
#include <math.h>
void main(){
float area, raio = 5.0;
rea = M_PI * raio * raio;
}
22
3.1
Operador de Atribuio
// constante!
b + 1 = a;
// expresso!
3.1.1
Converso de tipo.
// valor de i: 5
r = i ;
// valor de r: 5.0
A varivel i foi inicializada com o valor 5. Ao final da terceira instruo, r recebe o valor
5.0.
Nestas converses podem ocorrer alteraes dos valores convertidos se o operando da esquerda
for de um tipo que utilize menor numero de bytes que o operando da direita.
Exemplo: Algumas atribuies com converso de tipo e perda de informao:
int i;
float r = 654.321;
i = r;
// truncamento!
Aps a execuo deste trecho de programa o valor da varivel i ser 654 pois seu valor foi
truncado durante a converso.
Pode-se dizer que as converses potencialmente perigosas (onde h possibilidade de perda de
informao) so:
24
3.1.2
Tambm importante observar que os tipos em C tem intervalos bem definidos e os resultados
das operaes devem respeitar estes intervalos. Se a uma varivel for atribudo um valor que esteja fora
dos seus limites ento este valor ser alterado.
Exemplo: Observe as expresses abaixo, assuma que i seja uma varivel do tipo int.
i = 4999;
// o valor de i e
4999
i = 4999 + 1;
// o valor de i e
5000
i = 5000 + 30000;
// o valor de i e -30536
3.1.3
Atribuio mltipla.
E possvel atribuir um valor a muitas variveis em uma nica instruo. A esta operao d-se o
nome de atribuio mltipla.
Sintaxe: A sintaxe da atribuio mltipla seguinte:
var_1 = [var_2 = ... ] expresso;
25
3.2
Operadores Aritmticos
Existem cinco operadores aritmticos em C. Cada operador aritmticos est relacionado ao uma
operao aritmtica elementar: adio, subtrao, multiplicao e diviso. Existe ainda um operador (%)
chamado operador de mdulo cujo significado o resto da diviso inteira. Os smbolos dos operadores
aritmticos so:
Operador
26
Operao
adio.
subtrao.
multiplicao
diviso
a-4.0
b*c
valor_1/taxa
num%2
3.2.1
Restries de operandos.
Valor
6.4 + 2.1
8.5
7 - 2
2.0 * 2.0
4.0
6 / 3
47 % 2
Uma restrio ao operador de diviso (/) que o denominador deve ser diferente de zero. Se
alguma operao de diviso por zero for realizada o correra um erro de execuo do programa (run-time
error), o programa ser abortado e a mensagem divide error ser exibida.
Exemplo: A expresso abaixo invlida pois o primeiro operando no um numero inteiro.
Expresso
Valor
6.4 % 3
invalido!
// invlido!
num = (int)valor % 2;
// vlido!
Observe que usamos a converso de tipo para que o dado armazenado em valor fosse
transformado no tipo int assim a operao mdulo pode ser efetuada.
3.2.2
Converso de tipo.
O resultado de uma operao aritmtica depende dos tipos dos operandos. Se os operandos so
do mesmo tipo o resultado ser do mesmo tipo. Se os operando forem de tipos diferentes ento haver
uma converso de tipo tal que o tipo que ocupa menos espao de memria ser convertido para o tipo
que ocupa mais espao de memria e o resultado ser deste tipo. Em geral:
char int float double
Esta uma regra geral, alguns compiladores podem ter outras regras de converso.
Exemplo: Observe as converses de tipo abaixo:
Expresso
Valor
Converso
6 + 2.0
8.0
int float
7.000000 - 2.0000000000000
5.000000000000000
float double
2 * 3.000000000000000
6.000000000000000
int double
Observe que estas converses podem gerar resultados surpreendentes para o programador
desatento.
Exemplo: Observe as expresses abaixo. Assuma que as variveis num_i, num_f, den_i e
den_f so inicializadas como:
int
num_i = 7
, den_i = 2
28
Expresso
Valor
Operandos
Resultado
num_f / den_f
3.5
float / float
float
num_f / den_i
3.5
float / int
float
num_i / den_f
3.5
int
float
/ float
num_i / den_i
int
/ int
int
Observe que no exemplo acima o valor da ltima expresso 3 e no 3.5. Isto ocorre porque
como os dois operandos so tipo int o resultado e convertido para o tipo int e ocorre o truncamento. O
truncamento da diviso inteira feito de modo a obter o menor valor absoluto.
Em C caracteres so armazenados na memria como nmeros inteiros e por isso operaes
aritmticas so permitidas com tipos char. Os valores usados so os correspondentes da tabela ASCII.
Exemplo: Observe as expresses abaixo:
Expresso
Valor
Converso
A + 1
65 + 1
A + B
65 + 66 131
A + 32
65 + 32
3.2.4
66
97
Precedncia de operadores.
Valor
Ordem
1 + 2 - 3
+ -
24 - 3 * 5
* -
4 - 2 * 6 / 4 + 1
* / - +
11
/ % * +
6 / 2 + 11 % 3 * 4
Valor
Ordem
- +
105
- *
-1
* - / +
29
6 / ((2 + 11) % 3) * 4
24
+ % / *
3.3
Muitas vezes queremos alterar o valor de uma varivel realizando alguma operao aritmtica
com ela. Como por exemplo: i = i + 1 ou val = val * 2. Embora seja perfeitamente possvel
escrever estas instrues, foi desenvolvido na linguagem C uma instrues otimizadas com o uso de
operadores ditos operadores de atribuio aritmtica. Os smbolos usado so (+=, -=, *=, /= ,
%=). Deste modo as instrues acima podem ser rescritas como: i += 1 e val *= 2,
respectivamente.
Sintaxe: A sintaxe da atribuio aritmtica a seguinte:
var += exp;
var -= exp;
var *= exp;
var /= exp;
var %= exp;
onde var o identificador da varivel e exp uma expresso vlida. Estas instrues so
equivalentes as seguintes:
var = var + exp;
var = var - exp;
var = var * exp;
var = var / exp;
var = var % exp;
Exemplo: Observe as atribuies aritmticas abaixo e suas instrues equivalentes:
30
Atribuio aritmtica
Instruo equivalente
i += 1;
i = i + 1;
j -= val;
j = j - val;
num *= 1 + k;
troco /= 10;
resto %= 2;
resto = resto % 2;
O operador de atribuio aritmtica tem precedncia menor que os outros operadores at aqui
discutidos. Veja a tabela 3.1.
Programa Exemplo: O arquivo e0303.cpp traz um programa para visualizar alguns aspectos
relacionados com os operadores de atribuio aritmtica. Execute o programa passo-a-passo e observe o
valor das variveis.
3.4
Operadores Incrementais
Uma instruo de
var = var + 1
var ++
var = var + 1
-- var
var = var - 1
var --
var = var - 1
// a: ?
b: ?
c: ?
i: 3
a = i++;
// a: 3
b: ?
c: ?
i: 4
b = ++i;
// a: 3
b: 5
c: ?
i: 5
c = --i;
// a: 3
b: 5
c: 4
i: 4
Os operadores incrementais so bastante usados para o controle de laos de repetio, que sero
vistos na seo ??. importante que se conhea exatamente o efeito sutil da colocao do operador, pois
isto pode enganar o programador inexperiente.
31
Os operadores incrementais tm a mais alta precedncia entre todos, sendo superados apenas
pelos parnteses que tem precedncia ainda maior. Veja a tabela 3.1.
Programa Exemplo: O arquivo e0304.cpp traz um programa para visualizar alguns aspectos
relacionados com os operadores incrementais. Execute o programa passo-a-passo e observe o valor das
variveis.
3.5
de condies de controle. Uma condio de controle uma expresso lgica que avaliadas como
verdadeira ou falsa. Uma expresso lgica construda com operadores relacionais e lgicos.
3.5.1
Operadores relacionais
Operadores relacionais verificam a relao de magnitude e igualdade entre dois valores. So seis
os operadores relacionais em C:
Operador
Significado
>
maior que
<
menor que
>=
<=
==
igual a
!=
32
Valor
i == 7
r != s
i > r
6 >= i
i < j
s <= 5.9
Os operadores relacionais de igualdade (== e !=) tem precedncia menor que os de magnitude
(>, <, >= e <=). Estes, por sua vez, tem precedncia menor que os operadores aritmticos. Operadores
relacionais de mesma precedncia so avaliados da esquerda para a direita. Veja a tabela 3.1.
Exemplo: Observe as expresses lgicas abaixo e verifique o resultado de sua avaliao. Admita
que m e n so variveis tipo int com valores 4 e 1, respectivamente.
Expresso
Valor
Ordem de Operao
m + n == 5
==
m != 2 * n > m
>
6 >= n < 3 - m
>=
m == n <= m > m
<=
3.5.2
!=
>
<
!=
Operadores lgicos
Valor lgico
1.0
0.4
-5.2
operando for 0. Abaixo mostra-se o resultado das possveis combinaes entre os operandos para cada
operador lgico:
Operador &&:
op_1
Operador ||:
!op
Res
op_1
op_1 || op_2
Operador !:
op_2
op_2
Res
op
Res
O Operador && tem precedncia sobre o operador ||. Estes dois tm precedncia menor que os
operadores relacionais. O operador ! tem a mesma precedncia que os operadores incrementais. Veja a
tabela 3.1.
Exemplo: Observe as expresses lgicas abaixo e verifique o resultado de sua avaliao. Admita
que a, b e c so variveis tipo int com valores 0, 1 e 2, respectivamente.
Expresso
Valor
Ordem de Operao
a && b
c > b || a < c
>
<
||
a + b && !c - b
!b && c || a
&&
&&
||
Programa Exemplo: O arquivo e0305.cpp traz um programa para visualizar alguns aspectos
relacionados com os operadores lgicos e relacionais. Execute o programa passo-a-passo e observe o
valor das variveis.
3.6
Operador Condicional
O operador condicional (?:)
condicional pode ter dois valores diferentes dependendo de uma condio de controle.
34
Valor
i ? j : k
k == i && k != j ? i + j : i - j
i > k ? i : k
-1
3
O operador condicional tem baixa precedncia, precedendo, apenas, aos operadores de atribuio.
Veja a tabela 3.1.
Programa Exemplo: O arquivo e0306.cpp traz um programa para visualizar alguns aspectos
relacionados com o operador condicional. Execute o programa passo-a-passo e observe o valor das
variveis.
3.7
Funes de biblioteca
Uma funo um sub-programa (tambm chamado de rotina). Esta funo recebe informaes,
as processa e retorna outra informao. Por exemplo, podemos ter uma funo que receba um valor
numrico, calcule seu logaritmo decimal e retorne o valor obtido. Existem dois tipos de funes: funes
de biblioteca e funes de usurio. Funes de biblioteca so funes escritas pelos fabricantes do
compilador e j esto pr-compiladas, isto , j esto escritas em cdigo de mquina. Funes de usurio
so funes escritas pelo programador. Nesta seo trataremos somente das funes de biblioteca, funes
de usurio sero vistas no captulo ?.
35
3.7.1
O uso de funes
Antes de usar uma funo preciso saber como a funo esta declarada, isto , quais so os
parmetros que a funo recebe e quais so os para metros que a funo retorna. Estas informaes esto
contidas no manual do usurio do compilador ou em sua documentao on-line.
Sintaxe: A sintaxe de declarao de uma funo :
tipo_ret nome(tipo_1, tipo_2, ...)
onde nome o nome da funo, tipo_1, tipo_2, ... so os tipos (e quantidade) de parmetros
de entrada da funo e tipo_ret o tipo de dado de retorno da funo. Alm dos tipos usuais vistos na
seo 2.3, existe ainda o tipo void (vazio, em ingls) que significa que aquele parmetro inexistente.
Exemplo: A funo cos() da biblioteca math.h declarada como:
double cos(double);
Isto significa que a funo tem um parmetro de entrada e um parmetro de sada, ambos so do
tipo double.
Exemplo: A funo getch() da biblioteca conio.h declarada como:
int getch(void);
Isto significa que a funo no tem parmetros de entrada e tem um parmetro int de sada.
Para podermos usar uma funo de biblioteca devemos incluir a biblioteca na compilao do
programa. Esta incluso feita com o uso da diretiva #include colocada antes do programa principal,
como visto na seo 2.4.2.
Exemplo: Assim podemos usar a funo no seguinte trecho de programa:
#include <math.h>
// incluso de biblioteca
void main(){
double h = 5.0;
// hipotenusa
double co;
// cateto oposto
// angulo: /4
co = h * cos(alfa);
// fim do programa
As funes tm alta precedncia, sendo mais baixa apenas que os parnteses. A tabela 3.1 mostra
as precedncias de todos os operadores estudados neste captulo.
3.7.2
36
A seguir segue uma lista de todas as bibliotecas disponveis no compilador Turbo C++ 3.0
Borland: Ao longo do texto veremos o uso de muitas funes cobrindo uma boa parte destas bibliotecas,
porm o leitor que desejar tornar-se "fluente" na linguagem C pode (e deve) estud-las com profundidade.
alloc.h
assert.h
bcd.h
bios.h
complex.h
conio.h
ctype.h
dir.h
dirent.h
dos.h
errno.h
fcntl.h
float.h
fstream.h
generic.h
graphics.h
io.h
iomanip.h
iostream.h
limits.h
locale.h
malloc.h
math.h
mem.h
process.h
setjmp.h
share.h
signal.h
stdarg.h
stddef.h
stdio.h
stdiostr.h
stdlib.h
stream.h
string.h
strstrea.h
sys\stat.h
sys\timeb.h
sys\types.h
time.h
values.h
Vejamos algumas funcoes disponiveis nas bibliotecas C.
Biblioteca math.h
int abs(int i);
double fabs(double d);
Calcula o valor absoluto do inteiro i e do real d, respectivamente.
double sin(double arco);
double cos(double arco);
double tan(double arco);
double asin(double arco);
double acos(double arco);
double atan(double arco);
Funes trigonometricas do ngulo arco, em radianos.
double ceil(double num);
double floor(double num);
Funes de arredondamento para inteiro.
ceil() arredonda para cima. Ex. ceil(3.2) == 3.0;
floor() arredonda para baixo. Ex. floor(3.2) == 4.0;
double log(double num);
double log10(double num);
37
3.8
A tabela 3.1 mostra a ordem de precedncia de todos os operadores estudados neste captulo. Os
operadores de maior precedncia so os parnteses e as chamadas de funes. Os operadores de menor
precedncia so os operadores de atribuio.
Categoria
Operadores
Prioridade
parnteses
( )
interno externo
funo
nome()
ED
incremental, lgico
++ -- !
ED
aritmtico
* / %
ED
aritmtico
+ -
ED
relacional
>=
ED
relacional
== !=
ED
lgico
&&
ED
lgico
||
ED
condicional
?:
ED
atribuio
= += -= *= /= %=
ED
Tabela 3.1: Precedncia dos operadores. Maior precedncia no topo, menor precedncia na base.
38
39
4. Entrada e Sada
Para que um programa torne-se minimamente funcional preciso que ele receba dados do meio
externo (teclado, mouse, portas de comunicao, drives de disco, etc.) e emita o resultado de seu
processamento de volta para o meio externo (monitor, impressora, alto-falante, portas de comunicao,
drives de disco, etc.). De outro modo: um programa deve trocar informaes com o meio externo. Em C,
existem muitas funes pr-definidas que tratam desta troca de informaes. So as funes de entrada e
sada do C. Nos exemplos mostrados nos captulos anteriores foram vistas algumas funes de entrada
(scanf(), getch()) e algumas funes de sada (printf()). Neste captulo veremos, em detalhe,
estas e outras funes de modo a permitir escrever um programa completo em C.
Mostraremos, nas duas sees iniciais as mais importantes funes de entrada e sada de dados
em C: as funes printf() e scanf(). A partir do estudo destas funes possvel escrever um
programa propriamente dito com entrada, processamento e sada de dados.
4.1
Biblioteca: stdio.h
Declarao: int printf (const char* st_contr [, lista_arg]);
Propsito: A funo printf() (print formated) imprime dados da lista de argumentos
lista_arg formatados de acordo com a string de controle st_contr. Esta funo retorna um valor
inteiro representando o nmero de caracteres impressos.
Esta funo imprime dados numricos, caracteres e strings. Esta funo dita de sada formatada
pois os dados de sada podem ser formatados (alinhados, com nmero de dgitos variveis, etc.).
Sintaxe: A string de controle uma mscara que especifica (formata) o que ser impresso e de
que maneira ser impresso.
Exemplo: Observe no exemplo abaixo as instrues de sada formatada e os respectivos
resultados.
40
Instruo
Sada
printf(Ola, Mundo!);
Ola, Mundo!
printf(linha 1 \nlinha 2 );
linha 1
linha 2
Observe que na primeira instruo, a sada exatamente igual a string de controle. J na segunda
instruo a impresso se deu em duas linhas. Isto se deve ao \n que representa o cdigo ASCII para
quebra de linha (veja seo 2.1.3).
Nesta mascara possvel reservar espao para o valor de alguma varivel usando especificadores
de formato. Um especificador de formato marca o lugar e o formato de impresso das variveis contidas
na lista variveis. Deve haver um especificador de formato para cada varivel a ser impressa. Todos os
especificadores de formato comeam com um %.
Exemplo: Observe no exemplo abaixo as instrues de sada formatada e os respectivos
resultados. Admita que idade seja uma varivel int contendo o valor 29 e que tot e din sejam
variveis float cujo valores so, respectivamente, 12.3 e 15.0.
Instruo:
printf(Tenho %d anos de vida,idade);
Sada:
Tenho 29 anos de vida
Instruo:
printf(Total: %f.2 \nDinheiro: %f.2 \nTroco: %f.2,tot,din,din-tot);
Sada:
Total: 12.30
Dinheiro: 15.00
Troco: 2.70
4.2
Biblioteca: stdio.h
Declarao: int scanf(const char* st_contr [, end_var, ...]);
Propsito: A funo scanf() (scan formated) permite a entrada de dados numricos, caracteres
e 'strings' e sua respectiva atribuio a variveis cujos endereos so end_var. Esta funo dita de
entrada formatada pois os dados de entrada so formatados pela string de controle st_contr. a um
determinado tipo de varivel (int, float, char, ...).
42
4.3
Biblioteca: stdio.h
Declarao: int getchar(void);
Propsito: A funo getchar() (get character) l um caracter individual da entrada padro
(em geral, o teclado). Se ocorrer um erro ou uma condio de 'fim-de-arquivo' durante a leitura, a funo
retorna o valor da constante simblica EOF (end of file)definida na biblioteca stdio.h. Esta funo
permite uma forma eficiente de deteco de finais de arquivos.
Esta funo dita line buffered, isto , no retorna valores at que o caracter de controle line feed
(\n) seja lido. Este caracter, normalmente, enviado pelo teclado quando a tecla [enter]
pressionada. Se forem digitados vrios caracteres, estes ficaro armazenados no buffer de entrada at que
a tecla [enter] seja pressionada. Ento, cada chamada da funo getchar() ler um caracter
armazenado no buffer.
4.4
Biblioteca: stdio.h
Declarao: int putchar(int c);
Propsito: Esta funo putchar() (put character) imprime um caracter individual c na sada
padro (em geral o monitor de vdeo).
Programa Exemplo: O programa e0403.cpp mostra o uso das funes getchar() e
putchar() em um programa que l caracteres do teclado e os reimprime convertidos para maisculos.
4.5
Biblioteca: conio.h
Declarao:
int getch(void);
int getche(void);
44
Propsito: Estas funes fazem a leitura dos cdigos de teclado. Estes cdigos podem representar
tecla s de caracteres (A, y, *, 8, etc.), teclas de comandos ( [enter], [delete], [Page Up], [F1], etc.)
ou combinao de teclas ([Alt] + [A], [Shift] + [F1], [Ctrl] + [Page Down], etc.).
Ao ser executada, a funo getch() (get character) aguarda que uma tecla (ou combinao de
teclas) seja pressionada, recebe do teclado o cdigo correspondente e retorna este valor. A funo
getche()(get character and echoe) tambm escreve na tela, quando possvel, o caracter
correspondente.
Cdigo ASCII: ao ser pressionada uma tecla correspondente a um caracter ASCII, o teclado
envia um cdigo ao 'buffer' de entrada do computador e este cdigo lido. Por exemplo, se a tecla A for
pressionada o cdigo 65 ser armazenado no buffer e lido pela funo.
Cdigo Especial: ao serem pressionadas certas teclas (ou combinao de teclas) que no
correspondem a um caracter ASCII, o teclado envia ao 'buffer' do computador dois cdigos, sendo o
primeiro sempre 0. Por exemplo, se a tecla [F1] for pressionada os valores 0 e 59 sero armazenados e a
funo deve ser chamada duas vezes para ler os dois cdigos.
Programa exemplo: O arquivo e0404.cpp mostra um programa para a leitura de teclado. Este
programa usa a funo getch() para reconhecer teclas e combinao de teclas.
Programa exemplo: O arquivo e0405.cpp mostra um programa para a leitura de teclado
usando a funo getche().
4.6
Biblioteca: conio.h
Declarao: int cprintf (const char* st_contr [, lista_arg]);
Propsito: Esta funo cprintf() (color print formated) permite a sada de dados numricos,
caracteres e strings usando cores. O uso da funo cprintf() semelhante a printf()porm permite
que a sada seja a cores. Para que a sada seja colorida necessrio definir as cores de fundo e de letra
para a impresso antes do uso da funo.
Cores (Modo Texto)
Cor
Constante
Preto
BLACK
Azul
BLUE
Valor
Fundo
Letra
ok
ok
ok
ok
45
Verde
GREEN
ok
ok
Cian
CYAN
ok
ok
Vermelho
RED
ok
ok
Magenta
MAGENTA
ok
ok
Marrom
BROWN
ok
ok
Cinza Claro
LIGHTGRAY
ok
ok
Cinza Escuro
DARKGRAY
--
ok
Azul Claro
LIGHTBLUE
--
ok
Verde Claro
LIGHTGREEN
10
--
ok
Cian Claro
LIGHTCYAN
11
--
ok
Vermelho Claro
LIGHTRED
12
--
ok
Magenta Claro
LIGHTMAGENTA
13
--
ok
Amarelo
YELLOW
14
--
ok
Branco
WHITE
15
--
ok
Piscante
BLINK
128
--
ok
4.7
Biblioteca: dos.h
46
4.8
Biblioteca: conio.h
Declaraes: void clrscr(void);
void clreol(void);
Propsito: A funo clrscr() (clear screen) limpa a janela de tela e posiciona o cursor na
primeira linha e primeira coluna da janela (canto superior esquerdo da janela). A funo clreol()
(clear to end of line) limpa uma linha desde a posio do cursor at o final da linha mas no modifica a
posio do cursor. Ambas funes preenchem a tela com a cor de fundo definida pela funo
textbacground().
4.9
Biblioteca: conio.h
Declaraes: void gotoxy(int pos_x, int pos_y);
Propsito: Em modo texto padro, a tela dividida em uma janela de 25 linhas e 80 colunas. A
funo gotoxy() permite posicionarmos o cursor em qualquer posio (pos_x,pos_y) da tela.
Sendo que a posio (1,1) corresponde ao canto superior esquerdo da tela e a posio (80,25) corresponde
ao canto inferior direito. Como as funes printf() e cprintf() escrevem a partir da posio do
cursor, podemos escrever em qualquer posio da tela.
47
Propsito: Esta funo permite redefinir a janela de texto. As coordenadas esq e sup definem o
canto superior esquerdo da nova janela, enquanto as coordenadas inf e dir definem o canto inferior
direito da nova janela. Para reativar a janela padro escreve-se a instruo window(1,1,80,25).
Quando uma janela definida, o texto que ficar fora da janela fica congelado at que se redefina a janela
original.
48
5. Estruturas de Controle
estruturas de
deciso. A estrutura de repetio permite que um bloco de instrues seja executado repetidamente uma
quantidade controlada de vezes. A estrutura de deciso permite executar um entre dois ou mais blocos de
instrues. Neste captulo estudaremos em detalhe as instrues do C que permitem implementar estas
estruturas.
5.1
Condio de controle
Em todas as estruturas, existe pelo menos uma expresso que faz o controle de qual bloco de
instrues ser executado ou quantas vezes ele ser executado: o que chamamos de condio de
controle. Uma condio de controle uma expresso lgica ou aritmtica cujo resultado pode ser
considerado verdadeiro ou falso. Conforme vimos na seo 3.5, a linguagem C no possui, entretanto,
variveis ou constantes lgicas, possui somente expresses numricas, assim quando uma expresso
numrica se encontra em uma condio de controle, ela ser considerada falsa se seu valor for igual a
zero, e verdadeira se seu valor for diferente de zero.
Exemplo: Observe nas condies abaixo, seu valor numrico e seu significado lgico. Considere
as variveis int i = 0, j = 3;
condio
valor numrico
significado lgico
(i == 0)
verdadeiro
(i > j)
falso
(i)
falso
(j)
verdadeiro
Este fato deve ficar claro pois, nas estruturas que estudaremos neste captulo, quando for dito que
uma condio falsa ou verdadeira quer se dizer que seu valor e igual a zero ou diferente de zero.
5.2
Estrutura do...while
49
Sintaxe:
do{
bloco
}while(condio);
onde: condio uma expresso lgica ou numrica.
bloco um conjunto de instrues.
Esta estrutura faz com que o bloco de instrues seja executado pelo menos uma vez. Aps a
execuo do bloco, a condio avaliada. Se a condio verdadeira o bloco executado outra vez,
caso contrrio a repetio terminada. Ofluxograma desta estrutura mostrada na figura 5.1:
bloco
condio?
5.3
Estrutura while
50
Sintaxe:
while(condio){
bloco
}
onde: condio uma expresso lgica ou numrica.
bloco um conjunto de instrues.
Esta estrutura faz com que a condio seja avaliada em primeiro lugar. Se a condio
verdadeira o bloco executado uma vez e a condio avaliada novamente. Caso a condio seja falsa a
repetio terminada sem a execuo do bloco. Observe que nesta estrutura, ao contrrio da estrutura
do...while, o bloco de instrues pode no ser executado nenhuma vez, basta que a condio seja
inicialmente falsa. O fluxograma desta estrutura mostrada na figura 5.2:
condio?
bloco
5.4
Estrutura for
bloco
executado
novamente e o ciclo recomea, se a condio falsa termina-se o lao. Esta condio , em geral, uma
expresso lgica que determina o ultimo valor do contador. Por exemplo: i <= 100 ou cont > 0.
Exemplo: No trecho abaixo, o contador i inicializado com o valor 1. O bloco repetido
enquanto a condio i <= 10 for verdadeira. O contador incrementado com a instruo i++. Esta
estrutura, deste modo, imprime os nmeros 1, 2, ..., 9, 10.
for(i=1; i<=10; i++){
printf(" %d",i);
}
interessante notar que a mesma estrutura lgica pode ser implementada usando as estruturas
for ou do...while:
52
do{
bloco
bloco
i++;
}while(i <= 100);
Podem existir mais de uma expresso de inicializao e de incremento na estrutura
for. Estas expresses devem ser separadas por vrgula (,). Mas no pode haver mais de uma expresso
de condio. Por exemplo: for(i=0, j=10; i<10; i++, j--){...}
Programa exemplo: No arquivo e0503.cpp existe um programa que calcula a amplitude de
um conjunto de valores. Este programa exemplifica o uso da estrutura for...
5.5
A estrutura de deciso de um bloco permite que se execute (ou no) um bloco de instrues
conforme o valor de uma condio seja verdadeiro ou falso. O fluxograma desta estrutura mostrada na
figura 5.3.
condio
bloco
53
Tambm possvel escrever uma estrutura que execute um entre dois blocos de instrues. A
figura 5.4 mostra o fluxograma correspondente a esta estrutura de deciso.
condio?
bloco 1
bloco 2
bloco 1;
}else{
bloco 2;
}
onde: condio uma expresso lgica ou numrica.
bloco 1 e bloco 2 so conjuntos de instrues.
Se a condio for verdadeira o bloco 1 executado. Caso contrrio, o bloco 2
executado.
Exemplo: No trecho abaixo, se o valor de raiz*raiz for maior que num o valor de raiz
ser atribudo a max, caso contrario, ser atribudo a min.
if(raiz*raiz > num){
max = raiz;
}else{
min = raiz;
}
Programa Exemplo: O arquivo e0505.cpp mostra um programa que utiliza a estrutura
if...else para determinar o tipo de razes de uma equao de segundo grau.
5.5.3
Tambm possvel escrever uma estrutura que execute um entre mltiplos blocos de instrues.
A figura 5.5 mostra o fluxograma correspondente a esta estrutura de deciso.
55
Condio
1?
V
bloco 1
Condio
2?
V
bloco 2
Condio
3?
...
bloco 3
...
56
Exemplo: No trecho abaixo, uma determinada ao executada se o valor de num for positivo,
negativo ou nulo.
if(num > 0){
a = b;
}else if(num < 0){
a = b + 1;
}else{
a = b - 1;
}
Programa Exemplo: O arquivo e0506.cpp mostra um programa que utiliza a estrutura
if...else if para determinar se um nmero maior, menor ou igual a outro.
5.6
Estrutura switch...case
57
expresso
rotulo 1
conjunto 1
rotulo 2
conjunto 2
...
rotulo N
conjunto N
rotulo D
conjunto D
n e conjunto d so
O valor de expresso avaliado e o fluxo lgico ser desviado para o conjunto cujo rtulo
igual ao resultado da expresso e todas as instrues abaixo deste rtulo sero executadas. Caso o
resultado da expresso for diferente de todos os valores dos rtulos ento conjunto d executado.
Os rtulos devem ser expresses constantes inteiras diferentes entre si. O rtulo default opcional.
Esta estrutura particularmente til quando se tem um conjunto de instrues que se deve
executar em ordem, porm se pode comear em pontos diferentes.
Exemplo: O trecho abaixo ilustra o uso da instruo switch em um menu de seleo. Neste
exemplo, o programa iniciar o processo de usinagem de uma pea em um ponto qualquer dependendo do
valor lido.
int seleo;
puts("Digite estagio de usinagem:");
scanf("%d",&selecao);
switch(seleo){
case 1:
// desbaste grosso...
case 2:
// desbaste fino...
case 3:
// acabamento...
case 4:
// polimento...
}
Programa Exemplo: O arquivo e0507.cpp mostra um programa que utiliza a estrutura
switch para determinar o valor de um lanche.
5.7
As instrues vistas anteriormente podem sofrer desvios e interrupes em sua seqncia lgica
normal atravs do uso certas instrues. As instrues que veremos a seguir devem ser usadas com muita
parcimnia, pois fogem da lgica estruturada tem a tendncia de tornar um programa incompreensvel.
5.7.1 A instruo break.
Esta instruo serve para terminar a execuo das instrues de um lao de repetio (for,
do...while, while) ou para terminar um conjunto switch...case.
Quando em um lao de repetio, esta instruo fora a interrupo do lao independentemente
da condio de controle.
Exemplo: No trecho abaixo um lao de repetio l valores para o clculo de uma mdia. O lao
possui uma condio de controle sempre verdadeira o que, a principio, um erro: lao infinito. Porm, a
sada do lao se d pela instruo break que executada quando um valor negativo lido.
59
puts("digite valores:");
do{
puts("valor:");
scanf("%f",&val);
if(val < 0.0){
break;
// sada do lao
}
num++;
soma += val;
}while(1);
// sempre verdadeiro
printf("mdia: %f",soma/num);
Exemplo: No exemplo acima, o uso da instruo break poderia ter sido evitado, como segue:
puts("digite valores:");
do{
puts("valor:");
scanf("%f",&val);
if(val >= 0.0){
num++;
soma += val;
}
}while(val >= 0.0);
printf("mdia: %f",soma/num);
O outro uso da instruo break, em estruturas switch...case, serve para separar os
conjuntos de instrues em cada case.
Exemplo: Estrutura switch...case com a instruo break:
int tipo;
puts("Selecione o sabor de sua pizza:");
puts("Muzzarela Calabreza Alho&Oleo:");
tipo = getch();
switch(tipo){
case M:
// prepara pizza muzzarela...
case C:
// prepara pizza calabreza...
case A:
60
A instruo continue.
Esta instruo opera de modo semelhante a instruo break dentro de um lao de repetio.
Quando executada, ela pula as instrues de um lao de repetio sem sair do lao. Isto , a instruo
fora a avaliao da condio de conttrole do lao.
Exemplo: No trecho abaixo revemos um lao de repetio l valores para o clculo de uma
mdia. Se (val < 0.0) ento o programa salta diretamente para a condio de controle, sem executar
o resto das instrues.
puts("digite valores:");
do{
puts("valor:");
scanf("%f",&val);
if(val < 0.0){
continue;
// se val negativo...
// ...salta para...
}
num++;
soma += val;
// no so executadas!
// ...fim do lao
printf("mdia: %f",soma/num);
5.7.3
A instruo goto.
Esta instruo chamada de desvio de fluxo. A instruo desvia o programa para um rtulo
(posio identificada) no programa. So raros os casos onde a instruo goto necessria, no entanto, h
certas circunstncias, onde usada com prudncia, ela pode ser til.
61
// rtulo
puts("valor:");
scanf("%f",&val);
if(val < 0.0){
goto fim;
// se val negativo...
// ...salta para fim
}
num++;
soma += val;
// no so executadas!
goto inicio;
fim:
// rtulo
printf("mdia: %f",soma/num);
5.7.4
A funo exit().
Esta funo (no instruo) exit() , da biblioteca stdlib.h, uma funo que termina a
execuo de um programa. Normalmente um programa terminado quando se executa a ltima sua
instruo, porm pode-se terminar a execuo do programa a qualquer momento com o uso desta funo.
A funo exit() tem a seguinte declarao: void exit(int status). Onde o argumento
da funo um valor inteiro que ser passado para o Sistema Operacional: (varivel de sistema
errorlevel no DOS).
Exemplo: No trecho abaixo revemos um lao de repetio l valores para o clculo de uma
mdia. Foi usado a funo exit para terminar a execuo do programa.
62
puts("digite valores:");
do{
puts("valor:");
scanf("%f",&val);
if(val < 0.0){
// se val negativo...
printf("mdia: %f",soma/num);
// imprime resultado
exit(0);
// termina programa
}
num++;
soma += val;
}while(1);
63
6. Funes
Depois de definimos um funo, podemos us-la dentro de um programa qualquer. Dizemos que
estamos fazendo uma chamada a funo.
Exemplo: No exemplo abaixo chamamos a funo media2() dentro de um programa principal:
void main(){
float num_1, num_2, med;
puts(Digite dois nmeros:);
scanf(%f %f, &num_1, &num_2);
med = media2(num_1, num_2);
// chamada a funo
6.3.1
Quando escrevemos a definio de uma funo antes do programa principal e no mesmo arquivo
deste, nenhuma outra instruo necessria. A sintaxe geral para isto a seguinte:
Sintaxe: Uma funo escrita antes do programa principal:
tipo nomef(...){
// definio da funo
[corpo de funo]
}
void main(){
// programa principal
...
var = nomef(...)
// chamada da funo
...
}
// funo
med = (a + b) / 2.0;
return(med);
}
void main(){
// programa principal
// chamada da funo
6.3.2
// programa principal
// prottipo da funo
...
var = nomef(...)
// chamada a funo
...
}
tipo nomef(...){
// definio da funo
[corpo de funo]
}
// programa principal
// prottipo de media2()
67
// chamada a funo
// funo media2()
float med;
med = (a + b) / 2.0;
return(med);
}
Observe que o prottipo de uma funo nada mais que a declarao da funo sem o seu corpo.
Observe ainda que na lista de argumentos do prottipo podem ser escritos apenas os tipos dos
argumentos.
Programa exemplo: No arquivo e0602.cpp existe um programa que calcula o maior valor
entre dois nmeros digitados. Este programa faz uso da funo max()escrita pelo usurio.
6.3.3
Em C, como em muitas outras linguagens, permitido que o usurio crie uma funo em um
arquivo e um programa que a chame em outro arquivo distinto. Esta facilidade permite a criao de
bibliotecas de usurio: um conjunto de arquivos contendo funes escritas pelo usurio. Esta
possibilidade uma grande vantagem utilizada em larga escala por programadores profissionais.
Quando escrevemos a definio de uma funo em arquivo separado do programa principal
devemos incluir este arquivo no conjunto de arquivos de compilao do programa principal. Esta
incluso feita com a diretiva #include. Esta diretiva, vista nas sees 2.4.2 e 3.7.1, instrui o
compilador para incluir na compilao do programa outros arquivos que contem a definio das funes
de usurio e de biblioteca.
Sintaxe: A sintaxe de incluso de funes de usurio a seguinte:
#include path
// incluso da funo
void main(){
// programa principal
...
var = nomef(...)
...
68
// chamada a funo
}
Na diretiva #include, indicamos entre aspas duplas o caminho de localizao do arquivo onde
est definida a funo chamada.
Exemplo: A funo media2() est escrita em um arquivo separado.
#include c:\tc\userbib\stat.h
// incluso da funo
void main(){
// programa principal
// chamada a funo
Neste programa exemplo, os nveis hierrquicos das funes podem ser colocados da seguinte
maneira:
main()
regras()
abertura()
sorte()
plim_plim()
imprimec()
pinta()
saida()
simnao()
roleta()
bip()
No exemplo acima temos um primeiro nvel onde se encontra a funo main() [o programa
principal tambm uma funo] que chama as funes x, y, z. A funo x por sua vez chamas as funes
s, r, e t. Observe que neste exemplo os prottipos das funes esto colocados de modo a que as funes
de menor hierarquia so escritas antes das funes de maior hierarquia.
media2();
printf(\nA media destes nmeros e %f, med);
}
No exemplo acima, a, b, med so variveis globais definidas fora dos blocos das funes
media() e main(). Deste modo ambas as funes tem pleno acesso as variveis, podendo ser
acessadas e modificadas por quaisquer uma das funes. Assim no necessrio a passagem de
parmetros para a funo.
6.6 Recursividade
A recursividade talvez seja a mais importante vantagem das funes em C. Recurso o
processo pelo qual uma funo chama a si mesma
7. Vetores
Neste captulo estudaremos o conceito de vetor, sua declarao e uso. Como so usados vetores
em argumentos de funes. E, ainda, como trabalhar com vetores de mais de uma dimenso.
7.1 Introduo
Em muitas aplicaes queremos trabalhar com conjuntos de dados que so semelhantes em tipo.
Por exemplo o conjunto das alturas dos alunos de uma turma, ou um conjunto de seus nomes. Nestes
casos, seria conveniente poder colocar estas informaes sob um mesmo conjunto, e poder referenciar
cada dado individual deste conjunto por um nmero ndice. Em programao, este tipo de estrutura de
dados chamada de vetor (ou array, em ingls) ou, de maneira mais formal estruturas de dados
homogneas.
Exemplo: A maneira mais simples de entender um vetor atravs da visualizao de um lista,
de elementos com um nome coletivo e um ndice de referncia aos valores da lista.
n
nota
8.4
6.9
4.5
4.6
7.2
Nesta lista, n representa um nmero de referncia e nota o nome do conjunto. Assim podemos
dizer que a 2a nota 6.9 ou representar nota[1] = 6.9
Esta no a nica maneira de estruturar conjunto de dados. Tambm podemos organizar dados
sob forma de tabelas. Neste caso, cada dado referenciado por dois ndices e dizemos que se trata de um
vetor bidimensional (ou matriz)1. Vetores de mais de uma dimenso sero vistos na seo 7.5.
1
Alguns autores preferem chamar todos os tipos de estruturas homogneas, no importando o numero de ndices de referncia
(ou dimenses) de vetores. Outros preferem chamar de matrizes. Outros ainda distinguem vetores (uma dimenso) de matrizes
73
Declarao de vetores
7.2.2
(mais de uma dimenso), etc. No vamos entrar no mrito da questo (existem boas justificativas para todas as interpretaes) e,
nesta apostila, vamos usar a primeira nomenclatura: toda estrutura homognea de dados ser chamada de vetor.
74
Cada elemento do vetor referenciado pelo nome do vetor seguido de um ndice inteiro. O
primeiro elemento do vetor tem ndice 0 e o ltimo tem ndice tam-1. O ndice de um vetor deve ser
inteiro.
Exemplo: Algumas referncias a vetores:
#define MAX 5
int i = 7;
float valor[10];
// declarao de vetor
valor[1] = 6.645;
valor[MAX] = 3.867;
valor[i] = 7.645;
valor[random(MAX)] = 2.768;
valor[sqrt(MAX)] = 2.705;
7.2.2
// NO vlido!
Inicializao de vetores
Assim como podemos inicializar variveis (por exemplo: int j = 3;), podemos inicializar
vetores.
Sintaxe: A sintaxe para a inicializao dos elementos de um vetor :
tipo nome[tam] = {lista de valores};
onde:
lista de valores uma lista, separada por vrgulas, dos valores de cada elemento do
vetor.
Exemplo: Veja as inicializaes seguintes. Observe que a inicializao de nota gera o vetor do
exemplo do incio desta seo.
int dia[7] = {12,30,14,7,13,15,6};
float nota[5] = {8.4,6.9,4.5,4.6,7.2};
char vogal[5] = {'a, e, i, o, u'};
Opcionalmente, podemos inicializar os elementos do vetor enumerando-os um a um.
Exemplo: Observe que estas duas inicializaes so possveis:
int cor_menu[4] = {BLUE,YELLOW,GREEN,GRAY};
ou
int cor_menu[4];
75
cor_menu[0] = BLUE;
cor_menu[1] = YELLOW;
cor_menu[2] = GREEN;
cor_menu[3] = GRAY;
Programa Exemplo: O arquivo e0701.cpp contm um programa que mostra o uso de vetores:
declarao, inicializao, leitura e escrita de elementos...
Limites
Na linguagem C, devemos ter cuidado com os limites de um vetor. Embora na sua declarao,
tenhamos definido o tamanho de um vetor, o C no faz nenhum teste de verificao de acesso a um
elemento dentro do vetor ou no.
Por exemplo se declaramos um vetor como int valor[5], teoricamente s tem sentido
usarmos os elementos valor[0], ..., valor[4]. Porm, o C no acusa erro se usarmos
valor[12] em algum lugar do programa. Estes testes de limite devem ser feitos logicamente dentro do
programa.
Este fato se deve a maneira como o C trata vetores. A memria do microcomputador um espao
(fsico) particionado em pores de 1 byte. Se declaramos um vetor como int vet[3], estamos
reservando 6 bytes (3 segmentos de 2 bytes) de memria para armazenar os seus elementos. O primeiro
segmento ser reservado para vet[0], o segundo segmento para vet[1] e o terceiro segmento para
vet[2]. O segmento inicial chamado de segmento base, de modo que vet[0] ser localizado no
segmento base. Quando acessamos o elemento vet[i], o processador acessa o segmento localizado em
base+i. Se i for igual a 2, estamos acessando o segmento base+2 ou vet[2](o ultimo segmento
reservado para o vetor). Porm, se i for igual a 7, estamos a acessando segmento base+7 que no foi
reservado para os elementos do vetor e que provavelmente est sendo usado por uma outra varivel ou
contm informao espria (lixo).
Observe que acessar um segmento fora do espao destinado a um vetor pode destruir
informaes reservadas de outras variveis. Estes erros so difceis de detectar pois o compilador no
gera nenhuma mensagem de erro... A soluo mais adequada sempre avaliar os limites de um vetor
antes de manipul-lo.
76
A princpio este fato poderia parecer um defeito da linguagem, mas na verdade trata-se de um
recurso muito poderoso do C. Poder manipular sem restries todos os segmentos de memria uma
flexibilidade apreciada pelos programadores.
Programa Exemplo: O arquivo e0702.cpp contm um programa que mostra o acesso de
elementos dentro e fora de um vetor. Note que o compilador no acusa nenhum erro de sintaxe!
7.3.2
Tamanho parametrizado
Na linguagem C no possvel, usando a sintaxe descrita acima, declarar um vetor com tamanho
varivel.
Exemplo: O trecho de cdigo seguinte faz uma declarao errada de vetor.
...
int num;
puts("Quantos nmeros?");
scanf("%d, &num);
float valor[num];
...
Mas possvel declarar um vetor com tamanho parametrizado: usando uma constante
simblica. Declaramos uma constante simblica (parmetro) com a diretiva #define no cabealho do
programa e depois declaramos o vetor com esta constante simblica como tamanho do vetor. Deste modo
podemos alterar o nmero de elementos do vetor antes de qualquer compilao do programa. Esta uma
maneira simples de administrar o espao de memria usado pelo programa, e tambm testar os limites de
um vetor.
Programa Exemplo: O arquivo e0703.cpp contm um programa que mostra a declarao de
um vetor com tamanho parametrizado. Mostra tambm o uso deste parmetro como teste de limite do
vetor. Compile este programa com outros valores para o parmetro MAX e verifique que a execuo do
programa alterada automaticamente.
No capitulo seguinte, seo ?, ser vista uma maneira de declararmos um vetor com um nmero
varivel de elementos, usando ponteiros. Este tipo de declarao chamada de alocao dinmica de
memria.
77
// declarao da funo
...
}
Na chamada da funo:
void main(){
float valor[MAX]; // declarao do vetor
78
...
med = media(valor, n); // passagem do vetor para a funo
...
}
Programa Exemplo: O arquivo e0704.cpp contm um programa que mostra a passagem de
vetores para funes.
Ateno: Ao contrrio das variveis comuns, o contedo de um vetor pode ser modificado pela
funo chamada. Isto significa que podemos passar um vetor para uma funo e alterar os valores de seus
elementos. Isto ocorre porque a passagem de vetores para funes feita de modo especial dito
Passagem por endereo. Uma abordagem mais detalhada deste procedimento ser feita no captulo ?
sobre ponteiros.
Portanto devemos ter cuidado ao manipularmos os elementos de um vetor dentro de uma funo
para no modifica-los por descuido.
Programa Exemplo: O arquivo e0705.cpp contm um programa que mostra a modificao de
um vetor por uma funo. Neste caso a modificao desejada pois queremos ordenar os elementos do
vetor.
8.4
7.4
5.7
6.9
2.7
4.9
4.5
6.4
8.6
4.6
8.9
6.3
7.2
3.6
7.7
79
7.5.1
Declarao e inicializao
A declarao e inicializao de vetores de mais de uma dimenso feita de modo semelhante aos
vetores unidimensionais.
Sintaxe: A sintaxe para declarao de vetores multidimensionais :
tipo nome[tam_1][tam_2]...[tam_N]={{lista},{lista},...{lista}};
onde:
tipo o tipo dos elementos do vetor.
nome o nome do vetor.
[tam_1][tam_2]...[tam_N] o tamanho de cada dimenso do vetor.
{{lista},{lista},...{lista}} so as listas de elementos.
Exemplo: veja algumas declaraes e inicializaes de vetores de mais de uma dimenso.
Observe que a inicializao de nota gera a tabela do exemplo do incio desta seo.
float nota[5][3] = {{8.4,7.4,5.7},
{6.9,2.7,4.9},
{4.5,6.4,8.6},
{4.6,8.9,6.3},
{7.2,3.6,7.7}};
int tabela[2][3][2] = {{{10,15}, {20,25}, {30,35}},
{{40,45}, {50,55}, {60,65}};
Neste exemplo, nota um vetor duas dimenses ([][]). Este vetor composto de 5 vetores
de 3 elementos cada. tabela vetor de trs dimenses ([][][]). Este vetor composto de 2 vetores
de 3 sub-vetores de 2 elementos cada.
7.5.2
// declarao da funo
...
}
Na chamada da funo:
void main(){
int valor[5][7]; // declarao do vetor
...
med = media(valor, n); // passagem do vetor para a funo
...
}
Programa Exemplo: O arquivo e0706.cpp contm um programa que mostra a manipulao
de vetores bidimensionais: leitura de elementos, escrita, passagem para funes, etc.
Observaes: Algumas observaes a respeito de vetores multidimensionais podem ser feitas:
Do mesmo modo que vetores unidimensionais, os vetores multidimensionais podem ter seus
elementos modificados pela funo chamada.
Os ndices dos vetores multidimensionais, tambm comeam em 0. Por exemplo:
vet[0][0], o primeiro elemento do vetor.
Embora uma tabela no seja a nica maneira de visualizar um vetor bidimensional, podemos
entender o primeiro ndice do vetor como o ndice de linhas da tabela e o segundo ndice do
vetor como ndice das colunas.
81
8. Endereos e Ponteiros
9.1 Introduo
Toda informao (dado armazenado em varivel simples ou vetor) que manipulamos em um
programa est armazenado na memria do computador. Cada informao representada por um certo
conjunto de bytes (Ver captulo 2). Por exemplo: caracter (char): 1 byte, inteiro (int): 2 bytes, etc.
Cada um destes conjuntos de bytes, que chamaremos de bloco, tem um nome e um endereo de
localizao especifica na memria.
Exemplo: Observe a instruo abaixo:
int num = 17;
ao interpretar esta instruo, o processador pode especificar:
Nome da informao: num
Tipo de informao: int
Tamanho do bloco (nmero de bytes ocupados pela informao): 2
Valor da informao: 17
Endereo da informao (localizao do primeiro byte): 8F6F:FFF2 (hexadecimal)
Em geral, interessa ao programador apenas os nomes simblicos que representam as
informaes, pois com estes nomes que so realizadas as operaes do seu algoritmo. Porm, ao
processador interessa os endereos dos blocos de informao pois com estes endereos que vai
trabalhar.
Programa Exemplo: O arquivo e0801.cpp contm um programa com instrues para
inspecionar o endereo de uma varivel, usando o recurso Inspect do Turbo C++. Observe que o endereo
mostrado corresponde ao primeiro byte do bloco, mesmo que o bloco ocupe mais de um byte: No caso,
um float ocupa um bloco de 4 bytes.
82
8.2 Ponteiros
Ponteiros so variveis que contm endereos. Neste sentido, estas variveis apontam para algum
determinado endereo da memria. Em geral, o ponteiro aponta para o endereo de alguma varivel
declarada no programa.
8.2.1
Declarao de ponteiros.
Quando declaramos um ponteiro, devemos declar-lo com o mesmo tipo (int, char, etc.) do bloco
a ser apontado. Por exemplo, se queremos que um ponteiro aponte para uma varivel int (bloco de 2
bytes) devemos declar-lo como int tambm.
Sintaxe: A sintaxe da declarao de um ponteiro a seguinte:
tipo_ptr *nome_ptr_1;
ou
tipo_ptr* nome_ptr_1, nome_ptr_2, ...;
onde:
tipo_ptr : o tipo de bloco para o qual o ponteiro apontar.
* : um operador que indica que nome_ptr um ponteiro.
nome_ptr_1, nome_ptr_2,...: so os nomes dos ponteiros (os nomes dos ponteiros
obedecem as mesmas regras da seo 2.2.1)
Exemplo: Veja as seguintes instrues:
int *p;
float* s_1, s_2;
A primeira instruo declara um ponteiro chamado p que aponta para um inteiro. Este ponteiro
aponta para o primeiro endereo de um bloco de dois bytes. Sempre necessrio declarar o tipo do
ponteiro. Neste caso dizemos que declaramos um ponteiro tipo int.
A segunda instruo declara dois ponteiros (s_1 e s_2) do tipo float. Observe que o * est
justaposto ao tipo: assim todos os elementos da lista sero declarados ponteiros.
8.2.2
Operadores & e *
83
significa:
"leia o buffer do teclado, transforme o valor lido em um valor inteiro (2 bytes) e o armazene no bloco
localizado no endereo da varivel num".
Exemplo: Para se atribuir a um ponteiro o endereo de uma varivel escreve-se:
int *p, val=5;
p = &val;
// atribuio
Observe que o ponteiro p deve ser declarado anteriormente com o mesmo tipo da varivel para a
qual ele deve apontar.
O operador contedo (*) determina o contedo (valor) do dado armazenado no endereo de um
bloco apontado por um ponteiro. Por exemplo, *p determina contedo do bloco apontado pelo ponteiro p.
De forma resumida: o operador (*) determina o contedo de um endereo.
Exemplo: Para se atribuir a uma varivel o contedo de um endereo escreve-se:
int *p = 0x3f8, val;
val = *p;
// atribuio
Observaes:
84
O operador endereo (&) somente pode ser usado em uma nica varivel. No pode ser usado
em expresses como, por exemplo, &(a+b).
O operador contedo (*) somente pode ser usado em variveis ponteiros.
Programa Exemplo: O arquivo e0802.cpp contm um programa que mostra como se
manipulam ponteiros e variveis. Como se transportam informaes entre ponteiros e variveis.
// p recebe o endereo de s
...
Um ponteiro pode receber o valor de outro ponteiro, isto , pode receber o endereo apontado
por outro ponteiro, desde que os ponteiros sejam de mesmo tipo.
Exemplo: Observe o trecho abaixo:
...
float *p1, *p2, val;
p1 = &val;
p2 = p1;
int *p1;
float p2
p1 = 0x03F8;
p2 = (float)0x0FF6; // casting
...
A um ponteiro pode ser atribudo o valor nulo usando a constante simblica NULL (declarada
na biblioteca stdlib.h). Um ponteiro com valor NULL no aponta para lugar nenhum!
Algumas funes a utilizam para registrar uma atribuio ilegal ou sem sucesso (ver funo
malloc() adiante)
Exemplo: Observe o trecho abaixo:
#include <stdlib.h>
...
char *p;
p = NULL;
...
Uma quantidade inteira pode ser adicionada ou subtrada de um ponteiro. A adio de um
inteiro n a um ponteiro p far com que ele aponte para o endereo do n-simo bloco seguinte.
Exemplo: Observe o trecho abaixo:
...
double *p, *q, var;
p = &var
q = ++p;
if(px != py){
8.4.1
No captulo 6 (seo 6.5) afirma-se que o valor de uma varivel var de uma funo fun_1()
passada para uma outra funo fun_2() no podem ser alterado pela funo fun_2(). De fato, isto
verdade se passamos o valor da varivel var para a funo fun_2(). Mas o valor de var pode ser
alterado por fun_2() passamos seu endereo.
No primeiro caso, dizemos que a passagem de dados de uma funo para outra ocorreu por valor.
No segundo caso, dizemos que houve uma passagem por referncia. Vejamos em detalhe uma definio
destes tipos de passagem de dados entre funes:
Passagem por Valor: A passagem por valor significa que passamos de uma funo para outra o
valor de uma varivel, isto , a funo chamada recebe um cpia do valor da varivel. Assim qualquer
alterao deste valor, pela funo chamada, ser uma alterao de uma cpia do valor da varivel. O valor
original na funo chamadora no alterado pois o valor original e copia ficam em blocos de memria
diferentes.
Passagem por Referencia: A passagem por referencia significa que passamos de uma funo
para outra o endereo de uma varivel, isto , a funo chamada recebe sua localizao na memria
atravs de um ponteiro. Assim qualquer alterao no contedo apontado pelo do ponteiro ser uma
alterao no contedo da varivel original. O valor original alterado.
Sintaxe: A sintaxe da passagem de endereo a seguinte:
na funo chamada:
tipof nomef(tipop nomep){
...
onde:
tipof o tipo de retorno da funo.
87
Observe: ponteiros
int temp;
// varivel temporria
temp = *p1;
*p1 = *p2;
*p2 = temp;
}
void main(){
// programa principal
int a,b;
scanf("%d %d",&a,&b);
troca(&a,&b);
printf("%d %d",a,b);
}
Neste exemplo temos uma funo troca() que troca entre si os valores de duas variveis. Esta
funo recebe os endereos das variveis passadas pela funo main(), armazenando-os nos ponteiros
p1 e p2. Dentro da funo, troca-se os contedos dos endereos apontados.
Programa Exemplo: O arquivo e0804.cpp contm um programa que mostra a diferena entre
a passagem de dados por valor e passagem por referencia.
8.4.2
88
A passagem por referencia permite que (formalmente) uma funo retorne quantos valores se
desejar. Dissemos no captulo 6 (seo 6.2) que uma funo somente pode retornar um valor. Isto
continua sendo valido pois o C assim define funes. Porem com o uso de ponteiros pode-se contornar
esta situao. Vejamos:
Imagine que queremos escrever uma funo stat() com a finalidade de calcular a media aritmtica e o
desvio padro de um conjunto de dados. Observe: o retorno destes dados no poder ser via instruo
return() pois isto no permitido. A soluo criar (na funo main(), por exemplo) duas variveis
para armazenar os valores desejados (med e desvio, por exemplo) e ento passar os endereos destas
variveis para a funo stat(). A funo recebe esses endereos e os armazena em ponteiros (pm e pd,
por exemplo). Em seguida, faz os clculos necessrios, armazenando-os nos endereos recebidos. Ao
trmino da execuo da funo os valores de med e desvio sero atualizados automaticamente. Este
recurso bastante utilizado por programadores profissionais.
Programa Exemplo: O arquivo e0805.cpp contm um programa que mostra o retorno de
vrios dados de uma funo. Na verdade trata-se da passagem de valores por referencia.
8.4.3
Observe que nos exemplos acima, a passagem de endereos foi feita atravs do operador
endereo (&). Tambm possvel passar um endereo atravs de um ponteiro j que o contedo de um
ponteiro um endereo.
Exemplo: Observe o trecho de programa abaixo.
...
float *p, x;
p = &x;
funo(p); // passagem do ponteiro com o endereo de x.
...
Programa Exemplo: O arquivo e0806.cpp contm um programa que mostra a passagem de
endereo para uma funo usando um ponteiro. Observe a sintaxe alternativa para a funo scanf()!
8.5.1
Ponteiros e vetores
No capitulo 7 foi mostrado que na passagem de vetores para funes especifica-se apenas o nome
do vetor e que modificaes nos elementos do vetor dentro da funo chamada alteram os valores do
vetor no programa chamador (seo 7.4). Isto se deve ao fato de que, na linguagem C, vetores so
intimamente relacionados a ponteiros.
Em C, o nome de um vetor tratado como o endereo de seu primeiro elemento. Assim ao se
passar o nome de um vetor para uma funo est se passando o endereo do primeiro elemento de um
conjunto de endereos de memria.
Por exemplo, se vet um vetor, ento vet e &vet[0] representam o mesmo endereo. E
mais, podemos acessar o endereo de qualquer elemento do vetor do seguinte modo: &vet[i] e
equivalente a (vet + i). Aqui deve-se ressaltar que (vet + i) no representa uma adio
aritmtica normal mas o endereo do i-simo elemento do vetor vet (endereo contado a partir do
endereo inicial vet[0]).
Do mesmo modo que se pode acessar o endereo de cada elemento do vetor por ponteiros,
tambm se pode acessar o valor de cada elemento usando ponteiros. Assim vet[i] equivalente a
*(vet + i). Aqui se usa o operador contedo (*) aplicado ao endereo do i-simo elemento do vetor
vet.
Programa Exemplo: O arquivo e0807.cpp contm um programa que mostra a equivalncia
entre ponteiros e vetores.
8.5.2
Ponteiros e strings
Como dissemos, vagamente na seo 2.3.4, uma string um conjunto ordenado de caracteres.
Podemos, agora, dizer muito mais: Em C, uma string um vetor unidimensional de elementos caracteres
ASCII, sendo o ultimo destes elementos o caracter especial \0.
Sintaxe: As duas maneiras mais comuns de declararmos uma string so:
char nome[tam];
ou
char *nome;
90
onde:
nome o nome do vetor de caracteres e
tam seu tamanho.
Observe que sendo um vetor, uma string pode ser declarada tambm como um ponteiro. Alias a
segunda declarao representa justamente isto. Sabendo isto podemos realizar uma grande variedade de
manipulaes com strings e caracteres. Existe uma biblioteca padro C chamada string.h que
providencia algumas funes de manipulao de strings muito teis.
Programa Exemplo: O arquivo e0808.cpp contm um programa que mostra algumas
operaes usando-se strings (vetores e ponteiros).
onde:
pont o nome do ponteiro que recebe o endereo do espao de memria alocado.
tipo o tipo do endereo apontado (tipo do ponteiro).
91
// declarao do ponteiro
92
At agora usamos ponteiros para apontar para endereos de memria onde se encontravam as
variveis (dados). Algumas vezes necessrio apontar para funes, isto , apontar para o endereo de
memria que contem o inicio das instrues de uma funo. Quando assim procedemos, dizemos que
usaremos ponteiros para funes.
onde:
pont o nome do ponteiro.
funo o nome da funo.
93
Se um ponteiro contem o endereo de uma funo, ele pode ser usado no lugar da chamada da
funo.
Exemplo: o trecho de programa abaixo usa um ponteiro para chamar uma funo:
float fun(int a,int b){
...
}
void main(void){
float temp;
float (*pt)(int,int);
pt = &fun;
temp = (*pt)(10,20); // eqivale a: temp = fun(10,20);
...
}
Programa Exemplo: O arquivo e0810.cpp contm um programa que mostra como se utiliza o
ponteiro para funo.
8.7.2
Outra utilizao de ponteiros para funes na passagem de uma funo como argumento para
outra funo. Para que isso ocorra necessitamos:
Na declarao da funo a ser passada:
i) Nada de especial, apenas a definio normal:
tipo nome_p(lista){
...
}
Exemplo:
float soma(float a,float b){
...
}
Na funo receptora:
i) Declarar o ponteiro que recebe a funo passada na lista de argumentos:
tipo nome_r(..., tipo (*pt)(lista), ...){
94
Exemplo:
float grad(float x, float y, float (*p)(float,float)){
ii) Usar o ponteiro para funes nas chamadas da funo passada:
var = (*pt)(lista);
Exemplo:
valor = (*p)(x,y);
Na funo principal:
i) Passar o nome da funo chamada para a funo receptora:
var = nome_g(... , nome_p , ...);
Exemplo:
g = grad(x,y,soma);
Programa Exemplo: O arquivo e0811.cpp contm um programa que mostra como se utiliza
ponteiros na passagem de funes
95
As tabelas mostradas neste apndice representam os 256 cdigos usados nos computadores da
famlia IBM. Esta tabela refere-se ao American Standard Code for Information Interchange (cdigo
padro americano para troca de informaes), que um conjunto de nmeros representando caracteres ou
instrues de controle usados para troca de informaes entre computadores entre si, entre perifricos
(teclado, monitor, impressora) e outros dispositivos. Estes cdigos tem tamanho de 1 byte com valores de
00h a FFh (0 a 255 decimal). Podemos dividir estes cdigos em trs conjuntos: controle, padro e
estendido.
Os primeiros 32 cdigos de 00h at 1Fh (0 a 31 decimal), formam o conjunto de controle
ASCII. Estes cdigos so usados para controlar dispositivos, por exemplo uma impressora ou o monitor
de vdeo. O cdigo 0Ch (form feed) recebido por ima impressora gera um avano de uma pgina. O
cdigo 0Dh (carriage return) enviado pelo teclado quando a tecla ENTER pressionada. Embora exista
um padro, alguns poucos dispositivos tratam diferentemente estes cdigos e necessrio consultar o
manual para saber exatamente como o equipamento lida com o cdigo. Em alguns casos o cdigo tambm
pode representar um caracter imprimvel. Por exemplo o cdigo 01h representa o caracter (happy face).
Os 96 cdigos seguintes de 20h a 7Fh (32 a 127 decimal) formam o conjunto padro ASCII.
Todos os computadores lidam da mesma forma com estes cdigos. Eles representam os caracteres usados
na manipulao de textos: cdigos-fonte, documentos, mensagens de correio eletrnico, etc. So
constitudos das letras do alfabeto latino (minsculo e maisculo) e alguns smbolos usuais.
Os restantes 128 cdigos de 80h at FFh (128 a 255 decimal) formam o conjunto estendido
ASCII. Estes cdigos tambm representam caracteres imprimveis porem cada fabricante decide como e
quais smbolos usar. Nesta parte do cdigo esto definidas os caracteres especiais: , , , ...
96
Dec.
Hex.
Controle
00h
NUL
(Null)
01h
SOH
(Start of Heading)
02h
STX
(Start of Text)
03h
ETX
(End of
04h
EOT
(End of Transmision)
05h
ENQ
(Enquiry)
06h
ACK
(Acknowledge)
07h
BEL
(Bell)
08h
BS
(Backspace)
09h
HT
(Horizontal Tab)
10
0Ah
LF
11
0Bh
VT
(Vertical Tab)
12
0Ch
FF
(Form Feed)
13
0Dh
CR
(Carriage Return)
14
0Eh
SO
(Shift Out)
15
0Fh
SI
(Shift In)
16
10h
DLE
17
11h
DC1
(Device control 1)
18
12h
DC2
(Device control 2)
19
13h
DC3
(Device control 3)
20
14h
DC4
(Device control 4)
21
15h
NAK
(Negative Acknowledge)
22
16h
SYN
(Synchronous Idle)
23
17h
ETB
24
18h
CAN
(Cancel)
25
19h
EM
(End of Media)
26
1Ah
SUB
(Substitute)
27
1Bh
ESC
(Escape)
28
1Ch
FS
(File Separator)
29
1Dh
GS
(Group Separator)
30
1Eh
RS
(Record Separator)
31
1Fh
US
(Unit Separator)
Text)
(Line Feed)
97
Caracter
Dec.
Hex.
Caracter
Dec.
Hex.
Caracter
Dec.
Hex.
<espao>
32
20h
68
44h
104
68h
33
21h
69
45h
105
69h
"
34
22h
70
46h
106
6Ah
35
23h
71
47h
107
6Bh
36
24h
72
48h
108
6Ch
37
25h
73
49h
109
6Dh
&
38
26h
74
4Ah
110
6Eh
'
39
27h
75
4Bh
111
6Fh
40
28h
76
4Ch
112
70h
41
29h
77
4Dh
113
71h
42
2Ah
78
4Eh
114
72h
43
2Bh
79
4Fh
115
73h
44
2Ch
80
50h
116
74h
45
2Dh
81
51h
117
75h
46
2Eh
82
52h
118
76h
47
2Fh
83
53h
119
77h
48
30h
84
54h
120
78h
49
31h
85
55h
121
79h
50
32h
86
56h
122
7Ah
51
33h
87
57h
123
7Bh
52
34h
88
58h
124
7Ch
53
35h
89
59h
125
7Dh
54
36h
90
5Ah
126
7Eh
55
37h
91
5Bh
<delete>
127
7Fh
56
38h
92
5Ch
128
80h
57
39h
93
5Dh
129
81h
58
3Ah
94
5Eh
130
82h
59
3Bh
95
5Fh
131
83h
<
60
3Ch
96
60h
132
84h
61
3Dh
97
61h
133
85h
>
62
3Eh
98
62h
134
86h
63
3Fh
99
63h
135
87h
64
40h
100
64h
136
88h
65
41h
101
65h
137
89h
66
42h
102
66h
138
8Ah
67
43h
103
67h
139
8Bh
98
Caracter
Dec.
Hex.
Caracter
Dec.
Hex.
Caracter
Dec.
Hex.
140
8Ch
177
B1h
214
D6h
141
8Dh
178
B2h
215
D7h
142
8Eh
179
B3h
216
D8h
143
8Fh
180
B4h
217
D9h
144
90h
181
B5h
218
DAh
145
91h
182
B6h
219
DBh
146
92h
183
B7h
220
DCh
147
93h
184
B8h
221
DDh
148
94h
185
B9h
222
DEh
149
95h
186
BAh
223
DFh
150
96h
187
BBh
224
E0h
151
97h
188
BCh
225
E1h
152
98h
189
BDh
226
E2h
153
99h
190
BEh
227
E3h
154
9Ah
191
BFh
228
E4h
155
9Bh
192
C0h
229
E5h
156
9Ch
193
C1h
230
E6h
157
9Dh
194
C2h
231
E7h
158
9Eh
195
C3h
232
E8h
159
9Fh
196
C4h
233
E9h
160
A0h
197
C5h
234
EAh
161
A1h
198
C6h
235
EBh
162
A2h
199
C7h
236
ECh
163
A3h
200
C8h
237
EDh
164
A4h
201
C9h
238
EEh
165
A5h
202
CAh
239
EFh
166
A6h
203
CBh
240
F0h
167
A7h
204
CCh
241
F1h
168
A8h
205
CDh
242
F2h
169
A9h
206
CEh
243
F3h
170
AAh
207
CFh
244
F4h
171
ABh
208
DOh
245
F5h
172
ACh
209
D1h
246
F6h
173
ADh
210
D2h
247
F7h
174
AEh
211
D3h
248
F8h
175
AFh
212
D4h
249
F9h
176
B0h
213
D5h
250
FAh
99
Caracter
Dec.
Hex.
251
FBh
252
FCh
253
FDh
254
FEh
255
FFh
100
Entre os caracteres da tabela ASCII estendidos os mais teis esto, talvez, os caracteres de desenho de
quadro em linhas simples e duplas: os caracteres de B3h at DAh (179 a 218 decimal). Como a visualizao deste
conjunto difcil, o desenho abaixo pode auxiliar nesta tarefa:
196 194
218 +
205 203
+ 191
179
195 +
201 +
+ 187
185
186
+
180
204
197
192 +
206
+ 217
200 +
193
202
209
210
+ 188
213 +
+ 184
214 +
+ 183
198
181
199
182
216
212 +
207
215
+ 190
211 +
208
+ 189
5.10 Faa um programa que leia os trs parmetros a, b, c de uma equao de segundo grau e escreva suas
razes (reais ou complexas).
5.11 Faa um programa que execute um proteo de tela do seguinte modo: Ao iniciar o programa, um
caracter (ou outro qualquer) percorra a tela em direes aleatrias apagando os caracteres de fundo.
Ao se pressionar qualquer tecla o texto de fundo reaparece e o programa termina. Use as funes
gettext() e puttext().
5.12 Faa um programa que pea para o usurio adivinhar um nmero escolhido aleatoriamente entre 1 e
100. Se o usurio digitar um nmero errado, o programa responde o novo intervalo do nmero
procurado. Se o usurio acertou o nmero procurado, o programa diz quantos palpites foram dados.
Por exemplo:
O nmero procurado est entre 1 e 100:
Palpite: 45
O nmero procurado est entre 1 e 44:
Palpite: 27
O nmero procurado est entre 28 e 44:
Palpite: 36
Parabns! Voc acertou o nmero em 3 tentativas.
5.13 Faa um programa que leia um valor inteiro de 0 a 1000 escreva o seu valor por extenso. Por
exemplo:
Digite valor: 279
Extenso: duzentos e setenta e nove.
5.14 Faa um programa que coloque um caracter no centro da tela e permita o movimentao deste com o
uso das setas.
5.15 Implemente um rastro para o caracter do programa 5.14. Sugesto: use os caracteres de
preenchimento: 176d, 177d, 178d e 219d.
5.16 Faa um programa que desenhe um janela com bordas (simples ou duplas) em uma posio
centralizada da tela. Pinte o interior da janela com alguma cor diferente do fundo da tela. [Sugesto:
Use o lao for... para escrever as bordas e a funo clrscr() para pintar o interior da janela].
Captulo 6: Funes
6.1 Crie um funo float round(float r) que faa o arredondamento de nmeros reais: Por
exemplo: 5 = round(5.4), 7 = round(6.5).
6.2 Crie uma funo int sim_nao(void) que espera o usurio pressionar as teclas [s] ou [n]
retornando 1 ou 0 respectivamente. Se o usurio pressionar qualquer outra tecla um som (de
advertncia) de 50 Hz por 250 ms emitido.
6.3 Transforme o programa do exerccio 5.16 em uma funo com a seguinte declarao: int
borda(esq, sup, dir, inf, corf, corb) onde esq, sup, dir, inf so as
posies das bordas, corf, corb as cores do fundo e da borda da janela respectivamente. A funo
retorna 1 se houve algum erro na passagem dos parmetros ( esq > dir, por exemplo) e 0 caso
contrrio.
6.4 Faa uma funo que determine se trs nmeros a, b, c formam um tringulo ou no. A funo
deve ter a seguinte declarao int tringulo(float a, float b, float c) onde o
valor de retorno tem o seguinte significado:
0: no forma tringulo,
1: tringulo qualquer,
iii
2: tringulo issceles,
3: tringulo equiltero.
6.5 Faa uma funo que determine se um determinado numero primo ou no. A funo deve ter a
seguinte declarao int primo(int N) onde N o valor a ser testado. A funo deve retornar 1
se N primo e 0 caso contrrio. [Sugesto: Altere o programa do exerccio 5.3].
6.6 Transforme o programa do exerccio 5.7 em uma funo int fib(int n) que retorna o n-simo
numero de Fibonacci.
6.7 A mdia elptica2 (ou aritmtico-geomtrica) de dois nmeros positivos a e b [a < b], calculada do
seguinte modo: Chamando a n +1 = a n bn e bn +1 = ( a n + bn ) / 2 respectivamente as mdias
geomtrica e aritmtica desses nmeros obtemos uma seqncia de nmeros a0, a1, a2, ... e b0, b1, b2, ...
tal que a 0 < a1 < a 2 <L < b2 < b1 < b0 . O limite desta seqncia m = a = b . Por exemplo: a
mdia elptica de 4 e 7 5.5932... Faa uma funo double elip(double a, double
b) que calcule a mdia elptica de a e b. [Sugesto: Use um lao while(a < b)...].
6.8 O maior divisor comum dos inteiros positivos a e b, que abreviamos como mdc(a, b), o maior
nmero m tal que m divisor tanto de a quanto de b. Por exemplo: 4 = mdc(20,16), 7 = mdc(21,7). O
valor de m pode ser calculado com o seguinte algoritmo recursivo3, de Euclides:
se a > b ento mdc(a, b) igual a
b se resto(a, b) 0
mdc(b, resto(a, b)) caso contrrio.
Faa uma funo recursiva para o clculo do mximo divisor comum de dois nmeros.
6.9 Caso j no tenha feito assim, transforme a funo iterativa do exerccio 6.6 em uma funo
recursiva.
Captulo 7: Vetores
7.1 Escreva um programa que leia um vetor de N nmeros inteiros,(N<=100), inverta a ordem dos
elementos do vetor e imprima o vetor invertido. Por exemplo o vetor: {1, 3, 5, 7} ter seus
elementos invertidos: {7, 5, 3, 1}. Observao: necessrio inverter os elementos do vetor.
No basta imprimi-los em ordem inversa!
7.2 Escreva um programa que leia um vetor a de N nmeros reais, (N<=100),e um outro real k e
construa e imprima um outro vetor b cujos elementos so os respectivos elementos de a
multiplicados por k. Por exemplo: a = {1,2,3}, k = 5, b = {5,10,15}.
7.3 Escreva duas funes: uma que leia um vetor v de n nmeros inteiros, (n<=100), e outra que
escreva este vetor. A declarao destas funes devem ser, respectivamente: void le_vet(int
v, int n) e void escreve_vet(int v, int n).
7.4 Escreva um programa que leia um vetor gabarito de 10 elementos. Cada elemento de
gabarito contem um numero inteiro 1, 2, 3, 4 ou 5 correspondente as opes corretas de
uma prova objetiva. Em seguida o programa deve ler um vetor resposta, tambm de 10
elementos inteiros, contendo as respostas de um aluno. O programa deve comparar os dois vetores e
escrever o numero de acertos do aluno.
Descoberta pelo matemtico alemo Carl F. Gauss. Ver LIMA, E. L., Meu Professor de Matemtica,?,
p.123
3
Ver SMITH, J. D. Design and Analysis of Algorithms, Boston: PWS-Kent Pub. Co. 1989 p.272
iv
7.5 Escreva uma funo int min_vet(float v[], int n) receba um vetor e retorne o ndice
do menor elemento deste vetor.
7.6 Escreva uma funo int remove_dup(float v[], int n) receba um vetor e verifique a
existncia de elementos duplicados. Caso no existam elementos duplicados retorne 0. Caso
existam, remova estes elementos (deixando apenas um) e retorne o nmero de elementos removidos.
7.7 Escreva uma funo void insert(float v[], int n, float valor, int pos)
que faa a insero de valor na posio pos do vetor v, deslocando os demais elementos.
7.8 Transforme o programa do exemplo e0705.cpp em uma funo void ordem(int v, int
n) que ordene os elementos de um vetor v de n elementos inteiros.
7.9 Escreva uma funo int merge(float r[], float s[], float v[], int n, int
m) receba um vetor r de n elementos e outro vetor s de m elementos e construa um vetor v com os
elementos de r e s, ordenado e no duplicado. A funo deve retornar o tamanho do vetor v
construdo. Sugesto: Utilize as funes dos exerccios 7.6, 7.7 e 7.8.
7.10 A funo do exerccio 7.9 pode ser entendida como uma funo que retorna a unio entre dois
conjuntos. Escreva uma funo int intersec(float r[], float s[], float v[],
int n, int m) que construa um vetor v com a interseo entre r e s, ordenados. A funo
deve retornar o tamanho do vetor v construdo.
7.11 Escreva uma funo void desordem(int v, int n) que desordene os elementos de um
vetor v (no necessariamente ordenado) de n elementos inteiros. Sugesto: use o seguinte algoritmo:
para i de n-1 at 0 faa
j valor aleatrio entre 0 e i
v[i] v[j]
fim faa
Observao: Esta rotina pode ser usada para simular o processo de embaralhar as cartas de um
baralho.
7.12 Escreva uma funo int find(char v[], char t[], int m, int n) que receba um
vetor v de m elementos e um vetor t de n elementos (n < m). Esta funo deve verificar a
ocorrncia do padro t em v ou no. Se houver, deve retornar a posio inicial da primeira
ocorrncia. Por exemplo: se v={As bananas do Panam so bacanas} e p={anas}
deve retornar 6. Caso no haja ocorrncia, retorne -1. Observao: Algoritmos como esses so
usados em editores de texto4.
n
r r
7.13 O produto escalar entre dois vetores pode ser definido como: e = u v = ui v i , onde ui e vi so
5
i=0
y -.-5 .....
. .-.-.-
z --..
6 -....
? ..--..
1 .---7 --...
, --..--
2 ..--8 ---..
: ---...
3 ...-9 ----.
4 ....0 -----
Escreva um programa que leia uma frase digitada pelo usurio e emita pelo alto-falante do PC o som
correspondente a uma transmisso completa em cdigo Morse. Sugesto: Crie uma tabela
cdigo[40][5] em que cada linha represente um sinal contendo os nmeros 1 (ponto), 2 (trao)
ou 0 (fim do cdigo).
7.15 Existe um problema famoso no xadrez chamado Problema das 8 damas: consiste em dispor sobre o
tabuleiro (de 8 x 8 casas) do jogo um conjunto de 8 damas de tal forma que nenhuma dama fique na
mesma linha, coluna ou diagonal que outra. Escreva um programa que calcule pelo menos uma
soluo deste problema. Sugesto: crie um vetor tab[8][8] contendo 0 para uma casa vazia e 1
para uma casa ocupada. Escreva uma funo que crie as configuraes e outra rotina que teste a
soluo.
7.16 As populares calculadoras HP (Hewllet-Packard) usam a notao RPN (Reverse Polish Notation)
para o clculo de expresses numricas. Este tipo de notao torna mais fcil o clculo de expresses
complexas. Cada valor digitado guardado em uma pilha de dados e cada tecla de operao efetua
uma operao entre os ltimos dois valores da pilha. Por exemplo, para efetuar a expresso 2+5*3
digitamos:
[5] (colocamos o primeiro valor na pilha),
[enter] [3] (deslocamos 5 para a 2a posio da pilha e colocamos 3 para o 1o valor na pilha),
[*] (efetuamos a multiplicao dos dois valores, o valor 15 aparece na 1a posio da pilha),
[2] (deslocamos 15 para a 2a posio da pilha e colocamos 3 para o 1o valor na pilha)
[+] (adicionamos 2 ao resultado, 17 aparece na 1a posio da pilha).
Escreva um programa que simule uma calculadora RPN de 4 operaes (+,-,*,/) utilizando
vetores para representar a pilha de dados.
7.17 Reverse o nome de um antigo jogo de tabuleiro, que pode ser facilmente implementado em um
computador: consiste de um tabuleiro de 3x3 casas, com um disco branco ou preto dispostos,
inicialmente, de modo aleatrio em cada casa.
[1][2][3]
[4][5][6]
[7][8][9]
Ao selecionar uma das casas o jogador reverte a cor do disco daquela casa e de algumas casas
vizinhas conforme o esquema acima. O objetivo do jogo reverter todas as casas para uma mesma
cor. Escreva um programa que simule o tabuleiro do jogo de Reverse.
Ao pressionar
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
Reverte:
[1],[2] e [4]
[2],[1] e [3]
[3],[2] e [6]
[4],[1] e [7]
[5],[2],[4],[6] e [8]
[6],[3] e [9]
[7],[4] e [8]
[8],[7] e [9]
[9],[6] e [8]
7.18 Caso j no tenha feito assim, Rescreva o programa do exerccio 7.1 tornando-a recursiva.
7.19 Escreva uma funo que receba duas matrizes de ordem m e construa o produto matricial entre eles.
vi
Captulo 8: Ponteiros
8.1 Rescreva a funo round() do exerccio 6.1 para que receba o endereo da varivel a ser
arredondada. A nova funo deve ter a seguinte declarao void round(float *r) e deve
arredondar o prprio numero passado.
8.2 Escreva uma funo void troca(int *a, int *b) que permuta entre si os valores de a e b.
8.3 Escreva uma funo void stat(float vet, int N, float *med, float *dsvpd)
que receba um vetor de nmeros reais vet, seu tamanho N e calcule a mdia aritmtica med e o
desvio padro6 dsvpd destes valores.
8.4 Escreva uma funo void extremos(float vet, int N, float *max, float
*min) que receba um vetor de nmeros reais vet, seu tamanho N e determine o maior e o menor
(max e min) destes valores.
8.5 Rescreva o programa do exemplo 7.1 para que, usando alocao dinmica de memria , construa um
vetor de N elementos, sendo N digitado pelo usurio.
8.6 Escreva um programa que, usando alocao dinmica de memria, construa um vetor de N
elementos gerados aleatoriamente no intervalo [0,10], sendo N digitado pelo usurio. Em seguida
este programa deve chamar a funo remove_dup() do exerccio 7.6. necessria alguma
modificao no cdigo desta funo?
8.7 Escreva uma rotina void graf(float a float b, float (*pf)(float)) que recebe
um endereo de uma funo no ponteiro pf, os valores de extremos a e b e desenhe o grfico da
funo apontado por pf.
Ver GIOVANNI, J. R., BONJORNO, J. R., Matemtica, vol. 3, So Paulo: FTD, s.d. p. 320.
vii