Você está na página 1de 236

Algoritimos e

Programação II
Vanessa Lindemann

Algoritimos e
Programação II
Introdução

E sta disciplina dá continuidade ao estudo de lógica de programação


iniciado em Algoritmos e Programação I e introduz o aluno no universo
da programação, de forma que no final do semestre ele estará capacitado
a construir programas em linguagem C. Para isso, vamos estudar variáveis
indexadas, estruturas, ponteiros, funções e arquivos.

Só é possível aprender a programar, programando! Portanto, resolver


os exercícios propostos no final de cada capítulo, utilizando um compilador
C, é fundamental para atingir o objetivo desta disciplina. Optou-se por
usar o Dev-C++, que é um ambiente de desenvolvimento integrado, com
enorme potencial para desenvolver programas em linguagem C e C++ no
sistema operacional Windows.

Diante do exposto, sugere-se que o aluno vá direto ao Capítulo 10


para instalar e configurar o Dev-C++ no seu computador. Assim, a cada
capítulo estudado, será possível executar os exemplos e realizar os exercí-
cios propostos. A disciplina possui conteúdos cumulativos, ou seja, no final
do semestre, ainda estaremos utilizando conceitos estudados nas primeiras
semanas de aula. Portanto, é importante organizar o estudo, resolver os
problemas propostos periodicamente e não deixar as dúvidas para depois.

As referências bibliográficas sugerem obras de autores que fundamen-


tam os estudos realizados e oferecem ao aluno possibilidades de aprofun-
damento com leituras complementares.
Sumário

1 Introdução à Linguagem C....................................................5


2 Estruturas Básicas de Controle ............................................35
3 Variáveis Indexadas Unidimensionais ..................................61
4 Strings ................................................................................81
5 Variáveis Indexadas Bidimensionais ..................................101
6 Estruturas .........................................................................122
7 Ponteiros ..........................................................................134
8 Funções ............................................................................144
9 Arquivos ...........................................................................172
10 Dev-C++: instalação e configuração ................................198
Vanessa Lindemann

Capítulo 1

Introdução à Linguagem C

ÂÂ
A
linguagem C, criada por Dennis Ritchie na década
de 70, resultou de um processo evolutivo de lingua-
gens e, durante alguns anos, teve seu padrão baseado
na versão 5 do sistema operacional UNIX. Com a po-
pularização dos microcomputadores, várias versões de C
foram criadas, gerando muitas discrepâncias entre elas.
Para resolver essa situação, em 1983, o ANSI (American
National Standards Institute) estabeleceu um comitê para
definir um padrão que guiasse todas as implementações
da linguagem C.
A popularização da linguagem C deve-se a vários fa-
tores, dentre os quais destacam-se (a) o conjunto de ope-

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
6 Algoritmos e Programação II

radores e tipos de dados disponíveis; (b) a portabilidade,


podendo ser usada em máquinas de portes e de sistemas
operacionais diferentes; (c) as características de lingua-
gens de alto nível, aliadas às características de linguagens
de baixo nível (também conhecidas como linguagem de
máquina, manipulam bits, bytes e endereços).
C é uma linguagem de propósitos gerais, estruturada e
compilada (o compilador lê o código-fonte do programa
inteiro e converte-o em um código executável). Ela é utili-
zada para a construção de sistemas operacionais, compi-
ladores, interpretadores, editores de textos, planilhas ele-
trônicas, aplicativos para dispositivos móveis, programas
para a automação industrial, gerenciadores de bancos de
dados etc.
As próximas seções são dedicadas à apresentação de
conceitos e definições importantes e necessárias para o
início da programação em linguagem C.
Capítulo 1 Introdução à Linguagem C 7

1.1 Estrutura básica de um programa em


linguagem C

Um programa em linguagem C consiste em uma ou mais fun-


ções. A função principal, denominada main, indica onde o
programa inicia. A estrutura básica de um programa em C é
apresentada a seguir.

#include <nome da biblioteca>

main( ) {

// declaração de variáveis

// bloco de comandos

Bibliotecas são arquivos contendo várias funções que po-


dem ser incorporadas aos programas escritos em C (esses ar-
quivos são chamados arquivos de cabeçalho − cabeçalho em
inglês é header, o que explica a extensão .h usada logo
após o nome dos arquivos). A diretiva #include faz com
que as funções inseridas na biblioteca especificada possam ser
utilizadas no programa. As bibliotecas stdio.h e conio.h,
por exemplo, permitem a utilização de funções de entrada
e saída padrão e de funções de tela, respectivamente. São
exemplos de funções de tela, os comandos usados para limpar
a tela, posicionar o cursor em uma determinada posição na
tela, trocar a cor da fonte e/ou do fundo.

A diretiva #include pode ser usada de duas formas:


#include "nome da biblioteca" ou #include
8 Algoritmos e Programação II

<nome da biblioteca>. A diferença entre se usar " " e


< > é somente a ordem de procura pelo arquivo especificado
nos diretórios. Usa-se " " para informar o nome do arquivo
com o caminho completo, ou se o arquivo estiver no diretório
de trabalho. Quando o arquivo estiver no caminho padrão
do compilador (como é o caso de arquivos como stdio.h e
string.h, por exemplo), usa-se os símbolos < e >.

Os parênteses ao lado da palavra main indicam que ela


é uma função, enquanto as chaves delimitam o seu início e
o seu fim. O bloco de comandos que estiver entre as chaves
é executado sequencialmente quando a função for chamada.
Uma boa prática de programação do padrão ANSI é declarar
a função main como int main(void) e, no seu final, an-
tes de fechar a chave que delimita o corpo da função, incluir
a instrução return 0; − essa prática evita que, ao executar
os programas, alguns compiladores emitam uma mensagem
do tipo A função deve retornar um valor. Como o compilador
do Dev-C++, utilizado nesta disciplina, não emite esta men-
sagem, optou-se por não adotar essa prática nos exemplos
deste livro.

É importante salientar que a linguagem C é case sensitive,


ou seja, é sensível a letras maiúsculas e minúsculas (por exem-
plo, uma variável declarada como a é diferente de A) e todos
os programas devem, obrigatoriamente, ser escritos em letras
minúsculas. Outro detalhe importante é que cada instrução
primitiva é finalizada com um ponto-e-vírgula (vale destacar
que não há ponto e vírgula após as diretivas de compilação
#include e #define, nem após as estruturas de controle
apresentadas no próximo capítulo).
Capítulo 1 Introdução à Linguagem C 9

1.2 Identificadores

Em linguagem C, os nomes utilizados para referenciar variá-


veis, constantes e funções definidas pelo usuário são chama-
dos de identificadores.

A criação de um identificador deve seguir as seguintes regras:


podem ser formados por letras, números e sublinhado; devem
iniciar com uma letra ou com o sublinhado; letras minúsculas
e maiúsculas são consideradas caracteres distintos; não podem
ser palavras reservadas; podem conter qualquer tamanho, po-
rém apenas os 32 primeiros caracteres são significativos.

Além disso, é importante criar identificadores consideran-


do a sua aplicação para facilitar a leitura do código-fonte e,
consequentemente, o trabalho do programador. A quantidade
de horas trabalhadas por uma pessoa durante uma semana de
trabalho, por exemplo, pode ser armazenada em uma variável
chamada qtde_horas; enquanto uma função que irá verifi-
car se uma data é válida ou não pode ter como identificador
valida_data.

1.3 Tipos de dados

Os tipos de dados básicos em linguagem C são: int (número


inteiro), float (número real, representado em ponto flutuante),
double (número real, representado em ponto flutuante com
maior precisão), char (caractere) e void (vazio, sem valor). A
linguagem C não possui tipo de dado lógico (que pode assu-
10 Algoritmos e Programação II

mir verdadeiro ou falso), pois considera qualquer valor diferen-


te de 0 (zero) como verdadeiro; e também não possui um tipo
especial para armazenar cadeias de caracteres (strings),
estas são armazenadas em um vetor de caracteres. A Tabela
1.1 apresenta a lista de tipos básicos utilizados em C.

Tipo Faixa de valores Tamanho


char -127 a 127 8 bits
int -32.767 a 32.767 16 bits
float 3.4 E-38 a 3.4 E+38 32 bits
double 1.7 E-308 a 1.7 E+308 64 bits
void vazio, sem valor 0

Tabela 1.1 − Tipos de dados básicos da linguagem C

A faixa de valores apresentada está de acordo com o pa-


drão ANSI, e é considerada a faixa mínima. Dependendo do
processador e do compilador C que estiver sendo utilizado, o
tamanho e a faixa de valores podem variar.

1.4 Modeladores

É possível forçar que o resultado de uma expressão seja de um


tipo específico usando o conceito de modelador. A forma geral
de um modelador é (tipo)expressão onde tipo é um
dos tipos padrão da linguagem C.

Sendo r uma variável declarada do tipo float, as ex-


pressões a seguir resultam em valores diferentes. A primeira
Capítulo 1 Introdução à Linguagem C 11

expressão resulta 4, enquanto que a segunda, com o uso do


modelador, resulta 4.5.

r=9/2;

r=(float)9/2;

1.5 Declaração, inicialização e escopo de


variáveis

Variável é uma posição de memória, identificada por um nome


(identificador), usada para armazenar um dado de um deter-
minado tipo por vez. As variáveis são declaradas após a espe-
cificação de seus tipos, como pode ser observado nos exem-
plos a seguir.

float total;

int idade, cont;

A primeira linha da declaração de variáveis do exemplo


cria uma variável chamada total, que irá armazenar valores
do tipo real; na segunda linha, são criadas duas variáveis para
armazenar valores do tipo inteiro, idade e cont. Cada uma
dessas variáveis armazenará um único valor por vez.

As variáveis podem ser inicializadas no momento da sua


declaração, colocando o sinal de atribuição seguido da in-
formação desejada, como no exemplo apresentado a seguir,
em que cont é inicializada com 0 e resposta com S. É im-
12 Algoritmos e Programação II

portante destacar que os dados atribuídos a variáveis do tipo


caractere são envolvidos por apóstrofes.

int cont=0;

char resposta='S';

O local em que as variáveis são declaradas definem o seu


escopo, que pode ser global ou local. As variáveis de escopo
global, denominadas variáveis globais, são declaradas fora de
qualquer função, inicializadas automaticamente com 0 (zero)
e podem ser usadas em qualquer ponto do programa. As va-
riáveis locais são declaradas dentro de uma função, não são
inicializadas automaticamente e valem enquanto essa função
estiver ativa. As variáveis de escopo local têm preferência em
relação às de escopo global.

1.6 Definição de constantes

Uma constante irá representar um valor fixo, previamente


definido pelo programador e inalterável no programa. Uma
das formas de definir constantes em C é a partir da diretiva
#define, seguida do nome da constante e do valor que esta
representará no programa. No exemplo a seguir, apresenta-
-se a declaração da constante pi cujo valor é definido como
3.141516. Dessa forma, o programador usará pi no progra-
ma ao invés de usar 3.141516.

#define pi 3.141516
Capítulo 1 Introdução à Linguagem C 13

1.7 Códigos de formato

Os códigos de formato são constantes que definem o formato


dos dados a serem lidos e exibidos na tela. A Tabela 1.2 apre-
senta alguns dos códigos de formato disponíveis em C.

Código Formato
%c Caractere
%i Inteiro
%f Ponto flutuante
%lf Ponto flutuante longo (double)
%s Cadeia de caracteres (string)

Tabela 1.2 − Códigos de formatação

Eles são usados em funções de entrada e de saída de da-


dos (descritas na seção 1.12). A função de entrada scanf,
por exemplo, possui dois argumentos: o código de formato e
uma variável. No exemplo apresentado a seguir, o valor digi-
tado pelo usuário será armazenado na variável denominada
peso, declarada e formatada como float.

scanf("%f",&peso);

A função printf, exemplificada a seguir, também contém


dois argumentos: o primeiro é uma mensagem, apresentada
entre aspas; o segundo é uma variável, denominada dias. O
valor armazenado na variável dias será exibido na posição
em que aparece o código de formato usado na mensagem,
nesse caso o %i.
14 Algoritmos e Programação II

printf("Sua idade em dias e: %i", dias);

Os códigos de formato podem ter modificadores que espe-


cifiquem o tamanho do campo, o número de casas decimais e
um indicador de justificação à esquerda.

Especificador de largura mínima do campo: um valor


entre o símbolo % e o caractere de formato indica a largura
mínima do campo, preenchendo a saída com brancos (pa-
drão) ou com zeros (coloca-se um 0 antes do especificador de
tamanho). Quando um valor é maior que o mínimo definido,
este será impresso por completo. Exemplos: %05d preencherá
um número com menos de cinco dígitos com zeros à esquerda,
de maneira que seu tamanho total seja cinco.

Especificador do número de casas decimais: para defi-


nir o número de casas decimais a serem exibidas em um ponto
flutuante, usa-se um ponto entre o especificador de tamanho e
o número de casas decimais desejadas. Por exemplo: %6.2f
exibirá um valor com, no mínimo, seis dígitos de comprimento
no total, com duas casas decimais (o ponto usado antes das
casas decimais ocupa o espaço de um dígito, como pode ser
observado nos exemplos apresentados na Tabela 1.3).

Especificador para justificar informação à esquerda:


por definição, toda saída é justificada à direita. O uso do
sinal – depois do % faz com que a saída seja justificada à
esquerda. Exemplo: %-6.2f justificará à esquerda um valor
de ponto flutuante, com no mínimo seis dígitos no total, com
duas casas decimais.
Capítulo 1 Introdução à Linguagem C 15

A Tabela 1.3 apresenta exemplos da utilização dos especi-


ficadores de tipos. O caractere especial \n, usado nos exem-
plos, inicia uma nova linha antes de exibir o valor na tela.

Código Resultado
float valor=136.472;

printf("\n %f",valor); 136.472000


printf("\n %8.1f",valor); 136.5
printf("\n %08.1f",valor); 000136.5
printf("\n %-8.1f",valor); 136.5
int valor=790;

printf("\n %i",valor); 790


printf("\n %5i",valor); 790
printf("\n %05i",valor); 00790
printf("\n %-5i",valor); 790

printf("\n O total é %2i.",350); O total é 350.


printf("\n O total é %4i.",350); O total é 350.
printf("\n O total é %5i.",350); O total é 350.

Tabela 1.3 − Exemplo da utilização dos especificadores de tipos

1.8 Caracteres especiais

Os caracteres especiais são usados para representar alguma


formatação em particular e caracteres especiais que seriam
impossíveis de usar diretamente no código-fonte. Esses carac-
16 Algoritmos e Programação II

teres devem ser precedidos da barra invertida, como o \n que


representa nova linha. A Tabela 1.4 apresenta os caracteres e
seus significados.
Código Significado Código Significado
\a alerta (beep) \v tab vertical
\b retrocesso (backspace) \\ exibe barra invertida
\f avanço de página \’ exibe aspa única
\n nova linha \“ exibe aspas duplas
\r retorna ao início da linha \? exibe ponto de interrogação
\t tab horizontal \0 nulo

Tabela 1.4 Códigos de caracteres especiais

1.9 Comando de atribuição

O comando de atribuição, representado pelo sinal de igual-


dade, é utilizado para atribuir valores a variáveis. É importante
lembrar que os valores atribuídos a uma variável devem ser
compatíveis com o seu tipo. Alguns exemplos de atribuição
podem ser observados a seguir.

total=345.60;

resp='s';

cont=cont+1;

Os caracteres são representados entre apóstrofes ( ' ) e as


cadeias de caracteres entre aspas ( " ). Entretanto, caso seja
necessário atribuir uma cadeia de caracteres a uma variável,
utiliza-se a função strcpy, como ilustra o exemplo a seguir.

strcpy(nome,“Ana Paula Rocha”);


Capítulo 1 Introdução à Linguagem C 17

Para utilizar strcpy (abreviação de string copy) é preciso


inserir no programa, a partir da diretiva #include, a biblio-
teca string.h. Essa e outras funções para manipulação de
strings serão descritas no capítulo 4.

É possível atribuir um valor a duas ou mais variáveis a partir


de um único comando, como na instrução primitiva x=y=10,
em que as variáveis x e y recebem 10.

1.10 Operadores e funções

A linguagem C possui operadores e funções predefinidas des-


tinadas a cálculos matemáticos e à manipulação de caracte-
res. Os operadores aritméticos e relacionais são apresenta-
dos nas Tabelas 1.5 e 1.6, respectivamente. Os operadores
lógicos são apresentados na Tabela 1.7 e os operadores re-
duzidos na Tabela 1.8.

Operador Exemplo Descrição


+ a + b Soma o conteúdo de a e de b.
- a – b Subtrai o conteúdo de b do conteúdo de a.
* a * b Multiplica o conteúdo de a pelo conteúdo de b.
/ a / b Divide o conteúdo de a pelo conteúdo de b.
% a % b Obtém o resto da divisão de a por b.*

Tabela 1.5 − Operadores aritméticos


* O operador % só pode ser utilizado com operandos do tipo inteiro.
18 Algoritmos e Programação II

Operador Exemplo Descrição


== a==b Testa se o conteúdo de a é igual ao conteúdo de b.
!= a!=b Testa se o conteúdo de a é diferente do conteúdo de b.
<= a<=b Testa se o conteúdo de a é menor ou igual que o
conteúdo de b.
>= a>=b Testa se o conteúdo de a é maior ou igual que o
conteúdo de b.
< a<b Testa se o conteúdo de a é menor que o conteúdo de b.
> a>b Testa se o conteúdo de a é maior que o conteúdo de b.

Tabela 1.6 − Operadores relacionais

Operador Símbolo Descrição


e && Conjunção
ou || Disjunção
não ! Negação
Tabela 1.7 − Operadores lógicos

Expressão Equivalente com operadores reduzidos


total=total+valor; total+=valor;
num=num*5; num*=5;
d=d-valor; d-=valor;
x=x/5; x/=5;

Tabela 1.8 − Operadores reduzidos

Além dos operadores apresentados anteriormente, a lin-


guagem C disponibiliza operadores de pré e pós incremento e
decremento, descritos na Tabela 1.9.
Capítulo 1 Introdução à Linguagem C 19

Operador Descrição Pré-fixado Pós-fixado


++ Incrementa ++n n++
-- Decrementa --n n--

Tabela 1.9 − Operadores pré e pós-fixado

O operador ++ incrementa um ao valor do seu operando,


enquanto –- decrementa um. Esses operadores podem ser
usados antes (pré-fixados) ou depois (pós-fixados) do nome
da variável. Em ambos os casos a variável é incrementada ou
decrementada. Entretanto, ++n incrementa o valor da variá-
vel n antes que n seja usada e n++ usa o valor de n e depois
o incrementa.

Resumindo:

++i → incrementa o valor de i em um e depois o utiliza;

i++ → utiliza o valor de i e depois incrementa-o em um.

Logo, conclui-se que:

z=a; a=a+1; é equivalente a z=a++;

z=a; a=a-1; é equivalente a z=a--;

a=a+1; z=a; é equivalente a z=++a;

a=a-1; z=a; é equivalente a z=--a;


20 Algoritmos e Programação II

1.11 Comentários

Os comentários são textos que podem ser inseridos no pro-


grama com o objetivo de documentá-lo e não são analisados
pelo compilador. Os comentários de uma linha são precedi-
dos do símbolo //, enquanto o comentário de várias linhas
é envolvido por /* e */, conforme pode ser observado nos
exemplos a seguir.

// Este é um comentário de uma linha.

/* Este é um comentário

com mais de uma linha. */

1.12 Funções de entrada e saída de dados

As funções de entrada e saída de dados garantem a comuni-


cação do programa com o usuário e/ou outros dispositivos.
Nesta seção, serão abordadas apenas algumas funções de
entrada e saída de dados necessárias para prover a comuni-
cação do usuário com o programa, considerando o teclado
como periférico de entrada e a tela como periférico de saída.

As funções de saída de dados são utilizadas para exibir da-


dos na tela, seja uma mensagem, o resultado de uma expres-
são ou o conteúdo armazenado em uma variável. A função
de saída mais utilizada em C para este fim é a printf, cuja
sintaxe é apresentada a seguir.
Capítulo 1 Introdução à Linguagem C 21

printf(<string de controle>,<lista de argu-


mentos>);

A string de controle possui uma descrição de tudo que a


função vai exibir na tela, incluindo não apenas a mensagem,
mas também o formato de variáveis e/ou resultado de expres-
sões e suas respectivas posições nessa mensagem. Isso é feito
por meio do uso dos códigos de formatação vistos na Tabela
1.2. Para cada código de formatação incluído na mensagem,
é necessário ter um argumento na lista de argumentos, confor-
me ilustram os exemplos do Quadro 1.1.

Variáveis Exemplos de função de saída


float media; 01 printf("%.1f",media);
char nome[60]; 02 printf("Digite o nome do aluno: ");
03 printf("Média final = %.1f",media);
04 printf("%s obteve média
%.1f",nome,media);

Quadro 1.1 − Exemplos da sintaxe da função printf

No exemplo 01 do Quadro 1.1, a função printf possui


a string de controle onde aparece o código de formatação
%.1f e a variável media como argumento. Nesse caso, o
comando de saída exibirá apenas o valor armazenado na va-
riável media, formatado a partir do código de formato %.1f.
O código de formato %f indica que será exibido um valor do
tipo float, e o modificador .1 define que esse valor será
exibido com uma casa decimal. Se a variável media estiver
armazenando 8, por exemplo, o valor será exibido como 8.0.
22 Algoritmos e Programação II

No segundo exemplo, o comando de saída contém apenas


um literal na string de controle, que será reproduzido no dis-
positivo de saída.

No exemplo 03, a string de controle contém um literal e um


código de formatação ("Média final = %.1f") e a lista
de argumentos possui uma variável (media), resultando em
Média final = 9.3 (considerando que a variável media esteja
armazenando 9.333). O valor armazenado na variável media
é exibido na posição em que aparece o código de formato
%.1f, considerando apenas a primeira casa decimal.

Por fim, supondo que a variável nome armazene Joana e


a variável media armazene 5.77, a saída do exemplo 04 se-
ria Joana obteve média 5.8 (o valor 5.77 será arredondado
para 5.8). Nesse caso, a string de controle da função printf
contém um literal com dois códigos de formato (%s e %.1f)
e, consequentemente, a lista de argumentos possui duas vari-
áveis (nome e media). Essas variáveis devem ser listadas na
mesma ordem em que seus respectivos códigos de formato
aparecem na string de controle.

As funções de entrada de dados são utilizadas para receber


dados digitados pelo usuário. Os dados recebidos são arma-
zenados em variáveis já declaradas no programa. As funções
de entrada mais utilizadas em C são scanf, getch, getche
e fgets. Em geral, a função scanf é utilizada para ler dados
numéricos, as funções getch e getche para ler um único
caractere por vez e a função fgets para ler cadeias de carac-
teres (strings). A sintaxe dessas funções é apresentada a seguir.
Capítulo 1 Introdução à Linguagem C 23

scanf(<string de controle>,<lista de
argumentos>);

<variável> = getch();

<variável> = getche();

fgets(<variável>,<tamanho máximo da
variável>,stdin);

Na função scanf, a string de controle irá indicar o for-


mato dos dados a serem armazenados nas variáveis contidas
na lista de argumentos. Isso é feito a partir do uso dos códi-
gos de formatação vistos na Tabela 1.2. Para cada código
de formatação incluído na string de controle, é necessário ter
uma variável na lista de argumentos, precedida do símbolo
&, conforme ilustram os exemplos do Quadro 1.2. O símbolo
&, chamado operador de endereço, associa a variável a um
endereço de memória.

Variáveis Exemplos de função de entrada


float peso; 01 scanf("%f",&peso);
int idade; 02 scanf("%i",&idade);

Quadro 1.2 Exemplos da sintaxe da função scanf

No exemplo 01 do Quadro 1.2, a função scanf possui a


string de controle onde aparece o código de formatação %f e
o endereço da variável peso como argumento. Nesse caso,
o comando de entrada fará a leitura do valor digitado pelo
usuário e armazenará na variável peso. O código de formato
24 Algoritmos e Programação II

%f indica que será armazenado um valor do tipo float. O


segundo exemplo faz a leitura da variável idade, que é do
tipo int.

As funções getch e getche retornam um caractere. Nos


exemplos apresentados no Quadro 1.3, a variável letra re-
ceberá o caractere digitado pelo usuário. A diferença entre os
exemplos é que a função getche, além de capturar o carac-
tere digitado, o escreve na tela. Em ambos os casos, o usuário
não terá que teclar <ENTER> depois de digitar o caractere.

Variáveis Exemplos de função de entrada


char letra; 01 letra=getch();
02 letra=getche();

Quadro 1.3 − Exemplos da sintaxe das funções getch e getche

A função fgets é usada para ler uma cadeia de caracte-


res, ou seja, uma string. Ela possui três argumentos: o primeiro
argumento é a variável que irá armazenar a string digitada
pelo usuário; o segundo indica o tamanho máximo da string;
e o terceiro, nesse caso o stdin, indica que a entrada de da-
dos será realizada via teclado (std = standard + in = input, ou
seja, entrada padrão). Os exemplos apresentados no Quadro
1.4 ilustram o uso da função fgets.
Capítulo 1 Introdução à Linguagem C 25

Variáveis Exemplos de função de entrada


char fone[15]; 01 fflush(stdin);
char nome[60]; fgets(fone,15,stdin);
02 fflush(stdin);
fgets(nome,60,stdin);

Quadro 1.4 − Exemplos da sintaxe da função fgets

Como pode ser observado nos exemplos do Quadro 1.4,


a função fflush é usada antes da função fgets, com o
objetivo de liberar o buffer do teclado. O primeiro exemplo
lê a variável fone, que terá no máximo 14 caracteres, en-
quanto o exemplo 02 lê a variável nome, que terá no máximo
59 caracteres. Ao definir o tamanho máximo de uma string,
é preciso considerar que o espaço de um dos seus caracteres
será reservado para o \0 (caractere nulo), necessário para in-
dicar seu final. Mais detalhes sobre essa função, bem como
outras funções específicas para a manipulação de strings, se-
rão abordados no capítulo 4.

As funções printf, scanf e fgets pertencem à biblio-


teca stdio.h, enquanto as funções getch e getche fazem
parte da biblioteca conio.h.

1.13 Funções de tela

A Tabela 1.10 apresenta algumas funções de tela, utilizadas


para organizar a interface do programa com o usuário. Essas
funções fazem parte da biblioteca conio.h.
26 Algoritmos e Programação II

Sintaxe da função Descrição

Limpa a tela e posiciona o cursor no


clrscr()
canto superior esquerdo.
clreol() Limpa a linha.

Posiciona o cursor na coluna e linha


gotoxy(col,lin) determinadas (a tela padrão possui 80
colunas e 25 linhas).

textcolor(cor) Seleciona a cor do texto.

Seleciona a cor do fundo da tela


(para que todo o fundo fique da cor
textbackground(cor)
selecionada, deve-se utilizar a função
para limpar a tela logo após esta).

Exclui a linha em que o cursor está


posicionado, movendo todas as linhas
delline()
que estiverem abaixo desta, uma
posição para cima.
Insere uma linha na posição em que o
cursor está posicionado, movendo todas
insline()
as linhas que estiverem abaixo desta,
uma posição para baixo.

Tabela 1.10 − Funções de tela

A lista de cores básicas, disponíveis para serem utilizadas


nas funções textcolor e textbackground é exibida na
Tabela 1.11. É possível utilizar tanto o código da cor, quanto
seu nome em inglês, como parâmetro das funções. Exemplos:
textcolor(4) ou textcolor(RED). Nos dois exemplos,
a cor selecionada para o texto é a mesma, o vermelho.
Capítulo 1 Introdução à Linguagem C 27

Código Cor Código Cor Código Cor


0 Preto 6 Marrom 12 Alaranjado
1 Azul 7 Cinza claro 13 Magenta claro
2 Verde 8 Cinza escuro 14 Amarelo
3 Ciano 9 Azul claro 15 Branco
4 Vermelho 10 Verde claro
5 Magenta 11 Ciano claro

Tabela 1.11 − Lista de cores

1.14 Exemplo do uso das funções de


entrada e saída e de tela

A Figura 1.1 apresenta um programa que lê duas notas forne-


cidas pelo usuário, calcula e escreve a média entre elas. Nesse
exemplo, é possível observar o uso de vários dos conceitos e
funções estudados neste capítulo.
28 Algoritmos e Programação II

Figura 1.1 − Exemplo do uso das funções de tela, entrada e saída

Na linha 2, um comentário foi usado para descrever o pro-


blema que o programa resolve. Em seguida, nas linhas 4 e 5,
são listadas as bibliotecas necessárias para executar as fun-
ções utilizadas na solução do problema. A função principal
(main) aparece entre as linhas 7 e 23. No início da função,
tem-se a declaração de variáveis de escopo local (todas do
tipo float), seguida das funções que selecionam a cor do
texto e do fundo de tela, e do comando de limpar a tela. A
função gotoxy é utilizada várias vezes, antes das funções de
saída, para posicionar as mensagens em determinadas posi-
Capítulo 1 Introdução à Linguagem C 29

ções da tela. No final do programa, usa-se o getch para que,


ao executar, o programa mantenha a tela de exibição dos re-
sultados até que o usuário digite qualquer tecla para retornar
à tela de edição do compilador.

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) A sintaxe da declaração de uma variável em C inclui o nome


da variável seguido de um tipo.
a) Certo b) Errado
30 Algoritmos e Programação II

2) São nomes válidos para variáveis na linguagem C:


