Escolar Documentos
Profissional Documentos
Cultura Documentos
LINGUAGEM C
Prof. Erico Fagundes Anicet Lisboa, M. Sc.
erico@ericolisboa.eng.br
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 Entrada e Sada Bsicas_______________________________________________________________3
1.6.1 A Funo printf() _________________________________________________________________________ 3
1.6.2 A Funo scanf() _________________________________________________________________________ 4
2. OPERADORES ______________________________________________________ 5
2.1 Operadores aritmticos _______________________________________________________________5
2.2 Operador de atribuio _______________________________________________________________5
2.3 Operadores relacionais _______________________________________________________________5
2.4 Operadores lgicos ___________________________________________________________________6
2.5 Operadores bit a bit __________________________________________________________________6
2.6 Atribuies reduzidas ________________________________________________________________6
2.7 Operadores pr e ps fixados __________________________________________________________7
2.8 Operadores condicionais ______________________________________________________________7
2.9 Operador vrgula ____________________________________________________________________7
2.10 Precedncia de operadores ___________________________________________________________7
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
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
iv
7. DADOS ORGANIZADOS_____________________________________________ 40
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
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
linguagem C. Cada item do programa ser detalhado mais adiante no curso.
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;
printf("Quadrado do maior numero digitado: %f\n", c);
}
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.
A quinta linha uma linha vazia. ignorada pelo compilador e pode ser utilizada em qualquer lugar
dentro de um cdigo em C. Normalmente, utiliza-se para separar partes lgicas de um cdigo.
http://www.ericolisboa.eng.br
1 - Introduo
Linguagem C
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
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
Significado
constante inteira
constante octal
constante hexadecimal
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 representado
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
Significado
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
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
cadeia de caracteres
decimal sem sinal
hexadecimal
decimal longo
ponto flutuante longo (double)
Exemplos:
printf("Teste geral");
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.
http://www.ericolisboa.eng.br
2 - Operadores
Linguagem C
CAPTULO 2
OPERADORES
2
Tem o valor
7
1
3
2
3
0
Operao
Coloca o valor 3 em i
O valor 7 colocado em i
O valor 4 colocado em k; o valor da atribuio (4)
ento colocado em i
O valor 4 colocado em k; a adio realizada e o
valor 7 colocado em i
Valor da expresso
3
7
4
4
Valor
0
1
1
0
1
http://www.ericolisboa.eng.br
2 - Operadores
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.
2.4 Operadores lgicos
Os dois operadores lgicos binrios so && (e) e || (ou). O resultado de suas operaes tambm ser 0
(falso) ou 1 (verdadeiro).
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
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
igual a
a=a+2
i = i << 1
s = s / (7 + 2)
http://www.ericolisboa.eng.br
2 - Operadores
Linguagem C
Valor da expresso
10
10
11
9
Valor final de i
6
4
6
4
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
Valor
2
j+2
valor de k (antes do incremento)
valor de k (depois do incremento)
http://www.ericolisboa.eng.br
2 - Operadores
Linguagem C
Operador
()
[]
->
.
!
~
++
-(tipo)
*
&
sizeof
*
/
%
+
<<
>>
<
<=
>
>=
==
!=
&
^
|
&&
||
?:
=
op=
,
Descrio
chamada de funo
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
adio
subtrao
deslocamento esquerda
deslocamento direita
menor que
menor ou igual a
maior que
maior ou igual a
igualdade
desigualdade
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
Se expr1 for verdadeira, comando1 executado. Se for falsa, se expr2 for verdadeira, comando2
executado; caso contrrio, 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;
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
3.3
do-while
3.3.1 Sintaxe
do comando while (expr)
10
http://www.ericolisboa.eng.br
3 - Controle de fluxo
3.4
Linguagem C
for
3.4.1 Sintaxe
for (inicializacao, condicao, incremento) comando
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
devam permanecer. Se a expresso de teste for omitida, considerada verdadeira.
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;
}
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;
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;
}
13
http://www.ericolisboa.eng.br
4 - Funes
Linguagem C
CAPTULO 4
FUNES
4
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
iniciada a funo, a varivel criada. Quando a funo termina, a varivel apagada, sendo liberado
seu espao ocupado na memria.
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.
14
http://www.ericolisboa.eng.br
4 - Funes
Linguagem C
As funes s podem ser chamadas depois de terem sido declaradas. Caso sejam chamadas sem que
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);
}
}
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
compilador no reconhecer a funo.
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.
Exemplo: a funo Quadrado() recebe como argumento uma varivel real (a) e retorna o quadrado
dela.
float Quadrado(float a)
{
return a * a;
}
16
http://www.ericolisboa.eng.br
4 - Funes
Linguagem C
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.
4.4 Recursividade
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.
Exemplo: Funo fatorial(), utilizando 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).
17
http://www.ericolisboa.eng.br
4 - Funes
Linguagem C
equivalente a
main()
{
int n;
. . .
}
18
http://www.ericolisboa.eng.br
4 - Funes
Linguagem C
A sada ser:
i = 0
i = 1
i = 2
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;
19
http://www.ericolisboa.eng.br
4 - Funes
Linguagem C
Dado:
#define MAIS_UM(x) x+1
ento:
MAIS_UM(y)
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
Expresso pr-compilada
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)
Expresso pr-compilada
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))
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
matemtica math.h e a biblioteca de entrada e sada padro stdio.h.
4.6.4 Outras Diretivas
O preprocessador C possui ainda outras diretivas de pr-compilao. Alguns trechos do cdigo podem
ser ignorados pelo compilador, dependendo de alguns parmetros de pr-compilao.
21
http://www.ericolisboa.eng.br
4 - Funes
#if expr
#ifdef nome
#ifndef nome
Linguagem C
Se os resultados destes testes forem avaliados como verdadeiros, ento as linhas seguintes so
compiladas at que um #else ou um #endif seja encontrado.
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
definio de COMPILADOR.
#define COMPILADOR TC
/* Esta definicao precisa ser trocada para cada compilador*/
#if COMPILADOR == TC
/* Codigo para o Turbo C
#endif
#if COMPILADOR == GCC
/* Codigo para o Gnu C
#endif
22
http://www.ericolisboa.eng.br
5 - Vetores e Matrizes
Linguagem C
CAPTULO 5
VETORES E MATRIZES
5
5.1 Vetores
Um vetor armazena uma determinada quantidade de dados de mesmo tipo. Vamos supor o problema
de encontrar a mdia de idade de 4 pessoas. O programa poderia ser:
main()
{
int idade0, idade1, idade2, idade3;
printf("Digite a idade da pessoa 0: ");
scanf("%d", &idade0);
printf("Digite a idade da pessoa 1: ");
scanf("%d", &idade1);
printf("Digite a idade da pessoa 2: ");
scanf("%d", &idade2);
printf("Digite a idade da pessoa 3: ");
scanf("%d", &idade3);
printf("Idade media: %d\n", (idade0+idade1+idade2+idade3) / 4);
}
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
tipo referenciadas por um nico nome, onde cada varivel diferenciada atravs de um ndice, que
representado entre colchetes depois do nome da varivel.
A declarao
int idade[4];
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);
scanf("%d", &idade[i]);
}
for(i = 0; i < 4; i++)
soma += idade[i];
printf("Idade media: %d\n", soma / 4);
}
23
http://www.ericolisboa.eng.br
5 - Vetores e Matrizes
Linguagem C
=
=
=
=
=
=
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};
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
inicializadores que o especificado, o compilador acusa um erro.
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.
24
http://www.ericolisboa.eng.br
5 - Vetores e Matrizes
Linguagem C
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
utilizada na funo. o prprio vetor quem passado como argumento e pode ser alterado na funo.
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:
25
http://www.ericolisboa.eng.br
5 - Vetores e Matrizes
Linguagem C
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));
}
SADA
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"));
}
26
http://www.ericolisboa.eng.br
5 - Vetores e Matrizes
Linguagem C
SADA
(Algum valor menor que 0)
(Algum valor maior que 0)
0
Exemplo:
main()
{
char Nome[10];
strcpy(Nome, "Teste")
printf("%s\n", Nome);
}
SADA
Teste
Exemplo:
main()
{
char Nome[12];
strcpy(Nome, "Teste")
strcpy(Nome, "geral")
printf("%s\n", Nome);
}
SADA
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
27
http://www.ericolisboa.eng.br
5 - Vetores e Matrizes
Linguagem C
matriz de duas dimenses e, para cada par de colchetes adicionado, obtemos uma matriz com uma
dimenso a mais.
Por exemplo, a declarao
int A[5][6];
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"};
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
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.
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.
Dois operadores so utilizados para se trabalhar com ponteiros. Um o operador de endereo (&), que
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.
29
http://www.ericolisboa.eng.br
6 - Ponteiros
Linguagem C
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);
}
30
http://www.ericolisboa.eng.br
6 - Ponteiros
Linguagem C
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;
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
programa mostra estas possibilidades. Para mostrar o resultado de cada operao, o programa
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);
}
SAIDA
py-px = 1
px = 65492,
py = 65494,
px = 65494,
py = 65500,
py-px = 3
*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
O operador indireto (*) fornece o valor armazenado no endereo apontado.
6.3.3 Endereo
Como todas as variveis, os ponteiros tm um endereo e um valor. Seu valor o endereo de
memria apontado. O operador (&) retorna o endereo de memria utilizado para armazenar o
ponteiro. Em resumo:
-
32
http://www.ericolisboa.eng.br
6 - Ponteiros
Linguagem C
Nota-se no exemplo que fazemos com que o ponteiro px aponte para o vetor x. Repare que no
utilizado o operador endereo. Isto ocorre porque o nome do vetor j tratado pelo compilador como
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].
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.
Para passar para o caractere seguinte, foi utilizado o operador ++.
6.5 Alocao dinmica de memria
Quando um vetor declarado, o endereo de memria para o qual ele aponta no teve necessariamente
seu espao reservado (alocado) para o programa. Nos exemplos anteriores, os ponteiros utilizados
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
alocada no automaticamente liberada. necessrio que o programador libere a memria
dinamicamente alocada atravs da funo free.
6.5.2 Funo free
Sintaxe:
void free(void* block);
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);
}
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];
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
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
modificador const, neste caso, apesar de opcional, fornece segurana ao programador.
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
funo est localizada na memria.
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");
}
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);
qsort(piValor, 7, sizeof(int), OrdenaDecrescente);
Imprime(piValor, 7);
}
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
desordenados.
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.
39
http://www.ericolisboa.eng.br
7 - Dados organizados
Linguagem C
CAPTULO 7
DADOS ORGANIZADOS
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
...
};
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;
Cada membro da estrutura equivalente a uma varivel simples de seu tipo. O exemplo a seguir ilustra
a utilizao de estruturas.
40
http://www.ericolisboa.eng.br
7 - Dados organizados
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);
}
41
http://www.ericolisboa.eng.br
7 - Dados organizados
Linguagem C
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.
42
http://www.ericolisboa.eng.br
7 - Dados organizados
Linguagem C
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.
43
http://www.ericolisboa.eng.br
7 - Dados organizados
Linguagem C
Para acessarmos os dados membro da estrutura atravs de seu ponteiro, podemos escrever
(*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");
44
http://www.ericolisboa.eng.br
7 - Dados organizados
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
copiados.
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
espao ocupado por uma estrutura a soma do espao utilizado por seus dados membro, a memria
utilizada pela unio a memria ocupada por seu maior dado membro.
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
estrutura mas, uma vez alterado um dado membro, os outros so alterados tambm.
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.
45
http://www.ericolisboa.eng.br
7 - Dados organizados
Linguagem C
7.3 Enumerao
A linguagem C apresenta um tipo de dado adicional, chamado enumerao. Sua sintaxe :
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;
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};
46
http://www.ericolisboa.eng.br
8 - Entrada e sada
Linguagem C
CAPTULO 8
ENTRADA E SADA
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 num formato chamado registro ou bloco. usado para armazenar
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
arquivo gravado.
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
47
http://www.ericolisboa.eng.br
8 - Entrada e sada
Linguagem C
Este programa aguarda a entrada de uma linha de texto e termina quando a tecla <ENTER> for
pressionada. A linha gravada no arquivo saida.txt.
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
destrudo e reinicializado. Se no existir, ele ser criado.
Abrir um arquivo para gravao em anexo (append). Os dados sero adicionados
ao fim do arquivo existente, ou um novo arquivo ser criado.
48
http://www.ericolisboa.eng.br
8 - Entrada e sada
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)
{
printf("Impossivel abrir arquivo entrada.txt.");
return;
}
if((out = fopen("saida.txt", "wt")) == NULL)
{
printf("Impossivel abrir arquivo saida.txt.");
return;
}
while((fgets(ch, 1000, in)) != NULL)
fputs(ch, out);
49
http://www.ericolisboa.eng.br
8 - Entrada e sada
Linguagem C
fclose(in);
fclose(out);
}
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
resultados em outro arquivo, em forma de um relatrio de sada.
#include <stdio.h>
void main(void)
{
float distancia, tempo, velocidade;
FILE *in, *out;
if((in = fopen("entrada.txt", "rt")) == NULL)
{
printf("Impossivel abrir arquivo entrada.txt.");
return;
}
if((out = fopen("saida.txt", "wt")) == NULL)
{
printf("Impossivel abrir arquivo saida.txt.");
return;
}
fscanf(in, "%f%f", &distancia, &tempo);
velocidade = distancia / tempo;
fprintf(out, "Distancia percorrida: %10.2f km\n", distancia);
fprintf(out, "Tempo decorrido:
%10.2f h\n", tempo);
fprintf(out, "Velocidade media:
%10.2f km/h\n", velocidade);
fclose(in);
fclose(out);
}
50
http://www.ericolisboa.eng.br
8 - Entrada e sada
Linguagem C
Este programa l do arquivo entrada.txt a distncia percorrida e o tempo decorrido. feito o clculo da
velocidade mdia e a sada armazenada num arquivo texto, formatado. As sintaxes de fprintf() e
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
Os dados so armazenados em arquivos binrios da mesma forma que so armazenados na memria do
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);
}
51
http://www.ericolisboa.eng.br
8 - Entrada e sada
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;
}
fread(ch, sizeof(char), 20, in);
fread(valor, sizeof(int), 20, in);
for(i = 0; i < 20; i++)
printf("%c", ch[i]);
for(i = 0; i < 20; i++)
printf("\n%d", valor[i]);
fclose(in);
}
52
http://www.ericolisboa.eng.br
Linguagem C
ANEXO A
TABELA ASCII
A
As tabelas mostradas neste apndice representam os 256 cdigos usados nos computadores da famlia
IBM. Esta tabela refere-se ao American Standard Code for Information Interchange (cdigo padro
americano para troca de informaes), que um conjunto de nmeros representando caracteres ou
instrues de controle usados para troca de informaes entre computadores entre si, entre perifricos
(teclado, monitor, impressora) e outros dispositivos. Estes cdigos tem tamanho de 1 byte com valores
de 00h a FFh (0 a 255 decimal). Podemos dividir estes cdigos em trs conjuntos: controle, padro e
estendido.
Os primeiros 32 cdigos de 00h at 1Fh (0 a 31 decimal), formam o conjunto de controle ASCII.
Estes cdigos so usados para controlar dispositivos, por exemplo uma impressora ou o monitor de
vdeo. O cdigo 0Ch (form feed) recebido por ima impressora gera um avano de uma pgina. O
cdigo 0Dh (carriage return) enviado pelo teclado quando a tecla ENTER pressionada. Embora
exista um padro, alguns poucos dispositivos tratam diferentemente estes cdigos e necessrio
consultar o manual para saber exatamente como o equipamento lida com o cdigo. Em alguns casos o
cdigo tambm pode representar um caracter imprimvel. Por exemplo o cdigo 01h representa o
caracter 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: , , , ...
53
http://www.ericolisboa.eng.br
Linguagem C
Dec.
Hex.
Dec.
Hex.
00h
NUL
(Null)
00h
<espao>
01h
SOH
(Start of Heading)
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
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
Controle
Text)
54
Caractere
http://www.ericolisboa.eng.br
Linguagem C
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.
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
ADh
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.
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
respectivos tamanhos ocupados em memria.
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
B.2 Operadores
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.
58
http://www.ericolisboa.eng.br
Anexo B - Exerccios
Linguagem C
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,
c) taxa de juros cobrada,
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
59
http://www.ericolisboa.eng.br
Anexo B - Exerccios
Linguagem C
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);
}
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:
a) o teatro tem 10 fileiras de cadeiras (A,B, .. J), cada uma com 50 cadeiras.
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.
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);
}
62
http://www.ericolisboa.eng.br
Anexo B - Exerccios
Linguagem C
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.
63
http://www.ericolisboa.eng.br
Anexo B - Exerccios
Linguagem C
Em cada declarao, qual o tamanho (em bytes) do bloco de memria que ser alocado para
armazenar os valores das variveis v?
B.8 Entrada e Sada
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.:
64
http://www.ericolisboa.eng.br
Linguagem C
ANEXO C
EXEMPLOS DE FUNES
C
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.
66
http://www.ericolisboa.eng.br