Você está na página 1de 70

# APOSTILA DO CURSO

LINGUAGEM C
Prof. Erico Fagundes Anicet Lisboa, M. Sc.
erico@ericolisboa.eng.br

## Verso digital disponvel na internet

http://www.ericolisboa.eng.br

## RIO DE JANEIRO, RJ - BRASIL

NOVEMBRO DE 2001

ii

NDICE
1. INTRODUO ______________________________________________________ 1
1.1 Histria ____________________________________________________________________________1
1.2 Estruturao de um Programa em C ____________________________________________________1
1.3 Tipos ______________________________________________________________________________2
1.4 Variveis ___________________________________________________________________________2
1.5 Constantes _________________________________________________________________________2
1.6.1 A Funo printf() _________________________________________________________________________ 3
1.6.2 A Funo scanf() _________________________________________________________________________ 4

2.5 Operadores bit a bit __________________________________________________________________6
2.6 Atribuies reduzidas ________________________________________________________________6

## 3. CONTROLE DE FLUXO ______________________________________________ 9

3.1 if __________________________________________________________________________________9
3.2 while______________________________________________________________________________10
3.3 do-while ___________________________________________________________________________10
3.4 for________________________________________________________________________________11
3.5 break _____________________________________________________________________________11
3.6 switch ____________________________________________________________________________12

4. FUNES _________________________________________________________ 14
4.1 Definio de Funo _________________________________________________________________14
4.1.1 Variveis Locais_________________________________________________________________________ 14
4.1.2 Chamando Funes ______________________________________________________________________ 14
4.1.3 Programa Exemplo_______________________________________________________________________ 15

4.2 Argumentos________________________________________________________________________15
4.3 Valor de Retorno ___________________________________________________________________16

iii

4.5 Classes de Armazenamento ___________________________________________________________17
4.5.1 Classe de Armazenamento - auto ____________________________________________________________ 18
4.5.2 Classe de Armazenamento - extern __________________________________________________________ 18
4.5.3 Classe de Armazenamento - static ___________________________________________________________ 18
4.5.4 Classe de Armazenamento - register _________________________________________________________ 19

## 4.6 O Pr-processador C ________________________________________________________________19

4.6.1 A Diretiva #define _______________________________________________________________________ 19
4.6.2 A Diretiva #undef________________________________________________________________________ 21
4.6.3 A Diretiva #include ______________________________________________________________________ 21
4.6.4 Outras Diretivas _________________________________________________________________________ 21

## 5. VETORES E MATRIZES _____________________________________________ 23

5.1 Vetores____________________________________________________________________________23
5.1.1 Inicializao ____________________________________________________________________________ 24
5.1.2 Vetores como argumento de funes _________________________________________________________ 25

## 5.2 Vetores de Caracteres _______________________________________________________________25

5.2.1 A funo strlen() ________________________________________________________________________ 26
5.2.2 A funo strcmp() _______________________________________________________________________ 26
5.2.3 A funo strcpy() ________________________________________________________________________ 27
5.2.4 A funo strcat()_________________________________________________________________________ 27

5.3 Matrizes___________________________________________________________________________27
5.3.1 Inicializao ____________________________________________________________________________ 28
5.3.2 Matrizes como argumento de funes ________________________________________________________ 28

6. PONTEIROS _______________________________________________________ 29
6.1 Definio __________________________________________________________________________29
6.2 Passagem de Argumentos por Endereo ________________________________________________30
6.3 Operaes com Ponteiros_____________________________________________________________31
6.3.1 Atribuio______________________________________________________________________________ 32
6.3.2 Contedo ______________________________________________________________________________ 32
6.3.3 Endereo_______________________________________________________________________________ 32
6.3.4 Soma e diferena ________________________________________________________________________ 32
6.3.5 Comparaes ___________________________________________________________________________ 32
6.3.6 Ponteiros para void_______________________________________________________________________ 32

## 6.4 Ponteiros e Vetores__________________________________________________________________33

6.5 Alocao Dinmica de Memria _______________________________________________________34
6.5.1 Funo malloc() _________________________________________________________________________ 34
6.5.2 Funo free() ___________________________________________________________________________ 34
6.5.2 Exemplo das funes malloc() e free() _______________________________________________________ 34

iv

## 6.6 Ponteiros para Ponteiros _____________________________________________________________35

6.6.1 Passando matrizes alocadas dinamicamente como argumento de funes_____________________________ 36

## 6.7 Ponteiros para Funes ______________________________________________________________37

6.7.1 A funo qsort() _________________________________________________________________________ 37

7.1 Estruturas _________________________________________________________________________40
7.1.1 Acessando dados membro _________________________________________________________________ 40
7.1.2 Estruturas dentro de estruturas ______________________________________________________________ 41
7.1.3 Atribuio entre estruturas _________________________________________________________________ 42
7.1.4 Passando estruturas para funes ____________________________________________________________ 42
7.1.5 Vetores de estruturas _____________________________________________________________________ 43
7.1.6 Ponteiros para estruturas __________________________________________________________________ 43

## 7.2 Unies ____________________________________________________________________________45

7.3 Enumerao _______________________________________________________________________45

8.1 Arquivos Texto _____________________________________________________________________47
8.1.1 As funes fopen() e fclose() _______________________________________________________________ 48
8.1.2 As funes getc () e putc() _________________________________________________________________ 49
8.1.3 As funes fgets () e fputs() ________________________________________________________________ 49
8.1.4 As funes fprintf () e fscanf() ______________________________________________________________ 50

## 8.2 Arquivos Binrios___________________________________________________________________51

8.2.1 As funes fread () e fwrite() _______________________________________________________________ 51

## ANEXO A - TABELA ASCII ____________________________________________ 53

ANEXO B - EXERCCIOS ______________________________________________ 58
B.1 Introduo ________________________________________________________________________58
B.3 Controle de Fluxo __________________________________________________________________59
B.4 Funes ___________________________________________________________________________60
B.5 Vetores e Matrizes __________________________________________________________________61
B.6 Ponteiros __________________________________________________________________________63

## ANEXO C - EXEMPLOS DE FUNES __________________________________ 65

BIBLIOGRAFIA ______________________________________________________ 66

1 - Introduo

Linguagem C

CAPTULO 1
INTRODUO
1

1.1 Histria
A origem do nome da linguagem C muito simples. a linguagem que sucede a linguagem B. Por sua
vez, a linguagem B teve seu nome retirado da inicial do local onde ela foi desenvolvida: Laboratrios
Bell. A primeira verso da linguagem C foi escrita e implementada por D.M. Ritchie. Foi inicialmente
publicada no livro "The C Programming Language", por B.W. Kernighan & D.M. Ritchie em 1978.
Diversas verses de C, incompatveis, foram criadas. Estas verses funcionavam somente com um
determinado compilador, rodando apenas em uma nica plataforma, o que tornava os cdigos
computacionais muito restritos a determinadas condies. Em 1983, a ANSI (American National
Standards Institute) fundou uma comisso para definir uma verso padronizada para a linguagem C.
Esta verso chamou-se ANSI C. Desta forma, simplesmente compilando o cdigo fonte em qualquer
sistema, um programa escrito em ANSI C funciona em praticamente qualquer computador.
1.2 Estruturao de um programa em C
A seguir fornecido um programa exemplo, contendo algumas das principais funcionalidades da
main()
{
/* Programa exemplo */
float a, b, c;
printf("Digite dois numeros:\n");
scanf("%f", &a);
scanf("%f", &b);
if(a > b)
c = a * a;
else
c = b * b;
}

A primeira linha do programa, main(), indica que a primeira funo a ser executada, ou seja, por
onde o programa comea a execuo.
O abre-chaves, {, na segunda linha comea o corpo da funo.
A terceira linha, /* Programa exemplo */, um comentrio e ignorada pelo compilador.
Na quarta linha so declaradas as trs variveis que sero utilizadas pelo programa.
dentro de um cdigo em C. Normalmente, utiliza-se para separar partes lgicas de um cdigo.

## Prof. Erico Lisboa

http://www.ericolisboa.eng.br

1 - Introduo

Linguagem C

## As linhas 7 e 8 recebem dois valores do teclado, atravs da funo scanf().

As prximas 4 linhas calculam o valor da varivel c, dependendo da comparao entre a e b, feita pelo
bloco if-else.
A linha 13 imprime o resultado na tela, atravs da funo printf().
O fecha-chaves, }, na ltima linha encerra a funo.
1.3 Tipos
A linguagem C possui 5 tipos bsicos. So os tipos char, int, float, double e void. A tabela abaixo
Tipo
char
int

Descrio
caractere
inteiro

Tamanho
1 bytes
2 ou 4 bytes

float
double
void

ponto flutuante
ponto flutuante de dupla preciso
vazio

4 bytes
8 bytes
0 bytes

Intervalo
-128 a 127 ou 0 a 255
-32768 a 32767 ou
-214783648 a 214783647
-1.7E38 a 1.7E38 (preciso de 6 digitos)
-1.7E38 a 1.7E38 (preciso de 16 digitos)
-

O tamanho do tipo inteiro varia com o compilador utilizado. Este tipo possui ainda trs variaes, a
seguir:
Tipo
long int
short int
unsigned int

Descrio
inteiro longo
inteiro curto
inteiro sem sinal

Tamanho
4 bytes
2 bytes
2 ou 4 bytes

Intervalo
-214783648 a 214783647
-32768 a 32767
0 a 65535 ou 0 a 4294967295

1.4 Variveis
Em C, todas as variveis precisam ser declaradas. A declarao tem a forma
tipo nome-da-varivel
ou
tipo nome-da-varivel1, da-varivel2, ...
onde tipo o tipo da varivel e nomes-das-variveis so separadas por vrgulas.
Os nomes das variveis devem comear com uma letra ou o sublinhado ('A' a 'Z', 'a' a 'z' e '_'). O
restante do nome pode ser composto por letras, sublinhado ou nmeros. Tambm no so permitidos
como nomes de variveis palavras reservadas pela linguagem C. A tabela abaixo fornece alguns nomes
de variveis vlidos e no-vlidos.
Nomes vlidos
ABC
tomate
_g
agua_do_mar
carro5000

## Prof. Erico Lisboa

Nomes no vlidos
/ABC
int
g*
agua-do-mar
5000carro

http://www.ericolisboa.eng.br

1 - Introduo

Linguagem C

1.5 Constantes
Existem diversos tipos de constantes: inteira, ponto flutuante, caractere e cadeia de caracteres.
Constante numrica
10
017
0xFF, 0XF0
64L
78678537
74.1, 1., .5

constante inteira
constante octal
constante longa
constante longa (implcito)
constante de ponto flutuante