a) if, a*b_2, H789, &ya

b) A, b, Y, count

c) 9xy, a36, x*y, --j

d) 2_ou_1, \fim, h, j

e) i, j, int, obs

3) Em C, os nomes cont e Cont não podem ser emprega-


dos para representar a mesma variável ao longo de um
programa.
a) Certo b) Errado

4) Uma string é uma sequência de caracteres armazenada em


um vetor de caracteres.
a) Certo b) Errado

5) O que faz o seguinte programa em C ?

#include <stdio.h>
main( ){
int i=2;
printf("Valor de i = %i\n",i);
}
Capítulo 1 Introdução à Linguagem C 31

a) imprime: Valor de i = 2 e pula para a próxima linha;

b) imprime: Valor de i = 2\n;

c) pula para a próxima linha e imprime: Valor de i = 2;

d) imprime: Valor de i = 2;

e) nenhuma das alternativas anteriores.

6) Qual o resultado das variáveis j, k e l depois da seguinte


sequência de operações?
int j,k,l; j=k=10; l=++j; j=-j; k++;
j=j+k-l--;

a) j = -10, k = 10, l = 10

b) j = -11, k = 11, l = 10

c) j = -10, k = 11, l = 10

d) j = 11, k= 11, l = 11

e) nenhuma das alternativas anteriores

7) Na Linguagem C, os códigos de formatação de tipo de


dados NÃO estão corretamente associados na alternativa:
a) int - %i

b) double - %d

c) float - %f
32 Algoritmos e Programação II

d) char - %c

e) nenhuma das respostas anteriores

Parte II - Resolução de problemas

Resolva os problemas descritos a seguir, utilizando a Lin-


guagem C.

1) O custo final de um carro novo para o consumidor é a soma


do custo de fábrica, dos impostos e da porcentagem do
distribuidor. Supondo que os impostos totalizam 45% so-
bre o custo de fábrica e a porcentagem do distribuidor seja
de 20% sobre o valor total, escreva um programa que leia
o custo de fábrica de um carro, calcule e escreva o custo
final ao consumidor.

2) Sabe-se que, para iluminar de maneira correta os cômodos


de uma casa, para cada m2, deve-se usar 18W de potên-
cia. Faça um programa que receba as duas dimensões de
um cômodo (em metros), calcule e apresente a sua área (em
m2) e a potência de iluminação que deverá ser utilizada.

3) Uma empresa que promove espetáculos teatrais precisa de


um programa para definir o valor mínimo para o convite,
considerando o custo total do espetáculo e o número de lu-
gares disponíveis para o público no local da apresentação.

4) Sabe-se que:
1 pé = 12 polegadas;
Capítulo 1 Introdução à Linguagem C 33

1 jarda = 3 pés;

1 milha = 1760 jardas.

Faça um programa que receba uma medida em pés, faça


as conversões conforme a descrição acima e mostre os re-
sultados em polegadas, jardas e milhas.

5) Considerando uma aplicação de P reais à taxa de juros i


constante por um período de N meses, calcule e escreva
qual será o montante M após o término da aplicação, sen-
do M = P * (1 + i) N.

Respostas dos exercícios da Parte I


1) b; 2) b; 3) a; 4) a; 5) a; 6) b; 7) b.
Vanessa Lindemann

Capítulo 2

Estruturas Básicas de
Controle

ÂÂ
A o criar um programa, tem-se como objetivo a solução
de um determinado problema. Para que esse proble-
ma seja resolvido, as instruções primitivas devem estar or-
ganizadas de forma a representar um conjunto de ações,
que seguirá um fluxo de execução determinado por três
estruturas básicas de controle: sequencial, condicional e
repetitiva - temas abordados nas próximas seções.

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
Capítulo 2 Estruturas Básicas de Controle 35

2.1 Estrutura sequencial

A estrutura sequencial contém um conjunto de instruções que


serão executadas de forma linear, de cima para baixo, da es-
querda para a direita, sem nenhum desvio entre os símbolos
de início e fim do programa.

Figura 2.1 Exemplo da estrutura de controle sequencial


36 Algoritmos e Programação II

A Figura 2.1 apresenta um programa que calcula o salário


de um funcionário, cuja estrutura é sequencial. O programa
inicia com um comentário, que descreve o problema a ser re-
solvido, seguido da lista de bibliotecas necessárias. A função
principal (main) vai da linha 6 à 27, onde são declaradas as
variáveis (linhas 7, 8 e 9), ocorre a entrada de dados (entre
as linhas 12 e 17), o processamento (linhas 18, 19 e 20) e a
saída de dados (entre as linhas 22 e 25). Essas instruções são
executadas sequencialmente, do início ao final do programa,
sem nenhum desvio.

2.2 Estrutura condicional

A estrutura condicional é utilizada para desviar o fluxo de exe-


cução do algoritmo para diferentes partes da solução. Tam-
bém chamada de estrutura de seleção, ela divide-se em estru-
tura SE e estrutura ESCOLHA.

A estrutura SE é mais flexível, podendo utilizar na sua con-


dição todos os operadores relacionais (<, >, <=, >=, =,
<>) e, quando forem necessárias, mais de uma condição
com os operadores lógicos (E e OU) entre elas. Essa estrutura
também é classificada como estrutura condicional SE simples,
composta ou encadeada.

A sintaxe da estrutura condicional SE simples, em lingua-


gem C, é apresentada a seguir.

if(<condição ou lista de condições>)


Capítulo 2 Estruturas Básicas de Controle 37

<instrução ou bloco de instruções>

A condição é avaliada e, se retornar zero, que nessa si-


tuação em C significa falso, a instrução não será executada.
Quando resultar qualquer valor diferente de zero, que em C
nessa situação é considerado verdadeiro, a instrução será exe-
cutada. Essa estrutura pode conter mais de uma condição com
operadores lógicos entre elas e, também, pode conter um blo-
co de instruções a ser executado, ao invés de uma instrução
única. Vale lembrar que um bloco é composto por duas ou
mais instruções, delimitado por início e fim (em C, representa-
dos pelos símbolos { e }). O Quadro 2.1 apresenta três exem-
plos da estrutura condicional SE simples em linguagem C.

Com instrução única Com bloco de instruções Mais de uma condição e bloco
if(a>b) if(a>b){ if(a>b && a<>0 &&
b<>0){
printf("%i",a); a=a-b;

printf("%i",a);
a=a/b;
}
printf("%i",a);

Quadro 2.1 − Exemplos da sintaxe da estrutura condicional SE simples em C

A sintaxe da estrutura condicional SE composta, em lingua-


gem C, pode ser observada a seguir.

if(<condição ou lista de condições>)

<instrução ou bloco de instruções>


38 Algoritmos e Programação II

else

<instrução ou bloco de instruções>

Quando a condição avaliada resultar qualquer valor di-


ferente de zero, a instrução da cláusula if será executada;
caso contrário, quando resultar zero, é a instrução da cláusula
else que será executada.

O Quadro 2.2 exemplifica a utilização da estrutura condi-


cional SE composta em linguagem C. O programa apresenta-
do lê um valor inteiro e verifica se ele é par ou ímpar. Na colu-
na da esquerda, a solução aparece em português estruturado,
enquanto a coluna da direita apresenta a mesma solução em
linguagem C.
Capítulo 2 Estruturas Básicas de Controle 39

Problema: ler um valor do tipo inteiro e verificar se ele é par ou ímpar.


Português estruturado – SE Linguagem C - if
#include <stdio.h>
#include <conio.h>

algoritmo exemplo main() {


variáveis
valor: inteiro int valor;

início
clrscr();
gotoxy(10,10);
escrever("Digite um valor: ") printf("Digite um valor:
ler(valor) ");
scanf("%i",&valor);

se(valor mod 2 = 0)então gotoxy(10,14);

escrever(valor," é par.") if(valor%2==0)

senão printf("%i é par.",


valor);
escrever(valor," é ímpar.")
else
printf("%i é ímpar.",
valor);
fim

getch();
}

Quadro 2.2 − Exemplo da estrutura de controle condicional SE

Outro exemplo do uso da estrutura condicional SE com-


posta pode ser observado na Figura 2.2, onde o programa lê
duas notas, calcula a média do aluno e emite uma mensagem
de aprovado ou reprovado.
40 Algoritmos e Programação II

Figura 2.2 − Exemplo da estrutura de controle condicional SE


composta, em linguagem C

A aplicação da estrutura condicional SE encadeada, cuja


sintaxe em linguagem C é apresentada a seguir, pode ser ob-
servada na Figura 2.3 que verifica se um valor digitado pelo
usuário é positivo, negativo ou nulo.

if(<condição ou lista de condições>)

<instrução ou bloco de instruções>

else
Capítulo 2 Estruturas Básicas de Controle 41

if(<condição ou lista de condições>)

<instrução ou bloco de instruções>

else

<instrução ou bloco de instruções>

Figura 2.3 − Exemplo da estrutura de controle condicional SE


encadeada, em linguagem C

Em situações de igualdade para uma mesma variável, em


que é necessário comparar a variável com vários valores, utiliza-
-se a estrutura condicional SE encandeada (por exemplo, com-
parar uma variável op com as quatro operações básicas + - * e
/). Nesse caso, tem-se uma seleção de múltipla escolha.
42 Algoritmos e Programação II

O uso da estrutura condicional ESCOLHA, apresentado a


seguir, pode simplificar bastante a "cascata" de estruturas SE
necessária nessas situações. A estrutura ESCOLHA pode ser
utilizada nesses casos desde que a variável avaliada seja do
tipo inteiro ou caractere. A sintaxe da estrutura condicional
ESCOLHA, em linguagem C, é apresentada a seguir.

switch(<variável>){

case <1>: <instruções> break;

case <2>: <instruções> break;

case <n>: <instruções> break;

default: <instruções>

Se a variável avaliada tiver um dos valores listados nas op-


ções, as instruções correspondentes ao respectivo case serão
executadas. Quando a variável for diferente de todas as op-
ções listadas, a instrução (ou bloco de instruções) da cláusula
default será executada. A cláusula default é opcional
nessa estrutura. No final de cada case, aparece o break,
usado para encerrar a execução da estrutura condicional.

Para demonstrar a aplicação da estrutura condicional ES-


COLHA em linguagem C, o Quadro 2.3 apresenta um exem-
plo que executa as operações básicas de uma calculadora. Na
coluna da esquerda, a solução aparece em português estrutu-
rado e na da direita em linguagem C.
Capítulo 2 Estruturas Básicas de Controle 43

Problema: construir uma calculadora que contenha as operações: +, - , * e /.


Português estruturado - ESCOLHA Linguagem C - switch
#include <stdio.h>
#include <conio.h>

algoritmo exemplo main(){


variáveis
valor1,valor2,r: real float valor1,valor2, r;
operador: caractere char operador;
início
clrscr();
gotoxy(10,5);
escrever("Digite o 1º valor: ") printf("Digite o primeiro
ler(valor1) valor:");
scanf("%f",&valor1);
escrever("Digite o operador: ") gotoxy(10,8);
ler(operador) printf("Digite o operador: ");
gotoxy(29,8); operador=getc
escrever("Digite o 2º valor: ") he();
ler(valor2) gotoxy(10,11);
escolha(operador) printf("Digite o segundo valor:
caso "+": r valor1+valor2 ");
caso "-": r valor1-valor2 scanf("%f",&valor2);
caso "*": r valor1*valor2 switch(operador){
caso "/": se(valor2<>0)então case'+': r=valor1+valor2;
r valor1/valor2 break;
senão case'-': r=valor1-valor2;
r 0 break;
case'*': r=valor1*valor2;
senão break;
início case'/': if(valor2!=0)
escrever("Operador r = valor1 /
inválido") valor2;
r 0 else
fim r = 0;
fim break;
escrever ("Resultado = ", r) default: gotoxy(10,15);
fim printf("Operador
inválido!");
r=0;
}

gotoxy(10,18);
printf("Resultado = %3.2f",
r);
getch();
}

Quadro 2.3 − Exemplo da estrutura de controle condicional ESCOLHA, em


linguagem C
44 Algoritmos e Programação II

Outro exemplo do uso da estrutura condicional ESCOLHA


pode ser observado na Figura 2.4. Neste exemplo, o usuário
digita o código de um produto e a quantidade adquiria e o
programa calcula o total a pagar.

Figura 2.4 − Exemplo da estrutura de controle condicional ESCOLHA,


em linguagem C
Capítulo 2 Estruturas Básicas de Controle 45

2.3 Estrutura de repetição

Enquanto as estruturas condicionais, estudadas na seção ante-


rior, têm como objetivo escolher entre diferentes fluxos de exe-
cução a partir da avaliação de uma expressão, as estruturas
de repetição possibilitam que uma ou mais instruções sejam
executadas mais de uma vez no programa.

As estruturas de controle de repetição dividem-se em EN-


QUANTO, REPITA/ATÉ e PARA. Elas diferenciam-se em relação
ao momento em que a condição de interrupção será avaliada,
que pode ser antes ou depois da primeira iteração.

A estrutura de controle de repetição ENQUANTO permi-


te executar uma ou mais instruções repetidamente enquanto
sua condição de interrupção resultar verdadeiro. A sintaxe da
estrutura de repetição ENQUANTO, em linguagem C, é apre-
sentada a seguir.

while(<condição>)

<instrução ou bloco de instruções>

Como pode ser observado, a condição de interrupção é


verificada antes da execução da instrução ou bloco de instru-
ções a ser repetido. Se o resultado dessa condição for dife-
rente de zero (que, em linguagem C, significa verdadeiro), a
instrução ou bloco de instruções é executado e, logo após essa
iteração, o fluxo de execução retorna para o início da estrutura
while e a condição de interrupção é avaliada novamente.
Esse processo é repetido até que a condição avaliada resulte
zero (ou seja, falso em linguagem C). Nesse caso, o fluxo de
46 Algoritmos e Programação II

execução do programa continuará a partir da instrução ime-


diatamente após à estrutura while. Vale destacar que, como
a condição de interrupção é avaliada no início da estrutura de
controle, quando esta resultar zero na primeira vez em que for
verificada, a instrução ou bloco de instruções da estrutura não
será executado nenhuma vez.

Ao contrário da estrutura ENQUANTO, a condição de in-


terrupção da estrutura REPITA/ATÉ é verificada no final de cada
iteração. Em linguagem C, a sintaxe da estrutura de repetição
equivalente à estrutura REPITA/ATÉ, considerando o fato de
que a condição de interrupção é avaliada no final de cada
iteração, é apresentada a seguir.

do{

<instrução ou bloco de instruções>

} while(<condição>)

Uma ou mais instruções serão executadas repetidamente


enquanto a condição de interrupção da estrutura resultar ver-
dadeiro (em linguagem C, verdadeiro significa qualquer valor
diferente de zero). Como a condição só é avaliada no final de
cada iteração, a instrução ou bloco de instruções a ser repeti-
do será executado pelo menos uma vez, independente do valor
inicial da condição de interrupção. Depois de cada iteração,
se o resultado da condição for verdadeiro, o fluxo de execução
retorna para o início da estrutura. Esse processo é repetido
enquanto a condição de interrupção resultar verdadeiro.
Capítulo 2 Estruturas Básicas de Controle 47

A estrutura de repetição PARA, diferente das anteriores, é


controlada por uma variável de controle, como pode ser ob-
servado na sintaxe apresentada a seguir, em linguagem C.

for(v=vi;v<vf;v++)

<instrução ou bloco de instruções>

Onde: v representa a variável de controle; vi indica o valor


inicial da variável de controle; vf indica o valor final da variável
de controle; e v++ indica que a variável será incrementada
em um a cada iteração.

As estruturas de controle de repetição são exemplificadas


nos quadros a seguir. Para facilitar o entendimento, a coluna
da esquerda dos Quadros 2.4, 2.5 e 2.6 apresenta a solução
em português estruturado e a da direita em linguagem C.
48 Algoritmos e Programação II

Problema: ler 10 valores do tipo inteiro, calcular e escrever a média desses valores.
Português estruturado – ENQUANTO Linguagem C – while
#include <stdio.h>
#include <conio.h>

algoritmo exemplo main() {


variáveis
valor, soma, cont: inteiro int valor, soma, cont;
media: real float media;
início
cont 0 cont = 0;
soma 0 soma = 0;
enquanto(cont<10)faça while(cont<10)
início {
clrscr();
gotoxy(10,10);
escrever("Digite um printf("Digite um valor:
valor:") ");
ler(valor) scanf("%i",&valor);
cont cont + 1 cont = cont + 1;
soma soma + valor soma = soma + valor;
fim }
media soma / 10 media = soma / 10;
gotoxy(10,14);
escrever("Média = ", media) printf("Media = %.2f",
media);
fim getch();
}

Quadro 2.4 − Exemplo da estrutura de controle de repetição ENQUANTO


Capítulo 2 Estruturas Básicas de Controle 49

Problema: ler 25 valores, calcular e escrever o percentual de valores negativos.


Português estruturado – REPITA Linguagem C – do while
#include <stdio.h>
#include <conio.h>

algoritmo exemplo main() {


variáveis
cont: inteiro int cont;
valor, negativo, perc: real float valor, negativo, perc;
início
cont 0 cont = 0;
negativo 0 negativo = 0;
repita do{
clrscr();
gotoxy(10,10);
escrever("Digite um valor: printf("Digite um valor:
") ");
ler(valor) scanf("%f",&valor);
cont cont + 1 cont = cont + 1;
se (valor < 0) então if(valor < 0)
negativo negativo + 1 negativo = negativo
até(cont=25) + 1;
perc (negativo*100)/25 } while(cont<25);
perc = (negativo*100)/25;
escrever("% negativos= gotoxy(10,14);
",perc) printf("%% negativos= %.2f",
perc);
fim getch();
}

Quadro 2.5 − Exemplo da estrutura de controle de repetição REPITA

O exemplo utilizando a estrutura for, do Quadro 2.6,


apresenta a solução de um problema em que o número de
repetições é conhecido previamente. Nesses casos, na estrutu-
ra for(cont=1;cont<=10; cont++), a primeira instru-
ção inicializa a variável de controle (cont=1), a segunda ve-
rifica a condição de interrupção avaliando a mesma variável
(cont<=10) e a terceira incrementa a variável de controle em
um a cada iteração (cont++). É importante destacar que a pri-
50 Algoritmos e Programação II

meira instrução, usada para inicializar a variável de controle, é


executada uma única vez, no início da execução da estrutura.

Problema: ler um valor inteiro, entre 1 e 10, e escrever a sua tabuada.


Português estruturado – PARA Linguagem C – for
#include <stdio.h>
#include <conio.h>

algoritmo exemplo main() {


variáveis
valor, cont: inteiro int valor, cont;
início
clrscr();
gotoxy(10,5);
escrever("Digite um valor: printf("Digite um valor: ");
") scanf("%i",&valor);
ler(valor) if(valor>=1 && valor<=10)
se(valor>=1)e(valor<=10) for(cont=1;cont<=10;cont++)
para cont de 1 até 10 faça {
gotoxy(10,cont+7);
escrever(cont*valor) printf("
%i",cont*valor);
senão }
else{
escrever("Valor inválido.") gotoxy(10,7);
printf("Valor inválido.");
}
fim getch();
}

Quadro 2.6 − Exemplo da estrutura de controle de repetição PARA

Em português estruturado, a estrutura PARA só pode ser


utilizada para resolver problemas em que o número de repeti-
ções é previamente conhecido, como no exemplo anterior. Em
linguagem C, entretanto, a estrutura for é mais flexível, po-
dendo ser utilizada em outras situações, como exemplificado
nas Figuras 2.5 e 2.6.

O exemplo apresentado na Figura 2.5 lê vários valores e calcu-


la a média dos mesmos. A entrada de dados é encerrada quando
Capítulo 2 Estruturas Básicas de Controle 51

o usuário digitar zero. Na linha 14 do programa apresentado na


Figura 2.5, a estrutura for(cont=1;valor!=0;cont++)
inicializa a variável cont, que é usada para contar a quantida-
de de valores digitados pelo usuário; na segunda instrução da
estrutura, que verifica a condição de interrupção, é a variável
valor que é avaliada; e, por fim, a variável cont é incremen-
tada em um a cada iteração. Diferentemente do exemplo ante-
rior, nessa situação, a estrutura for manipula duas variáveis:
cont e valor.

Figura 2.5 − Exemplo da estrutura PARA, em linguagem C


52 Algoritmos e Programação II

No exemplo apresentado na Figura 2.6, o enunciado do


problema não define quantos valores serão lidos, nem indi-
ca a condição de interrupção. Nessa situação, é necessário
perguntar ao usuário, ao final de cada iteração, se ele deseja
continuar a execução do programa − por isso, foi criada a
variável resp para armazenar a resposta do usuário. A estru-
tura for(cont=1;resp!='N'||resp!='n';cont++),
linha 11, inicializa a variável cont, que é usada para contar
a quantidade de valores digitados pelo usuário; na segunda
instrução, que verifica a condição de interrupção, é a variável
resp que é avaliada; e, por fim, a variável cont é incremen-
tada em um a cada iteração.
Capítulo 2 Estruturas Básicas de Controle 53

Figura 2.6 − Exemplo da estrutura PARA, em linguagem C

Além dos exemplos apresentados até aqui, a linguagem


C permite muitas outras possibilidades para a estrutura for,
como demonstram os exemplos do Quadro 2.7.
54 Algoritmos e Programação II

Flexibilidade Exemplo de aplicação


Qualquer uma das três //Escreve nos. de 0 a 98 em incremento

partes da estrutura for de 2.


main() {
pode conter uma ou mais
int x,y;
instruções, separadas por
for(x=0,y=0;x+y<100;x=x+1,y=y+1)
vírgula.
printf("%i ",x+y);
}

É possível utilizar /* Imprime as letras minúsculas do

caracteres para definir alfabeto e seus respectivos códigos


decimais da tabela ASCII. */
valores iniciais e seus
main() {
limites, ao invés de
char ch;
inteiros.
for(ch='a';ch<'z';ch++)
printf("Valor ASCII de %c é %d.\
n",ch,ch);
}

É possível fazer chamada /* Lê caracteres, um a um até que seja

a funções em qualquer digitado X, e imprime o caractere


seguinte a partir do código ASCII. */
uma das partes da
main() {
estrutura.
char ch;
for(ch=getch();ch!='X';ch=getch())
printf("%c ",ch+1);
}

Qualquer uma das três /* Lê caracteres, um a um até que seja

partes da estrutura pode digitado X, e imprime o caractere


seguinte a partir do código ASCII. */
ser omitida, embora os
main() {
pontos-e-vírgulas per-
char ch;
maneçam. Se a parte de
for( ; (ch=getch())!='X'; )
inicialização ou a de in-
printf("%c ",ch+1);
cremento forem omiti-das, }
elas serão desconside-ra- /* Entra em laço infinito */
das. Quando a segunda main() {
parte é omitida, a condi- for( ; ; )
ção de teste é considerada printf("Laço infinito./n");
sempre verdadeira. }

Quadro 2.7 − Exemplos da flexibilidade da estrutura for


Capítulo 2 Estruturas Básicas de Controle 55

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) Na programação estruturada, são necessárias apenas três es-


truturas de controle para implementar algoritmos. São elas:
a) seleção, repetição e aninhamento

b) empilhamento, aninhamento e operação

c) sequência, aninhamento e seleção

d) sequência, seleção e repetição

e) função, operação e programa


56 Algoritmos e Programação II

2) if(var) é equivalente a if(var!=0).


a) Certo b) Errado

3) Para que faixa de valores da variável x o seguinte segmento


de código imprime a letra C?
if(x<=200)

if(x<=100)

if(x<0) printf("A")

else printf("B")

else printf("C")

else printf("D")

a) 0<x<100

b) x<=100

c) 100<x<=200

d) x>200

e) 100<=x<=200

4) Tendo em vista a sintaxe da linguagem de programação C,


e supondo que todas as variáveis da expressão

while(9<=H && P!=0 || F%2==0)


Capítulo 2 Estruturas Básicas de Controle 57

sejam do tipo inteiro, o laço de repetição NÃO será exe-


cutado se:

a) H < 9 e P ≠ 0 e F for par

b) H = 9 e P = 0 e F for ímpar

c) H ≥ 9 e P ≠ 0 e F ≠ 0

d) H > 9 e P = 0 e F = 0

e) Nenhuma das respostas anteriores

5) Considerando que x e y são números inteiros positivos, as-


sinale a alternativa que descreve a tarefa executada pelo
programa em C descrito a seguir.

#include<stdio.h>
main(){
int x,y,z,w;
printf("Digite os valores de x e y: ");
scanf("%d %d",&x,&y);
z=1;
while(z*y<=x)
z=z+1;
z=z-1;
w=x-z*y;
printf("%d %d \n",z,w);
}

a) Exibe, respectivamente, o valor correspondente às vari-


áveis x e y.
58 Algoritmos e Programação II

b) Exibe, respectivamente, o quociente e o resto da variável


x pela variável y.

c) Exibe, respectivamente, os dois primeiros números pri-


mos menores que x e y.

d) Exibe, respectivamente, o resto e o quociente da variável


x pela variável y.

e) Exibe, respectivamente, o valor correspondente às vari-


áveis x e y.

6) Quanto vale k no final da execução do seguinte trecho de


código?
k=0;
for(i=1; i<=n; i++)
for(j=i; j<=n; j++)
k=k+1;

a) n3

b) (n2–n)/2

c) n

d) n(n+1)/2

e) n-1
Capítulo 2 Estruturas Básicas de Controle 59

Parte II - Resolução de problemas


Resolva os problemas descritos a seguir, utilizando a Lingua-
gem C.

1) Escreva um programa que leia 20 valores, encontre e escre-


va o maior entre eles.

2) Construa um programa que leia um valor inteiro e positivo,


calcule e escreva o seu fatorial.
Exemplos: 4! = 1 x 2 x 3 x 4 = 24

5! = 1 x 2 x 3 x 4 x 5 = 120

Por definição, 0! = 1

3) Em uma eleição presidencial, existem 4 candidatos. Os vo-


tos são informados a partir de códigos, que obedecem a
seguinte regra: 1, 2, 3, 4 = voto para os respectivos can-
didatos; 5 = voto nulo; 6 = voto branco. Elabore um pro-
grama que leia o voto de cada um dos eleitores, calcule e
escreva: total de votos para cada candidato; total de votos
nulos; total de votos em branco. Como finalizador do con-
junto de dados tem-se o valor 0 (zero).

4) Elabore um programa que repita a leitura de uma data até


que ela seja válida. Para cada data incorreta, escrever a
mensagem "DATA INVÁLIDA". Quando a data for informa-
da corretamente, deve ser impressa a mensagem "DATA
VÁLIDA" e o programa deve ser encerrado. Para resolver
60 Algoritmos e Programação II

esse problema, use três variáveis para representar a data:


dia, mês e ano; não esqueça de considerar ano bissexto,
quando o mês de fevereiro tem 29 dias.

5) Durante uma pesquisa realizada entre os habitantes de uma


região, foram coletados os seguintes dados: idade, gêne-
ro e salário. Faça um programa que calcule e informe: a
média salarial do grupo; a maior idade do grupo; a quan-
tidade de mulheres com salário superior a R$ 5.000,00.

Respostas dos exercícios da Parte I


1) d; 2) a; 3) c; 4) b; 5) b; 6) d.
Vanessa Lindemann*

Capítulo 3

Variáveis Indexadas
Unidimensionais

ÂÂ
U ma variável simples representa um espaço da memó-
ria do computador onde é possível armazenar um úni-
co valor por vez. Os dados armazenados podem ser do
tipo inteiro, real, caractere ou cadeia de caracteres. Esses
conceitos, aliados às instruções primitivas de entrada e sa-
ída de dados e às estruturas de controle de fluxo sequen-
cial, condicionais e repetitivas, estudados nos capítulos
anteriores, permitem resolver diversos problemas como
visto até aqui. O uso de variáveis simples, entretanto, gera
algumas limitações como a exemplificada a seguir.

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
62 Algoritmos e Programação II

Problema: ordenar três valores do tipo inteiro.


Português estruturado Linguagem C

#include <stdio.h>
#include <conio.h>

algoritmo exemplo main() {


variáveis
a, b, c: inteiro int a, b, c;
início
clrscr();
gotoxy(10,5);
escrever("Digite 3 valores: printf("Digite 3 valores: ");
") scanf("%i %i %i",&a,&b,&c);
ler(a, b, c) gotoxy(10,8);
printf("Valores ordenados: ");
escrever("Valores ordenados: if(a<b)
") if(b<c)
se(a<b)então printf("%i %i %i",a,b,c);
se(b<c)então else
escrever(a,b,c) if(a<c)
senão printf("%i %i %i",a,c,b);
se(a<c) então else
escrever(a,c,b) printf("%i %i %i",c,a,b);
senão else
escrever(c,a,b) if(b<c)
senão if(a<c)
se(b<c)então printf("%i %i %i",b,a,c);
se(a<c)então else
escrever(b,a,c) printf("%i %i %i",b,c,a);
senão else
escrever(b,c,a) printf("%i %i %i",c,b,a);
senão getch();
escrever(c,b,a) }

fim

Quadro 3.1 − Exemplo da limitação do uso de variáveis simples

O programa descrito no Quadro 3.1 ordena três valo-


res do tipo inteiro. Nesse método de ordenação, utilizando
variáveis simples, ordenar n elementos implica em gerar
Capítulo 3 Variáveis Indexadas Unidimensionais 63

n! resultados diferentes. Logo, é impossível, por exemplo,


utilizar o mesmo método para ordenar 10 valores armaze-
nados em variáveis simples − além de ter que utilizar 10
variáveis com nomes diferentes, seriam necessários exibir
10! (3.628.800) resultados.
Uma forma de resolver esse problema é utilizar uma
variável indexada unidimensional, que representa um
conjunto de dados ordenados e homogêneo, armazena-
do de forma contínua na memória, acessível por um único
nome e um índice. Essas variáveis também são conhecidas
como matrizes unidimensionais, arranjos unidimensionais
ou vetores (nome que será adotado neste livro).
64 Algoritmos e Programação II

3.1 Estrutura

A estrutura de um vetor, cujo tamanho é 10, é ilustrada na Fi-


gura 3.1. À esquerda, a representação do vetor em algoritmo,
onde os índices variam de 1 a 10; à direita, a representação
em linguagem C, em que os índices variam de 0 a 9.

Algoritmo Linguagem C
notas notas

1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9
Índices: 1 a 10 Índices: 0 a 9

Figura 3.1 − Exemplos da estrutura de um vetor de tamanho 10

3.2 Declaração

Para declarar um vetor, é necessário definir o tipo dos dados


que serão armazenados nele, o nome (identificador) a partir do
qual ele será manipulado e o tamanho da variável, que indica
quantos valores ele poderá armazenar. A sintaxe da declara-
ção de um vetor, em linguagem C, é apresentada a seguir.

<tipo> <identificador>[<tamanho>];

Onde: tipo representa um dos tipos básicos; identificador


é o nome que será usado para manipular a variável; tamanho
indica a quantidade de elementos que a variável irá armazenar.
Capítulo 3 Variáveis Indexadas Unidimensionais 65

A Tabela 3.1 exemplifica como declarar um vetor para ar-


mazenar 10 elementos do tipo real, em português estruturado
e o equivalente em Linguagem C.

Português estruturado Linguagem C


notas: vetor [1..10] de real float notas[10];

Tabela 3.1 − Exemplo da declaração de um vetor

Um vetor pode ser inicializado no momento de sua decla-


ração. Ao executar int vet[5]={0} a variável vet é criada e
terá todas as suas posições inicializadas com zero; ao executar
int vet[5]={1,2,3,4,5} a variável será inicializada com um
valor diferente em cada posição.

3.3 Manipulação

Para acessar um elemento de um vetor, além de referenciar o


seu nome, é necessário indicar a posição do elemento deseja-
do. A posição do elemento do vetor, denominada índice, deve
ser indicada entre colchetes e pode ser uma constante, uma
expressão aritmética ou uma variável. Ao isolar um elemento
do vetor, é possível realizar instruções primitivas de entrada, de
saída e de atribuição. Alguns exemplos da instrução primitiva
de atribuição são apresentados na Tabela 3.2 e ilustrados na
Figura 3.2.
66 Algoritmos e Programação II

Português estruturado Linguagem C

notas[3] ← 9.5 notas[2] = 9.5;


i ← 3 i = 2;
notas[i] ← 9.5 notas[i] = 9.5;
Tabela 3.2 − Exemplo de atribuição a um elemento específico do vetor

notas
9,5
0 1 2 3 4 5 6 7 8 9

Figura 3.2 − Variável notas depois da instrução de atribuição, em


Linguagem C

Português estruturado Linguagem C


gotoxy(10,5);
escrever (“Informe os 10 printf(“Informe os 10 elementos do
elementos do vetor: ”) vetor: “);
para i de 1 até 10 faça for(i=0; i<10; i++){
gotoxy(i*5+10,8);
ler(notas[i]) scanf(“%f”,&notas[i]);
}

Tabela 3.3 − Exemplo da entrada de dados em um vetor

A Tabela 3.3 exemplifica a entrada de dados da variável


notas, declarada na Tabela 3.1. A Figura 3.3 ilustra o resul-
tado dessa variável, supondo que o usuário tenha digitado 9,
8.3, 5.1, 6, 7.9, 5.2, 9, 8, 9.7 e 5, nessa ordem.
Capítulo 3 Variáveis Indexadas Unidimensionais 67

notas
9 8.3 5.1 6 7.9 5.2 9 8 9.7 5
0 1 2 3 4 5 6 7 8 9

Figura 3.3 − Ilustração da variável notas depois da entrada de dados,


em Linguagem C

A função gotoxy(coluna,linha) é utilizada para po-


sicionar o cursor em uma determinada posição da tela. Ela é
usada antes de instruções primitivas de entrada e saída para
organizar os dados na tela. No exemplo de entrada de dados
da Tabela 3.3, em linguagem C, a função gotoxy(10,5)
posiciona o cursor na coluna 10 e na linha 5, antes da instru-
ção de saída, que irá imprimir na tela a mensagem "Informe
os 10 elementos do vetor: ". Essa mensagem será exibida uma
única vez, a partir da coluna 10, na linha 5.

Nesse mesmo exemplo, a função gotoxy(i*5+10,8)


aparece novamente, antes da instrução primitiva de entrada
de dados. Nesse caso, ela é usada para definir o local em que
os dados de entrada, digitados pelo usuário, serão exibidos
na tela. Como o usuário irá digitar 10 notas, para que todas
sejam exibidas na tela uma ao lado da outra, o primeiro parâ-
metro da função, que representa a coluna, não pode ser uma
constante (ou seja, não pode ser um valor fixo).

No exemplo, utiliza-se a expressão i*5+10 para definir a


coluna em que cada valor digitado pelo usuário será exibido.
Considerando que a variável i varia entre 0 e 9, os valores
seriam lidos nas colunas: 10, 15, 20, 25, 30, 35, 40, 45, 50
e 55 − sempre na linha 8. Observa-se, portanto, que o valor
que multiplica a variável i na expressão define o intervalo en-
68 Algoritmos e Programação II

tre as colunas (no exemplo, o intervalo entre um valor e outro


é de 5), enquanto o valor que é somado à variável i na ex-
pressão, define a primeira coluna a ser utilizada (no exemplo,
coluna 10).

3.4 Exemplos do uso de vetores

Esta seção é dedicada à resolução de alguns problemas, cujas


soluções utilizam variáveis indexadas unidimensionais, ou seja,
vetores. No primeiro exemplo, a solução é apresentada em
português estruturado e, em seguida, o equivalente em lingua-
gem C. Nos demais exemplos, utiliza-se apenas a representa-
ção em linguagem C.

 Exemplo 3.1
Problema: o professor de Algoritmos e Programação pre-
cisa de um programa que leia a nota final de 10 alunos, cal-
cule e escreva a média geral da turma.
Capítulo 3 Variáveis Indexadas Unidimensionais 69

Problema: ler a nota final de 10 alunos, calcular e escrever a média geral da turma.
Português estruturado Linguagem C
#include <stdio.h>
#include <conio.h>

algoritmo exemplo31 main() {


variáveis
notas: vetor[1..10] de real float notas[10];
soma, media: real float soma, media;
i: inteiro int i;
início
soma 0 soma=0;
clrscr();
gotoxy(10,5);
escrever("Digite as 10 notas: printf("Digite as 10 notas:
") ");
para i de 1 até 10 faça for(i=0;i<10;i++)
início {
gotoxy(i*5+10,8);
ler(notas[i]) scanf("%f",&notas[i]);
soma soma + notas[i] soma = soma + notas[i];
fim }
media soma/10 media = soma/10;
gotoxy(10,14);
escrever("Média turma printf("Média turma =
=",media) %.1f",media);
getch();
fim }

Quadro 3.2 − Solução para o problema do exemplo 3.1

Na solução apresentada no Quadro 3.2, criou-se um ve-


tor, com capacidade para armazenar 10 valores do tipo real.
Para realizar a entrada de dados e, em seguida, somar as no-
tas digitadas pelo usuário, foi utilizada a estrutura de repetição
PARA. Por fim, a média da turma foi calculada (dividindo a va-
70 Algoritmos e Programação II

riável que acumulou todas as notas pela quantidade de notas,


nesse caso, 10) e exibida para o usuário.

 Exemplo 3.2
Problema: o professor de Algoritmos e Programação pre-
cisa de um programa que leia a nota final de 10 alunos, calcu-
le a média geral da turma e, a seguir, informe quantos alunos
obtiveram nota superior à média da turma.

Figura 3.4 Solução, em linguagem C, para o problema do exemplo 3.2


Capítulo 3 Variáveis Indexadas Unidimensionais 71

Até a linha 18, a solução apresentada na Figura 3.4 é a


mesma do exemplo anterior: o programa emite uma mensa-
gem ao usuário solicitando que ele digite 10 notas, estas são
lidas e armazenadas em um vetor, acumuladas na variável
soma e, em seguida, a média é calculada. Entre as linhas 19
e 21, o programa percorre o vetor novamente, comparando
cada elemento com a variável media e, sempre que o valor
comparado for maior que a média calculada, incrementa a
variável cont em um. Por fim, o programa exibe a média da
turma e a quantidade de alunos com nota superior a ela.

Os exemplos 3.1 e 3.2 também podem ser usados para


justificar o uso de variáveis indexadas. No primeiro caso, até
seria possível resolver o problema sem utilizar um vetor: uma
variável simples poderia ser lida dez vezes, acumulando cada
valor lido na variável soma para, no final, calcular a média. No
exemplo 3.2, entretanto, essa solução não seria possível, já
que, para verificar a quantidade de alunos com nota superior
à média da turma, é necessário ter a nota de todos os alunos
para comparar com a variável media e, nesse caso, o progra-
ma só teria a nota do último aluno armazenada.

 Exemplo 3.3
Problema: faça um algoritmo que leia um vetor de 20 po-
sições, com elementos do tipo inteiro. A seguir, troque os ele-
mentos de lugar: o 1º com o 20º, o 2º com o 19º, o 3º com
o 18º, ... Finalmente, escreva o vetor modificado. A entrada e
a saída de dados desse exemplo são ilustradas na Figura 3.5.
72 Algoritmos e Programação II

Vetor v
2 4 9 12 6 98 7 35 11 42 55 1 3 64 13 5 20 8 14 24
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Vetor v modificado

24 14 8 20 5 13 64 3 1 55 42 11 35 7 98 6 12 9 4 2
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Figura 3.5 Ilustração do resultado do exemplo 3.3

Como pode ser observado na Figura 3.6, esse problema


foi resolvido em três etapas: a entrada de dados, que ocorre
entre as linhas 10 e 14; a troca dos elementos do vetor, rea-
lizada pelas instruções entre as linhas 15 e 20; e, por fim, a
saída de dados, que apresenta o vetor modificado, executada
entre as linhas 23 e 27.
Capítulo 3 Variáveis Indexadas Unidimensionais 73

Figura 3.6 − Solução, em linguagem C, para o problema do exemplo 3.3

Para realizar a troca, é necessário que todos os dados te-


nham sido armazenados no vetor, já que o primeiro elemento
será trocado com o último, o segundo com o penúltimo e assim
sucessivamente. Além disso, deve-se criar uma variável auxiliar.

O Quadro 3.3 ilustra a necessidade da variável auxiliar no


processo de troca. No exemplo, foram utilizadas duas variáveis
simples, A e B. Supondo que A armazena 5 e B 2, se forem
74 Algoritmos e Programação II

executadas as instruções A=B e B=A, o resultado será A e B ar-


mazenando 2. Logo, sem a variável auxiliar, as duas variáveis
ficariam com o mesmo valor. A solução correta, utilizando a
variável auxiliar, é apresentada no Quadro 3.4, onde AUX=A,
A=B e B=AUX.

Teste-de-mesa Saída

Variáveis A = 2
Instruções B = 2
A B
5 2

A = B 2 NÃO FUNCIONOU!

B = A 2

Quadro 3.3 − Troca de conteúdo entre duas variáveis, sem usar variável auxiliar

Teste-de-mesa Saída
A = 2
Variáveis
Instruções B = 5
AUX A B
5 2

AUX = A 5

A = B 2

B = AUX 5

Quadro 3.4 − Troca de conteúdo entre duas variáveis, usando uma


variável auxiliar
Capítulo 3 Variáveis Indexadas Unidimensionais 75

É importante observar que, nas etapas de entrada e saí-


da de dados do exemplo 3.3, o número de iterações é 20,
enquanto na etapa de trocas é 10. Isso ocorre porque o ve-
tor possui 20 elementos e, a cada iteração, dois elementos
são trocados. As trocas ocorrem entre os elementos v[i] e
v[19-i]. Assim, quando i for 0, 19-i será 19, de forma
que serão trocados os elementos v[0] com v[19]; quando
i for 1, 19-i será 18, então serão trocados os elementos
v[1] com v[18]; quando i for 2, 19-i será 17, trocando
v[2] com v[17]; esse processo será repetido até a variável
i chegar em 9, quando 19-i será 10 e serão trocados os
elementos v[9] com v[10].

 Exemplo 3.4
Problema: escreva um programa que leia um vetor (P) de
20 posições, com elementos do tipo inteiro. A seguir, encontre
a posição do menor elemento do vetor, conte e informe quan-
tos dos elementos do vetor são múltiplos desse valor.

A entrada e a saída de dados desse exemplo são ilustradas


na Figura 3.7, e a solução para o problema é descrita na Fi-
gura 3.8.

P 16 5 13 99 25 2 77 4 8 12 9 24 52 83 10 6 18 45 21 9
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Menor elemento = 2
Posição do menor elemento = 5
Quantidade de elementos múltiplos de 5 = 4
Figura 3.7 − Ilustração do resultado do exemplo 3.4
76 Algoritmos e Programação II

Figura 3.8 − Solução, em linguagem C, para o problema do exemplo 3.4

Considerando que os índices do vetor não são exibidos


para o usuário, e que ele não sabe que os índices em lingua-
gem C iniciam em zero, o resultado apresentado no exemplo
de entrada e saída da Figura 3.7 pode parecer estranho para
ele. O menor elemento do vetor é o valor dois, entretanto,
para o usuário, ele está na posição seis em vez da cinco. Para
resolver essa questão, basta alterar a instrução que armazena
Capítulo 3 Variáveis Indexadas Unidimensionais 77

a posição do menor elemento de posicao=i (linha 16 − Fi-


gura 3.8) para posicao=i+1.

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) Sobre variáveis indexadas unidimensionais, é CORRETO


afirmar:
I. Representam conjuntos ordenados de valores homogêneos,
que podem ser de qualquer um dos tipos básicos de dados.

II. São armazenadas na memória de forma contínua e


acessadas a partir de um único nome e um índice.

III. Também são conhecidas como vetores, arranjos ou


matrizes unidimensionais.
78 Algoritmos e Programação II

a) apenas II e III estão corretas;