Constantes de caractere so representadas entre apstrofos (') e equivalem ao nmero pelo qual o
caractere representado na mquina. A maioria das mquinas utiliza a representao ASCII (American
Standard Code for Information Interchange). Para permitir portabilidade, constantes de caractere
devem ser utilizadas no lugar de seus equivalentes inteiros.
Constante de caractere
'A'
'Z'
'='

Valor ASCII
65
90
61

Caracteres especiais so representados com a barra invertida (\) seguida de um determinado caractere.
Constante de caractere
'\n'
'\r'
'\t'
'\\'
'\0'
'\''
'\"'

caractere de mudana de linha (LF)
caractere de retorno de carro (CR)
caractere de tabulao (TAB)
caractere de barra invertida
caractere nulo
caractere apstrofo
caractere aspas

## O caractere nulo ('\0') colocado direita da cadeia, indicando o seu final.

"ABCDE"
""

Cadeia de caracteres armazenando os caracteres 'A', 'B', 'C', 'D', 'E' e '\0'
Cadeia de caracteres armazenando o caractere '\0'

Tamanho
6 bytes
1 byte

Nesta seo so apresentadas duas funes que sero utilizadas ao longo dos exerccios propostos no
curso. So as funes printf() e scanf(). O conceito de funes ser detalhado no Captulo 4.
1.6.1 A Funo printf()
A funo printf() uma das funes de E/S (entrada e sada) que podem ser usadas em C. Ela no faz
parte da definio da linguagem C, sendo includa em uma biblioteca (stdio.h) fornecida juntamente
com os compiladores. Esta funo serve para apresentar na tela uma expresso definida pelo usurio, e
segue a sintaxe
printf("expr. de controle", argumento1, argumento2, ),

## Prof. Erico Lisboa

http://www.ericolisboa.eng.br

1 - Introduo

Linguagem C

onde expr. de controle uma expresso definida, que pode conter alguns cdigos, apresentados na
tabela a seguir. Quando a funo printf() encontra um destes cdigos, ela o substitui pelo argumento
fornecido. Os argumentos podem ser nenhum ou quantos argumentos se fizerem necessrios.
Cdigo printf()
%c
%d
%e
%f
%g
&o
%s
%u
%x
%ld
%lf

Formato
caractere simples
decimal
notao cientfica
ponto flutuante
%e ou %f (o mais curto)
octal
decimal sem sinal
decimal longo
ponto flutuante longo (double)

Exemplos:
printf("Teste geral");

printf("Esta casa tem %d quartos\n", 2);

## Sada: Esta casa tem 2 quartos

printf("Nome: %s\nSexo: %c\nIdade: %d\n", "Pedro", 'M', 18);

Sexo: M
1.6.2 A Funo scanf()
A funo scanf() outra das funes de E/S (entrada e sada) que podem ser usadas em C. L do
funo. Sua sintaxe
scanf("expr. de controle", &argumento1, &argumento2, ),

## onde a expresso de controle utiliza os mesmos cdigos da funo printf().

Exemplo:
int i, j;
float f;
char c;
scanf("%d%d", &i, &j);
scanf("%f", &f);
scanf("%c", &c);

O operador de endereo (&), que precede os argumentos da funo, retorna o primeiro byte ocupado
pela varivel na memria do computador, e ser detalhado no captulo de ponteiros.

## Prof. Erico Lisboa

http://www.ericolisboa.eng.br

Linguagem C

CAPTULO 2
2

Os operadores aritmticos so os seguintes: + (adio), - (subtrao), * (multiplicao) e / (diviso).
No caso de diviso entre nmeros inteiros, o resultado truncado. O operador % fornece o resto da
diviso e s funciona como operador entre tipos inteiros. Ento:
Expresso
22 / 3
22 % 3
14 / 4
14 % 4
21 / 7
21 % 7

Tem o valor
7
1
3
2
3
0

O operador de atribuio (=) copia o valor do lado direito para a varivel, ou endereo, do lado
esquerdo. Alm disso, o operador = tambm retorna este valor. Isso significa que, ao fazer x = y, por
exemplo, o valor da varivel y ser copiado na varivel x, sendo este valor o resultado da operao.
Em outras palavras, se fizermos x = y = 0, ser processada inicialmente a operao y = 0, atribuindo o
valor 0 varivel y. Esta expresso fornece o resultado 0, que atribudo varivel x. No final do
processamento, ambas as variveis tero o valor 0.
Expresso
i=3
i=3+4
i=k=4
i = (k = 4) + 3

Operao
Coloca o valor 3 em i
O valor 7 colocado em i
O valor 4 colocado em k; o valor da atribuio (4)

Valor da expresso
3
7
4
4

Os operadores relacionais em C so: == (igual a), != (diferente de), > (maior que), < (menor que), >=
(maior ou igual a) e <= (menor ou igual a). O resultado de dois valores conectados por um operador
relacional ser 0 para falso ou 1 para verdadeiro.
Expresso
5<3
3<5
5 == 5
3 == 5
5 <= 5

## Prof. Erico Lisboa

Valor
0
1
1
0
1

http://www.ericolisboa.eng.br

Linguagem C

Em C, no existem variveis lgicas. Qualquer valor pode ser testado como verdadeiro ou falso. Se ele
for zero, falso. Se for qualquer valor diferente de zero, verdadeiro.
Os dois operadores lgicos binrios so && (e) e || (ou). O resultado de suas operaes tambm ser 0
Expresso
5 || 3
5 || 0
5 && 3
5 && 0
(i > 5) && (i <= 7)

Valor
1
1
1
0
1 se i for maior que 5 e menor ou igual a 7
0, qualque outro caso

O operador negao (!) inverte o sentido do valor que o segue. Qualquer valor no zero ser convertido
para 0 e um valor 0 ser convertido para 1.
Expresso
!5
!0
!(i > 5)

Valor
0
1
1 se i no for maior que 5
0, se i for maior que 5

## 2.5 Operadores bit a bit

Os operadores bit a bit operam apenas com nmeros inteiros. Os operadores so: & (e, bit a bit), | (ou,
bit a bit), ^ (ou exclusivo, bit a bit), ~ (negao, bit a bit), << (deslocamento esquerda) e >>
(deslocamento direita). So utilizados normalmente para ligar ou desligar bits ou para testar bits
especficos em variveis inteiras.
Expresso
1|2
0xFF & 0x0F
0x33 & 0xCC
0x0F << 2
0x1C >> 1

Valor
3
0x0F
0xFF
0x3C
0x0E

Expresso binria
00000001 | 00000010
11111111 & 00001111
00110011 | 11001100
00001111 << 2
00011100 >> 1

Valor binrio
00000011
00001111
11111111
00111100
00001110

## 2.6 Atribuies reduzidas

C oferece muitos operadores de atribuio que so reduo de outros operadores. Eles tomam a forma
de op=, onde op pode ser +, -, *, /, %, <<, >>, &, ^, |. A expresso f op= g anloga a
f = f op g. Por exemplo:
Expresso
a += 2
i <<= 1
s /= 7 + 2

## Prof. Erico Lisboa

igual a
a=a+2
i = i << 1
s = s / (7 + 2)

http://www.ericolisboa.eng.br

Linguagem C

Os operadores pr e ps-fixados incrementam (++) ou decrementam (--) uma varivel. Uma operao
aps a utilizao da varivel. Por exemplo, para uma varivel i inteira com valor 5:
Expresso
5 + (i++)
5 + (i--)
5 + (++i)
5 + (--i)

## Valor de i utilizado na avaliao

5
5
6
4

Valor da expresso
10
10
11
9

Valor final de i
6
4
6
4

Operadores condicionais so uma maneira rpida de selecionar um entre dois valores, baseado no valor
de uma expresso. A sintaxe :
expr1 ? expr2 : expr3

Se expr1 for verdadeira (no zero), ento o resultado o valor de expr2. Caso contrrio o valor de
expr3. Por exemplo:
Expresso
5?1:2
0?1:2
(a > b) ? a : b
(a > b) ? ((a > b) ? a : c) : ((b > c) ? b : c)

Valor
1
2
1
1

Numa seqncia de expresses separadas por vrgulas, as expresses so processadas da esquerda para
a direita sendo retornado o valor da expresso mais direita.
Expresso
5, 1, 2
i++, j + 2
i++, j++, k++
++i, ++j, ++k

Valor
2
j+2
valor de k (antes do incremento)
valor de k (depois do incremento)

Os operadores tm uma ordem de precedncia. Isto , sem parnteses, certas operaes so efetuadas
antes de outras com menor precedncia. Para operadores com precedncia igual, a associatividade da
esquerda para direita, com algumas excees (mostradas na tabela abaixo). Para se ter certeza da
interpretao, as expresses que se deseja interpretar primeiro devem ser agrupadas entre parnteses.
Cada conjunto de operadores na tabela possui a mesma precedncia. Os smbolos ainda no
mencionados sero descritos mais adiante (nos captulos sobre funes, matrizes e estruturas).

## Prof. Erico Lisboa

http://www.ericolisboa.eng.br

Linguagem C

()
[]
->
.
!
~
++
-(tipo)
*
&
sizeof
*
/
%
+
<<
>>
<
<=
>
>=
==
!=
&
^
|
&&
||
?:
=
op=
,

## Prof. Erico Lisboa

Descrio
elemento de matriz
ponteiro para membro de estrutura
membro de estrutura
negao lgica
negao bit a bit
incremento
decremento
menos unrio
converso (cast)
ponteiro
endereo
tamanho do objeto
multiplicao
elemento de matriz
resto da diviso
subtrao
deslocamento esquerda
deslocamento direita
menor que
menor ou igual a
maior que
maior ou igual a
e, bit a bit
ou exclusivo, bit a bit
ou, bit a bit
e, lgico
ou, lgico
condicional
atribuio
atribuio
vrgula

http://www.ericolisboa.eng.br

3 - Controle de fluxo

Linguagem C

CAPTULO 3
CONTROLE DE FLUXO
3

3.1

if

3.1.1 Sintaxe
if (expr) comando

if (expr) comando1 else comando2

if (expr1) comando1 else if (expr2) comando2 else comando3

3.1.2 Exemplos
/* Exemplo 1 */
if (a == 3)
b = 4;

/* Exemplo 2 */
if (a > b)
c = a * a;
else
c = b * b;

/* Exemplo 3 */
if (a == b)
c = 0;
else if (a > b)
c = a * a;
else
c = b * b;

Ateno:
Exemplo
if (a == 3) b = 4;
if (a = 3) b = 4;

## Prof. Erico Lisboa

Ao
Testa se o valor de a 3. Se for, atribui o valor 4 a b
Atribui 3 varivel a. Testa o valor 3 (verdadeiro); portanto, independente
do valor inicial de a ser atribudo 4 a b

http://www.ericolisboa.eng.br

3 - Controle de fluxo

3.2

Linguagem C

while

3.2.1 Sintaxe
while (expr) comando

Quando o programa chega na linha que contm o teste do comando while, ele verifica
se a expresso de teste verdadeira. Se for, o programa executa o comando uma vez e
torna a testar a expresso, at que a expresso seja falsa. Somente quando isso ocorrer,
o controle do programa passa para a linha seguinte ao lao.
Se, na primeira vez que o programa testar a expresso, ela for falsa, o controle do
programa passa para a linha seguinte ao lao, sem executar o comando nenhuma vez.
O corpo de um lao while pode ter um nico comando terminado por ponto-e-vrgula,
vrios comandos entre chaves ou ainda nenhuma instruo, mantendo o ponto-evrgula.
3.2.2 Exemplo
int i;
i = 0;
while (i < 6)
{
printf("%d\n", i);
i++;
}

3.3

do-while

3.3.1 Sintaxe
do comando while (expr)

O lao do-while bastante parecido com o lao while. A diferena que no lao dowhile o teste da condio executado somente depois do lao ser processado. Isso
garante que o lao ser executado pelo menos uma vez.
3.3.2 Exemplo
int i;
i = 0;
do
{
printf("%d\n", i);
i++;
} while (i < 6)

## Prof. Erico Lisboa

10

http://www.ericolisboa.eng.br

3 - Controle de fluxo

3.4

Linguagem C

for

3.4.1 Sintaxe
for (inicializacao, condicao, incremento) comando

## O lao for equivalente ao seguinte lao while:

inicializacao
while (condicao)
{
comando
incremento
}

3.4.2 Exemplos
int i;
for (i = 0; i < 6; i++)
{
printf("%d\n", i);
}

Qualquer uma das expresses do lao for pode conter vrias instrues separadas por vrgulas.
int i, j;
for (i = 0, j = 0; i + j < 100; i++, j+=2)
{
printf("%d\n", i + j);
}

Qualquer uma das trs partes de um lao for pode ser omitida, embora os ponto-e-vrgulas
int i = 0;
for (; i < 100;)
{
printf("%d\n", i++);
}

3.5 break
O comando break pode ser utilizado no corpo de qualquer estrutura de lao C (while, do-while e for).
Causa a imediata sada do lao e o controle passa para o prximo estgio do programa.
3.5.1 Exemplo
int i = 0;
while(1)
{
printf("%d\n", i++);
if (i >= 6) break;
}

## Prof. Erico Lisboa

11

http://www.ericolisboa.eng.br

3 - Controle de fluxo

3.6

Linguagem C

switch

3.6.1 Sintaxe
switch(expr)
{
case constante1:
comando1;
case constante2:
comando2;
case constante3:
comando3;
default:
comando4;
}

/*opcional*/
/*opcional*/
/*opcional*/
/*opcional*/
/*opcional*/

O comando switch verifica o valor de expr e compara seu valor com os rtulos dos casos. expr
deve ser inteiro ou caractere.
Cada caso deve ser rotulado por uma constante do tipo inteiro ou caractere. Esta constante deve
ser terminada por dois pontos (:) e no por ponto-e-vrgula.
Pode haver uma ou mais instrues seguindo cada case. Estas instrues no necessitam estar
entre chaves.
O corpo de um switch deve estar entre chaves.
Se um caso for igual ao valor da expresso, a execuo comea nele.
Se nenhum caso for satisfeito, o controle do programa sai do bloco switch, a menos que exista
um caso default. Se existir, a execuo comea nele.
Os rtulos dos casos devem ser todos diferentes.
O comando break causa uma sada imediata do programa. Se no houver um break seguindo
as instrues do caso, o programa segue executando todas as instrues dos casos abaixo, at encontrar
um break ou o fim do corpo do switch.
3.6.2 Exemplo
int mes;
...
switch(mes)
{
case 1:
printf("Janeiro\n");
break;
case 2:
printf("Fevereiro\n");
break;
case 3:
printf("Marco\n");
break;
case 4:
printf("Abril\n");
break;

## Prof. Erico Lisboa

12

http://www.ericolisboa.eng.br

3 - Controle de fluxo

Linguagem C

case 5:
printf("Maio\n");
break;
case 6:
printf("Junho\n");
break;
case 7:
printf("Julho\n");
break;
case 8:
printf("Agosto\n");
break;
case 9:
printf("Setembro\n");
break;
case 10:
printf("Outubro\n");
break;
case 11:
printf("Novembro\n");
break;
case 12:
printf("Dezembro\n");
break;
default:
printf("O numero nao equivale a nenhum mes\n");
break;
}

## Prof. Erico Lisboa

13

http://www.ericolisboa.eng.br

4 - Funes

Linguagem C

CAPTULO 4
FUNES
4

## 4.1 Definio de Funo

Funes servem para dividir um grande programa em diversas partes menores. Alm disso, permitem
que sejam utilizadas partes de programa desenvolvidas por outras pessoas, sem que se tenha acesso ao
cdigo-fonte. Como exemplo, em captulos anteriores foi utilizada a funo printf() sem que fossem
conhecidos detalhes de sua programao.
Programas em C geralmente utilizam diversas pequenas funes, ao invs de poucas e grandes
funes. Ao dividir um programa em funes, diversas vantagens so encontradas, como impedir que
o programador tenha que repetir o cdigo diversas vezes, facilitar o trabalho de encontrar erros no
cdigo.
Diversas funes so fornecidas juntamente com os compiladores, e esto presentes na norma ANSI,
(scanf(), printf() e outras), entre outras.
Uma funo tem a sintaxe
tipo nome(argumentos)
{
declaraes de variveis
comandos
}

onde:
tipo determina o tipo do valor de retorno (se omitido, assumido int);
nome representa o nome pelo qual a funo ser chamada ao longo do programa;
argumentos so informaes externas transmitidas para a funo (podem no existir).
Todo programa composto de funes, sendo iniciada a execuo pela funo de nome main().
4.1.1 Variveis Locais
A declarao das variveis, em C, deve vir no incio da funo, antes de qualquer comando. Uma
varivel declarada dentro do corpo de uma funo local, ou seja, s existe dentro da funo. Ao ser
4.1.2 Chamando Funes
Para executar uma funo, ela deve ser chamada no corpo de uma outra funo ( exceo da funo
main(), que executada no incio do programa). Uma chamada de funo feita escrevendo-se o nome
da funo seguido dos argumentos fornecidos, entre parnteses. Se no houver argumentos, ainda
assim devem ser mantidos os parnteses, para que o compilador diferencie a chamada da funo de
uma varivel. O comando de chamada de uma funo deve ser seguido de ponto-e-vrgula.

## Prof. Erico Lisboa

14

http://www.ericolisboa.eng.br

4 - Funes

Linguagem C

tenham sido declaradas, um erro de compilao ocorre.
4.1.3 Programa Exemplo
O programa abaixo composto de duas funes: main() e linha().
linha()
{
printf("------------------------------\n);
}
main()
{
linha();
printf("Programa exemplo de funcoes \n");
linha();
}
SAIDA
-----------------------------Programa exemplo de funcoes
------------------------------

A funo linha(), apresentada neste exemplo, escreve uma linha na tela. Esta funo chama uma outra
funo, printf(), da biblioteca C. Uma funo pode conter em seu corpo chamadas a outras funes.
A funo main() apresenta duas chamadas funo linha().
4.2 Argumentos
Argumentos so utilizados para transmitir informaes para a funo. J foram utilizados
anteriormente nas funes printf() e scanf().
Uma funo pode receber qualquer nmero de argumentos, sendo possvel escrever uma funo que
no receba nenhum argumento. No caso de uma funo sem argumentos pode-se escrev-la de duas
formas: deixando a lista de argumentos vazia (mantendo entretanto os parnteses) ou colocando o tipo
void entre parnteses.
O quinto tipo existente em C, void (vazio, em ingls), um tipo utilizado para representar o nada.
Nenhuma varivel pode ser declarada como sendo do tipo void. A funo main(), j utilizada em
captulos anteriores, um exemplo de funo sem argumentos.
Exemplo: o programa abaixo utiliza a funo EscreveCaractere(). Esta funo recebe como argumento
uma varivel caractere (ch) e uma varivel inteira (n) e faz com que o caractere ch seja impresso n
vezes.
EscreveCaractere(char ch, int n)
{
int i;
for(i = 0; i < n; i++)
{
printf("%c", ch);
}
}

## Prof. Erico Lisboa

15

http://www.ericolisboa.eng.br

4 - Funes

Linguagem C

main()
{
EscreveCaractere('-', 27);
printf("\nPrograma exemplo de funcoes\n");
EscreveCaractere('-', 27);
EscreveCaractere('\n', 3);
printf("Teste concluido\n");
}

Nota-se que no exemplo inicialmente definida a funo EscreveCaractere() para, somente depois, ser
definida a funo main(), que acessa a funo EscreveCaractere(). Caso a funo main() venha
primeiro, quando o compilador tentar compilar a linha que chama a funo EscreveCaractere(), o
Caso deseje-se definir a funo EscreveCaractere() antes da funo main(), deve-se inicialmente
declarar a funo EscreveCaractere(). A declarao de uma funo consiste em escrev-la da mesma
forma que na definio, sem o corpo da funo e seguida por ponto-e-vrgula.
O exemplo anterior ficaria da seguinte maneira:
EscreveCaractere(char ch, int n);
main()
{
EscreveCaractere('-', 27);
printf("\nPrograma exemplo de funcoes\n");
EscreveCaractere('-', 27);
EscreveCaractere('\n', 3);
printf("Teste concluido\n");
}
EscreveCaractere(char ch, int n)
{
int i;
for(i = 0; i < n; i++)
printf("%c", ch);
}

Quando o compilador encontra a primeira linha do cdigo, ele entende que a funo
EscreveCaractere() existe e tem a forma apresentada na declarao, mas ainda no est definida; ser
definida em algum lugar do cdigo. Portanto, ele consegue compilar as chamadas esta funo no
resto do programa.
4.3 Valor de Retorno
Valor de retorno o valor que uma funo retorna para a funo que a chamou. Seu tipo fornecido
antes do nome da funo na declarao.
dela.
{
return a * a;
}

## Prof. Erico Lisboa

16

http://www.ericolisboa.eng.br

4 - Funes

Linguagem C

## Na funo, so fornecidos o tipo do valor de retorno (float), o nome da funo (Quadrado) e o

argumento (a, do tipo float). No corpo da funo, encontrado o comando return. Este comando
fornece o valor de retorno da funo, fazendo com que ela termine. Uma funo pode ter diversos
comando return.
Exemplo: a funo Maximo() retorna o maior valor entre dois nmeros.
int Maximo(int a, int b)
{
if(a > b)
return a;
else
return b;
}

Esta outra funo possui dois argumentos inteiros (a e b) sendo o valor de retorno tambm inteiro. Este
um exemplo de funo que possui mais de um comando return.
A funo EscreveCaractere(), do exemplo fornecido na seo 4.2, um exemplo de funo que no
possui retorno. No caso, se for omitido o valor de retorno de uma funo, este valor assumido como
int. Se uma funo no retorna nada, seu tipo de retorno deve ser definido como void.
O comando return pode ser utilizado numa funo com tipo de retorno void. neste caso, o comando
no deve retornar nenhum valor, sendo chamado simplesmente seguido do ponto-e-vrgula.
Como foi visto nas sees anteriores, uma funo pode conter em seu corpo chamadas a outras
funes. Nesta seo veremos um caso particular em que uma funo chamada por ela prpria. A
este caso, d-se o nome de recursividade.
Sabe-se que N! = N * (N - 1)! e que 0! = 1.
int fatorial(int n)
{
if(n > 0)
return n * fatorial(n - 1);
else
return 1;
}

Note que existe dentro da funo recursiva uma possibilidade de o programa sair dela sem que ocorra a
chamada prpria funo (no caso de n menor ou igual a zero a funo retorna 1). Se no existisse
esta condio, a funo se chamaria infinitamente, causando o travamento do programa.
4.5 Classes de Armazenamento
Todas as variveis e funes C tm dois atributos: um tipo e uma classe de armazenamento. Os tipos,
como visto anteriormente, so cinco: int, long, float, double e void. As classes de armazenamento so
quatro: auto (automticas), extern (externas), static (estticas) e register (em registradores).

## Prof. Erico Lisboa

17

http://www.ericolisboa.eng.br

4 - Funes

Linguagem C

## 4.5.1 Classe de Armazenamento - auto

As variveis declaradas at agora nos exemplos so acessveis somente na funo a qual ela pertence.
Estas variveis so automticas caso no seja definida sua classe de armazenamento. Ou seja, o cdigo
main()
{
auto int n;
. . .
}

equivalente a
main()
{
int n;
. . .
}

## 4.5.2 Classe de Armazenamento - extern

Todas as variveis declaradas fora de qualquer funo so externas. Variveis com este atributo sero
conhecidas por todas as funes declaradas depois delas.
/* Testa o uso de variaveis externas */
int i;
void incrementa(void)
{
i++;
}
main()
{
printf("%d\n", i);
incrementa();
printf("%d\n", i);
}

## 4.5.3 Classe de Armazenamento - static

Variveis estticas possuem dois comportamentos bem distintos: variveis estticas locais e estticas
externas.
Quando uma varivel esttica declarada dentro de uma funo, ela local quela funo. Uma
varivel esttica mantm seu valor ao trmino da funo. O exemplo a seguir apresenta uma funo
contendo uma varivel esttica.
void soma(void)
{
static int i = 0;
printf("i = %d\n", i++);
}
main()
{
soma();
soma();
soma();
}

## Prof. Erico Lisboa

18

http://www.ericolisboa.eng.br

4 - Funes

Linguagem C

i = 0
i = 1
i = 2

O segundo uso de static associado a declaraes externas. Declarar uma varivel esttica externa
indica que esta varivel ser global apenas no arquivo fonte no qual ela foi declarada, e s a aprtir de
sua declarao. Esta declarao usada como mecanismo de privacidade e impede que outros arquivos
tenham acesso variavl.
4.5.4 Classe de Armazenamento - register
A classe de armazenamento register indica que a varivel ser guardada fisicamente numa memria de
variveis do tipo int e char. Basicamente, variveis register so usadas para aumentar a velocidade de
processamento.
O pr-processador C um programa que examina o programa-fonte em C e executa certas
compilao.
4.6.1 A Diretiva #define
A diretiva #define substitui determinados cdigos predefinidos pelo usurio. Possui a forma
#define nome xxxxx

onde nome o smbolo a ser trocado e xxxxx qualquer expresso. O comando pode continuar em
mais de uma linha utilizando-se a barra invertida (\) para indicar a continuao na linha de baixo.
Ao ser criado um #define, o precompilador substitui todas as ocorrncias de nome no cdigo fonte
pela expresso xxxxx fornecida.
Exemplo: a seguir definimos algumas constantes simblicas.
#define
#define
#define
#define

PI 3.14159
ON 1
OFF 0
ENDERECO 0x378

void main()
{
...
}

No exemplo acima, definimos PI como 3.14159. Isto significa que em todas as ocorrncias do texto, PI
ser trocado por 3.14159. Assim, a instruo
area = PI * raio * raio;

## Prof. Erico Lisboa

19

http://www.ericolisboa.eng.br

4 - Funes

Linguagem C

## area = 3.14159 * raio * raio;

ponto-e-vrgula na substituio.
#define pode ter argumentos. Eles so fornecidos imediatamente aps o nome:
#define nome(arg1,arg2,...) xxxxx

#define MAIS_UM(x) x+1

ento:
MAIS_UM(y)

y+1

## #defines podem referenciar #defines anteriores. Por exemplo:

#define PI
#define PI_2

3.141592653589793
2*PI

Um uso tpico de #define e substituir algumas chamadas a funes por cdigo direto. Vamos supor,
por exemplo, que quisssemos criar uma macro equivalente a uma funo que multiplique dois
nmeros. A macro
#define PRODUTO(a,b) a*b

## parece atender ao problema. Vamos testar:

Expresso original
resposta = PRODUTO(a,b);
resposta = PRODUTO(x,2);
resposta = PRODUTO(a+b,2);

resposta = a*b;
resposta = x*2;
resposta = a+b*2;

Para as duas primeiras expresses, a macro funcionou bem. J para a terceira, a pricpio desejaramos o
produto de a + b por 2. A expresso pr-compilada no fornece isso, j que o operador * processado
antes do operador +. A soluo para evitar este problema por os argumentos na definio entre
parnteses, ou seja:
#define PRODUTO(a,b) (a)*(b)

## Novamente, parece atender ao problema. Vamos testar:

Expresso original
resposta = PRODUTO(a,b);
resposta = PRODUTO(x,2);
resposta = PRODUTO(a+b,2);
resposta = PRODUTO(2,4) / PRODUTO(2,4);

## Prof. Erico Lisboa

resposta = (a)*(b);
resposta = (x)*(2);
resposta = (a+b)*(2);
resposta = (2)*(4)/(2)*(4);

20

http://www.ericolisboa.eng.br

4 - Funes

Linguagem C

Esta macro continua atendendo s duas primeiras expresses, passa a atender terceira. Entretanto,
para a quarta expresso, no obtivemos o resultado desejado. A princpio, desejaramos efetuar os dois
produtos, que so idnticos, dividir um pelo outro, obtendo como resposta 1`. Ao utilizar a macro,
como os operadores * e / possuem a mesma precedncia, eles so executados na ordem em que so
encontrados. Ou seja, a diviso feita antes do segundo produto ter sido efetuado, o que fornece o
resultado 16 para a expresso. A soluo para este problema ser redundante no uso de pernteses ao
se construir macros. A macro PRODUTO definida ento por
#define PRODUTO(a,b) ((a)*(b))

Ainda assim, colocar os parnteses em macros no atende a todos os casos. Por exemplo, a macro
#define DOBRO(a) ((a)+(a))

## apesar de conter todos os parnteses necessrios, se for utilizada na expresso

resposta = DOBRO(++x)

resposta = (++x)+(++x)

## que incrementar a varivel x duas vezes, ao invs de uma.

Ou seja, MACROS NO SO FUNES. Tenha sempre cuidado em sua utilizao.
4.6.2 A Diretiva #undef
A diretiva #undef tem a seguinte sintaxe:
#undef nome

Esta diretiva anula uma definio de #define, o que torna nome indefinido.
4.6.3 A Diretiva #include
A instruo #include inclui outro arquivo fonte dentro do arquivo atual. Possui duas formas:
#include "nome-do-arquivo"
#include <nome-do-arquivo>

A primeira inclui um arquivo que ser procurado no diretrio corrente de trabalho. A segunda incluir
um arquivo que se encontra em algum lugar predefinido.
Os arquivos includos normalmente possuem #defines e declaraes de funes. Os compiladores
fornecem uma srie de funes que so definidas em arquivos de cabealho, com extenso .h, que
posem ser includos no cdigo-fonte escrito pelo programador. So alguns exemplos a biblioteca
4.6.4 Outras Diretivas
O preprocessador C possui ainda outras diretivas de pr-compilao. Alguns trechos do cdigo podem

## Prof. Erico Lisboa

21

http://www.ericolisboa.eng.br

4 - Funes

#if expr
#ifdef nome
#ifndef nome

Linguagem C

## testa para verificar se a expresso com constantes inteiras

exp diferente de zero
testa a ocorrncia de nome com #define
testa se nome no est definido (nunca foi definido com
#define ou foi eliminado com #undef)

sinaliza o comeo das linhas a serem compiladas se o teste
do if for falso
finaliza os comandos #if, #ifdef ou #ifndef

#else
#endif

Exemplo: a seqncia seguinte permite que diferentes cdigos sejam compilados, baseado na
/* Codigo para o Turbo C
#endif
/* Codigo para o Gnu C
#endif

## Prof. Erico Lisboa

22

http://www.ericolisboa.eng.br

5 - Vetores e Matrizes

Linguagem C

CAPTULO 5
VETORES E MATRIZES
5

5.1 Vetores
de encontrar a mdia de idade de 4 pessoas. O programa poderia ser:
main()
{
printf("Digite a idade da pessoa 0: ");
printf("Digite a idade da pessoa 1: ");
printf("Digite a idade da pessoa 2: ");
printf("Digite a idade da pessoa 3: ");
}

Suponhamos agora que desejssemos encontrar a mdia das idades de 500 pessoas. A tarefa passa a ser
bem mais trabalhosa, sendo em diversos casos impraticvel se resolver da maneira apresentada acima.
A soluo para este problema a utilizao de vetores. Um vetor uma srie de variveis de mesmo
representado entre colchetes depois do nome da varivel.
A declarao

aloca memria para armazenar 4 inteiros e declara a varivel idade como um vetor de 4 elementos.
O programa da mdia das idades poderia ser substitudo por:
main()
{
int idade[4], i, soma = 0;
for(i = 0; i < 4; i++)
{
printf("Digite a idade da pessoa %d: ", i);
}
for(i = 0; i < 4; i++)
printf("Idade media: %d\n", soma / 4);
}

## Prof. Erico Lisboa

23

http://www.ericolisboa.eng.br

5 - Vetores e Matrizes

Linguagem C

## Ao escrever o mesmo programa utilizando vetores, a complexidade do cdigo fica independente do

tamanho do vetor.
Para acessar um determinado elemento do vetor, deve-se chamar o elemento pelo nome da varivel
seguido do ndice, entre colchetes. Note que o ndice comea em 0, e no em 1. Ou seja, o elemento

## no o segundo elemento e sim o terceiro, pois a numerao comea de 0. Em nosso exemplo

utilizamos uma varivel inteira, i, como ndice do vetor.
Suponhamos o seguinte programa:
main()
{

=
=
=
=
=
=

15;
16;
17;
18;
19;
20;

Nota-se que neste programa, definimos a varivel idade como um vetor de 5 elementos (0 a 4).
Definimos os elementos do vetor mas, na ltima definio, ultrapassamos o limite do vetor. A
linguagem C no realiza verificao de limites em vetores. Quando o vetor foi definido, o compilador
reservou o espao de memria equivalente a 5 variveis inteiras, ou seja, 10 bytes. Quando tentamos
acessar um elemento que ultrapasse o limite de um vetor, estamos acessando uma regio de memria
que no pertence a esse vetor.
5.1.1 Inicializao
A linguagem C permite que vetores sejam inicializados. No caso, ser inicializada uma varivel
contendo o nmero de dias de cada ms:
int numdias[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

## O nmero de elementos do vetor pode ser omitido, ou seja

int numdias[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

Se nenhum nmero for fornecido para inicializar o vetor, o compilador contar o nmero de itens da
lista de inicializao e o fixar como dimenso do vetor.
Na falta de inicializao explcita, variveis extern e variveis static so inicializadas com valor zero;
variveis automticas tm valor indefinido (isto , lixo).
Se h menos inicializadores que a dimenso especificada, os outros sero zero. Se h mais
Em C no h como se especificar a repetio de um inicializador, nem de se inicializar um elemento
no meio de um vetor sem inicializar todos os elementos anteriores ao mesmo tempo.

## Prof. Erico Lisboa

24

http://www.ericolisboa.eng.br

5 - Vetores e Matrizes

Linguagem C

## 5.1.2 Vetores como argumentos de funes

Vetores podem ser passados tambm como argumentos de funes. Vamos rescrever o programa que
calcula a mdia das idades para um programa contendo uma funo que receba um vetor e retorne a
sua mdia.
int media(int valor[], int nElementos)
{
int i, soma = 0;
for(i = 0; i < nElementos; i++)
soma += valor[i];
return soma / nElementos;
}
main()
{
for(i = 0; i < 5; i++)
{
printf("Digite a idade da pessoa %d: ", i);
}
}

Note que na declarao da funo, o argumento que representa o vetor declarado com colchetes.
Alm dele, passamos como argumento da funo tambm o tamanho do vetor. Sem ele, a funo no
tem como saber o tamanho do vetor que foi passado a ela como argumento.
Na funo main(), chamamos a funo media() passando dois atributos: idade e 5. Para acessarmos um
elemento do vetor, escrevemos aps o seu nome o ndice do elemento desejado entre colchetes (por
exemplo, idade[0]). A chamada ao nome de um vetor sem que seja fornecido o ndice de um
determinado elemento representa o primeiro endereo de memria acessado por esse vetor. Ou seja, ao
passarmos um vetor como argumento da funo, o compilador no cria uma cpia do vetor para ser
5.2 Vetores de caracteres
O vetor de caracteres, tambm conhecidos como string, uma das formas de dados mais importantes
da linguagem C. usado para manipular texto, como palavras, nomes e frases. Em algumas
linguagens, como Pascal e Basic, string um tipo primitivo. Em C, tratada como um vetor de
elementos do tipo char. Cada elemento pode ser acessado individualmente, como em qualquer vetor,
atravs do uso de colchetes.
Sempre que o compilador encontra qualquer coisa entre aspas, ele reconhece que se trata de uma string
constante, isto , os caracteres entre aspas mais o caractere nulo ('\0'). Para declarar uma varivel do
tipo string, deve-se declar-la como um vetor de caracteres, ou seja:
char Nome[50];

Esta declarao cria a varivel Nome como string, ou vetor de caracteres, permitindo um comprimento
de at 50 caracteres. Vale lembrar que o ltimo caractere de uma string deve ser o caractere nulo, ou
seja, temos 49 caracteres para trabalhar livremente. A declarao:

## Prof. Erico Lisboa

25

http://www.ericolisboa.eng.br

5 - Vetores e Matrizes

Linguagem C

## char Nome[5] = "Pedro";

invlida, por no ter sido reservado espao suficiente para as 6 variveis ('P', 'e', 'd', 'r', 'o' e '\0').
Para manipulao de strings, so fornecidas diversas funes na biblioteca C (arquivo string.h).
Algumas dessas funes so descritas a seguir. A sintaxe apresentada para cada funo no
exatamente a sintaxe fornecida pela biblioteca, mas representa basicamente o que a funo executa e j
foi explicado at o presente momento.
5.2.1 A funo strlen()
A funo strlen() retorna o nmero de caracteres da string, sem contar o caractere nulo.
Sintaxe:
int strlen(char[] s);

Exemplo:
main()
{
char Nome[6] = "Navio";
printf("%d\n%d\n", strlen("Barco a vela"), strlen(Nome));
}
12
5

Note que os espaos fazem parte da string, e so simplesmente caracteres, assim como letras e
algarismos.
5.2.2 A funo strcmp()
A funo strcmp() compara duas strings. Retorna
- um valor menor que zero se a primeira string for menor que a segunda;
- zero se as strings forem iguais;
- um valor maior que zero se a primeira string for maior que a segunda.
Entende-se pr comparao entre strings, sua posio em ordem alfabtica. A ordem alfabtica
baseada na tabela ASCII (Anexo A). Portanto, cuidado ao comparar maisculas com minsculas, pois
na tabela ASCII as letras maisculas possuem um valor menor que as letras minsculas, ou seja, o
caractere 'Z' vem antes do caractere 'a'.
Sintaxe:
int strcmp(char[] s1, char[] s2);

Exemplo:
main()
{
printf("%d\n", strcmp("Ariranha", "Zebra"));
printf("%d\n", strcmp("Zebra", "Ariranha"));
printf("%d\n", strcmp("Zebra", "Zebra"));
}

## Prof. Erico Lisboa

26

http://www.ericolisboa.eng.br

5 - Vetores e Matrizes

Linguagem C

(Algum valor menor que 0)
(Algum valor maior que 0)
0

## Espaos e outros caracteres especiais tambm so considerados na comparao, algumas vezes no

fornecendo o que se espera de uma ordenao alfabtica.
5.2.3 A funo strcpy()
A funo strcpy() copia o contedo de uma string para outra. A string de destino j tem que ter espao
Sintaxe:
void strcpy(char[] destino, char[] origem);

Exemplo:
main()
{
char Nome[10];
strcpy(Nome, "Teste")
printf("%s\n", Nome);
}
Teste

## 5.2.4 A funo strcat()

A funo strcat() concatena duas strings, ou seja, anexa o contedo de uma na outra. Similarmente
funo strcpy(), a string de destino tem que ter espao reservado na memria.
Sintaxe:
void strcat(char[] destino, char[] origem);

Exemplo:
main()
{
char Nome[12];
strcpy(Nome, "Teste")
strcpy(Nome, "geral")
printf("%s\n", Nome);
}
Testegeral

5.3 Matrizes
A linguagem C permite vetores de qualquer tipo, inclusive vetores de vetores. Por exemplo, uma
matriz um vetor em que seus elementos so vetores. Com dois pares de colchetes, obtemos uma

## Prof. Erico Lisboa

27

http://www.ericolisboa.eng.br

5 - Vetores e Matrizes

Linguagem C

dimenso a mais.
Por exemplo, a declarao
int A[5][6];

## indica que A uma matriz 5x6 e seus elementos so inteiros.

5.3.1 Inicializao
As matrizes so inicializadas como os vetores, ou seja, os elementos so colocados entre chaves e
separados por vrgulas. Como seus elementos so vetores, estes, por sua vez, tambm so inicializados
com seus elementos entre chaves e separados por vrgulas. Por exemplo:
int A[5][6] = { { 1, 2, 3, 4,
{ 7, 8, 9, 10,
{13, 14, 15, 16,
{19, 20, 21, 22,
{25, 26, 27, 28,

5,
11,
17,
23,
29,

6},
12},
18},
24},
30} };

Caso as matrizes sejam de caracteres, isto equivalente a termos um vetor de strings. Sua inicializao
pode se dar da forma
char Nome[5][10] = {"Joao",
"Jose",
"Maria",
"Geraldo",
"Lucia"};

J
J
M
G
L

o
o
a
e
u

a
s
r
r
c

o
e
i
a
i

\0
\0
a
l
a

\0
\0
\0
d
\0

\0
\0
\0
o
\0

\0
\0
\0
\0
\0

\0
\0
\0
\0
\0

\0
\0
\0
\0
\0

## 5.3.2 Matrizes como argumento de funes

A passagem de uma matriz para uma funo similar passagem de um vetor. O mtodo de passagem
do endereo da matriz para a funo idntico, no importando quantas dimenses ela possua, j que
sempre passado o endereo da matriz.
Entretanto, na declarao da funo, a matriz um pouco diferente. A funo deve receber o tamanho
das dimenses a partir da segunda dimenso. Por exemplo:
void Determinante(double A[][5]);

Note que fornecido a segunda dimenso da matriz. Isto necessrio para que, ao chamarmos o
elemento A[i][j], a funo saiba a partir de que elemento ela deve mudar de linha. Com o nmero de
elementos de cada linha, a funo pode obter qualquer elemento multiplicando o nmero da linha pelo
tamanho de cada linha e somando ao nmero da coluna.
Por exemplo, o elemento A[2][3], o elemento de ndice 13, j que 2 * 5 + 3 = 13.

## Prof. Erico Lisboa

28

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

CAPTULO 6
PONTEIROS
6

6.1 Definio
Uma varivel declarada como ponteiro armazena um endereo de memria. A declarao
int *a;

indica que a varivel a um ponteiro que aponta para um inteiro, ou seja, armazena o endereo de uma
varivel inteira.
retorna o endereo de memria da varivel. Este operador j foi utilizado em captulos anteriores. O
outro o operador indireto (*) que o complemento de (*) e retorna o contedo da varivel existente
no endereo (ponteiro). O exemplo a seguir ilustra a utilizao desses operadores.
#include <stdio.h>
void main(void)
{
int* a;
int b = 2;
int c;
a = &b;
c = b;
printf("%d %d %d\n", *a, b, c);
b = 3;
printf("%d %d %d\n", *a, b, c);
}
SAIDA
2 2 2
3 3 2

No exemplo acima, as variveis b e c so declaradas como inteiras, ou seja, cada uma delas ocupa dois
bytes, em endereos de memria diferentes. A varivel a declarada como um ponteiro que aponta
para um inteiro. O comando a = &b indica que a varivel a armazenar o endereo da varivel b. J o
comando c = b indica que a varivel c, que fica armazenada em outro endereo de memria, guardar
o valor da varivel b.
A primeira linha de impresso nos fornece o contedo do ponteiro a, obtido atravs do operador
indireto (*), e o valor das variveis b e c. Note que o contedo do ponteiro a o valor da varivel b, j
que ele aponta para o endereo da varivel.
Ao alterarmos o valor da varivel b, o contedo de seu endereo alterado. A varivel c, por ocupar
outro endereo de memria, permanece inalterada. J o contedo do ponteiro a foi alterado, j que
aponta para o endereo da varivel b.

## Prof. Erico Lisboa

29

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

## 6.2 Passagem de Argumentos por Endereo

At o momento, utilizamos funes e seus argumentos em todos os casos foram passados por valor,
isto , criada uma cpia da varivel dentro da funo. Nesta seo veremos a passagem de
argumentos por endereo, onde a prpria varivel utilizada na funo, e no uma cpia dela.
Suponha o seguinte programa:
#include <stdio.h>
void troca(int a, int b)
{
int aux;
aux = a;
a = b;
b = aux;
}
void main(void)
{
int a = 2;
int b = 3;
printf("%d %d\n", a, b);
troca(a, b);
printf("%d %d\n", a, b);
}

A funo troca() tem como objetivo receber duas variveis inteiras e trocar o seu valor. Escrita da
maneira proposta no exemplo acima, ao chamarmos a funo, so criadas cpias das variveis a e b
dentro da funo troca(). Estas cpias, que s existem dentro da funo, tem o seu valor trocado, mas
isso no implica nenhuma alterao nas variveis a e b da funo main().
Para que possamos alterar o valor de argumentos dentro de uma funo, necessrio que estes
argumentos sejam passados por endereo. Desta forma, a funo trabalhar com a prpria varivel
fornecida como argumento. O programa reescrito como:
#include <stdio.h>
void troca(int* pa, int* pb)
{
int aux;
aux = *pa;
*pa = *pb;
*pb = aux;
}
void main(void)
{
int a = 2;
int b = 3;
printf("%d %d\n", a, b);
troca(&a, &b);
printf("%d %d\n", a, b);
}

## Prof. Erico Lisboa

30

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

## Percebem-se algumas alteraes, descritas a seguir.

-

a funo troca() passa a receber argumentos do tipo int*, ao invs de int. Isto necessrio para
que a funo receba o endereo das variveis fornecidas, e possa alterar-lhes o valor;

dentro da funo, as variveis a e b so tratadas com o operador indireto (*), para que
possamos trabalhar com seu contedo;

## Na chamada da funo troca(), so passados como argumentos os endereos das variveis,

Neste curso ns j passamos argumentos para funes atravs de seu endereo. Isto foi utilizado na
funo scanf(). O motivo para utilizarmos o operador endereo (&) na funo scanf() e no o
utilizarmos na funo printf() que somente a primeira altera o valor das variveis que foram passadas
como argumento.
6.3 Operaes com ponteiros
A linguagem C oferece cinco operaes bsicas que podem ser executadas em ponteiros. O prximo
imprimir o valor do ponteiro (que um endereo), o valor armazenado na varivel apontada e o
endereo do prprio ponteiro.
#include <stdio.h>
void main(void)
{
int x = 5;
int y = 6;
int* px;
int* py;
/* Atribuicao de ponteiros */
px = &x;
py = &y;
/* Comparacao de ponteiros */
if(px < py)
printf("py-px = %u\n", py - px);
else
printf("px-py = %u\n", px - py);
printf("px = %u, *px = %d, &px = %u\n",
printf("py = %u, *py = %d, &py = %u\n",
px++;
printf("px = %u, *px = %d, &px = %u\n",
py = px + 3;
printf("py = %u, *py = %d, &py = %u\n",
printf("py-px = %u\n", py - px);

py, *py, &py);
px, *px, &px);
py, *py, &py);

}
SAIDA
py-px = 1
px = 65492,
py = 65494,
px = 65494,
py = 65500,
py-px = 3

## Prof. Erico Lisboa

*px
*py
*px
*py

=
=
=
=

5, &px =
6, &py =
6, &px =
-24, &py

65496
65498
65496
= 65498

31

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

6.3.1 Atribuio
Um endereo pode ser atribudo a um ponteiro atravs do operador igual (=). No exemplo, atribumos
a px o endereo de x e a py o endereo de y.
6.3.2 Contedo
6.3.3 Endereo
Como todas as variveis, os ponteiros tm um endereo e um valor. Seu valor o endereo de
ponteiro. Em resumo:
-

## 6.3.4 Soma e diferena

Ponteiros permitem os operadores soma (+), diferena (-), incremento (++) e decremento (--). Estas
operaes no so tratadas como soma e diferena comuns entre inteiros. Elas levam em conta o
No exemplo, a varivel px antes do incremento valia. 65492. Depois do incremento ela passou a valer
65494 e no 65493. O incremento de um ponteiro faz com que ele seja deslocado levando-se em conta
o tamanho da varivel apontada. No caso de um inteiro, o ponteiro ser deslocado 2 bytes, que o que
ocorre no exemplo.
Assim como no incremento, o decremento, a soma e a diferena levam em conta o tamanho da varivel
apontada. Assim, com py = px + 3, a varivel py passou a apontar para um endereo de memria
localizado 6 bytes depois de px.
6.3.5 Comparaes
Os operadores ==, !=, >, <, <=, >= so aceitos entre ponteiros e comparam os endereos de memria.
6.3.6 Ponteiros para void
Como dito anteriormente, ponteiros podem apontar para qualquer tipo de varivel. Podemos ter
inclusive ponteiros que apontam para o tipo void. Estes ponteiros armazenam um endereo de
memria, sem que seja definido qual o tipo de varivel que ocupa aquele espao de memria.
Em ponteiros para void (void*), no possvel a utilizao do operador indireto (*), uma vez que o
compilador no sabe para qual o tipo de varivel ele deva converter o contedo do endereo apontado.
Tambm no so permitidos os operadores de soma e diferena, j que o compilador no sabe quanto
espao ocupa a varivel armazenada naquele endereo.

## Prof. Erico Lisboa

32

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

## 6.4 Ponteiros e vetores

Vetores em C so tratados pelo compilador como ponteiros. Isso significa que o nome do vetor
representa o endereo ocupado pelo seu primeiro elemento. O programa a seguir exemplifica a
utilizao de ponteiros representando vetores:
#include <stdio.h>
void main(void)
{
int i, *px, x[] = {8, 5, 3, 1, 7};
px = x;
for(i = 0; i < 5; i++)
{
printf("%d\n", *px);
px++;
}
}

Nota-se no exemplo que fazemos com que o ponteiro px aponte para o vetor x. Repare que no
um endereo. No caso, seria possvel ao invs de
px = x;

utilizarmos
px = &x[0];

O mesmo resultado seria obtido, j que o nome do vetor tratado como um ponteiro que aponta para o
endereo do primeiro elemento do vetor.
A linha que incrementa o valor de px faz com que o ponteiro aponte para o endereo de memria do
prximo inteiro, ou seja, o prximo elemento do vetor.
Escreveremos agora o mesmo programa de outra maneira:
#include <stdio.h>
void main(void)
{
int x[] = {8, 5, 3, 1, 7};
int i;
for(i = 0; i < 5; i++)
printf("%d\n", *(x + i));
}

Note que neste exemplo chamamos cada elemento do vetor atravs de *(x + i). Como pode-se notar,
*(x
*(x
*(x
...
*(x

+ 0) = *x = x[0];
+ 1) = x[1];
+ 2) = x[2];
+ indice) = x[indice].

## Prof. Erico Lisboa

33

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

Como exemplo, vamos fazer uma funo equivalente funo strcpy, da biblioteca string.h.
int strcpy(char* s1, char* s2)
{
/* Copia a string s2 em s1 */
while(*s2 != '\0')
{
*s1 = *s2;
s1++;
s2++;
}
*s1 = '\0';
}

Nesta funo, todos os caracteres de s2 sero copiados em s1, at que seja encontrado o caractere nulo.
6.5 Alocao dinmica de memria
Quando um vetor declarado, o endereo de memria para o qual ele aponta no teve necessariamente
sempre apontavam para outras variveis existentes.
Nesta seo veremos o caso de alocao dinmica, isto , memria alocada em tempo de execuo do
programa. Para isto, usaremos as funo malloc e free, presentes nas bibliotecas stdlib.h e alloc.h.
6.5.1 Funo malloc
Sintaxe:
void* malloc(unsigned long size);

A funo malloc aloca um espao de memria (size bytes) e retorna o endereo do primeiro byte
alocado. Como pode-se alocar espao para qualquer tipo de varivel, o tipo de retorno void*. Tornase necessrio converte-lo para um ponteiro do tipo desejado.
No caso de no haver espao suficiente para alocar a quantidade de memria desejada, a funo
retorna um ponteiro para o endereo 0 (ou NULL). Caso a varivel size fornecida seja 0, a funo
tambm retorna NULL.
Ao contrrio das variveis estaticamente alocadas apresentadas at agora, o a memria dinamicamente
dinamicamente alocada atravs da funo free.
6.5.2 Funo free
Sintaxe:
void free(void* block);

## A funo free desaloca a memria alocada..

6.5.3 Exemplo das funes malloc e free
A seguir ser fornecido um exemplo das funes malloc e free.

## Prof. Erico Lisboa

34

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

#include <string.h>
#include <stdio.h>
#include <alloc.h>
void main(void)
{
char* str = (char*) malloc(10);
strcpy(str, "Alo mundo");
printf("Variavel str: %s\n", str);
free(str);
}

## O programa apresentado aloca dinamicamente 10 bytes e associa o endereo do bloco alocado ao

ponteiro str. Como a funo malloc retorna void*, necessrio converter o resultado para o tipo
A partir da trabalha-se com o ponteiro normalmente. Ao terminar a utilizao do espao alocado,
necessrio liberar a memria, atravs da funo free.
6.6 Ponteiros para ponteiros
Como apresentado anteriormente, ponteiros podem apontar para qualquer tipo de varivel, inclusive
para outros ponteiros. A seguir ser fornecido um exemplo de uma matriz alocada dinamicamente.
#include <stdio.h>
#include <alloc.h>
void main(void)
{
float** Matriz;
int nLinhas, nColunas, i, j;
printf("Quantas linhas?\n");
scanf("%d", &nLinhas);
printf("Quantas colunas?\n");
scanf("%d", &nColunas);
/* Aloca a matriz */
Matriz = (float**) malloc(nLinhas * sizeof(float*));
for(i = 0; i < nLinhas; i++)
Matriz[i] = (float*) malloc(nColunas * sizeof(float));
/* Define os elementos da matriz */
for(i = 0; i < nLinhas; i++)
for(j = 0; j < nColunas; j++)
Matriz[i][j] = i * j;
/* Imprime a matriz */
for(i = 0; i < nLinhas; i++)
{
for(j = 0; j < nColunas; j++)
printf("%f\t", Matriz[i][j]);
printf("\n");
}
/* Desaloca a matriz */
for(i = 0; i < nLinhas; i++)
free(Matriz[i]);
free(Matriz);
}

## Prof. Erico Lisboa

35

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

Note que neste exemplo no se sabe inicialmente qual ser o tamanho da matriz. Caso desejssemos
alocar o espao estaticamente, seria necessrio definir a matriz com nmero de linhas e colunas
grande, de modo que a escolha do usurio no ultrapassasse entes limites. Por exemplo,
float Matriz[1000][1000];

## H dois inconvenientes imediatos de se alocar vetores e matrizes estaticamente quando no sabemos

de antemo o seu tamanho: um espao de memria provavelmente desperdiado; e ficamos limitados
ao tamanho definido inicialmente. Alocando memria dinamicamente, somente a quantidade
necessria de memria utilizada, ao passo que nosso limite de tamanho o limite fsico de memria
Para alocar a matriz, inicialmente alocamos espao para um vetor de ponteiros. O tamanho deste vetor
ser o nmero de linhas da matriz. Cada um destes ponteiros apontar para um vetor de float
O acesso a cada elemento da matriz feito de forma semelhante matriz alocada estaticamente. O
primeiro ndice entre colchetes retorna o vetor que contm a linha da matriz equivalente quele ndice.
O segundo ndice entre colchetes fornece o elemento contido na coluna.
Note que as linhas no se localizam necessariamente juntas na memria, podendo estar em qualquer
lugar. O vetor de ponteiros indica onde cada linha se encontra na memria.
Para desalocar a matriz, necessrio desalocar primeiro cada linha para s ento desalocar o vetor de
ponteiros.
6.6.1 Passando matrizes alocadas dinamicamente como argumento de funes
No captulo 5, vimos como passar uma matriz estaticamente alocada como argumento de uma funo.
Era necessrio que a funo conhecesse o nmero de colunas da matriz, para que soubesse onde
acabava uma linha e comeava outra. Este problema no existe com matrizes dinamicamente alocadas,
podendo ser passada uma matriz de qualquer tamanho para a funo.
Para que a funo saiba o tamanho da matriz, necessrio que se passe como argumento o seu
tamanho. O exemplo abaixo ilustra uma funo que recebe trs matrizes A, B e C. Esta funo soma A
com B e armazena o resultado em C.
void SomaMatrizes(int nLinhas, int nColunas, float** C,
const float** A, const float** B)
{
int i, j;
for(i = 0; i < nLinhas; i++)
{
for(j = 0; j < nColunas; j++)
{
C[i][j] = A[i][j] + B[i][j];
}
}
}

Para chamar esta funo, necessrio que se tenha trs matrizes de float alocadas dinamicamente.
Estas matrizes devem ter o mesmo tamanho, j que no possvel somar matrizes de tamanhos

## Prof. Erico Lisboa

36

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

diferentes. Note que, desenvolvendo a funo para matrizes alocadas dinamicamente, possvel
utilizar matrizes de qualquer tamanho.
Note a utilizao do modificador const nos argumentos A e B da funo. Isto indica que so
argumentos constantes, isto , seus elementos no sero alterados dentro da funo. A utilizao do
Sabe-se, antes de escrever a funo, que ela no deve mexer nos argumentos A e B. Como matrizes
so passadas por endereo, a princpio a funo poderia alterar estes argumentos. Como no se deseja
que a funo altere os argumentos A e B, coloca-se o modificador const frente dos argumentos
constantes.
Caso tentemos modificar dentro da funo algum elemento da matriz A ou da matriz B, o compilador
acusar erro de compilao. Se no utilizssemos o modificador const, s perceberamos o erro muito
depois, com sadas incorretas do programa. O tempo de depurao de erros de compilao muito
menor que o de erros de execuo.
6.7 Ponteiros para funes
Um ponteiro para uma funo um caso especial de tipo apontado. Se voc definiu um ponteiro para
funo e inicializou-o para apontar para uma funo particular ele ter o valor do endereo onde a
O exemplo seguinte mostra este uso.
#include <stdio.h>
void ImprimeOla(void)
{
printf("Ola");
}
void Imprime(const char* str)
{
printf(str);
}
void main(void)
{
void (*f1)(void);
void (*f2)(const char*);
f1 = ImprimeOla;
f2 = Imprime;
(*f1)();
(*f2)(" mundo!\n");
}

## 6.7.1 A funo qsort()

No captulo 5 utilizamos o mtodo da bolha para a ordenao de um vetor. Este mtodo, apesar de
bastante intuitivo, lento quando comparado a outros mtodos de ordenao. A biblioteca C contm
uma funo de ordenao que utiliza o algoritmo quick sort, consideravelmente mais rpido que o

## Prof. Erico Lisboa

37

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

mtodo da bolha: a funo qsort. Esta funo est presente na biblioteca stdlib.h. Sua sintaxe a
seguinte.
void qsort(void* base, unsigned long nelem, unsigned long width,
int(*fcmp)(const void*, const void*));

Esta funo ordena nelem elementos de tamanho width localizados em base. O usurio deve fornecer
uma funo de comparao, fcomp, que compara dois elementos, elem1 e elem2. Esta funo deve
retornar
< 0, se elem1 < elem2
= 0, se elem1 == elem2
> 0, se elem1 > elem2

Note que tanto base quanto os argumentos da funo, elem1 e elem2 so do tipo void*. Isto
necessrio j que deseja-se que a funo ordene qualquer tipo de varivel.
Como exemplo, vamos criar um programa que ordena um vetor em ordem crescente e decrescente.
#include <stdio.h>
#include <stdlib.h>
int OrdenaCrescente(const void* pa, const void* pb)
{
int* px = (int*) pa;
int* py = (int*) pb;
return (*px) - (*py);
}
int OrdenaDecrescente(const void* pa, const void* pb)
{
int* px = (int*) pa;
int* py = (int*) pb;
return (*py) - (*px);
}
void Imprime(int* piValor, int iTamanho)
{
int i;
for(i = 0; i < iTamanho; i++)
{
printf("%d ", piValor[i]);
}
printf("\n");
}
void main(void)
{
int piValor[] = {1, 5, 3, 7, 4, 5, 9};
qsort(piValor, 7, sizeof(int), OrdenaCrescente);
Imprime(piValor, 7);
Imprime(piValor, 7);
}

## Prof. Erico Lisboa

38

http://www.ericolisboa.eng.br

6 - Ponteiros

Linguagem C

Na funo main(), o programa declara um vetor piValor e o inicializa com nmeros inteiros
Em seguida, o programa chama a funo qsort() para orden-lo em ordem crescente. Na chamada,
fornecido o vetor, piValor (lembrando: vetores so ponteiros), o nmero de elementos, 7, o tamanho de
cada elemento, obtido atravs do operador sizeof, e a funo de comparao, OrdenaCrescente().
Completada a ordenao, o programa imprime o vetor, atravs da funo Imprime().
O programa chama novamente a funo qsort() para orden-lo em ordem decrescente. A nica
diferena que agora a funo de ordenao fornecida a funo OrdenaDecrescente().
As funes OrdenaCrescente() e OrdenaDecrescente() tem que ter a sintaxe exigida pela funo
qsort(), ou seja, recebem dois argumentos void* e retornam um int que indica qual dos dois
argumentos vem na frente na ordenao. Como recebem argumentos void*, necessrio converter
para o tipo int antes de comparar.
A funo OrdenaCrescente() retorna a diferena entre o primeiro e o segundo elementos. Isso faz com
que o valor retorno satisfaa s condies impostas pela funo qsort(). A funo OrdenaDecrescente()
retorna o contrrio da funo OrdenaCrescente(), de modo que a funo qsort() interprete um valor
maior como vindo frente na ordenao.
A funo qsort() pode ordenar um vetor de qualquer tipo de varivel, desde que definidos os critrios
de comparao entre dois elementos do vetor.

## Prof. Erico Lisboa

39

http://www.ericolisboa.eng.br

Linguagem C

CAPTULO 7
7

7.1 Estruturas
Estrutura um conjunto de variveis, provavelmente de tipos diferentes, agrupadas e descritas por um
nico nome.
Por exemplo, numa folha de pagamento, desejamos guardar diversos registros (ou estruturas)
representando funcionrios. Cada funcionrio, neste caso, possui alguns atributos, entre eles: nome
(string), nmero do departamento (inteiro), salrio (float), alm de outros. Uma estrutura define um
novo tipo composto, contendo diversos tipos bsicos (ou compostos).
Para definir uma estrutura, definem-se os elementos dentro dela:
struct etiqueta
{
declarao da varivel membro
declarao da varivel membro
...
};

## Po exemplo, a estrutura definida por:

struct
{
int
char
int
};

Data
dia;
mes[10];
ano;

cria um novo tipo, chamado Data. Uma varivel do tipo Data contm um dia (inteiro), um ms (string)
e um ano (inteiro).
Para declarar variveis do tipo Data, deve-se utilizar a palavra-chave struct antes do tipo. Por
exemplo:
struct Data hoje;

## declara uma varivel de nome hoje, do tipo struct Data.

hoje.Ano = 2001;
hoje.Dia++;
strcpy(hoje.Mes, "Abril");
int iDia = hoje.Dia;

Cada membro da estrutura equivalente a uma varivel simples de seu tipo. O exemplo a seguir ilustra
a utilizao de estruturas.

## Prof. Erico Lisboa

40

http://www.ericolisboa.eng.br

Linguagem C

#include <stdio.h>
#include <string.h>
void main(void)
{
struct Data
{
int Dia;
char Mes[10];
int Ano;
};
struct Data hoje;
hoje.Dia = 4;
strcpy(hoje.Mes, "Outubro");
hoje.Ano = 2001;
printf("%d de %s de %d\n", hoje.Dia, hoje.Mes, hoje.Ano);
}

## 7.1.2 Estruturas dentro de estruturas

Estruturas podem conter outras estruturas em seu interior. Por exemplo, em uma agenda telefnica
podemos guardar, alm do telefone de cada pessoa, outros dados como o endereo e a data de
nascimento.
#include <stdio.h>
#include <string.h>
void main(void)
{
struct Data
{
int Dia;
char Mes[10];
int Ano;
};
struct Pessoa
{
char Nome[50];
char Telefone[20];
char Endereco[50];
struct Data Nascimento;
};
struct Pessoa pessoa1;
strcpy(pessoa1.Nome, "Joo");
strcpy(pessoa1.Telefone, "2222-2222");
strcpy(pessoa1.Endereco, "Av. Pres. Vargas, 10/1001");
pessoa1.Nascimento.Dia = 15;
strcpy(pessoa1.Nascimento.Mes, "Janeiro");
pessoa1.Nascimento.Ano = 1980;
printf("%s\n%s\n%s\n%d de %s de %d\n",
pessoa1.Nome, pessoa1.Telefone, pessoa1.Endereco,
pessoa1.Nascimento.Dia, pessoa1.Nascimento.Mes, pessoa1.Nascimento.Ano);
}

## Prof. Erico Lisboa

41

http://www.ericolisboa.eng.br

Linguagem C

## 7.1.3 Atribuies entre estruturas

Na verso original do C impossvel atribuir o valor de uma varivel estrutura a outra do mesmo tipo,
usando uma simples expresso de atribuio. Seus dados membro tinham que ser atribudos um a um.
Nas verses mais modernas de C, esta forma de atribuio j possvel. Isto , se pessoa1 e pessoa2
so variveis estrutura do mesmo tipo, a seguinte expresso pode ser usada:
pessoa1 = pessoa2;

## 7.1.4 Passando estruturas para funes

Verses mais recentes de C ANSI permitem que estruturas sejam passadas como argumento de
funes. Como exemplo, vamos reescrever o exemplo chamando uma funo que imprime os atributos
de uma pessoa.
#include <stdio.h>
#include <string.h>
struct Data
{
int Dia;
char Mes[10];
int Ano;
};
struct Pessoa
{
char Nome[50];
char Telefone[20];
char Endereco[50];
struct Data Nascimento;
};
void ImprimePessoa(struct Pessoa p)
{
printf("%s\n%s\n%s\n%d de %s de %d\n",
p.Nome, p.Telefone, p.Endereco,
p.Nascimento.Dia, p.Nascimento.Mes, p.Nascimento.Ano);
}
void main(void)
{
struct Pessoa pessoa1;
strcpy(pessoa1.Nome, "Joo");
strcpy(pessoa1.Telefone, "2222-2222");
strcpy(pessoa1.Endereco, "Av. Pres. Vargas, 10/1001");
pessoa1.Nascimento.Dia = 15;
strcpy(pessoa1.Nascimento.Mes, "Janeiro");
pessoa1.Nascimento.Ano = 1980;
ImprimePessoa(pessoa1);
}

Note que, como mais de uma funo do programa vai acessar as estruturas, elas so declaradas fora do
escopo de qualquer funo, o que as torna globais.

## Prof. Erico Lisboa

42

http://www.ericolisboa.eng.br

Linguagem C

## 7.1.5 Vetores de estruturas

Assim como qualquer tipo bsico, podemos ter vetores de estruturas. Estes vetores so definidos da
mesma maneira que vetores de tipos bsicos.
Vamos modificar o exemplo anterior para que trabalhemos com um vetor de pessoas.
#include <stdio.h>
#include <string.h>
struct Data
{
int Dia;
char Mes[10];
int Ano;
};
struct Pessoa
{
char Nome[50];
char Telefone[20];
char Endereco[50];
struct Data Nascimento;
};
void ImprimePessoa(struct Pessoa p)
{
printf("%s\n%s\n%s\n%d de %s de %d\n",
p.Nome, p.Telefone, p.Endereco,
p.Nascimento.Dia, p.Nascimento.Mes, p.Nascimento.Ano);
}
void main(void)
{
struct Pessoa pessoa[100];
strcpy(pessoa[0].Nome, "Joo");
strcpy(pessoa[0].Telefone, "2222-2222");
strcpy(pessoa[0].Endereco, "Av. Pres. Vargas, 10/1001");
pessoa[0].Nascimento.Dia = 15;
strcpy(pessoa[0].Nascimento.Mes, "Janeiro");
pessoa[0].Nascimento.Ano = 1980;
ImprimePessoa(pessoa[0]);
strcpy(pessoa[1].Nome, "Jos");
strcpy(pessoa[1].Telefone, "2222-2221");
strcpy(pessoa[1].Endereco, "Av. Pres. Vargas, 10/1002");
pessoa[1].Nascimento = pessoa[0].Nascimento;
ImprimePessoa(pessoa[1]);
}

No exemplo acima, note que cada elemento do vetor do tipo da estrutura Pessoa. O vetor
inicialmente dimensionado com 100 elementos, ou seja, podemos utilizar at 100 pessoas diferentes no
vetor.

## Prof. Erico Lisboa

43

http://www.ericolisboa.eng.br

Linguagem C

## 7.1.6 Ponteiros para estruturas

Ponteiros podem apontar para estruturas da mesma maneira que apontam para qualquer varivel. Por
exemplo, um ponteiro para a estrutura Data seria declarado como:
struct Data* pHoje = &hoje;

Para acessarmos os dados membro da estrutura atravs de seu ponteiro, podemos escrever
(*pHoje).Dia

## ou podemos acessar os dados membro de um ponteiro atravs do operador (->)

pHoje->Dia

Vamos alterar a funo ImprimePessoa, no exemplo anterior, para que receba o endereo da pessoa, ao
invs de uma cpia. A vantagem de escrever a funo desta maneira o aumento da velocidade de
processamento, j que necessrio copiar apenas o endereo, ao invs de todo o contedo da varivel.
#include <stdio.h>
#include <string.h>
struct Data
{
int Dia;
char Mes[10];
int Ano;
};
struct Pessoa
{
char Nome[50];
char Telefone[20];
char Endereco[50];
struct Data Nascimento;
};
void ImprimePessoa(struct Pessoa* p)
{
printf("%s\n%s\n%s\n%d de %s de %d\n",
p->Nome, p->Telefone, p->Endereco,
p->Nascimento.Dia, p->Nascimento.Mes, p->Nascimento.Ano);
}
void main(void)
{
struct Pessoa pessoa[100];
strcpy(pessoa[0].Nome, "Joo");
strcpy(pessoa[0].Telefone, "2222-2222");
strcpy(pessoa[0].Endereco, "Av. Pres. Vargas, 10/1001");
pessoa[0].Nascimento.Dia = 15;
strcpy(pessoa[0].Nascimento.Mes, "Janeiro");
pessoa[0].Nascimento.Ano = 1980;
ImprimePessoa(&pessoa[0]);
strcpy(pessoa[1].Nome, "Jos");
strcpy(pessoa[1].Telefone, "2222-2221");
strcpy(pessoa[1].Endereco, "Av. Pres. Vargas, 10/1002");

## Prof. Erico Lisboa

44

http://www.ericolisboa.eng.br

Linguagem C

pessoa[1].Nascimento = pessoa[0].Nascimento;
ImprimePessoa(&pessoa[1]);
}

recomendvel que estruturas muito grandes sejam sempre passadas por endereo. No caso, a
estrutura Pessoa ocupa 134 bytes (50 do nome, 20 do telefone, 50 do endereo e mais 14 da estrutura
Data - 2 do dia, 10 do ms e mais 2 do ano). Passando o argumento por valor, o programa ser
obrigado a copiar 134 bytes, ao passo que passando por endereo, apenas os 4 bytes do ponteiro so
7.2 Unies
Uma unio permite que as mesmas localizaes de memria sejam referenciadas de mais de um modo.
Sua sintaxe semelhante da estrutura.
union etiqueta
{
declarao da varivel membro
declarao da varivel membro
...
};

A diferena que a estrutura armazena todos os seus dados membro individualmente, enquanto a
unio utiliza o mesmo espao de memria para armazenar todos os seus dados membro. Enquanto o
Po exemplo, a unio definida por:
union Mes
{
int numero;
char nome[10];
};

ocupa 10 bytes (relativos ao dado nome). Podemos acessar seus dados da mesma forma que na
Ao trabalhar com unies, deve-se acessar apenas um dos dados membro, dependendo do tipo de uso.
Por exemplo, se definirmos
Mes mes;
strcpy(mes.nome, "Janeiro");

e tentarmos obter
mes.numero

o valor retornado m valor sem sentido, j que o espao de memria ocupado foi alterado por outra
varivel.
No tendo problemas de falta de memria, deve-se optar pela utilizao de estruturas ao invs de
unies.

## Prof. Erico Lisboa

45

http://www.ericolisboa.eng.br

Linguagem C

7.3 Enumerao
enum identificacao {enum1, enum2 ...};

Por exemplo:
enum dias {segunda, terca, quarta, quinta, sexta, sabado, domingo};

especifica que dias uma identificao para uma varivel do tipo enum, que somente pode ter os
valores de segunda a domingo.
Podemos declarar variveis do tipo do enumerado acima, por exemplo:
enum dias dia;

## os tipos de enumerao so representados internamente por inteiros. O primeiro identificador recebe o

valor 0, o prximo 1 e assim sucessivamente. Ou seja, na enumerao dias, segunda vale 0, terca vale
1 e assim sucessivamente, at domingo, que vale 6.
se declararmos
enum dias {segunda = 2, terca, quarta, quinta, sexta};

nesta enumerao, segunda vale 2, terca vale 3 e assim sucessivamente, at sexta, que vale 6. Se
declararmos
enum dias {segunda = 2, quarta = 4, quinta = 5};

## Prof. Erico Lisboa

46

http://www.ericolisboa.eng.br

Linguagem C

CAPTULO 8
8

Neste captulo, sero apresentados as operaes de C para leitura e gravao em disco. Operaes em
disco so executadas em arquivos. A biblioteca C oferece um pacote de funes para acessar arquivos
de quatro maneiras diferentes:

Os dados so lidos e escritos um caractere por vez. Oferece as funes getc() e putc().

## Os dados so lidos e escritos de modo formatado. Oferece as funes fscanf() e fprintf().

seqncias de dados como vetores e estruturas. Oferece as funes fread() e fwrite().

Outra maneira de classificar operaes de acesso a arquivos conforme a forma como eles so abertos:
em modo texto ou em modo binrio. Estes conceitos sero apresentados nas sees a seguir.
8.1 Arquivos Texto
Um arquivo aberto em modo texto interpretado em C como seqncias de caracteres agrupadas em
linhas. As linhas so separadas por um nico caractere chamado caractere de nova linha ou LF (line
feed), de cdigo ASCII 10 decimal. equivalente ao caractere '\r'.
Alguns sistemas operacionais, como o DOS, representam a mudana de linha por dois caracteres: O
caractere de retorno de carro ou CR (carriage return), de cdigo ASCII 13 decimal (caractere '\n') e
o caractere LF. Neste caso, o compilador C converte o par CR/LF em um nico caractere de nova linha
quando um arquivo em modo texto lido e converte o caractere de nova linha no par CR/LF quando o
O cdigo em C independente do sistema operacional que estamos utilizando, tratando a mudana de
linha sempre da mesma forma.
O exemplo abaixo l caracteres de um arquivo texto e armazena em outro arquivo texto. Para executar
este exemplo, crie um arquivo texto de nome entrada.txt, contendo algumas frases. Este arquivo pode
ser criado em qualquer editor de texto no formatado (evite usar o Word ou o WordPad, por serem de
texto formatado. Utilize, por exemplo, o prprio compilador ou o Bloco de Notas). Por exemplo, o
arquivo entrada.txt pode ter o seguinte contedo:
Linguagem C
Programa teste

## O cdigo do programa fornecido a seguir.

#include <stdio.h>
void main(void)
{
char ch;
FILE *in, *out;

## Prof. Erico Lisboa

47

http://www.ericolisboa.eng.br

Linguagem C

## if((in = fopen("entrada.txt", "rt")) == NULL)

{
return;
}
if((out = fopen("saida.txt", "wt")) == NULL)
{
printf("Impossivel abrir arquivo saida.txt.");
return;
}
while((ch = getc(in)) != EOF)
putc(ch, out);
fclose(in);
fclose(out);
}

Este programa aguarda a entrada de uma linha de texto e termina quando a tecla <ENTER> for
A estrutura FILE est presente na biblioteca stdio.h e armazena informaes sobre o arquivo. Esta
estrutura no ser discutida neste curso.
8.1.1 As funes fopen() e fclose()
Quando abrimos um arquivo, a informao que recebemos (se o arquivo for aberto) um ponteiro para
a estrutura FILE. Cada arquivo que abrimos ter uma estrutura FILE com um ponteiro para ela.
A funo fopen() tem a seguinte sintaxe:
FILE* fopen(const char* filename, const char* mode);

Esta funo recebe como argumentos o nome do arquivo a ser aberto (filename) e o modo de abertura
(mode). Retorna um ponteiro para a estrutura FILE, que armazena informaes sobre o arquivo aberto.
O nome do arquivo pode ser fornecido com ou sem o diretrio onde ele est localizado. Caso se deseje
fornecer o caminho completo do arquivo, lembre-se que a contrabarra em C no um caractere, e sim
um meio de fornecer caracteres especiais. O caractere contrabarra representado por '\\'. Ou seja,
em DOS o caminho completo de um arquivo pode ser, por exemplo, "C:\\temp\\saida.txt".
A lista de modos de abertura de arquivos apresentada a seguir.
"r"
"w"
"a"

Abrir um arquivo para leitura (read). O arquivo deve estar presente no disco.
Abrir um arquivo para gravao (write). Se o arquivo estiver presente, ele ser
ao fim do arquivo existente, ou um novo arquivo ser criado.

"+"
"b"
"t"

## A adio deste smbolo permite acesso de leitura e escrita.

Abrir um arquivo em modo binrio.
Abrir um arquivo em modo texto.

## Prof. Erico Lisboa

48

http://www.ericolisboa.eng.br

Linguagem C

Caso o arquivo possa ser aberto, a funo retorna um ponteiro para a estrutura FILE contendo as
informaes sobre o arquivo. Caso contrrio, retorna NULL. No exemplo, verificado se o arquivo foi
aberto com xito. Caso negativo, o programa apresenta uma mensagem de erro e termina a execuo.
O erro na abertura de arquivo pode ser causado por diversos fatores: espao insuficiente em disco (no
caso de gravao), arquivo inexistente (no caso de leitura) etc.
Ao ser aberto um arquivo necessrio que ele seja fechado aps utilizado. Isto feito por meio da
funo fclose(). Sua sintaxe a seguinte:
int fclose(FILE* f);

Para fechar o arquivo, basta chamar a funo fclose() e passar como argumento o ponteiro para a
estrutura FILE que contm as informaes do arquivo que se deseja fechar. Em caso de xito, a funo
retorna 0. Caso contrrio, retorna EOF (end-of-file). EOF definido na biblioteca stdio.h atravs da
diretiva #define e indica fim de arquivo.
8.1.2 As funes getc () e putc()
A funo getc() l um caractere por vez do arquivo. Sua sintaxe
int getc(FILE* f);

A funo recebe como argumento um ponteiro para FILE e retorna o caractere lido. Em caso de erro,
retorna EOF.
A funo putc() o complemento de getc(). Ela escreve um caractere no arquivo. Sua sintaxe
int putc(int ch, FILE* f);

A funo recebe como argumentos um caractere e um ponteiro para FILE. O valor retornado o
prprio caractere fornecido. Em caso de erro, a funo retorna EOF.
8.1.3 As funes fgets () e fputs()
O exemplo a seguir faz a mesma coisa que o exemplo anterior. A nica diferena que ao invs de
acessar os arquivos texto caractere a caractere, eles sero acessados linha a linha.
#include <stdio.h>
void main(void)
{
char ch[1001];
FILE *in, *out;
if((in = fopen("entrada.txt", "rt")) == NULL)
{
return;
}
if((out = fopen("saida.txt", "wt")) == NULL)
{
printf("Impossivel abrir arquivo saida.txt.");
return;
}
while((fgets(ch, 1000, in)) != NULL)
fputs(ch, out);

## Prof. Erico Lisboa

49

http://www.ericolisboa.eng.br

Linguagem C

fclose(in);
fclose(out);
}

## A funo fgets() tem a seguinte sintaxe.

char* gets(char* s, int n, FILE* f);

Esta funo l caracteres do arquivo os coloca na string s. A funo pra de ler quando l n-1
caracteres ou o caractere LF ('\r'), o que vier primeiro. O caractere LF includo na string. O
caractere nulo anexado ao final da string para marcar seu final. Em caso de xito, a funo retorna s.
Em caso de erro ou fim do arquivo, retorna NULL.
A funo fputs() o complemento de fgets(). Ela escreve uma seqncia de caracteres no arquivo. Sua
sintaxe
int putc(char* s, FILE* f);

A funo recebe como argumentos uma string e um ponteiro para FILE. O valor retornado o ltimo
caractere fornecido. Em caso de erro, a funo retorna EOF.
Note que a funo copia a string fornecida tal como ela para o arquivo. Se no existir na string, no
inserido o caractere de nova linha (LF) nem o caractere nulo.
8.1.4 As funes fprintf () e fscanf()
Para leitura e gravao de arquivos com formatao, so utilizadas as funes fprintf() e fscanf(). Estas
funes so semelhantes a printf() e scanf(), utilizadas ao longo do curso.
O programa a seguir l dados de um arquivo, executa um processamento com os dados lidos e grava os
#include <stdio.h>
void main(void)
{
FILE *in, *out;
if((in = fopen("entrada.txt", "rt")) == NULL)
{
return;
}
if((out = fopen("saida.txt", "wt")) == NULL)
{
printf("Impossivel abrir arquivo saida.txt.");
return;
}
fscanf(in, "%f%f", &distancia, &tempo);
fprintf(out, "Distancia percorrida: %10.2f km\n", distancia);
fprintf(out, "Tempo decorrido:
%10.2f h\n", tempo);
fclose(in);
fclose(out);
}

## Prof. Erico Lisboa

50

http://www.ericolisboa.eng.br

Linguagem C

Este programa l do arquivo entrada.txt a distncia percorrida e o tempo decorrido. feito o clculo da
fscanf() so semelhantes s sintaxes de printf() e scanf() exceto pela incluso do primeiro argumento,
que um ponteiro para a estrutura FILE.
As strings de formatao utilizadas nestas funes so as mesmas utilizadas nas funes printf() e
scanf().
8.2 Arquivos Binrios
computador. Ou seja, ao guardarmos o valor de uma varivel float num arquivo binrio, ela ocupa no
arquivo os mesmos 4 bytes que ocupa na memria.
Arquivos guardados em modo binrio no so facilmente entendidos por uma pessoa que o esteja
lendo. Em compensao, para um programa muito fcil interpretar este arquivo.
Ao guardarmos valores em modo texto, o compilador converte o valor da varivel para uma forma de
apresent-lo atravs de caracteres. Por exemplo, o nmero inteiro 20000, apesar de ocupar somente
dois bytes na memria, para ser armazenado em um arquivo texto ocupa pelo menos cinco bytes, j
que cada caractere ocupa um byte.
Arquivos binrios normalmente so menores que arquivos texto, contendo a mesma informao. A
velocidade de leitura do arquivo tambm consideravelmente reduzida ao utilizarmos arquivos
binrios.
Em compensao, a visualizao do arquivo no traz nenhuma informao ao usurio, pelo fato de
serem visualizados os caracteres correspondentes aos bytes armazenados na memria. No caso de
variveis char, a visualizao idntica em arquivos texto e binrios.
8.2.1 As funes fread() e fwrite()
O programa abaixo grava um arquivo binrio contendo 2 vetores de 20 elemento cada um: o primeiro
vetor de caracteres e o segundo de variveis inteiras.
#include <stdio.h>
void main(void)
{
char ch[20] = "Teste geral";
int valor[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
FILE *out;
out = fopen("binario.bin", "wb");
if(out == NULL)
{
printf("Impossivel abrir arquivo binario.bin.");
return;
}
fwrite(ch, sizeof(char), 20, out);
fwrite(valor, sizeof(int), 20, out);
fclose(out);
}

## Prof. Erico Lisboa

51

http://www.ericolisboa.eng.br

Linguagem C

Ao executar este programa, ele gera um arquivo binrio, binario.bin. Se voc tentar visualizar este
arquivo num editor como o Bloco de Notas, do Windows, conseguir distinguir os 20 primeiros bytes,
que o vetor de caracteres. A partir da, os bytes utilizados pelo compilador para armazenar os valores
inteiros no fazem mais sentido quando visualizados.
O programa abaixo l o arquivo binario.bin e apresenta os valores lidos na tela.
#include <stdio.h>
void main(void)
{
char ch[20];
int valor[20];
FILE *in;
in = fopen("binario.bin", "rb");
if(in == NULL)
{
printf("Impossivel abrir arquivo binario.bin.");
return;
}
for(i = 0; i < 20; i++)
printf("%c", ch[i]);
for(i = 0; i < 20; i++)
printf("\n%d", valor[i]);
fclose(in);
}

## Prof. Erico Lisboa

52

http://www.ericolisboa.eng.br

## Anexo A - Tabela ASCII

Linguagem C

ANEXO A
TABELA ASCII
A

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
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 J (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: , , , ...

## Prof. Erico Lisboa

53

http://www.ericolisboa.eng.br

Linguagem C

## Tabela A.1 - Conjunto de controle ASCII

Dec.

Hex.

Dec.

Hex.

00h

NUL

(Null)

00h

<espao>

01h

SOH

01h

02h

STX

(Start of Text)

02h

"

03h

ETX

(End of

03h

04h

EOT

(End of Transmision)

04h

05h

ENQ

(Enquiry)

05h

06h

ACK

(Acknowledge)

06h

&

07h

BEL

(Bell)

07h

'

08h

BS

(Backspace)

08h

09h

HT

(Horizontal Tab)

09h

10

0Ah

LF

(Line Feed)

10

0Ah

11

0Bh

VT

(Vertical Tab)

11

0Bh

12

0Ch

FF

(Form Feed)

12

0Ch

13

0Dh

CR

(Carriage Return)

13

0Dh

14

0Eh

SO

(Shift Out)

14

0Eh

15

0Fh

SI

(Shift In)

15

0Fh

16

10h

DLE

16

10h

17

11h

DC1

(Device control 1)

17

11h

18

12h

DC2

(Device control 2)

18

12h

19

13h

DC3

(Device control 3)

19

13h

20

14h

DC4

(Device control 4)

20

14h

21

15h

NAK

(Negative Acknowledge)

21

15h

22

16h

SYN

(Synchronous Idle)

22

16h

23

17h

ETB

## (End Transmission Block)

23

17h

24

18h

CAN

(Cancel)

24

18h

25

19h

EM

(End of Media)

25

19h

26

1Ah

SUB

(Substitute)

26

1Ah

27

1Bh

ESC

(Escape)

27

1Bh

28

1Ch

FS

(File Separator)

28

1Ch

<

29

1Dh

GS

(Group Separator)

29

1Dh

30

1Eh

RS

(Record Separator)

30

1Eh

>

31

1Fh

US

(Unit Separator)

31

1Fh

## Prof. Erico Lisboa

Controle

Text)

54

Caractere

http://www.ericolisboa.eng.br

Linguagem C

## Prof. Erico Lisboa

Dec.

Hex.

Caractere

Dec. Hex.

64

40h

96

60h

65

41h

97

61h

66

42h

98

62h

67

43h

99

63h

68

44h

100

64h

69

45h

101

65h

70

46h

102

66h

71

47h

103

67h

72

48h

104

68h

73

49h

105

69h

74

4Ah

106

6Ah

75

4Bh

107

6Bh

76

4Ch

108

6Ch

77

4Dh

109

6Dh

78

4Eh

110

6Eh

79

4Fh

111

6Fh

80

50h

112

70h

81

51h

113

71h

82

52h

114

72h

83

53h

115

73h

84

54h

116

74h

85

55h

117

75h

86

56h

118

76h

87

57h

119

77h

88

58h

120

78h

89

59h

121

79h

90

5Ah

122

7Ah

91

5Bh

123

7Bh

92

5Ch

124

7Ch

93

5Dh

125

7Dh

94

5Eh

126

7Eh

95

5Fh

127

7Fh

<delete>

55

Caractere

http://www.ericolisboa.eng.br

Linguagem C

Dec.

## Prof. Erico Lisboa

Hex.

Caractere

Dec. Hex.

Caractere

128

80h

160

A0h

129

81h

161

A1h

130

82h

162

A2h

131

83h

163

A3h

132

84h

164

A4h

133

85h

165

A5h

134

86h

166

A6h

135

87h

167

A7h

136

88h

168

A8h

137

89h

169

A9h

138

8Ah

170

AAh

139

8Bh

171

ABh

140

8Ch

172

ACh

141

8Dh

173

142

8Eh

174

AEh

143

8Fh

175

AFh

144

90h

176

B0h

145

91h

177

B1h

146

92h

178

B2h

147

93h

179

B3h

148

94h

180

B4h

149

95h

181

B5h

150

96h

182

B6h

151

97h

183

B7h

152

98h

184

B8h

153

99h

185

B9h

154

9Ah

186

BAh

155

9Bh

187

BBh

156

9Ch

188

BCh

157

9Dh

189

BDh

158

9Eh

190

BEh

159

9Fh

191

BFh

56

http://www.ericolisboa.eng.br

Linguagem C

Dec.

## Prof. Erico Lisboa

Hex.

Caractere

Dec. Hex.

Caractere

192

C0h

224

E0h

193

C1h

225

E1h

194

C2h

226

E2h

195

C3h

227

E3h

196

C4h

228

E4h

197

C5h

229

E5h

198

C6h

230

E6h

199

C7h

231

E7h

200

C8h

232

E8h

201

C9h

233

E9h

202

CAh

234

EAh

203

CBh

235

EBh

204

CCh

236

ECh

205

CDh

237

EDh

206

CEh

238

EEh

207

CFh

239

EFh

208

DOh

240

F0h

209

D1h

241

F1h

210

D2h

242

F2h

211

D3h

243

F3h

212

D4h

244

F4h

213

D5h

245

F5h

214

D6h

246

F6h

215

D7h

247

F7h

216

D8h

248

F8h

217

D9h

249

F9h

218

DAh

250

FAh

219

DBh

251

FBh

220

DCh

252

FCh

221

DDh

253

FDh

222

DEh

254

FEh

223

DFh

255

FFh

57

http://www.ericolisboa.eng.br

Anexo B - Exerccios

Linguagem C

ANEXO B
EXERCCIOS
B

EXERCCIOS

B.1 Introduo
1. Fazer um programa que imprima na tela o nome de todos os tipos de dados utilizados pelo C e seus
2. Quais dos seguintes nomes so vlidos para variveis em C?
a) 5ij
b) _abc
c) a_b_c
d) 00TEMPO
e) int
f) A123
g) a123
h) x**x
i) __A
j) a-b-c
k) OOTEMPO
l) \abc
m) *abc
1. Que valor tm as seguintes expresses:
a) 7 / 2
b) 7 % 2
c) 7.0 / 2
d) 7 / 2.0
e) 7.0 / 2.0
2. Fazer um programa para transformar graus Farenheit em Celsius. A frmula para converso a
seguinte:
C F 32
=
5
9
onde:
C Temperatura em graus Celsius
F Temperatura em graus Farenheit
3. Fazer um programa para transformar graus Celsius em Farenheit. A frmula de converso
fornecida no exerccio anterior.

## Prof. Erico Lisboa

58

http://www.ericolisboa.eng.br

Anexo B - Exerccios

Linguagem C

## 4. Implementar um programa que calcule a mdia aritmtica de trs nmeros reais.

B.3 Controle de Fluxo
1. Fazer um programa que leia dois nmeros inteiros e apresente o maior deles.
2. Fazer um programa que leia trs nmeros inteiros e apresente o maior deles.
3. Fazer um programa que mostre ao usurio quatro opes de operao:
b) subtrao
c) multiplicao
d) diviso
Aps a seleo da opo desejada, leia dois nmeros e realize a operao, exibindo a resultado na
tela.
4. O que ser impresso pelo seguinte programa ?
main()
{
int x = 1, y = 1;
if (y<0)
if (y>0)
x = 3;
else
x = 5;
printf(x= %d\n, x);
}

5. Supondo que a populao de um pas, tomado como comparao, seja de 200 milhes de
habitantes em 2000 e que sua taxa de crescimento seja de 1,3% ao ano. Fazer um programa para
calcular o ano em que um outro pas, cuja populao e taxa de crescimento sejam fornecidas pelo
usurio, iguale ou ultrapasse a populao do pas base.
6. Implementar um programa que dados:
a) saldo em conta corrente (negativo),
b) limite de cheque especial,
calcule quantos meses a conta poder ficar sem receber depsito sem exceder o limite
7. Fazer um programa que realize a operao de exponenciao, sendo que
a) O usurio dever digitar a base e o expoente;
b) A base dever ser um nmero real e positivo;
c) O expoente dever ser um nmero inteiro.
8. Fazer um programa para calcular o fatorial de um nmero, sendo que
N! = N*(N-1)!
0! = 1.
9. Fazer um programa para calcular o N-simo termo da seqncia de Fibonacci. Sendo que
Fn = Fn-1 + Fn-2
F0 = 0
F1 = 1

## Prof. Erico Lisboa

59

http://www.ericolisboa.eng.br

Anexo B - Exerccios

Linguagem C

## Logo, temos que a seqncia ficar: 0,1,1,2,3,5,8, ...

10. Implementar um programa que calcule a quantidade de divisores de um nmero
11. Implementar um programa que escreva um nmero de 1 a 99, por extenso.
12. Implementar um programa que leia o dia e ms de nascimento de uma pessoa e imprima o seu
signo no horscopo.
Aries
21/03 at 20/04
Touro
21/04 at 20/05
Gmeos
21/05 at 20/06
Cncer
21/06 at 21/07
Leo
22/07 at 22/08
Virgem
23/08 at 22/09
Libra
23/09 at 22/10
Escorpio
23/10 at 21/11
Sagitrio
22/11 at 21/12
Capricrnio
22/12 at 20/01
Aqurio
21/01 at 19/02
Peixes
20/02 at 20/03
13. Implemente um programa que transforme nmeros arbicos em romanos, at 999.
Exemplo:
1
I
5
V
10
X
50
L
100
C
500
D
B.4 Funes
1. Criar uma funo para a exponenciao, considerado o expoente inteiro.
2. Criar uma funo que calcule o fatorial de um nmero inteiro
3. Criar uma funo recursiva que calcule o fatorial de um nmero inteiro, sendo que:
N! = N*(N-1)!
0! = 1.
4. Fazer uma funo para calcular o N-simo termo da seqncia de Fibonacci. Sendo que
Fn = Fn-1 + Fn-2
F0 = 0
F1 = 1
Logo, temos que a seqncia ficar: 0,1,1,2,3,5,8, ...
5. Fazer uma funo recursiva para calcular o N-simo termo da seqncia de Fibonacci.
6. Fazer um programa que calcule os nmeros palndromos de 0 a 5000. O programa dever solicitar
do usurio uma das seguintes alternativas:
a) Calcular nmeros palndromos
b) Terminar

## Prof. Erico Lisboa

60

http://www.ericolisboa.eng.br

Anexo B - Exerccios

Linguagem C

OBS. Nmero Palndromo aquele que tem igual valor se lido da esquerda para direita ou viceversa. Ex. 0,1, ... 9, 11, 22, ..., 99, 101, 111, 121, ...
7. Implementar um programa que calcule o MDC de dois nmeros atravs do seguinte algortmo:
Funo MDC(M,N)
Incio
Se (M < N) ento
Resp := MDC(N,M)
Fim-se
Se (N = 0) ento
Resp := M;
Seno
Resp := MDC(N,Resto(M,N));
Fim-se
Retorne Resp;
Fim

8. Faca a estrutura de um programa principal que calcule a potncia de um nmero fazendo chamada
a seguinte funo:
potencia(int x, int n)
{
int p;
for (p=1;n>0;--n)
p *= x;
return(p);
}

## OBS. Caso exista algum erro na funo potncia, corrija-o.

9. Considere a seguinte funo que calcula a rea de um tringulo de lados a, b e c:
#include <math.h>

## /* arquivo onde eest definida a funcao sqrt() */

AreaTri( )
{
x = (a+b+c)/2.0;
area = x*(x-a)*(x-b)*(x-c);
area = sqrt(area);
}

Faca um programa que calcule a rea do tringulo de lados a=3, b=4 e c=5, utilizando a funcao
acima.
B.5 Vetores e Matrizes
1. Fazer um programa que leia dez nmeros inteiros e apresente o maior deles.
2. Fazer um programa para ler um nome (mximo de 50 caracteres) e abreviar os nomes do meio.
Exemplo: Joaquim Jos da Silva Xavier, ficaria: Joaquim J. d. S. Xavier
3. Fazer um programa que faa a reserva de lugares em um teatro sendo que:
b) os lugares so identificados com uma letra (coluna) e um nmero (fila)
Exemplo: A-04, B-23 etc.
c) O programa dever solicitar do usurio qual lugar ele deseja ocupar.

## Prof. Erico Lisboa

61

http://www.ericolisboa.eng.br

Anexo B - Exerccios

Linguagem C

d) Caso o lugar indicado no esteja vago, o programa dever avisar ao usurio para que escolha um
novo lugar.
e) Caso o lugar indicado esteja vago, este dever ser reservado ao usurio.
f) Sempre que uma dada fileira (1a., 2a. 3a. etc.) estiver totalmente ocupada, o programa dever
informar ao usurio antes que ele efetue a escolha.
g) Ao final de cada reserva o programa dever indicar o total de lugares ocupados e o total de
lugares vagos.
4. Analise o cdigo abaixo e responda:
a) para que serve a funo dada ?
b) de que maneira deveramos ter a funo main() para chamar corretamente esta funo ?
c) indique os possveis erros de compilao e corrija-os;
int avg(float a[], int size)
{
int i;
float sum;
sum = 0;
for (i=0;i < size; i++)
sum += a[i];
return(sum / size);
}

## 5. Analise o cdigo abaixo e responda:

a) para que serve a funo dada ?
b) de que maneira deveramos ter a funo main() para chamar corretamente esta funo ?
strpos(char s1[],char s2[])
{
int len1, len2;
int i, j1, j2;
len1 = strlen(s1);
len2 = strlen(s2);
for (i=0; i+len2 <= len1; i++)
for (j1 = i, j2 = 0; j2 <= len2 && s1[j1] == s2[j2]; j1++, j2+++
if (j2 == len2)
return(i);
return(-1);
}

## 6. Analise o cdigo abaixo e responda:

a) para que serve a funo dada ?
b) de que maneira deveramos ter a funo main() para chamar corretamente esta funo ?
strcat(char s1[], char s2[])
{
int i, j;
for (i=0; s1[i] != '\0'; i++)
;
for (j=0; s2[j] != '\0'; s1[i++] = s2[j++])
;
}

## Prof. Erico Lisboa

62

http://www.ericolisboa.eng.br

Anexo B - Exerccios

Linguagem C

## 7. Analise o cdigo abaixo e responda:

a) para que serve a funo dada ?
b) de que maneira deveramos ter a funo main() para chamar corretamente esta funo ?
substr(char s1[], int i, int j, char s2[])
{
int k, m;
for (k = i, m = 0; m < j; s2[m++] = s1[k++])
;
s2[m] = '\0';
}

8. A MODA de um vetor de nmeros o nmero m no vetor que repetido com maior freqncia. Se
mais de um nmero for repetido com freqncia mxima igual, no existir uma moda. Escreva
uma funo em C que aceite um vetor de nmeros e retorne a moda ou uma indicao de que a
moda no existe.
9. A mediana de um vetor de nmeros o elemento m do vetor, tal que a metade dos nmeros
restantes no vetor maior ou igual a m e a outra metade menor ou igual a m, se o nmero de
elementos no vetor for mpar. Se o nmero de elementos for par, a mediana ser a mdia dos dois
elementos, m1 e m2, tal que metade dos elementos restantes maior ou igual a m1 e m2, e metade
dos elementos menor ou igual a m1 e m2. Escreva uma funo em C que aceite um vetor de
nmeros e retorne a mediana dos nmeros do vetor.
10. Faca um programa que lei um vetor de 20 posies de inteiros e imprima o maior e o segundo
maior valor do vetor.
B.6 Ponteiros
1. Quais das seguintes instrues so corretas para declarar um ponteiro?
a) int_ptr x;
b) int *x;
c) *int x;
d) *x;
2. Qual a maneira correta de referenciar ch, assumindo que o endereo de ch foi atribudo ao
ponteiro pch?
a) *pch
b) &pch
c) pch
3. Na expresso float* pf, o que do tipo float?
a) a varivel pf
b) o endereo de pf
c) a varivel apontada por pf
d) nenhuma das anteriores
4. Assumindo que o endereo da varivel var foi atribudo a um ponteiro pvar, escreva uma expresso
que divida var por 10 sem utilizar a varivel var.

## Prof. Erico Lisboa

63

http://www.ericolisboa.eng.br

Anexo B - Exerccios

Linguagem C

5. Considere as seguintes declaraes:
struct ss
{
char a[10]; int b;
} v;
union uu
{
char a[10]; int b;
} v;

Em cada declarao, qual o tamanho (em bytes) do bloco de memria que ser alocado para
armazenar os valores das variveis v?
1. Faa um programa em C que receba como argumentos o nome de dois arquivos e a seguir efetue a
cpia do primeiro arquivo no segundo arquivo.
2. Faa um programa que leia o ms e ano e imprima a folha do calendrio correspondente ao ms.
Exemplo: Para mes=9 e ano=1995 teremos a sada:
SETEMBRO DE 1995
DOM SEG TER QUA QUI SEX SAB
1
2
3
4
5
6
7
8
9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

O programa deve levar em conta que fevereiro tem 29 dias se: (resto(ano/4)=0 e
resto(ano/100)<>0) ou (resto(ano/400)=0). Para determinar em que dia da semana cai o
primeiro dia do ms e ano, utilize o seguinte algoritmo:
E1.:
E2.:
E3.:
E4.:
E5.:
E6.:

## se mes>2, ento v para E3

mes = mes +10, ano = ano-1, v para E4
mes = mes - 2
aux1 = ano / 100, aux2 = resto(ano/100)
aux3 = 106 + (13*mes-1)/5 + aux2/4 + aux1/4
dia_semana = resto((aux3+aux2-2aux1+1)/7)

## Desta forma, se:

dia_semana = 0, ento o dia primeiro cai num domingo,
dia_semana = 1, ento o dia primeiro cai numa segunda-feira, e assim por diante.
Obs: As divises nas expresses acima so divises inteiras.

## Prof. Erico Lisboa

64

http://www.ericolisboa.eng.br

## Anexo C - Exemplos de funes

Linguagem C

ANEXO C
EXEMPLOS DE FUNES
C

## C.1 Funo de ordenao - mtodo da bolha

{
int iFlag;
int iAux;
int i;
do
{
iFlag = 0;
for(i = 0; i < iTamanho - 1; i++)
{
{
iFlag = 1;
}
}
} while(iFlag == 1);
}

## Prof. Erico Lisboa

65

http://www.ericolisboa.eng.br

Referncias

Linguagem C

REFERNCIAS
1

DEITEL, H. M., DEITEL, P. J., 1999, Como programar em C, LTC - Livros Tcnicos e Cientficos
Editora, Rio de Janeiro, Brasil.
KEINIGHAN, B. e RITCHIE, D., C - A linguagem de programao, Editora Campus.
MIZRAHI, V. V., 1990, Treinamento em linguagem C - Curso completo. Mdulos 1 e 2, McGrawHill, So Paulo, Brasil.
PUGH, K., 1990, Programando em linguagem C, Trad.: Jos R. Martins, Roberto C. Mayer,
McGraw-Hill, So Paulo, Brasil.
SCHELDT, H. C Completo e Total. Makron Books.

## Prof. Erico Lisboa

66

http://www.ericolisboa.eng.br