b) apenas I e II estão corretas;

c) apenas a II está correta;

d) apenas I e III estão corretas;

e) todas estão corretas.

2) Para declarar um vetor, é necessário definir o tipo dos da-


dos que serão armazenados nele, o identificador pelo qual
ele será manipulado; e o tamanho da variável, que indica
quantos valores ele poderá armazenar.
a) Certo b) Errado

3) Considerando a declaração e a inicialização de variáveis


indexadas, assinale a alternativa INCORRETA.
a) float notas[30];

b) int n[10]={0};

c) int n[8]={12,43,78,10,25,01,29,18};

d) char letras[5]={a,b,c,d,e};

e) char respostas[12]={'x'}.

4) Seja um vetor declarado como int vet[10]; qual ele-


mento desse vetor é acessado por vet[2]?
Capítulo 3 Variáveis Indexadas Unidimensionais 79

a) primeiro elemento;

b) segundo elemento;

c) terceiro elemento;

d) quarto elemento;

e) nenhuma das respostas anteriores.

5) Considerando a declaração a seguir: int vet[30];


a instrução abaixo acessa corretamente os elementos do
vetor?

for(j=0; j<=30; j++)

vet[j] = j*j;

a) Sim b) Não

Parte II - Resolução de problemas

Resolva os problemas descritos a seguir, utilizando a Lin-


guagem C.

1) Elabore um programa em C que leia um vetor de 15 po-


sições com elementos do tipo caractere. Conte e escreva
quantas vezes a letra “a” aparece no vetor.

2) Faça um programa em C que leia um vetor de 20 posi-


ções do tipo real. Troque a 1ª posição com a 11ª, a 2ª
80 Algoritmos e Programação II

com a 12ª, a 3ª com a 13ª, ..., 10ª com a 20ª. Escreva


o vetor modificado.

3) Construa um programa que crie um vetor de 16 posições,


colocando 1 nas posições cujos índices são múltiplas de 4
e 0 nas demais posições. Escreva o vetor criado.

4) Escreva um programa que crie um vetor U, com 10 ele-


mentos, cujo conteúdo é formado a partir da expressão P
+ Q * 2, sendo que P e Q são lidas toda vez em que um
elemento de U é criado. Escreva o vetor criado.

5) Faça um programa que leia dois vetores X(10) e Y(10). Crie


e escreva um vetor Z que seja a diferença entre X e Y.

x 8 4 6 12 7 9 3 1 2 6

y 4 5 5 10 1 3 3 5 9 1

z 4 -1 1 2 6 6 0 -4 -7 5

6) Elabore um programa em C que leia um vetor de 12 posições


com elementos do tipo inteiro. A seguir, ordene os elemen-
tos do vetor (ordem crescente) e escreva o vetor modificado.

Respostas dos exercícios da Parte I


1 - e; 2 - a; 3 - d; 4 - c; 5 - b.
Vanessa Lindemann*

Capítulo 4

Strings

ÂÂ
S
trings são cadeias de caracteres, usadas para arma-
zenar e manipular dados textuais como, por exemplo,
nomes, endereços e senhas com caracteres alfanuméri-
cos. Em linguagem C, diferente de outras linguagens de
programação, string não é um tipo de dado formal, mas,
sim, um vetor de caracteres terminado pelo caractere \0
(caractere nulo, cujo código ASCII decimal é zero). Essa
terminação é importante, pois é a única forma das ou-
tras funções da linguagem reconhecerem o final de uma
string. Os fundamentos necessários para manipular strings
são apresentados nas próximas seções.

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
82 Algoritmos e Programação II

4.1 Declaração e inicialização

Uma string deve ser declarada como um vetor de caracteres,


definindo um identificador e o seu tamanho. Por exemplo,

char nome[21];

declara uma string que poderá armazenar no máximo 20


caracteres, mais o caractere \0. A Figura 4.1 ilustra a estrutura
criada na memória para armazenar a string declarada.

nome

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Figura 4.1 − Estrutura da variável nome declarada como string

Uma string pode ser inicializada na sua declaração, como


ilustram os exemplos a seguir.

char nome[21]={'A','n','a','

','C','l','a','r','a','\0'};

char nome[21]="Ana Clara";

No primeiro exemplo, os caracteres são inicializados um a


um entre apóstrofes e o conjunto de caracteres é envolto por
chaves. O segundo exemplo apresenta uma forma de iniciali-
zação equivalente e consideravelmente mais simples, onde a
string aparece entre aspas e o caractere especial \0 é incluído
automaticamente. Essas duas instruções têm o mesmo efeito,
cujo resultado é ilustrado na Figura 4.2.
Capítulo 4 Strings 83

nome
A n a C l a r a \0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Figura 4.2 − Variável nome após de ser declarada e inicializada

Como uma string é um vetor de caracteres, essa pode ser


manipulada como tal. Para acessar um determinado caractere
de uma string, por exemplo, basta utilizar o seu índice, como
ilustram os exemplos a seguir.

nome[0] = 'x';

printf("%c", nome[4]);

4.2 Entrada de dados

A função scanf é bastante limitada para a leitura de strings,


como ilustra o exemplo do Quadro 4.1, onde o usuário digita
seu nome e sobrenome e o programa exibe apenas seu nome.

Exemplo: leitura de uma string Resultado


#include <stdio.h>
#include <conio.h>
main() { Digite seu nome:
char nome[21]; Marcos Sereno
clrscr();
Olá Marcos!
gotoxy(10,5);
printf("Digite seu nome: ");
scanf("%s",nome);
gotoxy(10,8);
printf("Olá %s!", nome);
getch();
}
Quadro 4.1 − Entrada de dados de uma string usando a função scanf
84 Algoritmos e Programação II

Isso acontece porque a função scanf("%s",nome) lê


cada caractere não branco e os armazena a partir do endere-
ço nome. O processo termina quando um caractere branco é
encontrado. Nesse momento, o caractere \0 é incluído auto-
maticamente na primeira posição livre do vetor.

Então, no exemplo do Quadro 4.1, quando o usuário di-


gita um espaço em branco entre seu nome e sobrenome, a
função scanf inclui o caractere \0 na variável nome, exata-
mente na posição em que este foi digitado. O sobrenome não
é armazenado na variável e, consequentemente, não é exibido
na tela. Por isso, a função scanf não é indicada para a leitura
de strings.

Um detalhe a ser observado na instrução


scanf("%s",nome) é a ausência do operador de en-
dereço (&) antes do segundo argumento da função. Esse
operador não é utilizado com vetor e matriz porque os no-
mes dessas variáveis já representam seus endereços iniciais
(exemplo: a instrução scanf("%s",nome) é equivalente a
scanf("%s",&nome[0])).

Uma função adequada para a leitura de strings é a fgets,


que tem por objetivo ler uma string da entrada padrão que,
por default, é o teclado. A sintaxe da função fgets é apre-
sentada a seguir.

fgets(<variável>,<tamanho máximo da
variável>,stdin);

Ela possui três argumentos: o primeiro é a variável que irá


armazenar a string digitada pelo usuário; o segundo indica o
Capítulo 4 Strings 85

tamanho máximo da string; e o terceiro, nesse caso o stdin,


indica que a entrada de dados será realizada via teclado (std
= standard + in = input, ou seja, entrada padrão). Ao definir
o tamanho máximo de uma string, é preciso considerar que o
espaço de um dos seus caracteres será reservado para o \0
(caractere nulo), necessário para indicar seu final. Exemplos da
utilização da função fgets são apresentados no Quadro 4.2.

Variáveis Exemplos de função de entrada


char fone[15]; 01 fflush(stdin);
char nome[60]; fgets(fone,15,stdin);
02 fflush(stdin);
fgets(nome,60,stdin);

Quadro 4.2 − Exemplos da sintaxe da função fgets

Como pode ser observado nos exemplos do Quadro 4.2,


a função fflush é usada antes da função fgets, com o
objetivo de liberar o buffer do teclado. O primeiro exemplo
lê a variável fone, que terá no máximo 14 caracteres e será
informada pelo usuário por meio do teclado. O exemplo 02 lê
a variável nome, que terá no máximo 59 caracteres.

Reescrevendo o exemplo apresentado no Quadro 4.1, uti-


lizando a função fgets, o resultado do programa será o espe-
rado, ou seja, nome e sobrenome digitados pelo usuário serão
armazenados na string e exibidos corretamente na tela. Essa
solução é apresentada na Figura 4.3.
86 Algoritmos e Programação II

Figura 4.3 − Entrada de dados de uma string usando a função fgets

4.3 Saída de dados

As strings podem ser exibidas na tela utilizando tanto a função


printf quanto a função puts, descritas a seguir.

printf(<string de controle>,<lista de ar-


gumentos>);

puts(<argumento>);

Como pode ser observado, a diferença entre essas funções


é que utilizando printf é possível imprimir um literal com o
conteúdo de uma ou mais variáveis de qualquer tipo, enquan-
to a função puts permite exibir apenas um literal ou o conte-
údo de uma string por vez, seguido de nova linha. O Quadro
4.3 apresenta exemplos dessas funções.
Capítulo 4 Strings 87

Variáveis Exemplos de função de saída


float media; 01 printf("%s obteve média
char nome[60]; %.1f",nome,media);
02 printf("%s\n",nome);
03 puts("Aluno: ");
04 puts(nome);

Quadro 4.3 − Exemplos das funções printf e puts

Supondo que a variável nome armazene Joana e a variável


media 5.77, a saída do exemplo 01 seria Joana obteve média
5.8 (o valor 5.77 é arredondado para 5.8). No exemplo 02,
será exibido apenas o conteúdo da variável nome, ou seja, Jo-
ana. Os exemplos 03 e 04 escrevem, respectivamente, o literal
Aluno: e o conteúdo da variável nome, Joana, passando para
nova linha após cada impressão. Portanto, para escrever duas
strings na mesma linha, é necessário utilizar a função printf
(como no exemplo 01). As instruções dos exemplos 02 e 04
têm o mesmo efeito: exibem o conteúdo da variável nome e
iniciam nova linha.

4.4 Funções para manipulação de strings

Nesta seção, serão descritas mais algumas funções da biblio-


teca string.h para a manipulação de strings. A biblioteca
string.h deverá ser incluída no programa a partir da diretiva
#include para que as funções possam ser utilizadas.

O Quadro 4.4 descreve a função strcpy. Como pode ser


observado nos exemplos 01 e 02, a função strcpy pode co-
88 Algoritmos e Programação II

piar uma string constante, como Ana Clara, ou o conteúdo


de uma variável para outra variável string. No exemplo 01,
a função strcpy é utilizada para realizar a atribuição de um
valor qualquer a uma variável string, ou seja, a variável nome
recebe Ana Clara. No exemplo 02, o conteúdo armazenado
na variável str1, que é Teste, é copiado para a variável str2.

strcpy(<string_destino>,<string_origem>)
Descrição Exemplos de aplicação
Copia o 01 char nome[20];
conteúdo de strcpy(nome,"Ana Clara");
uma string 02 char str1[10]="Teste",str2[10];
para outra. strcpy(str2,str1);

Quadro 4.4 − Função strcpy (abreviação de string copy)

A função strcmp, exemplificada no Quadro 4.5, compara


o conteúdo de duas strings e retorna zero quando estas forem
idênticas. No exemplo 01, as variáveis str1 e str2 são com-
paradas e, se o retorno da função for zero, o programa exibe
a mensagem Strings iguais!, caso contrário, exibe a mensagem
Strings diferentes. No exemplo 02, como a parte ==0 foi omi-
tida da expressão, quando a variável senha for diferente de
xP1eR, o retorno da função será um valor diferente de zero. Em
linguagem C, qualquer valor diferente de zero nessa situação é
considerado verdadeiro, ou seja, a expressão resulta verdadei-
ro e a mensagem Acesso negado. será exibida na tela.
Capítulo 4 Strings 89

strcmp(<string1>,<string2>)
Descrição Exemplos de aplicação
Compara duas 01 if(strcmp(str1,str2)==0)
strings e retorna printf("Strings iguais!");
zero quando else
estas forem printf("Strings diferentes.");
idênticas.
02 if(strcmp(senha,"xP1eR"))
printf("Acesso negado.");

Quadro 4.5 − Função strcmp (abreviação de string compare)

O valor de retorno da função strcmp será

<0 se string1 < string2


0 se string1 = string2
>0 se string1 > string2

Nesse caso, "menor que" e "maior que" significa que, se as


duas strings forem colocadas em ordem alfabética, a primeira
é menor que a segunda. A Figura 4.4 apresenta um programa
que testa o retorno da função strcmp em algumas situações.
A saída desse programa é 0, -1, 1, 1 e 1.

A Figura 4.5 ilustra um exemplo da aplicação da função


strcmp, utilizada para validar uma senha. O programa solicita
que o usuário digite sua senha e verifica se ela está correta,
caso contrário, repete a entrada de dados. Esse processo é
90 Algoritmos e Programação II

repetido até que a senha correta seja digitada ou até que o


usuário tenha feito três tentativas erradas.

Vale lembrar que a função strcmp diferencia letras mi-


núsculas de letras maiúsculas, portanto, exR7u é diferente de
exr7u. Para comparar duas strings sem considerar se os ca-
racteres estão em caixa-baixa ou caixa-alta, deve-se utilizar a
função stricmp, cuja sintaxe é a mesma da strcmp.

Figura 4.4 − Exemplo que testa o retorno da função strcmp


Capítulo 4 Strings 91

Figura 4.5 − Exemplo da aplicação da função strcmp

A função strlen retorna o tamanho de uma string, ou


seja, a quantidade de caracteres armazenados nela, sem con-
siderar o \0. O Quadro 4.6 apresenta alguns exemplos do
uso dessa função. No primeiro exemplo, a função strlen é
usada como argumento da instrução de saída para imprimir
o tamanho da string nome, nesse caso 10; o exemplo 02 uti-
liza a função strlen para limitar o número de iterações da
estrutura for.
92 Algoritmos e Programação II

strlen(<string>)
Descrição Exemplos de aplicação
Retorna o 01 char nome[35]="João Pedro";
tamanho de printf("%i",strlen(nome));
uma string. 02 char frase[50]="Conta letra a";
for(i=0;i<strlen(frase);i++){
if(frase[i]=='a')
cont++;
}

Quadro 4.6 − Função strlen (abreviação de string length)

O Quadro 4.7 exemplifica o uso da função strcat que


concatena duas strings, ou seja, junta uma string ao final de
outra. No exemplo, o conteúdo da variável s2 é copiado para
o final da variável s1. O programador deve observar se a va-
riável destino tem espaço suficiente para receber o conteúdo
copiado, já que o compilador não faz essa verificação. O con-
teúdo da variável s2 não é alterado. A saída desse programa
seria bom dia.
strcat(<string_destino>,<string orgiem>)
Descrição Exemplo de aplicação
Concatena duas 01 char s1[10]="bom ",s2=[5]="dia";
strings. strcat(s1,s2);
printf("%s",s1);

Quadro 4.7 − Função strcat (abreviação de string catenate)

Outro exemplo da aplicação da função strcat é apresen-


tado na Figura 4.6. Na linha 6, a variável titulo é inicializada
Capítulo 4 Strings 93

com brancos e, entre as linhas 9 e 11, esta recebe o conteúdo


das variáveis str1, str2 e str3, cujo resultado será Lingua-
gem C.

Figura 4.6 − Exemplo da aplicação da função strcat

As funções strupr (abreviação de string uppercase) e


strlwr (abreviação de string lowercase) são utilizadas para
converter os caracteres de uma string para maiúscula ou mi-
núscula, respectivamente. A Figura 4.7 ilustra a aplicação des-
sas funções.
94 Algoritmos e Programação II

Figura 4.7 − Exemplo da aplicação das funções strupr e strlwr

A Figura 4.8 apresenta um exemplo da aplicação da fun-


ção strstr(s1,s2), que tem como objetivo procurar a pri-
meira ocorrência da substring s2 na string s1. A função retorna
um ponteiro para o primeiro caractere da substring encontrada
ou \0 (nulo) quando esta não estiver presente na string.
Capítulo 4 Strings 95

Figura 4.8 Exemplo da aplicação da função strstr

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.
96 Algoritmos e Programação II

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) Sobre string é CORRETO afirmar:


I. São cadeias de caracteres, usadas para armazenar e
manipular dados textuais.

II. Em linguagem C, uma string não é um tipo formal, mas


um vetor de caracteres terminado pelo caractere \0.

III. Uma matriz declarada com tamanho de 15 pode arma-


zenar até 15 caracteres.

a) apenas I está correta;

b) apenas I e III estão corretas;

c) apenas I e II estão corretas;

d) apenas a II está correta;

e) todas estão corretas.

2) Na declaração de uma string o tipo é e devem


ser definidos o eo . Marque
a alternativa que completa corretamente as lacunas.
a) vetor, identificador, tamanho;
Capítulo 4 Strings 97

b) char, identificador e nome;

c) qualquer tipo básico, identificador, tamanho;

d) char, identificador, tamanho;

e) string, nome, tamanho.

3) Assinale a opção CORRETA.


a) A instrução char num(25); declara uma string.

b) A instrução char s={'T','e','s','t','e','\0'}; declara e inicia-


liza a string s.

c) A expressão nome[4] acessa o quinto elemento da


string.

d) A instrução nome="George Papu" atribui o literal Ge-


orge Papu à variável nome.

e) Todas as afirmações anteriores estão corretas.

4) Qual é a função mais apropriada para ler uma string com-


posta por várias palavras?
a) fgets

b) scanf

c) puts

d) printf

e) getche
98 Algoritmos e Programação II

5) O que há de errado com o seguinte trecho de código?


char a[8],b[8];
strcpy(a,"abacate");
strcpy(b,"banana");
if(a<b)
printf("%s vem antes de %s no dicionário",a,b);
else
printf("%s vem depois de %s no dicionário",a,b);
a) A condição da estrutura if deveria ser (a>b).

b) As variáveis a e b não foram inicializadas.

c) A função printf deveria usar o %c ao invés de %s.

d) Não é possível comparar as strings com a expressão


(a<b).

e) O trecho de código apresentado não possui erros.

6) Considerando a declaração
char frase[50];

a instrução abaixo acessa corretamente todos os elementos


da string.

for(i=0;i<=50;i++)

printf("%c",frase[i]);

a) Sim

b) Não
Capítulo 4 Strings 99

Parte II - Resolução de problemas

Resolva os problemas descritos a seguir, utilizando a Lingua-


gem C.

1) Elabore um programa em C que leia um caractere e uma


string com, no máximo, 20 caracteres, conte e escreva quan-
tas vezes o caractere lido inicialmente aparece na string.

2) Escreva um programa em C para ler uma frase com, no


máximo, 40 caracteres, contar e imprimir o número de
caracteres dessa frase sem utilizar a função strlen.

3) Construa um programa em linguagem C para ler uma string


com, no máximo, 40 caracteres. A seguir, converta todas
as letras minúsculas existentes na frase para maiúsculas e
escreva a string modificada.

4) Faça um programa que leia o nome e o sobrenome de uma


pessoa separadamente. O programa deve juntar as duas
strings em uma só e escrever na tela: a nova string, o seu
tamanho, a quantidade de nomes (exemplo: Maria Tereza
Gaston = 3 nomes) e a primeira letra do nome.

5) Faça um programa que leia repetidamente uma string e


mostre o seu tamanho (número de caracteres ocupados)
até que o valor digitado seja FIM. O programa deverá
mostrar quantas strings foram digitadas e o número total
de caracteres, sem considerar a palavra FIM. Utilize a fun-
ção scanf para fazer a leitura das strings.
100 Algoritmos e Programação II

Exemplo

Digite uma string: AULA

Tamanho: 4

Digite uma string: PROVA

Tamanho: 5

Digite uma string: FIM

Total de strings digitadas: 2

Total de caracteres: 9

6) Ler um valor n que representa o número de pares de pa-


lavras que serão lidas (declarar duas strings que poderão
ter no máximo 20 caracteres). A seguir, ler os n pares e
imprimir para cada par: IGUAIS se as palavras informadas
forem iguais; DIFERENTES se as palavras informadas fo-
rem diferentes; ORDEM CRESCENTE se as palavras foram
informadas em ordem crescente; ORDEM DECRESCENTE
se as palavras foram informadas em ordem decrescente.

Respostas dos exercícios da Parte I


1 - c; 2 - d; 3 - c; 4 - a; 5 - d; 6 - b.
Vanessa Lindemann*

Capítulo 5

Variáveis Indexadas
Bidimensionais

ÂÂ
N
o capítulo 3, uma variável indexada unidimensional
foi definida como um conjunto de dados ordenados e
homogêneos, armazenado de forma contínua na memória,
acessível a partir de um único nome e um índice. A única
diferença entre essa definição e a de uma variável indexada
bidimensional, diz respeito aos índices que, nesse caso, são
dois − um para representar as linhas e outro para repre-
sentar as colunas. Essas variáveis também são conhecidas
como arranjos bidimensionais, matrizes bidimensionais ou,
simplesmente, matrizes (nome que será adotado neste livro).

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
102 Algoritmos e Programação II

5.1 Estrutura

A estrutura de uma matriz em linguagem C é ilustrada na Figu-


ra 5.1. Em algoritmo, o limite inicial do índice de cada dimen-
são é 1, enquanto que em Linguagem C é 0.

Algoritmo Lingagem C
notas notas
1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8
10 9
1 2 3 0 1 2
Índices das linhas: 1 a 10 Índices das linhas: 0 a 9

Índices das colunas: 1 a 3 Índices das colunas: 0 a 2

Figura 5.1 − Exemplo da estrutura de uma matriz bidimensional 10x3

5.2 Declaração

Para declarar uma matriz, é necessário definir o nome (iden-


tificador) por meio do qual ela será manipulada; o tamanho
Capítulo 5 Variáveis Indexadas Bidimensionais 103

da variável, que indica quantos valores ela poderá armazenar


(número de linhas e número de colunas); e, finalmente, o tipo
dos dados que serão armazenados nela. A sintaxe da declara-
ção de uma matriz, em linguagem C, é apresentada a seguir.

<tipo> <identificador>[<linhas>][<colu-
nas>];

Onde: tipo representa um dos tipos básicos; identificador é


o nome que será usado para manipular a variável; linhas e co-
lunas definem o tamanho da matriz, ou seja, indicam quantas
linhas e quantas colunas ela terá.

A Tabela 5.1 exemplifica como a matriz da Figura 5.1 é


declarada em português estruturado e o equivalente em Lin-
guagem C.

Português estruturado Linguagem C


notas: matriz [1..10,1..3] de
float notas[10][3];
real

Tabela 5.1 − Exemplo da declaração de uma matriz bidimensional

Uma matriz pode ser inicializada no momento de sua de-


claração. Ao executar int m[2][3]={0} a variável m é criada
e terá todas as suas posições inicializadas com o valor zero;
para atribuir um valor diferente a cada posição da matriz, usa-
-se a sintaxe int m[2][3]={1,2,3,4,5,6} ou, ainda, int
m[2][3]={{1,2,3},{4,5,6}}. As chaves mais internas desse
último exemplo, delimitam os elementos de cada uma das li-
nhas da matriz, nesse caso, 1, 2 e 3 serão armazenados na
104 Algoritmos e Programação II

primeira linha e 4, 5 e 6 na segunda. A Figura 5.2 apresenta


um exemplo da inicialização de matrizes.

Figura 5.2 − Exemplo da inicialização de matrizes

5.3 Manipulação

Para acessar um elemento de uma matriz, além de referenciar


o nome da variável (identificador), é necessário indicar a po-
sição do elemento desejado. A posição do elemento de uma
matriz, denominada índice, deve ser indicada entre colchetes
e pode ser uma constante, uma expressão aritmética ou uma
Capítulo 5 Variáveis Indexadas Bidimensionais 105

variável. Ao isolar um elemento da matriz, é possível realizar


instruções primitivas de entrada, de saída e de atribuição.

Alguns exemplos da instrução primitiva de atribuição são


apresentados na Tabela 5.2. Na coluna da esquerda, os exem-
plos aparecem em português estruturado e na coluna da di-
reita, em linguagem C. Em notas[2][0] = 7.7, por exemplo,
o primeiro índice representa a linha e o segundo a coluna da
matriz, ou seja, o valor 7.7 será armazenado na terceira linha
e na primeira coluna da matriz, como ilustra a Figura 5.3.

Português estruturado Linguagem C


notas[3,1] 7.7 notas[2][0]=7.7;

notas[3,2] 7.9 notas[2][1]=7.9;

notas[3,3] (notas[3,1] + notas[2][2]=(notas[2][0] +


notas[3,2])/2 notas[2]
[1])/2;
l 3 l=2;

c 1 c=0;

notas[l,c] 7.7 notas[l][c]=7.7;

c 2 c=1;

notas[l,c] 7.9 notas[l][c]=7.9;

c 3 c=2;

notas[l,c] (notas[l,1] + notas[l][c]=(notas[l][0] +


notas[l,2])/2 notas[l][1])
/ 2;

Tabela 5.2 − Exemplo de atribuição de valores a uma matriz


106 Algoritmos e Programação II

notas
0
1 7.7 7.9 7.8
2
3
4
5
6
7
8
9
0 1 2
Figura 5.3 − Variável notas depois das instruções de atribuição, em
Linguagem C

A Tabela 5.3 exemplifica a entrada de dados utilizando ma-


triz. A Figura 5.4 ilustra o resultado da variável notas, supondo
que o usuário tenha digitado os seguintes dados: aluno 1, 5.9 e
3.1; aluno 2, 8.5 e 6.5; aluno 3, 7.7 e 7.9; aluno 4, 9.0 e 8.2...
Capítulo 5 Variáveis Indexadas Bidimensionais 107

Português estruturado Linguagem C


gotoxy(30,5);

escrever ("Informe as notas do printf("Informe as notas do 3º


3º aluno: ") aluno: ");

ler(notas[3,1]) scanf("%f",&notas[2][0]);

ler(notas[3,2]) scanf("%f",&notas[2][1]);

notas[3,3] (notas[3,1]+ notas[2][3] = (notas[2][0] +


notas[3,2])/2 notas [2]
[1])/2;

gotoxy(10,5);

escrever("Informe as notas dos printf("Informe as notas dos

alunos: ") alunos: ");

para l 1 até 10 faça for(l=0;l<10;l++) {

para c 1 até 2 faça for(c=0;c<2;c++) {

gotoxy(c*4+10,l*2+8);

ler(notas[l,c]) scanf("%f",&notas[l]
[c]);

Tabela 5.3 − Exemplos de entrada de dados em uma matriz


108 Algoritmos e Programação II

notas
0 5.9 3.1 4.5
1 8.5 6.5 7.5
2 7.7 7.9 7.8
3 9.0 8.2 8.6
4 8.1 9.2 8.7
5 6.2 6.4 6.3
6 4.1 5.0 4.6
7 7.9 8.1 8.0

8 6.2 6.4 6.3

9 5.7 5.0 5.4


0 1 2
Figura 5.4 − Variável notas depois da entrada de dados, em Linguagem C

5.4 Exemplos

Essa seção é dedicada à resolução de alguns problemas, cujas


soluções utilizam variáveis indexadas bidimensionais, ou seja,
matrizes. No primeiro exemplo, a solução é apresentada em
português estruturado e, em seguida, o equivalente em lingua-
gem C. Nos demais exemplos, utiliza-se apenas a representa-
ção em linguagem C.

 Exemplo 5.1
Problema: ler uma matriz 3x4 do tipo inteiro, somar seus
elementos e apresentar o resultado.
Capítulo 5 Variáveis Indexadas Bidimensionais 109

Problema: ler uma matriz 3x4 do tipo inteiro e somar seus elementos.
Português estruturado Linguagem C
#include <stdio.h>
#include <conio.h>

algoritmo exemplo main() {


variáveis
m: matriz[1..3,1..4] de inteiro int m[3][4];
l, c, soma: inteiro int l, c, soma;
início
soma 0 soma=0;
clrscr();
gotoxy(10,5);
escrever("Matriz 3x4: ") printf("Matriz 3x4: ");
para l de 1 até 3 faça for(l=0;l<3;l++)
para c de 1 até 4 faça for(c=0;c<4;c++)
início {
gotoxy(c*5+10,l*2+8);
ler(m[l][c]) scanf("%i",&m[l][c]);
soma soma + m[l][c] soma = soma + m[l][c];
fim }
gotoxy(10,16);
escrever("Soma =",soma) printf("Soma = %i",soma);
getch();
fim }

Quadro 5.1− Solução para o problema do exemplo 5.1

É importante lembrar que, na declaração da matriz, a pri-


meira dimensão refere-se às linhas e a segunda às colunas,
portanto, o exemplo do Quadro 5.1 int m[3][4] declara
uma matriz com três linhas e quatro colunas, cujos elementos
serão do tipo inteiro. Como a matriz tem duas dimensões, são
necessárias duas variáveis para representar seus índices, nesse
caso, l e c, e duas estruturas de repetição para percorrê-los.
Destaca-se, ainda, que na função gotoxy(c*5+10,l*2+8)
110 Algoritmos e Programação II

os dois parâmetros são definidos através de expressões, va-


riando tanto as colunas quanto as linhas.

 Exemplo 5.2
Problema: ler uma matriz 2x3 do tipo inteiro, encontrar e
escrever o maior elemento e sua posição na matriz.

Figura 5.5 Solução, em linguagem C, para o problema do exemplo 5.2

As estruturas de repetição for (linhas 11 e 12) são usadas


para percorrer todas as posições da matriz. Em cada posição,
ocorre a entrada de dados (função scanf − linha 14), cujo
Capítulo 5 Variáveis Indexadas Bidimensionais 111

valor é comparado com a variável maior. Se o valor digitado


pelo usuário for maior que o valor armazenado na variável
maior (condição avaliada na linha 15), a variável maior re-
cebe o valor digitado (linha 16) e as variáveis linha e col-
una recebem a posição desse valor na matriz (linhas 17 e
18). Vale lembrar que as variáveis linha e coluna recebem,
respectivamente, l+1 e c+1 porque os índices em linguagem
C iniciam em zero e, sem somar um, o usuário não entenderia
o resultado (sem somar um aos índices, o resultado do teste
de mesa do Quadro 5.2, por exemplo, seria Posição = linha
1 e coluna 2, diferente do que o usuário visualiza na matriz,
que é linha 2 e coluna 3). Ao sair dos laços de repetição, o
programa exibe na tela o maior elemento e sua posição na
matriz (linhas 22 a 25).

O teste de mesa do programa da Figura 5.5 é apresentado


no Quadro 5.2. Para simular a execução desse programa, foi
considerada a entrada dos seguintes dados: 5 3 6 4 2 8 − lis-
tados à esquerda no Quadro 5.2.
112 Algoritmos e Programação II

Exemplo 5.2 - Procura o maior elemento e sua posição em uma matriz.


Entrada Teste de mesa Saída
5 3 6 Variáveis Maior elemento
4 2 8
Linha =8
l c m[l][c] maior linha coluna
06 0
Posição
11
= linha 2 e
12
coluna 3
14 m[0][0] = 5
16 5
17 1
18 1
12 1
14 m[0][1] = 3
12 2
14 m[0][2] = 6
16 6
17 1
18 3
12 3
11 1
12 0
14 m[1][0] = 4
12 1
14 m[1][1]= 2
12 2
14 m[1][2]= 8
16 8
17 2
18 3
12 3
11 2

Quadro 5.2 − Teste de mesa do exemplo 5.2


Capítulo 5 Variáveis Indexadas Bidimensionais 113

A simulação de execução começa na linha 06 (Figura 5.5),


onde a variável maior é inicializada com zero, gerando o
primeiro registro na tabela do teste de mesa (Quadro 5.2).
Nas linhas 11 e 12, aparecem as estruturas de repetição for,
uma na sequência da outra − a primeira usada para percorrer
as linhas e a segunda as colunas da matriz. Como pode ser
observado no teste de mesa, para cada valor de l (variável
usada no primeiro for), todos os valores de c (variável usada
no segundo for) serão executados. Para l igual a 0, c será 0,
1 e 2, quando c for 3 a condição c<3 (linha 12 − Figura 5.5)
não é satisfeita e esse laço de repetição é encerrado (linha 20).
Ao chegar na linha 21, a chave que indica o fim da primeira
estrutura de repetição, desvia a execução do programa para o
seu início (linha 11), quando l passa a ser 1 e todo o processo
é repetido (para l igual a 1, c será 0, 1 e 2) até que a variável
l seja 2 e a condição l<2 resulte falso.

 Exemplo 5.3
Problema: ler uma matriz 3x3 do tipo caractere, trocar os
elementos da primeira com a última linha e escrever a matriz
modificada. A Figura 5.6 ilustra um exemplo de dados de en-
trada e saída para esse problema.

0 a a a 0 c c c
1 b b b 1 b b b
2 c c c 2 a a a
0 1 2 0 1 2

Figura 5.6 − Ilustração de dados de entrada e saída do exemplo 5.3


114 Algoritmos e Programação II

Como pode ser observado na Figura 5.7, esse problema


foi resolvido em três etapas: a entrada de dados, que ocorre
entre as linhas 10 e 14; a troca dos elementos da matriz, re-
alizada pelas instruções entre as linhas 15 e 19; e, por fim, a
saída de dados, que apresenta a matriz modificada, executada
entre as linhas 22 e 26.

Para realizar a troca, é necessário que todos os dados te-


nham sido armazenados na matriz, já que os elementos da pri-
meira linha serão trocados com os elementos da terceira linha.
Além disso, deve-se criar uma variável auxiliar (a necessidade
do uso da variável auxiliar para realizar trocas foi explicada no
exemplo 3.3 do capítulo 3).
Capítulo 5 Variáveis Indexadas Bidimensionais 115

Figura 5.7 − Solução, em linguagem C, para o problema do exemplo 5.3

É importante observar que, nas etapas de entrada e saída


de dados, foram utilizadas duas estruturas de repetição, um
for para percorrer as linhas e outro para as colunas. Na etapa
de trocas, entretanto, utiliza-se apenas uma estrutura de repeti-
ção para percorrer as colunas (linha 15). Isso ocorre porque as
linhas a serem trocadas são "fixas", ou seja, o programa troca
os elementos da linha 0 com os elementos da linha 2.
116 Algoritmos e Programação II

 Exemplo 5.4
Problema: ler duas matrizes 2x4, criar e escrever uma ter-
ceira matriz com a soma dos elementos das duas primeiras.

A solução para esse problema, em que mais de uma matriz


é manipulada no programa, é apresentada na Figura 5.8.

Figura 5.8 − Solução, em linguagem C, para o problema do exemplo 5.4


Capítulo 5 Variáveis Indexadas Bidimensionais 117

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) Sobre variáveis indexadas bidimensionais, é CORRETO afirmar:


I. Representam conjuntos ordenados de valores homo-
gêneos, que podem ser de qualquer um dos tipos básicos
de dados.

II. São armazenadas na memória de forma contínua e


acessadas a partir de um único nome e um índice.

III. Também são conhecidas como arranjos ou matrizes bi-


dimensionais.

a) apenas II e III estão corretas;

b) apenas I e II estão corretas;

c) apenas a II está correta;


118 Algoritmos e Programação II

d) apenas I e III estão corretas;

e) todas estão corretas.

2) Para declarar uma matriz, é necessário definir o tipo dos


dados que serão armazenados nela, o identificador a par-
tir do qual ela será manipulada; e o tamanho da variável
(quantidade de linhas e de colunas), que indica quantos
valores ela poderá armazenar.
a) Certo b) Errado

3) Considerando a declaração e a inicialização de variáveis


indexadas, assinale a alternativa INCORRETA.
a) float m[2][2];

b) int m[5][5]={0};

c) int mat[2][4]={{12,43},{78,10},{25,01},{29,18}};

d) char letras[3][3]={'a','b','c','d','e','f','g','h','i'};

e) char respostas[4][6]={'s'}.

4) Considerando o programa a seguir,


main( ){

int m[2][2]={{2,7},{5,8}},i=0,j=0;

printf("%05i \n",m[i++][j]);
Capítulo 5 Variáveis Indexadas Bidimensionais 119

printf("%-4i %-4i",i,++j);

que valores serão exibidos na tela após sua execução?

a) 2, 1 e 0

b) 2, 0 e 0

c) 00002, 1 e 0

d) 00002, 1 e 1

e) 2, 0001 e 0001

5) Considerando a declaração de variáveis abaixo,


int m[2][6]={2,3,5,4,1,0,6,4,3,2,7,0},l,c;

o que faz o trecho que código a seguir?

for(l=0;l<2;l++)

for(c=0;c<5;c++)

m[l][5]+=m[l][c];

a) Soma todos os elementos de uma matriz 2x6 do tipo


inteiro.

b) Para cada linha, soma os elementos das primeiras cin-


co colunas da matriz e armazena na sexta coluna.
120 Algoritmos e Programação II

c) Soma os elementos entre as colunas 0 e 5, armazenan-


do o total na última posição da matriz.

d) Para cada linha, soma os elementos das primeiras qua-


tro colunas da matriz e armazena na quinta coluna.

e) Em cada linha da matriz, substitui o elemento da sexta


coluna pelos outros elementos da matriz.

Parte II - Resolução de problemas

Resolva os problemas descritos a seguir, utilizando a Lingua-


gem C.

1) Elabore um programa em C que leia uma matriz 3x5 com


elementos do tipo inteiro, calcule e escreva a quantidade
de valores entre 15 e 20, inclusive.

2) Faça um programa em C que leia uma matriz 4x4 com


elementos do tipo caractere. A seguir, troque os elemen-
tos da coluna 1 com os elementos da coluna 4 e escreva
a matriz modificada.

3) Construa um programa que leia uma matriz 4x5, calcule e


mostre: a quantidade de elementos pares; a soma dos ele-
mentos ímpares; a média de todos os elementos da matriz.

4) Escreva um programa que leia uma matriz 6x6 do tipo


inteiro, calcule e informe a soma dos elementos da dia-
gonal principal.
Capítulo 5 Variáveis Indexadas Bidimensionais 121

5) Faça um programa que leia um valor inteiro e, a seguir, leia


uma matriz M(3x4). Crie uma matriz que receba o resulta-
do do valor digitado inicialmente pelo usuário multiplicado
por um dos elementos da matriz. Veja o exemplo:

Matriz M Matriz resultante


Valor = 2 6 4 1 2 12 8 2 4
1 2 4 7 2 4 8 14
2 6 3 8 4 12 6 16

Respostas dos exercícios da Parte I


1 - d; 2 - a; 3 - c; 4 - d; 5 - b.
Vanessa Lindemann*

Capítulo 6

Estruturas

ÂÂ
A
s estruturas, também denominadas registros, são
variáveis compostas heterogêneas que permitem ar-
mazenar um conjunto de dados na memória, agrupados
sob um mesmo nome, gerando novos tipos de dados. A
estrutura serve para organizar de forma lógica um dado
cujo valor é composto por mais de uma variável como,
por exemplo, uma data que é composta por três valores,
correspondentes a dia, mês e ano.

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
Capítulo 6 Estruturas 123

6.1 Declaração

Ao declarar uma estrutura, cria-se um tipo novo, definindo um


identificador para ele; o nome das variáveis que farão parte
da estrutura e o tipo de dados que serão armazenados em
cada uma delas. Finalmente, declara-se uma variável do tipo
criado, a partir da qual a estrutura será manipulada. A sintaxe
da declaração de uma estrutura em português estruturado é
apresentada a seguir.

tipo <identificador_tipo_novo> = registro

<variavel 1>: <tipo>

<variavel 2>: <tipo>

<variavel n>: <tipo>

fim

variáveis

<variavel>: <identificador_tipo_novo>

A Figura 6.1 apresenta um exemplo de uma estrutura cria-


da para armazenar dados de um aluno: número de matrícula,
nome, nota 1, nota 2 e média. O Quadro 6.1 mostra como
essa estrutura seria declarada em português estruturado e o
equivalente em linguagem C.
124 Algoritmos e Programação II

Aluno
Matrícula: 01200
Nome: Ana Sonan
Nota 1: 7.5
Nota 2: 8.5
Média: 8.0
Figura 6.1 − Exemplo de estrutura que armazena dados de um aluno

Português estruturado Linguagem C


tipo reg = registro struct reg {
matricula: inteiro int matricula;
nome: cadeia char nome[60];
n1, n2, media: real float n1, n2, media;
fim };
variáveis
aluno: reg struct reg aluno;

Quadro 6.1 − Exemplo da declaração de uma estrutura

Em linguagem C, as estruturas são definidas a partir da pa-


lavra reservada struct, normalmente com escopo global (no
início do programa, antes da função main). A declaração das
variáveis que compõem a estrutura, denominadas membros da
estrutura, segue as regras para declaração de variáveis simples
em C, entretanto, estas não podem ser inicializadas. Os mem-
bros da estrutura podem ser de um tipo básico ou até mesmo
vetores e outras estruturas. O tamanho total de uma estrutura,
em bytes, é igual à soma do tamanho de seus membros.
Capítulo 6 Estruturas 125

A definição da estrutura não é o suficiente para que ela


possa ser utilizada. Por isso, depois de criá-la, é necessário
declarar uma variável para armazenar dados do programa.
No exemplo do Quadro 6.1, a instrução struct reg aluno;
declara a variável aluno com o tipo criado, que é struct reg.
Quando necessário, a variável aluno pode ser inicializada,
com valores para cada um dos seus membros entre chaves
e separados por vírgula, na ordem em que foram definidos,
como mostra o exemplo a seguir.

struct reg aluno={01200,"Ana Sonan",7,9,8};

6.2 Manipulação

Para acessar os membros de uma estrutura, além de refe-


renciar o nome da variável declarada, é necessário indicar o
membro desejado. Ao isolar um membro da estrutura, é possí-
vel realizar instruções primitivas de entrada, de saída e de atri-
buição. Exemplos da instrução de atribuição são apresentados
no Quadro 6.2 e de entrada de dados no Quadro 6.3.

Português estruturado Linguagem C


aluno.matricula 01200 aluno.matricula = 01200;

aluno.nome "Ana Sonan" strcpy(aluno.nome,"Ana Sonan");

aluno.n1 7.5 aluno.n1 = 7.5;

Quadro 6.2 − Exemplo de atribuição de valores aos membros de uma


estrutura
126 Algoritmos e Programação II

Português estruturado Linguagem C


escrever("Número de gotoxy(20,5);
matrícula:")
printf ("Número de matrícula: ");
ler(aluno.matricula)
scanf("%i",&aluno.matricula );

gotoxy(20,7);
escrever("Nome do aluno: ")
printf("Nome do aluno: ");
ler(aluno.nome)
fflush(stdin);
fgets(aluno.nome,60,stdin);

gotoxy(20,9);
escrever("Nota 1: ") printf("Nota 1: ");
ler(aluno.g1) scanf("%f",&aluno.n1 );

Quadro 6.3 − Exemplos de entrada de dados utilizando uma estrutura

A Figura 6.2 ilustra um exemplo simples da aplicação


dos conceitos estudados até aqui, neste capítulo. O progra-
ma lê a matrícula, o nome e as notas de um aluno, calcula
e apresenta sua média. Os dados lidos são armazenados
em uma estrutura.
Capítulo 6 Estruturas 127

Figura 6.2 − Exemplo de declaração e manipulação de uma estrutura

Entre as linhas 4 e 8 do programa da Figura 6.2, a es-


trutura reg é criada e a variável aluno declarada. Dife-
rentemente da declaração apresentada do Quadro 6.1, a
variável aluno foi declarada junto com o tipo novo criado,
colocando o nome da variável entre a chave que fecha a es-
trutura e o ponto e vírgula final. No exemplo do Quadro 6.1,
a variável foi declarada separada, após criar a estrutura, por
128 Algoritmos e Programação II

meio da instrução struct reg aluno;. As duas formas


de declaração estão corretas.

6.3 Vetores de estruturas

No exemplo anterior, só é possível armazenar os dados de um


aluno. Para armazenar os dados de mais de um aluno, pode-
-se, por exemplo, criar um vetor de estruturas. Em um vetor
de estruturas, cada elemento do vetor é uma estrutura, como
ilustra a Figura 6.3.

aluno aluno aluno


Matrícula: 01200 Matrícula: 00987 Matrícula: 00845
Nome: Ana Sonan Nome: Carlos Kremtz Nome: Maria Rediske
Nota 1: 5.0 Nota 1: 9.2 Nota 1: 7.5
Nota 2: 8.5 Nota 2: 8.8 Nota 2: 8.5
Média: 6.7 Média: 9.0 Média: 9.0

0 1 ... 9
Figura 6.3 − Exemplo de um vetor de estruturas

Um vetor de estruturas é declarado da mesma forma que


outros tipos de vetores já estudados, indicando seu tama-
nho entre colchetes, ao lado do nome da variável (exemplo:
struct aluno turma[10]). Para acessar um elemento de
um vetor de estruturas, deve-se colocar o índice, entre colche-
tes, logo à direita do nome do vetor, antes do ponto (exemplo:
turma[i].matricula).
Capítulo 6 Estruturas 129

O exemplo da Figura 6.4 lê a matrícula, o nome e as notas


de uma turma de 10 alunos. O programa armazena esses da-
dos em um vetor de estruturas como o ilustrado na Figura 6.3.
Além dos dados de entrada, a estrutura possui uma variável
para armazenar a média do aluno, calculada a partir das suas
notas. Ao finalizar a entrada de dados, o programa exibe um
relatório com todos os dados cadastrados.

Figura 6.4 − Exemplo de um vetor de estruturas


130 Algoritmos e Programação II

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) , também denominadas , são variáveis


compostas que permitem armazenar um con-
junto de dados na memória, agrupados sob um mesmo
nome, gerando novos .
A alternativa que completa corretamente as lacunas acima é:

a) estruturas - registros - homogêneas - tipos de dados;

b) estruturas - arranjos - heterogêneas - tipos de dados;

c) estruturas - registros - heterogêneas - tipos de dados;

d) registros - vetores - heterogêneas – estruturas;

e) registros - arranjos - heterogêneas - vetores de estruturas.


Capítulo 6 Estruturas 131

2) Sobre estruturas, é CORRETO afirmar:


I. Uma estrutura serve para organizar de forma lógica um
dado cujo valor é composto por mais de uma variável.

II. Ao declarar uma estrutura, cria-se um tipo de dado novo.

III. A definição da estrutura (criação do tipo novo) já é o


suficiente para que ela possa ser utilizada para armazenar
dados no programa.

a) apenas I e II estão corretas;

b) apenas I e III estão corretas;

c) apenas II e III estão corretas;

d) apenas I está correta;

e) I, II e III estão corretas.

3) A seguir, a declaração de um vetor de estruturas, cujas vari-


áveis foram inicializadas.
struct pessoa{
int cod=0;
char nome[60];
float peso=0,altura=0;
}equipe[10];

O trecho de código acima está:

a) Certo b) Errado
132 Algoritmos e Programação II

4) Uma estrutura pode ser inicializada conforme o exemplo a


seguir.

struct reg{
int cod,ano;
char modelo[15],cor[15],placa[9];
float preco;
};
struct reg automovel = {114,2014,"Gol","IXU
8912","preto",35000.00};

a) Certo b) Errado

5) reg[2].cpf acessa a variável cpf do segundo elemen-


to do vetor de estruturas declarado como reg.
a) Certo b) Errado

Parte II - Resolução de problemas

Resolva os problemas descritos a seguir, utilizando a Lingua-


gem C.

1) A agência de pesquisas "IBOPI" precisa de um programa


para cadastrar os dados de um levantamento realizado
nos clubes do Rio Grande do Sul, sobre os atletas de vo-
leibol. As informações a serem armazenadas, para cada
atleta, são: número de inscrição na federação, clube que
representa, nome, idade e altura. Além da opção para ca-
Capítulo 6 Estruturas 133

dastrar atletas, o programa deverá oferecer a opção de


listagem de todos os dados dos atletas. Considerar, no
máximo, 100 atletas.

2) Foi feita uma pesquisa com professores de uma universi-


dade. Foram coletados os seguintes dados de cada pro-
fessor: nome, idade, tempo de serviço na universidade e
quantidade de disciplinas que ministra. Faça um programa
que, a partir desses dados, calcule e informe: o percentual
de professores com idade entre 30 e 50 anos, a quanti-
dade de professores com mais de 10 anos de serviço, a
média de disciplinas ministrada por professor bem como a
quantidade de professores que ministram mais disciplinas
que a média. Considerar, no máximo, 50 professores.

3) Uma pesquisa coletou informações sobre as característi-


cas físicas de 10 modelos de uma agência, quais sejam:
gênero (F - feminino, M - masculino), idade, peso e al-
tura. Para facilitar o trabalho de tabulação, os alunos
de Algoritmos e Programação II deverão desenvolver um
programa para identificar:
 a maior idade entre os modelos;
 a porcentagem de modelos por gênero;
 o nº de homens com mais de 1,85 m;
 o peso médio das mulheres.

Respostas dos exercícios da Parte I


1 - c; 2 - a; 3 - b; 4 - b; 5 - b.
Vanessa Lindemann*

Capítulo 7

Ponteiros

ÂÂ
P
onteiro é uma variável que armazena um endereço de
memória. Essa é a razão para o seu nome: ele aponta
para outra variável. Como qualquer variável em C, um
ponteiro deve ser declarado antes de ser usado. Para de-
clarar um ponteiro, basta inserir * entre o tipo e o nome
da variável. No exemplo a seguir, o ponteiro declarado irá
apontar para uma variável do tipo inteiro.
int *ptr;

Para trabalhar com ponteiros, utiliza-se dois operadores es-


pecíficos: * e &. O operador & é colocado antes do nome
de uma variável para obter o seu endereço. Ao atribuir esse

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
Capítulo 7 Ponteiros 135

endereço a um ponteiro, diz-se que o ponteiro está "apon-


tando para" a variável. O operador de conteúdo * só pode
ser utilizado com ponteiros, ele obtém o valor da variável
apontada pelo ponteiro, operação esta que é chamada de
"referência indireta".

As variáveis valor e pt são declaradas e inicializa-


das no trecho de código a seguir. Usa-se o operador de
endereçamento (&) na inicialização do ponteiro para que
este receba o endereço de memória da outra variável. A
Figura 7.1 ilustra o resultado dessas instruções, simulando
a memória: a variável valor armazena 35 no endereço
de memória 8711, conteúdo armazenado na variável pt.
Portanto, pt aponta para valor.
int *pt, valor;

valor=35;

pt=&valor;

Memória

valor
35
8711

pt
8711
9376
Figura 7.1 − Exemplo da manipulação de ponteiros
136 Algoritmos e Programação II

O trecho de código a seguir apresenta mais alguns exem-


plos da manipulação de ponteiros, cujos resultados são ilus-
trados na Figura 7.2.

int x=10,y=2,z,*pt1,*pt2;

pt1=&x;

pt2=&y;

z=*pt1+*pt2;

Memória
4902 6321
pt1 z
9120 12

8872 8735 9120


y pt2 x
2 8872 10

Figura 7.2 − Exemplo da manipulação de ponteiros

O programa exibido na Figura 7.3 também exemplifica o


uso de ponteiros. Nele, a variável v é inicializada com 15 (lin-
ha 5) e a variável p, declarada como um ponteiro, recebe o
endereço de memória de v (linha 7). Assim, ao escrever *p, o
valor exibido será exatamente o mesmo de v, já que *p aponta
para v.
Capítulo 7 Ponteiros 137

Figura 7.3 − Exemplo da manipulação de ponteiros

A saída gerada na instrução da linha 11, é Valor inicial: v


= 15 *p=15. Na linha 13, acontece uma atribuição via re-
ferência indireta, onde a variável v recebe 30, de forma que
a saída gerada na linha 16 é Valor alterado: v = 30 *p=30.
138 Algoritmos e Programação II

7.1 Usando ponteiros para manipular


vetores

Em linguagem C, quando o nome de um vetor aparece sem


o índice, este corresponde ao endereço de memória do seu
primeiro elemento. Portanto, ptr=&vet[0] é equivalente a
ptr=vet, como pode ser observado no exemplo apresentado
a seguir.

int vet[]={3, 7, 8}, *ptr;

ptr = vet;

printf("%i", *ptr);

O vetor é inicializado com 3, 7 e 8 e, em seguida, a variável


ptr recebe o endereço de memória do primeiro elemento de
vet. Logo, ao escrever *ptr, será exibido o valor 3.

Um exemplo da manipulação de vetores utilizando pontei-


ros pode ser observado na Figura 7.4.
Capítulo 7 Ponteiros 139

Figura 7.4 − Exemplo da manipulação de vetores com ponteiros

Esse programa lê uma frase qualquer digitada pelo usuá-


rio e armazena na variável frase, declarada como string. Em
seguida, percorre o vetor, caractere a caractere, utilizando a
variável do tipo ponteiro na estrutura de repetição (linha 15).
Na primeira parte da estrutura for, ptr=frase é equivalente à
ptr=&frase[0], ou seja, ptr recebe o endereço do primeiro
elemento do vetor; na segunda parte, a instrução *ptr!='\0'
verifica o conteúdo armazenado na posição atual do vetor e
retorna verdadeiro até que o caractere especial \0 seja encon-
trado; por fim, na terceira parte, a variável ponteiro é incre-
mentada com a instrução ptr++, fazendo o ponteiro passar
para a próxima letra da string (ou seja, o ponteiro passa para
a próxima posição de um vetor de caracteres).
140 Algoritmos e Programação II

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) Considere as seguintes afirmativas:


I. Ponteiros são variáveis que armazenam endereços de
memória. O ponteiro aponta para o endereço de memória
de uma variável declarada no programa.

II. Uma variável declarada como ponteiro deve ser do mesmo


tipo que o conteúdo da variável para a qual ela vai apontar.

III. O operador de endereço (&) determina o endereço de


memória de uma variável, enquanto o operador de conte-
údo (*) determina o conteúdo da variável armazenada no
endereço apontado por um ponteiro.

Está(ão) correta(s):
Capítulo 7 Ponteiros 141

a) apenas I e III

b) apenas I e II

c) apenas II e III

d) apenas a I

e) I, II e III

2) Na expressão float *pt o que é do tipo float?


a) o endereço de pt;

b) a variável apontada por pt;

c) o endereço apontado por pt;

d) a variável pt;

e) nenhuma das respostas anteriores.

3) Que valor será escrito no trecho de código a seguir?


int a=8, b=3, *p;
p=&a;
(*p)++;
p=&b;
*p=a/b;
printf(" %i ",a+b);

a) 12 b) 8 c) 14 d) 3 e) 6
142 Algoritmos e Programação II

4) Dado o código-fonte a seguir, escrito em Linguagem C:

#include<stdio.h>
int main(void){
int n[]={2,4,6,8,10};
int *p;
p=&n[0];
p+=3;
printf(“Valor: %d”,*p);
(*p)++;
printf(“Valor: %d”,*p);
}

A saída do programa é:

a) Valor: 6 Valor: 8

b) Valor: 8 Valor: 9

c) Valor: 4 Valor: 5

d) Valor: 8 Valor: 10

e) Valor: 6 Valor: 7

5) Dado o código-fonte a seguir, escrito em Linguagem C:

#include<stdio.h>
main(){
int x[]={9,10,11,12,13};
int *p;
p=&x[2];
Capítulo 7 Ponteiros 143

p++;
printf("Valor 1: %d", *p);
(*p)+=2;
printf("Valor 2: %d \n",*p);

A saída do programa é:

a) Valor 1: 11 Valor 2: 12

b) Valor 1: 12 Valor 2: 14

c) Valor 1: 11 Valor 2: 13

d) Valor 1: 11 Valor 2: 15

e) Valor 1: 12 Valor 2: 13

Respostas dos exercícios da Parte I


1 - e; 2 - b; 3 - a; 4 - b; 5 - b.
Vanessa Lindemann*

Capítulo 8

Funções

ÂÂ
A
lém da função main e das diversas funções pré-defi-
nidas das bibliotecas padrões da linguagem, um pro-
grama em C pode conter funções definidas pelo próprio
programador, que só serão executadas se forem, direta ou
indiretamente, chamadas pela função principal.

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
Capítulo 8 Funções 145

As funções são criadas para organizar o código fon-


te do programa, resolvem problemas bem específicos e,
se forem bem construídas, são facilmente reutilizadas. O
programador pode, por exemplo, criar uma biblioteca (ar-
quivo de cabeçalho) com funções para validar data, va-
lidar hora e desenhar bordas, que poderão ser utilizadas
sempre que necessário, incorporando-as aos seus progra-
mas a partir da diretiva #include.
A sintaxe de uma função em linguagem C é apresen-
tada a seguir.
tipo_de_retorno identificador(lista_
de_parâmetros){
// declaração de variáveis locais
// corpo da função
return(valor);
}

 Tipo de retorno: a função pode retornar um valor para


a função chamadora. O tipo de retorno indica qual o
tipo do dado que será devolvido. Nos casos em que a
função não retorna nenhum valor, funcionando como
um procedimento, o tipo de retorno deve ser definido
como void.
 Identificador: indica o nome da função, a partir do
qual o bloco de código correspondente à função será
chamado.
 Lista de parâmetros: os parâmetros de uma função
são variáveis locais automaticamente inicializadas com
os valores passados no momento da sua chamada.
Cada um dos parâmetros deve ser declarado, indicando
146 Algoritmos e Programação II

o seu tipo e nome. Se a função não receber nenhum


valor por parâmetro, os parênteses ao lado do nome da
função ficam vazios.
 Declaração de variáveis locais: as variáveis de escopo
local devem ser declaradas e só podem ter seus valores
acessados dentro da função, enquanto esta estiver ativa.
 Corpo da função: conjunto de instruções que com-
põem a função. É onde é resolvido o problema para o
qual a função foi escrita.
 Return: o comando return finaliza a execução da fun-
ção que está sendo executada. Se a função retornar al-
gum valor, esse comando é obrigatório. Se a função for
do tipo void (ou seja, não retorna nenhum valor), esse
comando não é necessário.
Existem duas formas de passagem de parâmetros às
funções: passagem de parâmetros por valor (onde uma
cópia do valor passado pela função chamadora é for-
necido à função chamada) e passagem de parâmetros
por referência (quando o que é passado da função cha-
madora à função chamada, é o endereço de memória
das variáveis) − temas abordados nas próximas seções.
Uma mesma função, se receber mais que um argumen-
to, pode combinar passagem de parâmetro por valor e
por referência.
Capítulo 8 Funções 147

8.1 Passagem de parâmetros por valor

Na passagem de parâmetros por valor, o parâmetro passado


para a função é uma cópia da variável (argumento), de forma
que alterar a variável dentro da função que a recebeu não irá
alterar a variável original, da qual ela foi copiada.

Um exemplo da passagem de parâmetros por valor é apre-


sentado na Figura 8.1. As variáveis a e b são declaradas e
inicializadas com zero na função principal (linha 11). Na li-
nha 17, a instrução incrementa(a,b); faz a chamada à
função, enviando as variáveis a e b como parâmetros. Nesse
momento, o programa desvia seu fluxo de execução para a
linha 24, quando o conteúdo das variáveis a e b é copiado
para as variáveis x e y (ou seja, x e y recebem zero). Dentro
da função, as variáveis x e y são incrementadas (linhas 25 e
26) e têm seus valores exibidos na tela (linha 28). Ao encontrar
o final da função, na linha 29, o fluxo de execução do progra-
ma retorna à função principal, onde irá executar a instrução
seguinte à chamada da função − nesse caso, linha 19. Na
função principal, os valores das variáveis a e b são exibidos
novamente na tela (linha 20), demonstrando que estes não
foram alterados dentro da função incrementa.

Sempre que uma função é chamada antes do ponto onde


ela foi criada, deve-se declarar o protótipo da função acima
do início do programa. O protótipo corresponde à primeira
linha da função (onde aparece o seu nome) finalizada por um
ponto-e-vírgula − isso pode ser observado no exemplo da Fi-
gura 8.1. A função incrementa é chamada na linha 17, antes
do ponto em que ela foi criada, que é entre as linhas 24 e
148 Algoritmos e Programação II

29, por isso, na linha 8, foi incluído o protótipo da função (o


protótipo da função "avisa" ao compilador que a função cha-
mada na linha 17 está descrita mais adiante, caso contrário,
ele retornaria um erro de função não identificada).

Figura 8.1 − Exemplo da passagem de parâmetros por valor

No exemplo da Figura 8.1, o tipo void antes do nome da


função incrementa indica que esta não retorna nenhum va-
Capítulo 8 Funções 149

lor à função chamadora, diferente do programa apresentado


na Figura 8.2, que retorna um valor inteiro.

Esse programa, lê dois valores na função principal (val-


or1 e valor2) e faz a chamada à função fsoma (linha 20)
enviando-os como parâmetros. As variáveis v1 e v2 recebem
uma cópia do conteúdo de valor1 e valor2 (linha 27).
Dentro da função fsoma, a variável result recebe o resul-
tado da soma de v1 e v2 (linha 29). O conteúdo da variável
result é enviado à função chamadora. Na linha 20, a va-
riável soma recebe o retorno da função fsoma. O esquema
da Figura 8.3 ilustra o vai e volta de valores e a função main
e a fsoma.
150 Algoritmos e Programação II

Figura 8.2 − Exemplo da passagem de parâmetros por valor, com retorno

Figura 8.3 − Exemplo da passagem de parâmetros por valor, com retorno


Capítulo 8 Funções 151

8.2 Passagem de parâmetros por


referência

Quando a função precisa alterar o valor da variável passada


como argumento, é o endereço da variável que deve ser pas-
sado como parâmetro, o que caracteriza a passagem de pa-
râmetros por referência. Como é o endereço de memória da
variável que é passado como parâmetro, a variável que recebe
o parâmetro, na função chamada, deve ser declarada como
um ponteiro. Isso pode ser observado no programa da Figura
8.4. A diferença entre esse programa e o anterior (apresenta-
do na Figura 8.2) é que com a passagem de parâmetros por
referência, o conteúdo das variáveis a e b é alterado de dentro
da função incrementa.
152 Algoritmos e Programação II

Figura 8.4 − Exemplo da passagem de parâmetros por referência

Como foi explicado anteriormente, o que caracteriza a pas-


sagem de parâmetros por referência é que, ao invés de fazer
uma cópia do conteúdo das variáveis a e b, envia-se à função
chamada, os endereços dessas variáveis. Para enviar o ende-
reço de uma variável à função chamada, é necessário incluir
o & antes do seu nome, como pode ser observado na linha 17
da Figura 8.4. Consequentemente, na função chamada, os
parâmetros devem ser declarados como ponteiros para rece-
Capítulo 8 Funções 153

ber os endereços enviados, como pode ser observado na linha


24 do programa da Figura 8.4. As instruções (*x)++ e (*y)++
(linhas 25 e 26) alteram o valor das variáveis originais a e b, o
que pode ser confirmado pela saída do programa.

O programa da Figura 8.5 apresenta mais um exemplo da


passagem de parâmetros por referência. Esse programa lê dois
caracteres na função main e faz a chamada à função troca,
enviando os endereços de memória das variáveis lidas, para
que estas tenham seus conteúdos trocados dentro da função
troca. Quando o programa retorna o fluxo de execução para
a função main, o conteúdo das variáveis é exibido na tela.
154 Algoritmos e Programação II

Figura 8.5 − Exemplo da passagem de parâmetros por referência

Os endereços são passados como parâmetros por duas ra-


zões: (a) pela eficiência − é mais rápido passar o endereço de
uma estrutura, por exemplo, do que a estrutura em si; (b) pela
possibilidade de manipular fisicamente uma variável externa a
uma função − normalmente, o resultado de uma chamada de
função é expresso pelo valor de retorno da função, entretanto,
Capítulo 8 Funções 155

se os endereços das variáveis são passados como parâmetros,


a função pode afetar diretamente quantas variáveis forem ne-
cessárias na função chamadora.

8.3 Vetores como argumento de funções

Sempre que um vetor for passado como parâmetro, obriga-


toriamente, ele será passado por referência. Ao fazer a cha-
mada a uma função com um vetor como argumento, o que
é enviado à função chamada é um ponteiro que armazena
o endereço do primeiro elemento do vetor. O programa da
Figura 8.6 exemplifica como passar um vetor como parâmetro
para uma função.
156 Algoritmos e Programação II

Figura 8.6 − Exemplo de vetor como argumento da função

Na linha 11, a string frase é inicializada com o literal Al-


terando letras de uma frase − este é exibido na tela por meio
da instrução da linha 14. A chamada à função substitui
aparece na linha 16, onde a string frase é enviada à função
chamada, junto com os caracteres e e X (como foi explicado
no capítulo anterior, em linguagem C, sempre que o nome de
um vetor aparece sem o índice, este corresponde ao endereço
de memória do seu primeiro elemento).
Capítulo 8 Funções 157

Na função substitui, consequentemente, foram decla-


rados três parâmetros para receber os valores enviados: char
*str, char atual, char novo − um ponteiro para
receber o endereço do primeiro elemento do vetor e duas va-
riáveis do tipo char para receber as letras e e X. A estrutura
for (linha 26) é usada para percorrer todas as posições da
variável frase e substituir as letras e por X (linhas 27 e 28).
Ao retornar o fluxo de execução do programa para a função
main, a variável frase é exibida já com as alterações reali-
zadas dentro da função.

Apesar de vetores serem enviados como parâmetros sem-


pre por referência, como foi explicado no início desta seção,
o primeiro parâmetro formal da função substitui, declara-
do como char *str, também poderia ser declarado como
char str[100] ou char str[], como ilustram os exem-
plos do Quadro 8.1 − nos dois exemplos a variável v1 terá
seus valores incrementados em um dentro da função.
158 Algoritmos e Programação II

Exemplos de vetor como argumento da função

main( ){ main( ){
int i, int i,v1[5]={0,0,0,0,0};
v1[5]={0,0,0,0,0};
incrementa(v1);
incrementa(v1);
for(i=0;i<5;i++)
for(i=0;i<5;i++) printf("%i ",v1[i]);
printf("%i }
",v1[i]);
}
void incrementa(int *v2){
int i;
void incrementa(int
for(i=0;i<5;i++){
v2[5]){
*v2=*v2+1;
int i;
v2++;
for(i=0;i<5;i++)
}
v2[i]++;
}
}

Quadro 8.1 − Exemplos da declaração de vetor como parâmetro formal

8.4 Matrizes como argumento de funções

Os programas apresentados nas Figuras 8.7 e 8.8 exempli-


ficam como usar matrizes como argumentos de funções. No
primeiro exemplo, o programa lê uma matriz 3x4 na função
main e um valor que será pesquisado nela. Na linha 23, ocor-
re a chamada à função consulta, que têm como argumentos
a matriz e o valor lido. Na função chamada, a matriz é per-
Capítulo 8 Funções 159

corrida e seus elementos são comparados com o valor a ser


pesquisado nela (linha 34), sendo que cada vez que o valor é
encontrado, a variável cont é incrementada em um (linha 35).
Neste exemplo, a função consulta não retorna nenhum valor
à função main, por isso esta foi declarada com o tipo void.

Figura 8.7 − Exemplo de matriz como argumento da função

No exemplo da Figura 8.8, o programa lê uma matriz 4x4


na função main e a envia como parâmetro à função maior,
160 Algoritmos e Programação II

que irá percorrer a matriz e identificar qual o maior elemen-


to. O maior elemento, por sua vez, é enviado via retorno à
função main.

Figura 8.8 − Exemplo de matriz como argumento da função


Capítulo 8 Funções 161

8.5 Estruturas como argumento de


funções

Os exemplos do Quadro 8.2 demonstram como fazer a passa-


gem de parâmetros por valor e por referência quando o argu-
mento da função é uma estrutura. No primeiro caso, a estrutu-
ra que está sendo passada à função vai ser copiada, membro
a membro, para o parâmetro formal da função. No segundo
exemplo, na passagem de parâmetros por referência, usa-se
um ponteiro para a estrutura.
162 Algoritmos e Programação II

Estrutura como argumento da função


Passagem de parâmetros por valor Passagem de parâmetros por referência

struct notas { struct notas {


float med; float med;
char result; char result;
}; };

void modifica(struct notas void modifica(struct notas


caluno); *ptaluno);

main( ){ main( ){
struct notas aluno; struct notas aluno;

aluno.med=8; aluno.med=8;
aluno.result='A'; aluno.result='A';
printf("Dados iniciais:"); printf("Dados iniciais:);
printf("%.1f ",aluno.med); printf("%.1f ",aluno.med);
printf("%c",aluno.result); printf("%c",aluno.result);

modifica(aluno); modifica(&aluno);

printf("Dados depois da printf("Dados depois da


função:”); função");
printf("%.1f ",aluno.med); printf("%.1f ",aluno.med);
printf("%c",aluno.result); printf("%c",aluno.result);
} }

void modifica(struct notas void modifica(struct notas


caluno){ *ptaluno){
caluno.med=3; ptaluno->med=3;
caluno.result='R'; ptaluno->result='R';
printf("Cópia do aluno); printf("Aluno);
printf("%.1f ",caluno.med); printf("%.1f ",ptaluno->med);
printf("%c",caluno.result); printf("%c",ptaluno->result);
} }

Quadro 8.2 − Exemplos de estrutura como argumento da função


Capítulo 8 Funções 163

Ponteiros que apontam para estruturas podem ser declara-


dos e inicializados da mesma forma que ponteiros que apon-
tam para variáveis simples. A única particularidade deste tipo
de ponteiro é que, para acessar indiretamente o valor armaze-
nado no membro de uma estrutura por meio de um ponteiro,
usa-se o operador -> (seta) e não o * (asterisco) utilizado nos
demais tipos de ponteiros. O uso desse operador pode ser
observado na função modifica do exemplo de passagem de
parâmetros por referência do Quadro 8.2

8.6 Estruturas como retorno de funções

O programa da Figura 8.7, que verifica se uma data é válida,


exemplifica o uso de uma estrutura como argumento e retorno
da função.
164 Algoritmos e Programação II

Figura 8.7 − Exemplo de estrutura como argumento e retorno da função


Capítulo 8 Funções 165

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) Indique se as afirmações abaixo são verdadeiras (V) ou fal-


sas (F).
( ) Função é um segmento de programa que executa uma
tarefa específica. São exemplos de funções das bibliotecas
padrão da linguagem C: printf(), scanf(), str-
len().

( ) Uma função pode retornar para o programa que a


chamou, um valor de qualquer tipo de dado. Esse retorno
é feito pela função return() que termina a execução
da função chamada e retorna o valor para a função cha-
madora. Se a função não retorna nenhum valor, o tipo do
retorno deve ser definido como void.
166 Algoritmos e Programação II

( ) Uma função pode ser escrita antes ou depois do ponto


em que é chamada. Quando a função é escrita antes do
ponto onde é chamada e no mesmo arquivo deste, faz-
-se necessário incluir um protótipo da função chamada.
Quando a função é escrita depois do ponto onde é cha-
mada e no mesmo arquivo deste, nenhuma outra instrução
é necessária.

( ) Em C, o usuário pode criar uma função em um arquivo


e ter um programa que a chame em outro arquivo, criando
assim suas próprias bibliotecas. A inclusão da função, cria-
da em um arquivo separado, no programa é feita a partir
da diretiva #include.

Está(ão) correta(s):

a) V V V V

b) V V F V

c) V V F F

d) F V F V

e) V V V F

2) A forma de passagem de parâmetros em que o endereço de


uma variável é enviado como parâmetro à função chama-
da, que recebe sua localização na memória a partir de um
ponteiro, fazendo qualquer alteração no conteúdo apon-
tado pelo ponteiro ser uma alteração da variável original,
é denominada passagem de parâmtros:
Capítulo 8 Funções 167

a) por estrutura

b) por ponteiro

c) recursiva

d) por referência

e) por valor

3) Qual o valor de retorno da função abaixo, caso ela receba


como parâmetros os valores 3 e 5?

int teste(int x,int y){


int *ptr1,*ptr2;
ptr1=&x;
ptr2=ptr1;
(*ptr2)++;
ptr2=&y;
*ptr2=*ptr2*2;
return y-x;
}

a) 12

b) 8

c) 14

d) 3

e) 6
168 Algoritmos e Programação II

4) Após a execução do programa abaixo, que valores estarão


armazenados nas variáveis r, s e retorno?

int fcalcula(int *a,int *b){


*b = *b + 2;
*a = *a % *b;
return *a + *b;
}
main(){
int r=5,s=2,retorno;
retorno=fcalcula(&r,&s);
printf(“%i”,retorno);

a) r = 2 s = 3 retorno = 5

b) r = 8 s = 3 retorno = 11

c) r = 1 s = 4 retorno = 5

d) r = 5 s = 3 retorno = 8

e) r = 5 s = 2 retorno = 7

5) Após a execução do programa abaixo, que valores estarão


armazenados nas variáveis x, y e retorno?

int fcalcula(float *g,float *k){


Capítulo 8 Funções 169

*g = *g / ++(*k);
return *g + *k;
}
main(){
float x=9,y=2,retorno;
retorno=fcalcula(&x,&y);
printf(“%i”,retorno);
}

a) r = 4.5 s = 3 retorno = 7.5

b) r = 4.5 s = 2 retorno = 6.5

c) r = 3 s = 3 retorno = 6

d) r = 5 s = 3 retorno = 8

e) r = 3 s = 2 retorno = 5

Parte II - Resolução de problemas

Resolva os problemas descritos a seguir, utilizando a Lingua-


gem C.

1) Crie uma função que receba, via passagem de parâmetros,


um caractere e retorne 1 se este for uma vogal ou 0 caso
seja uma consoante. Na função main(), escreva o resulta-
do do teste.

2) Crie uma função que receba, via passagem de parâmetros,


uma string qualquer de no máximo 40 caracteres, verifique
170 Algoritmos e Programação II

e retorne à função principal a quantidade de palavras que


ela possui. Escreva o resultado na função principal.

3) Leia um valor do tipo inteiro na função principal e, a partir


da passagem de parâmetros por referência, envie-o para
uma função que verifique se ele é um valor primo ou não.
Um valor primo só é divisível por ele mesmo e por 1 (exem-
plo de números primos: 5, 13 e 19). A função criada deve-
rá substituir o valor original por 1 quando este for primo e
por 0 quando não for. Por fim, escreva o resultado do teste
na função principal.

4 ) Escreva uma função que receba duas strings de no máximo


15 caracteres, via passagem de parâmetros; verifique se
elas são iguais; retorne -1 à função chamadora se elas
forem iguais ou o índice do primeiro caractere não coin-
cidente quando elas forem diferentes. Na função chama-
dora, emita uma mensagem, por exemplo: strings iguais
ou strings diferentes: o primeiro caractere diferente está na
posição 6.
Exemplo 01 Exemplo 02
String 1: contar String 1: livro
String 2: contagiar String 2: livro
Retorno: 5 Retorno: -1

5) Na teoria de sistemas, define-se como elemento minimax de


uma matriz o menor elemento da linha onde se encontra
o maior elemento da matriz. Crie uma função que deverá
receber por parâmetro uma matriz 3x4, com elementos do
Capítulo 8 Funções 171

tipo inteiro, encontrar o elemento minimax e retorná-lo à


função principal, onde o mesmo será escrito.

Respostas dos exercícios da Parte I


1 - b; 2 - d; 3 - e; c - b; 5 - c.
Vanessa Lindemann*

Capítulo 9

Arquivos

ÂÂ
E
ste capítulo é dedicado à apresentação de um progra-
ma em linguagem C que exemplifica a manipulação de
registros e arquivos. O programa implementa um sistema
gerenciador de dados de alunos, disponibilizando as se-
guintes opções aos usuários: gravar dados, gerar listagem
de alunos, consultar dados de um aluno específico, editar
ou excluir registros de alunos.
São armazenados os seguintes dados referentes aos
alunos: código, nome, nota 1, nota 2 e média. Esses da-
dos são manipulados a partir do uso de uma struct, cria-
da entre as linhas 21 e 25 da Figura 9.1, cuja variável foi

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
Capítulo 9 Arquivos 173

declarada como reg.


Para manipular um arquivo em linguagem C, é ne-
cessário declarar uma variável do tipo ponteiro utilizando
FILE * (como pode ser observado na linha 27 da Figura
9.1). Depois de declarado, o arquivo deve ser aberto para
que o programa possa ler dados já gravados nele ou gra-
var novos dados e, por fim, este deve ser fechado.
Antes de apresentar o código fonte do programa, que
exemplifica a implementação das operações citadas, en-
tende-se necessário fazer uma breve descrição das fun-
ções específicas para manipulação de arquivos, utilizadas
no exemplo − conteúdo apresentado na próxima seção.
174 Algoritmos e Programação II

9.1 Funções para manipulação de


arquivos

Função: fopen

Sintaxe: FILE *fopen(char *nome, char *modo)

Descrição: abre um arquivo, tornando-o disponível para


ser acessado pelo programa.

Parâmetros: nome do arquivo físico a ser aberto e modo


de abertura. O modo de abertura indica o tipo de acesso ao
arquivo e deve conter uma combinação válida dos caracteres
apresentados na Tabela 9.1.
Caractere Descrição
r Abre o arquivo somente para leitura.
Cria um arquivo para escrita. Se já existir um arquivo
w
com o mesmo nome, este será sobreposto pelo novo.
Abre um arquivo para escrita no seu final (append).
a
Ou, se o arquivo não existir, será criado.
Em conjunto com uma opção anterior, permite acesso
+
de leitura e escrita.
b Indica o uso de arquivo binário.
t Indica o uso de arquivo texto.
Tabela 9.1 − Modos de abertura de arquivos

Valor de retorno: se o arquivo for aberto corretamente, re-


torna um endereço que será atribuído para uma variável de
tipo FILE *; ou, em caso de erro, retorna nulo.

Exemplo
de aplicação: arq=fopen("cad_aluno.
txt","ab") − função incluir, linha 70 da Figura 9.3. O
Capítulo 9 Arquivos 175

nome do arquivo físico, salvo no diretório de trabalho, é cad_


aluno.txt. O modo de abertura ab indica que o arquivo será
aberto e o cursor (apontador de registros) será posicionado no
seu final para escrita ou, se o arquivo ainda não existir, ele será
criado. A variável arq recebe o endereço do arquivo cad_alu-
no.txt no disco, ou seja, ela é associada ao arquivo físico e
será utilizada nas outras funções de manipulação.

Função: fclose

Sintaxe: int fclose(FILE *arquivo)

Descrição: fecha um arquivo aberto.

Parâmetros: a variável que recebeu o valor de retorno da


função fopen, associada ao arquivo a ser fechado.

Valor de retorno: a função retorna zero quando o arquivo


é fechado corretamente.

Exemplo de aplicação: fclose(arq) − função incluir,


linha 100 da Figura 9.3. É importante fechar o arquivo após
seu uso para garantir que qualquer dado que tenha permane-
cido no buffer associado ao fluxo de saída seja gravado em
disco.
176 Algoritmos e Programação II

Função: rewind

Sintaxe: void rewind(FILE *arquivo)

Descrição: posiciona o cursor (apontador de registros) no


início do arquivo.

Parâmetros: a variável que recebeu o valor de retorno da


função fopen, associada ao arquivo cujo cursor será reposi-
cionado.

Valor de retorno: a função não retorna valor.

Exemplo de aplicação: rewind(arq) − função consulta,


linha 174 da Figura 9.5. Nesse caso, para cada nova consulta
realizada, o cursor será posicionado no início do arquivo.

Função: feof

Sintaxe: int feof(FILE *arquivo)

Descrição: verifica se o final do arquivo foi atingido (eof =


end of file).

Parâmetros: a variável que recebeu o valor de retorno da


função fopen, associada ao arquivo cujo final será testado.

Valor de retorno: a função retorna um valor diferente de


zero se o arquivo chegou ao fim, caso contrário retorna zero.

Exemplo de aplicação: while(!feof(arq)) − função li-


star, linha 117 da Figura 9.4. A condição de interrupção da
estrutura while repete seu bloco de instruções enquanto não
for o final do arquivo. Quando o programa chegar ao final do
Capítulo 9 Arquivos 177

arquivo, a função feof retornará um valor diferente de zero


(que, em C, significa verdadeiro); esse valor será negado pelo
operador lógico ! resultando zero (ou seja, falso); quando a
condição da estrutura while resulta falso, sua execução é in-
terrompida.

Função: fread

Sintaxe: int fread(void *endereco, int tama-


nho, int num, FILE *arquivo)

Descrição: lê um conjunto de bytes de um arquivo e arma-


zena-os na posição de memória indicada no primeiro parâ-
metro.

Parâmetros: endereço da área de memória onde serão ar-


mazenados os dados lidos do arquivo; tamanho em bytes da
variável a ser lida; número de variáveis a serem lidas; a variá-
vel que recebeu o valor de retorno da função fopen, associada
ao arquivo que será lido.

Valor de retorno: a função retorna o número de variáveis


lidas e avança o cursor de arquivo tamanho*num bytes.

Exemplo de aplicação: teste=fread(&reg,sizeof(struct


aluno),1,arq) − função listar, linha 123 da Figura 9.4. O
primeiro parâmetro &reg, indica que os dados lidos do arquivo
serão copiados para a área de memória destinada à variável
reg; a expressão sizeof(struct aluno), calcula o tamanho
em bytes dos dados a serem transferidos do arquivo para a va-
riável reg; o 1 indica que será lida uma unidade do tamanho
178 Algoritmos e Programação II

calculado por vez; e, o último parâmetro da função, indica de


onde os dados serão lidos, nesse caso, do arquivo associado
à variável arq.

Função: fwrite

Sintaxe: int fread(void *buffer, int tama-


nho, int num, FILE *arquivo)

Descrição: escreve (grava) um conjunto de bytes em um ar-


quivo. Se o cursor estiver apontando para uma área já existen-
te do arquivo, os novos dados irão sobrescrever os anteriores.
Se estiver apontando para o final do arquivo, o tamanho do
arquivo será aumentado e os os novos dados serão anexados.

Parâmetros: endereço da área de memória onde estão os


dados a serem escritos no arquivo; tamanho em bytes da va-
riável a ser escrita; número de variáveis a serem escritas; a
variável que recebeu o valor de retorno da função fopen, as-
sociada ao arquivo que será escrito.

Valor de retorno: a função retorna o número de variáveis


escritas e avança o cursor de arquivo tamanho*num bytes.

Exemplo de aplicação: teste=fwrite(&reg,sizeof(struct


aluno),1,arq) − função incluir, linha 90 da Figura 9.3.
Os parâmetros são os mesmos da função fread, só que, ao
contrário desta, o fluxo de dados vai da memória para o ar-
quivo. O primeiro parâmetro indica o endereço da área de
memória em que estão os dados a serem gravados; a expres-
são sizeof(struct aluno), calcula o tamanho em bytes dos
Capítulo 9 Arquivos 179

dados a serem transferidos da memória para o arquivo; o 1


indica que será gravada uma unidade do tamanho calculado
por vez; e, o último parâmetro da função, indica onde os da-
dos serão gravados, nesse caso no arquivo associado à vari-
ável arq.

Função: fseek

Sintaxe: int fseek(FILE *arquivo, int qtde,


int origem)

Descrição: altera a posição do cursor do arquivo, indican-


do onde será feito o próximo acesso.

Parâmetros: a variável que recebeu o valor de retorno da


função fopen, associada ao arquivo cujo cursor será reposi-
cionado; quantidade de bytes que o cursor será movimentado;
indica uma da posições possíveis (descritas na Tabela 9.2),
relativas à movimentação que será feita.

Parâmetro Descrição
SEEK_SET Posiciona a partir do início do arquivo.
SEEK_CUR Relativo à posição atual.
SEEK_END Retrocede do final do arquivo.

Tabela 9.2 − Parâmetro origem da função fseek

Valor de retorno: a função retorna zero se o deslocamento


ocorreu normalmente.
180 Algoritmos e Programação II

Exemplo de aplicação: fseek(arq,apontador *


sizeof(struct aluno),SEEK_SET) − função editar, linha
273 da Figura 9.6. O primeiro parâmetro indica a variável
associada ao arquivo onde o cursor será reposicionado; a
expressão apontador * sizeof(struct aluno), calcula o
tamanho em bytes do deslocamento (a variável apontador ar-
mazena a quantidade de registros gravados no arquivo antes
do registro a ser sobreposto); o último parâmetro define que o
deslocamento vai se dar a partir do início do arquivo.

9.2 Programa exemplo da manipulação


de registros e arquivos

Esta seção é dedicada à apresentação do código fonte do pro-


grama que exemplifica a manipulação de registros e arquivos,
descrito no inicio do capítulo. O código fonte é apresentado
na íntegra, entretanto, foi dividido em várias figuras para faci-
litar seu entendimento − entre uma figura e outra foram inclu-
ídas algumas explicações.

É aconselhável que o aluno implemente esse exemplo antes


de resolver os exercícios propostos no final do capítulo. Para
facilitar a digitação do código no editor do compilador, procu-
re manter as instruções nas mesmas linhas em que estas apa-
recem nas figuras (para exibir o número da linha à esquerda
do código fonte no editor do Dev-C++, como nesse exemplo,
leia a seção 10.3 do capítulo 10).
Capítulo 9 Arquivos 181

A Figura 9.1 inicia com um comentário que contém infor-


mações sobre o programa implementado. Em seguida, entre
as linhas 7 e 9, aparecem as diretivas de compilação, indican-
do que serão utilizados os arquivos de cabeçalho stdio.h,
conio.h e string.h; e, entre as linhas 13 e 17, os protótipos
das funções. As variáveis de escopo global são declaradas en-
tre as linhas 21 e 29. Na linha 27, a instrução FILE *arq
declara um ponteiro para um arquivo, cuja variável foi deno-
minada arq. É importante destacar que FILE deve ser escrito
em caixa-alta, caso contrário será gerado um erro de sintaxe.

Figura 9.1 − Exemplo da manipulação de registros e arquivos - parte 1


182 Algoritmos e Programação II

A função principal (main), ponto de início da execução


de programas em linguagem C, aparece entre as linhas 33
e 64 da Figura 9.2. Este trecho do programa é responsável
por exibir um menu para o usuário, com as opções do siste-
ma gerenciador de dados de alunos (linhas 38 a 45); ler a
opção escolhida (linha 47) e, a partir daí, fazer a chamada à
função correspondente (linhas 48 a 62). Depois de executada
a função escolhida pelo usuário, o programa retornará para
o menu. Esse processo é repetido até que o usuário digite a
opção 6 para sair.

Figura 9.2 − Exemplo da manipulação de registros e arquivos - parte 2


Capítulo 9 Arquivos 183

A Figura 9.3 apresenta a função incluir, responsável por


gravar os dados dos alunos no arquivo. Basicamente, a função
abre o arquivo (linha 70), realiza a entrada de dados e calcula
a média do aluno (linhas 76 a 85), grava os dados no arquivo
(linha 90) e verifica se o usuário deseja continuar cadastrando
alunos − caso afirmativo, repete a execução a partir da en-
trada de dados. Ao final, o arquivo é fechado (linha 100). As
funções específicas para manipulação de arquivos usadas no
trecho de código da Figura 9.3, quais sejam fopen, fwrite e
fclose, foram explicadas em detalhes na seção anterior.

Figura 9.3 − Exemplo da manipulação de registros e arquivos - parte 3


184 Algoritmos e Programação II

A listagem geral de alunos cadastrados no sistema é ge-


rada a partir da função listar, apresentada na Figura 9.4.
O arquivo é aberto pela instrução arq=fopen("cad_aluno.
txt","rb"), linha 109 da Figura 9.4. O primeiro parâmetro
é o mesmo em todas as funções do programa, pois associa
a variável arq ao arquivo físico que será manipulado. O se-
gundo parâmetro, entretanto, se refere ao modo de abertura
do arquivo e, nesse caso, rb indica que o arquivo será aberto
apenas para leitura.

A função fopen (linha 109) retorna um endereço à vari-


ável arq ou, em caso de erro, retorna nulo. Na linha 112, a
estrutura condicional if(arq) avalia o valor armazenado na
variável arq, se este for diferente de nulo os dados podem ser
lidos do arquivo e exibidos na tela (linhas 112 a 146), caso
contrário, o programa emite a mensagem "Arquivo vazio" (li-
nhas 147 a 151).

Depois de abrir o arquivo, o programa exibe um cabeçalho


para o relatório de alunos (linhas 111 a 115) e, por meio da
estrutura while, faz a leitura de todos os registros gravados
no arquivo para exibi-los na tela (linhas 117 a 141). A condi-
ção de interrupção da estrutura while utiliza a função feof
para verificar quando o arquivo chegou ao seu final (linha
117). Essa função, bem como a função fread (linha 123),
que faz a leitura dos dados do arquivo, foram explicadas na
seção anterior.
Capítulo 9 Arquivos 185

Figura 9.4 − Exemplo da manipulação de registros e arquivos - parte 4

Nessa função, foi criada uma variável linha, inicializada


com o valor 9 (linha 107). Ela é utilizada como parâmetro nas
funções gotoxy que antecedem as funções de saída (linhas
126 a 130) e, enquanto ela for menor que 17, a cada registro
exibido na tela, ela é incrementada (linhas 131 e 132). Isso
186 Algoritmos e Programação II

significa que os dados dos alunos serão exibidos na tela, entre


as linhas 9 e 17. Quando a variável linha chegar em 17,
para cada registro a ser exibido na tela, a primeira linha usada
pela listagem será deletada (nesse caso, a linha 9) e uma nova
linha será inserida no final (na linha 17), fazendo com que os
registros "rolem" na tela. Isso é implementado entre as linhas
133 e 139, com o uso das funções delline() e insline(),
ambas da biblioteca conio.h. A função delline() apaga a
linha atual do cursor e puxa todas as linhas subsequentes uma
linha para cima. A função insline(), ao contrário, insere
uma nova linha na posição atual do cursor.
Capítulo 9 Arquivos 187

Figura 9.5 − Exemplo da manipulação de registros e arquivos - parte 5


188 Algoritmos e Programação II

A Figura 9.5 exibe o trecho do programa responsável pela


função consultar, que possibilita ao usuário pesquisar da-
dos dos alunos. O argumento de pesquisa é o nome do alu-
no, portanto, logo depois de abrir o arquivo (linha 161), o
programa solicita que o usuário digite o nome do aluno a ser
pesquisado (linhas 169 e 171).

Na linha 173 da Figura 9.5, a variável achei é inicializa-


da com zero. Em seguida, a função rewind é usada para po-
sicionar o cursor (apontador de registros) no início do arquivo
(linha 174). Depois, enquanto não for o final do arquivo e a
variável achei for zero (linha 175), o programa lê os regis-
tros do arquivo, um por vez (linha 181), e compara o campo
nome com o argumento de pesquisa (linha 185). Quando os
dois forem iguais, os outros campos do registro serão exibidos
na tela e a variável achei recebe 1, para que a busca seja
finalizada. Caso o programa não encontre o nome procurado
no arquivo, a busca será finalizada por ter chegado ao final
do arquivo e a variável achei continuará com zero. Assim,
ao sair da estrutura while, o programa verifica se achei é
igual a zero e, se for, emite a mensagem "Registro não encon-
trado" (linhas 198 a 201). A consulta será repetida enquanto
o usuário responder que deseja continuar. No final, o arquivo
é fechado (linha 206).

Vale destacar que, da forma como a busca foi implementa-


da aqui, ao encontrar o primeiro registro cujo campo nome é
igual ao argumento de pesquisa, a consulta é encerrada. Para
que a busca continuasse, exibindo todos os registros do arqui-
vo com o nome igual ao argumento de pesquisa, seria neces-
sário alterar a linha 175 de while(!eof(arq) && achei==0)
Capítulo 9 Arquivos 189

para while(!eof(arq)). Nesse caso, a variável achei não


seria usada para encerrar o laço de repetição, mas apenas
para emitir a mensagem "Registro não encontrado", quando
fosse o caso. Além dessa alteração, seriam necessários alguns
ajustes para exibir mais de um registro por consulta.

As funções editar (Figuras 9.6 e 9.7) e excluir (Figuras


9.8 e 9.9) iniciam fazendo uma busca, pois antes de alterar
ou excluir um registro, é necessário encontrá-lo. Esse processo
de busca é implementado exatamente igual à busca da função
consultar, descrita anteriormente.

Na função editar, depois de encontrar o registro a ser


alterado e exibir seus dados na tela, o programa solicita que
o usuário digite os novos dados (linhas 253 a 260), calcula
e exibe a nova média (linhas 262 e 263) e pede para o usu-
ário confirmar a alteração (linhas 265 e 266). Se o usuário
confirmar, o programa posiciona o cursor no arquivo usando
a função fseek (linha 273), de forma que os novos dados,
gravados com fwrite (linha 274), sobreponham os anteriores.
A função fseek foi explicada na seção anterior.
190 Algoritmos e Programação II

Figura 9.6 − Exemplo da manipulação de registros e arquivos - parte 6(a)


Capítulo 9 Arquivos 191

Figura 9.7 Exemplo da manipulação de registros e arquivos - parte 6(b)

Figura 9.8 − Exemplo da manipulação de registros e arquivos - parte 7(a)


192 Algoritmos e Programação II

Figura 9.9 − Exemplo da manipulação de registros e arquivos - parte 7(b)

A diferença entre as funções editar e excluir (Figuras


9.8 e 9.9) é que, na segunda, ao invés do usuário digitar os
dados a serem alterados, o programa atribui branco às variá-
veis textuais e zero às variáveis numéricas (linhas 338 a 342) e
grava essas alterações no arquivo, sobrepondo os dados ante-
riores. Trata-se, portanto, de uma exclusão lógica, pois, apesar
de os dados serem apagados, fisicamente o registro continua
Capítulo 9 Arquivos 193

ocupando o mesmo espaço no arquivo. Para que os registros


excluídos não sejam exibidos na listagem geral de alunos, a
estrutura condicional da linha 125 da função listar (Figura
9.4), verifica se o campo nome é diferente de branco antes de
exibir os dados do registro na tela.

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Atividades

Parte I - Questões objetivas

1) Associe a segunda coluna de acordo com a primeira.


(1) fopen()

(2) fclose()

(3) feof ()

(4) fread()
194 Algoritmos e Programação II

(5) fwrite()

(6) fseek()

(7) rewind()

( ) Retorna zero enquanto não encontrar o final do arquivo.

( ) Cria ou abre arquivos.

( ) Desloca o ponteiro do arquivo para uma posição de-


terminada.

( ) Grava dados no arquivo.

( ) Fecha arquivos.

( ) Lê dados do arquivo.

( ) Posiciona o cursor no início do arquivo.

A ordem correta de respostas da segunda coluna é:

a) 6 - 7 - 3 - 5 - 2 - 4 - 1

b) 3 - 1 - 6 - 5 - 2 - 4 - 7

c) 3 - 1 - 7 - 5 - 2 - 4 - 6

d) 7 - 1 - 6 - 5 - 2 - 4 - 3

e) 3 - 1 - 5 - 6 - 2 - 4 - 7

2) A função
fopen("teste.txt","ab");
Capítulo 9 Arquivos 195

a) Cria o arquivo teste.txt para escrita. Se o arquivo já existe


em disco, este será sobreposto.

b) Cria ou abre o arquivo teste.txt apenas para leitura.

c) Abre o arquivo teste.txt para escrita no seu final. Caso o


arquivo ainda não exista, este será criado.

d) Abre o arquivo teste.txt para leitura e escrita.

e) Nenhuma das respostas anteriores.

3) Sobre a função fclose, é correto afirmar.


a) É usada para fechar arquivos.

b) Todo arquivo aberto deve ser fechado.

c) É importante fechar o arquivo após seu uso para garantir


que qualquer dado que tenha permanecido no buffer, asso-
ciado ao fluxo de saída, seja gravado em disco.

d) A função retorna zero quando o arquivo é fechado cor-


retamente.

e) Todas as afirmações anteriores estão corretas.

4) O operador sizeof:
a) especifica o tamanho de uma struct.

b) retorna a quantidade de registros de um arquivo.

c) retorna o número de campos de uma struct.


196 Algoritmos e Programação II

d) calcula o tamanho em bytes de uma variável ou uma


expressão.

e) nenhuma das respostas anteriores.

5) O primeiro parâmetro da função fwrite indica o ende-


reço da área de memória em que estão os dados a se-
rem gravados; o segundo parâmetro indica o tamanho em
bytes dos dados a serem transferidos da memória para o
arquivo; o terceiro parâmetro indica quantas unidades do
tamanho calculado serão gravadas; e o último parâmetro
da função, indica onde os dados serão gravados.
a) Certo b) Errado

Parte II - Resolução de problemas

Resolva os problemas descritos a seguir, utilizando a Lingua-


gem C.

1) Campeonato Gaúcho de Voleibol


A Confederação Brasileira de Voleibol necessita de um
sistema para gerenciar dados referentes aos atletas de
voleibol dos clubes que irão participar do Campeona-
to Gaúcho. As informações a serem armazenadas, para
cada atleta, são: código do clube que o atleta representa,
nome, idade e altura. O sistema deve permitir ao usuário
editar ou excluir atletas da base, listar atletas por clube,
listar todos os atletas do campeonato.
Capítulo 9 Arquivos 197

2) Controle de viagens aéreas


O sistema deve permitir ao usuário cadastrar e consultar
voos, a partir de um menu de opções. A opção de cadastro
deve ler um conjunto de dados composto por número do
voo, origem e destino, permitindo que o usuário encerre esse
processo digitando 0 (zero) para o número do voo. A opção
consultar deverá ler o número do voo e apresentar origem e
destino (ou uma mensagem informando que o voo não foi
encontrado, quando for o caso), permitindo que o usuário
faça quantas consultas quiser. Por fim, a opção listar voos
deverá apresentar a lista de todos os voos cadastrados.

3) Pesquisa sobre acidentes de trânsito


O IBOPE está fazendo um levantamento sobre acidentes
de trânsito em 2014. Em cada município, são coletados os
seguintes dados: código do município, quantidade de veí-
culos de passeio, quantidade de acidentes de trânsito com
vítimas e quantidade de acidentes sem vitímas. Faça um
sistema para gerenciar esses dados, oferecendo as opções
de cadastro, consulta por código de município, listagem
geral e estatística. Essa última opção, deve apresentar as
seguintes informações: total de acidentes em 2014, a mé-
dia de veículos entre os municípios pesquisados, o maior
e o menor índice de acidentes de trânsito com vítimas e a
que cidades pertencem.

Respostas dos exercícios da Parte I


1 - b; 2 - c; 3 - e; 4 - d; 5 - a.
Vanessa Lindemann*

Capítulo 10

Dev-C++: instalação e
configuração

ÂÂ
P
ara atingir os objetivos de aprendizagem da disciplina
de Algoritmos e Programação II, é imprescindível que o
aluno utilize um compilador para compilar e executar os
exemplos e exercícios propostos neste livro. Apenas ler os
exemplos não basta, para aprender a programar é preciso
"colocar a mão na massa"!
Nesta disciplina, optou-se por usar o Dev-C++, que
é um ambiente de desenvolvimento integrado (IDE − Inte-
grated Development Environment), com grande potencial

* Doutora em Informática na Educação pela UFRGS (2008); professora dos cursos


da Computação da ULBRA
Capítulo 10 Dev-C++: instalação e configuração 199

para desenvolver programas em linguagem C e C++ no


sistema operacional Windows. Desenvolvido por Colin La-
place, Mike Berg e Hongli Lai, o Dev-C++ é gratuito e
está disponível para download em http://www.bloodshed.
net/dev/devcpp.html.
O Dev-C++ integra um editor de textos ao compila-
dor para linguagem C denominado gcc (GNU Compiler
Collection) − ele usa a porta MinGW do gcc, que é uma
versão do compilador para Windows. A função do com-
pilador é traduzir o código fonte de um programa escrito
em uma linguagem de alto nível, como a linguagem C
por exemplo, em uma linguagem de baixo nível, de for-
ma que o computador compreenda as instruções a serem
executadas.
Com o Dev-C++ é possível criar aplicações para
console (executadas na janela do prompt de comandos) −
como as que serão implementadas nesta disciplina, apli-
cações gráficas (interface com menus, abas e outros itens
visuais), bibliotecas estáticas, DLLs, além de gerenciar
projetos de forma simples. Sua interface segue o padrão
das melhores ferramentas de desenvolvimento do merca-
do, permitindo visualizar mensagens de erro, compilar,
debugar e testar programas com facilidade.
As próximas seções descrevem, passo a passo, como
instalar, configurar e utilizar o Dev-C++ para compilar e
executar os exemplos e exercícios propostos nesta disciplina.
200 Algoritmos e Programação II

10.1 Instalando o Dev-C++

Como mencionado anteriormente, o Dev-C++ está disponí-


vel para download em http://www.bloodshed.net/dev/devcpp.
html, site oficial da ferramenta. Para construir os exemplos ilus-
trados nas figuras deste livro, foi utilizada a versão 4.9.9.2.
Depois de fazer o download do arquivo de instalação do Dev-
-C++, execute-o seguindo os passos apresentados entre as
Figuras 10.1 e 10.6.

Ao iniciar o processo de instalação, será necessário definir


a linguagem a ser utilizada no processo de instalação − sele-
cione Português e clique no botão OK (Figura 10.1); aceitar os
termos do contrato de licença (Figura 10.2); escolher o tipo de
instalação − mantenha a opção Full selecionada e clique no
botão Seguinte (Figura 10.3); e, por fim, definir o diretório des-
tino para a instalação − mantenha o diretório padrão sugeri-
do c:\Dev-Cpp e clique no botão Instalar (Figura 10.4). Após
esses passos, a instalação será executada (Figura 10.5) e, ao
ser concluída, exibirá a tela ilustrada na Figura 10.6. Clicando
no botão Terminar dessa tela, o Dev-C++ será executado.

Figura 10.1 − Instalação do Dev-C++: seleção da linguagem


Capítulo 10 Dev-C++: instalação e configuração 201

Figura 10.2 Instalação do Dev-C++: contrato de licença


202 Algoritmos e Programação II

Figura 10.3 Instalação do Dev-C++: tipo de instalação


Capítulo 10 Dev-C++: instalação e configuração 203

Figura 10.4 Instalação do Dev-C++: diretório para instalação


204 Algoritmos e Programação II

Figura 10.5 − Instalação do Dev-C++: processo em execução


Capítulo 10 Dev-C++: instalação e configuração 205

Figura 10.6 Instalação do Dev-C++: processo concluído

A primeira vez em que o Dev-C++ é executado, é possível


configurar algumas características do ambiente de desenvol-
vimento, conforme ilustram as Figuras 10.7 e 10.8 − estas,
por sua vez, poderão ser modificadas mais tarde por meio do
menu Ferramentas. A primeira característica a ser configurada
refere-se à linguagem − selecione Portuguese (Brazil) e cli-
que no botão Next (Figura 10.7). Em seguida, na Figura 10.8,
o sistema sugere um recurso relacionado ao uso de classes,
como não é o caso nesta disciplina, altere a opção para No, I
prefer to use Dev-C++ without it e clique no botão Next. Apa-
recerá, então, a tela da Figura 10.9 que encerra o processo
de configuração inicial do Dev-C++. Ao clicar no botão Ok,
o ambiente de desenvolvimento será aberto.
206 Algoritmos e Programação II

Figura 10.7 − Primeira execução do Dev-C++: seleção da linguagem


Capítulo 10 Dev-C++: instalação e configuração 207

Figura 10.8 − Primeira execução do Dev-C++: altere a opção para NÃO


208 Algoritmos e Programação II

Figura 10.9 − Primeira execução do Dev-C++: configurações


concluídas

10.2 Instalando a biblioteca conio.h

Concluída a instalação do Dev-C++, a próxima tarefa é ins-


talar e configurar a biblioteca conio.h. Esta não é uma bi-
blioteca padrão no Dev-C++, mas pode ser instalada. Nos
exemplos deste livro, várias funções que fazem parte dessa
biblioteca foram utilizadas: getch, getche, clrscr, gotoxy,
textcolor, textbackground, delline e insline. Para utilizá-
-las, entretanto, é necessário ter a biblioteca conio.h instalada
Capítulo 10 Dev-C++: instalação e configuração 209

e configurada e referenciá-la, por meio da diretiva #include,


no início dos programas.

Os arquivos necessários para instalar a biblioteca conio.h


estão disponíveis na sala de aula virtual desta disciplina. De-
pois de fazer o download do material, siga o passo a passo
descrito a seguir. É importante destacar, entretanto, que a bi-
blioteca conio.h só irá funcionar nativamente para sistemas
operacionais de 32 bits − para usá-la em sistemas operacio-
nais de 64 bits, outras configurações são necessárias.

As pastas include e lib devem ser copiadas para o diretório


onde o Dev-C++ foi instalado − o diretório padrão, caso este
não tenha sido alterado no processo de instalação, é c:\Dev-
-Cpp. Como já existem duas pastas lá com esses nomes, será
necessário confirmar a substituição das pastas existentes pelas
pastas novas.

Em seguida, o Dev-C++ deve ser inicializado. Por meio


do menu Ferramentas, opção Opções do compilador (confor-
me ilustra a Figura 10.10), a biblioteca será configurada. Na
janela Opções do compilador, serão configurados parâmetros
nas abas Compilador (Figura 10.11), Diretórios (Figura 10.12)
e Programas (Figura 10.14).
210 Algoritmos e Programação II

Figura 10.10 − Configurando a biblioteca conio.h no Dev-C++

Na aba Compilador, a opção Adicione estes comandos à


linha de comando do linker deverá ser selecionada e o coman-
do -lconio deverá ser incluído na caixa de texto logo abaixo
da opção selecionada, como pode ser observado na Figura
10.11.
Capítulo 10 Dev-C++: instalação e configuração 211

Figura 10.11 − Configurando a biblioteca conio.h no Dev-C++

Na mesma janela (Opções do compilador), porém na aba


Diretórios − aba Binários, devem constar os caminhos dos di-
retórios listados na Figura 10.12. Para adicioná-los, caso estes
não estejam listados, basta clicar no botão localizado no canto
inferior direito da caixa de texto onde os caminhos são listados
e selecioná-los (um de cada vez), como ilustra a Figura 10.13.
Depois de selecionado o diretório, clique no botão Ok para
fechar a janela aberta e, em seguida, no botão Adicionar para
incluí-lo na lista.
212 Algoritmos e Programação II

Figura 10.12 − Configurando a biblioteca conio.h no Dev-C++


Capítulo 10 Dev-C++: instalação e configuração 213

Figura 10.13 − Configurando a biblioteca conio.h no Dev-C++

Na última aba da janela Opções do compilador, a aba


Programas, o caminho C:\Dev-Cpp\bin\ destacado na Figura
10.14, deverá ser incluído antes de todos os nomes de progra-
mas da lista, como ilustra a Figura 10.15. Importante: caso o
diretório padrão tenha sido alterado no processo de instalação
do Dev-C++, o diretório utilizado deverá substituir a parte C:\
Dev-Cpp\.
214 Algoritmos e Programação II

Figura 10.14 − Configurando a biblioteca conio.h no Dev-C++


Capítulo 10 Dev-C++: instalação e configuração 215

Figura 10.15 Configurando a biblioteca conio.h no Dev-C++

Configurações concluídas, basta clicar no botão Ok para


salvá-las. O exemplo da Figura 10.16 pode ser usado para
verificar se a biblioteca foi instalada e configurada correta-
mente. Para compilar o exemplo, abra um arquivo novo aces-
se o menu Arquivo, opção Novo --> Arquivo Fonte. Depois
de digitar o código da Figura 10.16, acesse o menu Arquivo,
opção Salvar para salvar o arquivo. Para compilar e executar
o exemplo, selecione a opção Compilar e Executar do menu
Executar, como ilustra a Figura 10.17.
216 Algoritmos e Programação II

Figura 10.16 − Testando a biblioteca conio.h no Dev-C++

Figura 10.17 − Compilando e executando um exemplo em Dev-C++


Capítulo 10 Dev-C++: instalação e configuração 217

Se a biblioteca foi configurada corretamente, uma janela


como a mostrada na Figura 10.18 será exibida. Caso contrá-
rio, o compilador não reconhecerá as funções da biblioteca
conio.h, indicando erros como os que podem ser observados
na parte inferior da Figura 10.19.

Figura 10.18 − Saída do exemplo que testa a biblioteca conio.h no


Dev-C++
218 Algoritmos e Programação II

Figura 10.19 − Biblioteca conio.h não identificada no Dev-C++

10.3 Configurando a interface do editor


do Dev-C++

O Dev-C++ está pronto para ser utilizado, incluindo a biblio-


teca conio.h que já foi instalada e configurada. Esta seção
descreve, passo a passo, como ajustar algumas configurações
referentes ao editor do Dev-C++, visando melhorar a sua
interface e facilitar a realização das atividades.

Para configurar o editor, mantenha o arquivo do exemplo


anterior aberto. Em seguida, acesse a opção Opções do editor
do menu Ferramentas, como ilustra a Figura 10.20. Na janela
Opções do editor, dois parâmetros serão alterados: inclusão
Capítulo 10 Dev-C++: instalação e configuração 219

de uma linha na margem direita, para delimitar o espaço de


digitação (aba Geral − Figura 10.21); inclusão dos números
das linhas à esquerda da área de digitação, para facilitar a
digitação dos exemplos do livro (aba Display − Figura 10.22).
O resultado dessas alterações pode ser observado na Figura
10.23.

Figura 10.20 − Configurando o editor do Dev-C++


220 Algoritmos e Programação II

Figura 10.21 − Configurando o editor do Dev-C++: margem direita


Capítulo 10 Dev-C++: instalação e configuração 221

Figura 10.22 − Configurando o editor do Dev-C++: números das linhas


222 Algoritmos e Programação II

Figura 10.23 − Resultado das configurações do editor do Dev-C++

Por fim, a área de edição dos programas do Dev-C++


pode ser aumentada. Considerando que, nos exemplos e exer-
cícios deste livro, não utiliza-se o conceito de classes, sugere-
-se desabilitar o navegador de classes e projetos e o item clas-
ses da barra de ferramentas − como ilustram as Figuras 10.24
e 10.25, respectivamente. Após essas alterações, o ambiente
de trabalho ficará como o ilustrado na Figura 10.26.
Capítulo 10 Dev-C++: instalação e configuração 223

Figura 10.24 − Desabilitar o navegador de classe e projetos do


Dev-C++

Figura 10.25 − Desabilitar o item classes da barra de ferramentas do


Dev-C++
224 Algoritmos e Programação II

Figura 10.26 Resultado das alterações na interface do Dev-C++

10.4 Utilizando o Dev-C++

Uma janela com dicas é exibida sempre que o Dev-C++ for


inicializado (Figura 10.27). Para desabilitá-la, basta marcar a
opção Não exibir dicas na inicialização, localizada na parte
inferior da janela, antes de fechá-la. Ou, se preferir, utilize os
botões Próxima e Anterior para visualizar outras dicas. Ao fe-
char essa janela, visualiza-se o editor do Dev-C++ − Figura
10.28.
Capítulo 10 Dev-C++: instalação e configuração 225

Figura 10.27 − Janela de dicas exibida na inicialização do Dev-C++


226 Algoritmos e Programação II

Figura 10.28 − Editor do Dev-C++

Um arquivo novo pode ser criado a partir do menu Arquivo,


opção Novo --> Arquivo Fonte, como ilustra a Figura 10.29,
ou a partir das teclas de atalho Ctrl+N. A Figura 10.30 apre-
senta um arquivo novo, em que algumas linhas de código fo-
ram incluídas. No canto superior esquerdo, é possível observar
que o arquivo ainda não foi salvo.
Capítulo 10 Dev-C++: instalação e configuração 227

Figura 10.29 − Opção para criar um arquivo novo no Dev-C++

Figura 10.30 − Arquivo novo


Para salvá-lo, selecione a opção Salvar do menu Arquivo,
como ilustra a Figura 10.31, ou use as teclas de atalho Ctrl+S.
Na janela da Figura 10.32, digite o nome do arquivo e man-
tenha o tipo de arquivo C++ Source Files (*.cpp,*.cc,*.cxx,*.
c++,*.cp) − esse exemplo foi salvo com o nome Meu primeiro
exemplo.
228 Algoritmos e Programação II

Figura 10.31 − Opção para salvar arquivo no Dev-C++

Figura 10.32 − Salvando um arquivo no Dev-C++

Ao modificar o exemplo, inserindo as linhas de código


apresentadas na Figura 10.33, aparece um asterisco em frente
Capítulo 10 Dev-C++: instalação e configuração 229

ao nome do arquivo para indicar que este sofreu modificações


e deve ser salvo novamente.

Figura 10.33 − Arquivo modificado

Depois de concluído o exemplo, basta selecionar a opção


Compilar e Executar no menu Executar, como ilustra a Figura
10.34, ou teclar F9. Se o código não tiver nenhum erro, a ja-
nela da Figura 10.35 será exibida.
230 Algoritmos e Programação II

Figura 10.34 Compilar e executar arquivo no Dev-C++

Figura 10.35 − Resultado da execução do exemplo

Para fechar um arquivo aberto, selecione a opção Fechar


do menu Arquivo, como ilustra a Figura 10.36, ou use as te-
clas de atalho Ctrl+F4. Para abrir um arquivo existente, utilize
Capítulo 10 Dev-C++: instalação e configuração 231

a opção Abrir Projeto ou Arquivo, conforme ilustra a Figura


10.37, ou as teclas de atalho Ctrl+O. Em seguida, selecione
o arquivo a ser aberto e clique no botão Abrir − Figura 10.38.

Figura 10.36 − Opção para fechar arquivo no Dev-C++

Figura 10.37 − Opção para abrir arquivo no Dev-C++


232 Algoritmos e Programação II

Figura 10.38 − Seleção do arquivo a ser aberto no Dev-C++

Quando vários arquivos estiverem abertos, estes serão lis-


tados em abas, como pode ser observado na Figura 10.39.
Para acessar qualquer um deles, basta clicar sobre a aba com
o seu nome.
Capítulo 10 Dev-C++: instalação e configuração 233

Figura 10.39 − Vários arquivos abertos no Dev-C++

As Figuras 10.40 e 10.41 ilustram dois erros comuns nos


primeiros programas desenvolvidos pelos alunos em lingua-
gem C. No primeiro caso (Figura 10.40), o compilador indica
que faltou ponto-e-vírgula no final da instrução da linha ante-
rior a que está marcada. O erro é indicado na parte inferior da
janela: expected ; before printf.
234 Algoritmos e Programação II

Figura 10.40 − Erro comum em programas em C: esperando ponto-e-vírgula


Capítulo 10 Dev-C++: instalação e configuração 235

Figura 10.41 − Erro comum em programas em C: biblioteca não


referenciada

O erro da Figura 10.41 simula uma situação em que o


programa utiliza várias funções de uma biblioteca que não foi
referenciada a partir da diretiva #include no início do pro-
grama. Neste caso, faltou referenciar a biblioteca conio.h,
por isso as funções clrscr, gotoxy e getch não foram re-
conhecidas pelo compilador. Para corrigir o erro, a instrução
#include<conio.h> deve ser incluída no início do programa.
236 Algoritmos e Programação II

Referências Bibliográficas

DEITEL, Paul; DEITEL, Harvey. C: como programar. 6.ed. São


Paulo: Pearson Prentice Hall, 2011.

FORBELLONE, André Luiz Villar; EBERSPÄCHER, Henri Frederi-


co. Lógica de Programação: a construção de algoritmos
e estruturas de dados. 3.ed. São Paulo: Prentice Hall, 2005.

ISAIA FILHO, Eduardo; LINDEMANN, Vanessa. Algoritmos e


Programação I. Canoas: Ed. ULBRA, 2013.

Você também pode gostar