Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 1
Programação
e
Estrutura de Dados
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 2
1. Introdução à Programação e Estrutura de Dados
1.1 Programação
Programação de computadores nada mais é do que algoritmos escritos numa linguagem
de computador (Pascal, C, Cobol, Fortran, Java, Visual Basic entre outras) e que são
interpretados e executados por uma máquina, no caso um computador.
1.2 Estrutura de Dados
Hoje em dia, a grande maioria das pessoas utiliza a agenda do celular para armazenar
seus contatos. As tarefas de uma agenda de contatos são basicamente duas:
1) Definir como as informações dos contatos serão armazenadas. Uma informação
armazenada em algum lugar (pedaço de papel, livro, computador, etc) é um dado.
2) Disponibilizar operações para criar, recuperar, ordenar, atualizar e remover contatos.
Além de operações para informar o estado da agenda (a quantidade de contatos existentes na
agenda ou a quantidade de espaço disponível para novos contatos).
A primeira tarefa é crucial para o desempenho. Se a agenda armazena as informações de
uma forma desorganizada então será muito mais complicado manipular os dados de forma
eficiente. A escolha de como guardar as informações deve levar em consideração as
operações que serão disponibilizadas pela agenda. Por exemplo, seria interessante manter os
contatos em ordem alfabética para facilitar a busca.
Mas, apesar da importância de como os contatos são armazenados, a organização interna
da agenda não precisa e não deve ser exposta ao usuário. Afinal de contas, o que o usuário
deseja é usar a agenda através das operações e que tudo seja feito o mais rápido possível.
A única coisa que precisa ser mostrada para o usuário são as operações que ele pode fazer
na agenda (inserir, recuperar, atualizar, remover contato, saber quantos contatos estão na
agenda, etc). Este conjunto de operações é a interface que o usuário tem com a agenda.
Cada celular pode implementar a sua agenda de contatos de uma forma totalmente
diferente um do outro, na tentativa de obter mais performance, ser mais confiável ou gastar
menos memória. Porém o conjunto básico de operações oferecidas pelas agendas é sempre o
mesmo. Isso facilita a vida do usuário pois se ele tiver que trocar de celular não vai ter que
aprender novamente como usar uma agenda de contatos.
Essa é a grande vantagem em se pensar em interface. Mantida a interface, podemos trocar
uma agenda que não é tão eficiente ou que já não atende mais as nossas necessidades por
outra mais eficiente ou adequada, sem problemas em ter de aprender a usar a nova agenda:
troca-se a implementação, mas não mudamos a interface.
Uma agenda de celular pode ser vista como uma estrutura de dados. Uma estrutura de
dados mantém os dados organizados seguindo alguma lógica e disponibiliza operações para
o usuário manipular os dados.
É importante, quando programar, não misturar dado e estrutura de dados em uma coisa
só. Um dado é uma informação armazenada e estrutura de dados é quem administra os
dados. O ideal é que a estrutura de dados seja o mais independente possível dos dados que
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 3
ela vai armazenar. Desta forma pode-se aproveitar a mesma estrutura de dados para diversos
tipos de dados. Por exemplo, é melhor ter uma agenda genérica do que uma agenda de
telefones. Uma agenda genérica pode ser utilizada para guardar telefones, ou emails, ou até
mesmo guardar outra estrutura dentro dela: contatos, que seriam compostos por nome,
telefone e email.
Algumas estruturas de dados são apenas agrupamentos de dados sem um objetivo de
aplicar algum algoritmo ou tirar proveito de sua estrutura. Um exemplo seria a estrutura
Contato. Algumas outras estruturas são mais espertas e trabalhosas, como a Agenda, assim
como Listas Ligadas, Vetores, Tabelas de Espalhamento e outras que veremos no decorrer
do texto. Estas estruturas, por sua característica mais complexa e de poder ser reutilizada em
outros contextos, devem ser criadas da forma mais independente possível dos dados que
estarão dentro dela. Em outras palavras, não devemos misturar a Agenda e o Contato de
maneira rígida, para que com isso possamos criar outras Agendas, como por exemplo, uma
Agenda de Fornecedor.
1.3 Motivação
Todo mundo já experimentou sopa de letrinhas quando criança. Aliás, quando as crianças
tomam sopa de letrinhas, elas ficam muito mais interessadas em formar as palavras do que
em tomar a sopa.
O que chama mais a atenção é que nesta brincadeira de criança aparece um conceito bem
interessante de estrutura de dados. Quando a sopa é servida, as letras estão todas espalhadas
sem ordem alguma e sem nenhum significado. Quando você escolhe um grupo de letras e as
coloca em seqüência formando uma palavra, este grupo de letras ganha um valor semântico,
ou seja, ganha um significado.
O grupo de letrinhas que você escolhe para formar uma palavra pode conter letras
repetidas sem problema nenhum. A única regra é que as letras postas em seqüência devem
formar uma palavra existente em alguma língua.
As músicas também são exemplos em que a definição de uma seqüência dos elementos
agrega valor semântico. Uma música é composta de notas musicais. Quando estas notas
estão “espalhadas”, elas não significam muita coisa. Já quando colocadas em uma seqüência
adequada, formam uma música que as pessoas podem apreciar. Além disso, uma mesma
nota musical pode aparecer mais de uma vez em uma única música.
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 4
Outro exemplo em que a seqüência dos elementos é importante são as rotas de aviões.
Imagine o nome de várias cidades sem nenhuma ordem. Desta maneira, estes nomes não
significam muita coisa. Mas, se eles forem colocados em alguma seqüência então poderiam
formar a rota de uma aeronave.
1.4 Problema da Listagem
Uma certa instituição de ensino está incentivando os seus alunos a participarem de
eventos cadêmicos em troca de créditos para obter desconto nas mensalidades.
Para participar, o aluno deve comparecer em algum dos eventos cadastrados na
instituição e depois escrever um relatório sobre o conteúdo apresentado no evento. Este
relatório será avaliado por um professor e receberá uma pontuação de 0 a 100.
A instituição quer manter uma listagem dos alunos que entregaram relatórios. Cada
relatório entregue por um aluno corresponde a uma entrada na lista. Então, os alunos que
entregarem mais de um relatório irão aparecer mais de uma vez na listagem.
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 5
Por exemplo, suponha que entregaram relatórios os alunos Rafael, Paulo e Ana. Rafael
entregou apenas um relatório; Paulo entregou dois relatórios; e Ana entregou três relatórios.
Uma possível listagem neste caso seria assim:
1) Rafael
2) Paulo
3) Ana
4) Paulo
5) Ana
6) Ana
A listagem também deve manter a ordem de pontuação obtida pelos relatórios dos alunos.
Por exemplo, suponha que o Rafael teve pontuação máxima(100) no seu relatório; O Paulo
teve pontuação 70 em um relatório e 50 no outro; Ana teve pontuação 60, 40 e 40 nos seus
relatórios. Então, a listagem ficaria assim:
1) Rafael (100)
2) Paulo (70)
3) Ana (60)
4) Paulo (50)
5) Ana (40)
6) Ana (40)
Conforme os alunos forem entregando os relatórios, novas entradas serão adicionadas na
listagem. Uma nova entrada pode ser inserida em qualquer posição seguindo do critério da
pontuação do relatório do aluno.
Por exemplo, suponha que o Rafael entregou mais um relatório com pontuação 65. A
listagem deveria ser atualizada para:
1) Rafael (100)
2) Paulo (70)
3) Rafael (65)
4) Ana (60)
5) Paulo (50)
6) Ana (40)
7) Ana (40)
Para gastar os créditos obtidos com os relatórios, o aluno deve pedir para retirar uma das
suas entradas na listagem. Os créditos são proporcionais a colocação da entrada do aluno na
listagem.
Por exemplo, se o Paulo quiser gastar uma das suas duas entradas na lista ele deve
escolher entre a de 70 pontos a 50 pontos. A de 70 é a segunda da lista e a de 50 é a quinta.
Suponha que ele escolha a de 50 pontos então a nova listagem ficaria assim:
1) Rafael (100)
2) Paulo (70)
3) Rafael (65)
4) Ana (60)
5) Ana (40)
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 6
6) Ana (40)
Quando o aluno quiser usar seus créditos ele deve verificar antes se ele tem entradas na
listagem. Para isso, ele deve ir à secretária da instituição.
A instituição pode querer saber qual é o aluno que está na primeira posição da listagem
ou o que está na última. Na verdade, seria interessante para a instituição poder facilmente
saber qual é o aluno que está em qualquer posição que ela queira.
Vimos que uma estrutura de dados deve definir duas coisas:
1) A maneira como a informação será armazenada.
2) A interface de uso com o usuário.
Uma vez definidas todas as operações temos então a interface de uso da nossa estrutura
de dados.
Interface da Lista:
1) Adiciona um dado elemento no fim da Lista.
2) Adiciona um dado elemento em um dada posição.
3) Pega o elemento de uma dada posição.
4) Remove o elemento de uma dada posição.
5) Verifica se um dado elemento está contido na Lista.
6) Informa a quantidade de elementos da Lista.
Um fato bem interessante que ocorre quando programamos pensando primeiro na
interface, como estamos fazendo aqui, é que após a definição da interface já sabemos como
usar a estrutura que ainda nem desenvolvemos.
Se soubermos como usar a estrutura já sabemos como testá-la. Estes testes poderão ser
executados durante o desenvolvimento e não somente no fim. Isso é interessante, pois,
possibilita a eliminar erro mais rápido, logo que eles aparecem, e pode evitar erros em
cascata (erros que são causados por outros erros).
“A morte do homem começa no instante em que ele desiste de aprender” – Albino Teixeira
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 7
2. REVISÃO (Constantes, Variáveis e Tipos de Variáveis)
Variáveis e constantes são os elementos básicos que um programa manipula. Uma variável é
um espaço reservado na memória do computador para armazenar um tipo de dado
determinado. Variáveis devem receber nomes para poderem ser referenciadas e modificadas quando necessário. Um programa deve conter declarações que especificam de que tipo são as variáveis que ele utilizará e as vezes um valor inicial. Tipos podem ser por exemplo: inteiros, reais, caracteres, etc. As expressões combinam variáveis e constantes para calcular novos valores.
2.1 Constantes
Constante é um determinado valor fixo que não se modifica ao longo do tempo, durante a
execução de um programa. Conforme o seu tipo, a constante é classificada como sendo
numérica, lógica e literal. Exemplo de constantes:
N1+N2+N3 Constante
2.2 Variáveis
Variável é a representação simbólica dos elementos de um certo conjunto. Cada variável
corresponde a uma posição de memória, cujo conteúdo pode se alterado ao longo do tempo
durante a execução de um programa. Embora uma variável possa assumir diferentes valores,
ela só pode armazenar um valor a cada instante. Exemplos de variáveis
VARIÁVEL
CONTEÚDO DA VARIÁVEL
VARIÁVEIS
Total = Produto * Quantidade
3
NOME = “JOSE”
IDADE = 50
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 8
2.3 Tipos de Variáveis
As variáveis e as constantes podem ser basicamente de quatro tipos: Numéricas, caracteres,
Alfanuméricas ou lógicas.
Inteiro: Qualquer número inteiro (negativo, nulo ou positivo).
Exemplo: -100, 0, 1, 2, 1250.
• Real: Qualquer número real, nulo ou positivo.
Exemplo: -10, -1.5, 11.2, 0,1, 2, 50.
• Caracter: Caracteres alfanuméricos.
Exemplo: casa, Win31, 123, alfa#2, etc...
• Lógico: valor lógico verdadeiro ou falso
Exemplo: x > y ?
2.4 EXERCÍCIOS
1) O que é uma constante? Dê dois exemplos.
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
2) O que é uma variável? Dê dois exemplos.
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
3 Linguagem C , C++ e C++ Builder
Linguagem poderosa criada em 1971 por Denis Ritchie com implementação do conceito POO
em 1983 por Bjarne Stroustrup recebendo o nome de C++ (++ é chamado de pós-incremento
na linhagem C). Em 2003, a Empresa Borland implementou sua plataforma gráfica para o
ambiente Windows, chamando de C++ Builder.
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 9
3.1 Declaração das Variáveis EM C
A declaração das variáveis segue a ordem, primeiro o seu tipo seguido das variáveis.
int km, velocidade;
float media, km_litro;
string nome;
3.2 Tamanho de bytes de cada tipo de variável no C
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 10
3.3 Operadores Aritméticos em C
Descrição Símbolo Soma + Subtração - Multiplicação * Divisão / Resto da divisão %
3.4 Operadores Relacionais em C
Os operadores relacionais são utilizados para comparar String de caracteres e
Números. Os valores a serem comparados podem ser caracteres ou variáveis.
Estes operadores sempre retornam valores lógicos (verdadeiro ou falso/ True ou False)
Para estabelecer prioridades no que diz respeito a qual operação executar primeiro, utilize os parênteses.
Os operadores relacionais são:
Descrição Símbolo Igual a =
Diferente de != Maior que > Menor que < Maior ou igual a >= Menor ou igual a <= Igual comparação ==
Exemplo:
Tendo duas variáveis A = 5 e B = 3 Os resultados das expressões seriam:
Expressão Resultado A == B Falso
A != B Verdadeiro
A > B Verdadeiro
A < B Falso
A >= B Verdadeiro
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 11
3.5 Operadores Lógicos
Os operadores lógicos servem para combinar resultados de expressões, retornando se o
resultado final é verdadeiro ou falso. Os operadores lógicos são:
Exemplos:
Suponha que temos três variáveis A = 5, B = 8 e C =1 Os resultados das expressões seriam:
Expressão Resultado
( A == B && B > C ) Falso ( A != B || B < C ) Verdadeiro !(A <= B) Falso
3.6 Funções Básicas de Matemática em C
A linguagem C e rica em funções prontas dentro de suas bibliotecas para determinadas
operações que veremos de acordo com a necessidade de nossas operações em Estrutura de
Dados.
Exemplo:
sqrt, pow, cos, sin, tan, fmod (funções da biblioteca math.h);
3.7 Funções de Transformação de Tipo em C++ Builder
A <= B Falso
E &&
OU ||
NÃO !
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 12
A linguagem C++ Builder foi implementada para o ambiente gráfico e recebeu outras
funções para de transformações de dados, tanto para cálculos como para visualização de
resultados.
Exemplo:
StrToFloat (Transforma uma String em um valor real);
FloatToStr (Transforma um valor real em String);
StrToInt (Transforma uma String em valor inteiro);
IntToStr (Transforma um valor inteiro em uma String);
Atof (O mesmo que StrToFloat);
Atoi (O mesmo que StrToInt).
3.8 Comandos e Objetos Básicos usados em C++ Builder
3.9 Comandos e Objetos Básicos usados em C++ Builder
A Linguagem C e Java são muito rigorosas com os seus comandos. Elas diferem a forma
que as variáveis são criadas, como também a sintaxe de seus comandos.
Exemplo:
Exemplos (Comandos):
Float -> é diferente de float; string -> é diferente de String; int -> é diferente de Int;
strtofloat -> é diferente de StrToFloat;
Exemplos(Variáveis):
Int a -> é diferente de int B; String aluno -> é diferente de String Aluno;
float media -> é diferente de float MEDIA;
{ } (Inicio e Fim);
Edit (Objeto Caixa de Texto);
ListBox (Objeto Caixa de Texto)
ShowMessage (Comando);
if (Comando se);
else (Comando senão);
For (Comando de repetição Para);
While (Comando de repetição Enquanto);
Do (Comando de repetição Faça);
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 13
3.10 Atribuição de Valores a uma Variável em C
É colocar o conteúdo na variável com o mesmo tipo que foi definido.
Exemplos:
{
funcionario = „Joao‟;
cargo = „Programador‟;
salario = 1500.00;
ir = 150.00; sl = salario – ir }
4 Familiarizando com o ambiente C++ Builder Exemplos1:
1) Receber 2 valores do teclado, processar a operação soma e mostrar o resultado. C++ Builder ( Tela Gráfica ) (Código) ( função atoi – resultado em Edit )
void __fastcall TForm1::Button1Click(TObject *Sender) { float V1, V2, Soma; V1 = atof(Edit1->Text.c_str()); V2 = atof(Edit2->Text.c_str()); Soma = V1 + V2; Edit3->Text = Soma; }
Edit3
Button1
Edit2
Edit1
Label1 Label2 Label3
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 14
C++ Builder ( Tela Gráfica - ListBox) (Código)
- Comando StrToFloat - resultado em ListaBox resultado em Edit
Exemplo 2:
2) Receber o Nome do funcionário, Salário atual, Taxa de Reajuste em %, em seguida calcule e mostre: O aumento e novo salário do funcionário.
C++ Builder ( Tela Gráfica ) C++ Builder ( Código )
void __fastcall TForm1::Button1Click(TObject *Sender) { float V1, V2, Soma; V1 = StrToFloat(Edit1->Text); V2 = StrToFloat(Edit2->Text); Soma = V1 + V2; ListBox1->Items->Add(Soma); }
void __fastcall TForm1::Button1Click(TObject *Sender) { float V1, V2, Soma; V1 = StrToFloat(Edit1->Text); V2 = StrToFloat(Edit2->Text); Soma = V1 + V2; Edit3->Text = Soma; }
void __fastcall TForm1::Button1Click(TObject *Sender) { String Funcionario; float SalarioAtual, TaxaR, Reajuste, NovoSalario; SalarioAtual = atof(Edit2->Text.c_str()); TaxaR = atof(Edit3->Text.c_str()); Reajuste = (SalarioAtual * TaxaR) / 100; SalarioAtual = SalarioAtual + Reajuste;
Edit4->Text = Reajuste; Edit5->Text = SalarioAtual;
}
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 15
4.1 EXERCÍCIOS
1) Receber o Nome do Aluno, Disciplina, Bimestre, Nota1, Nota2, Nota3, em seguida calcule e mostre: A média ponderada do aluno.
2) Receber a Base e Altura de um Triângulo, em seguida usando a fórmula ( A = (base . altura ) / 2 ), calcule e mostre: A área do Triângulo.
5 Estrutura Condicional em C
Como vimos nos exemplos anteriores em “Operações Lógicas”, verificamos que na
maioria das vezes necessitamos tomar decisões no andamento do programa. Essas decisões
interferem diretamente no andamento do algoritmo ou programa. Portanto, Uma estrutura de
decisão permite a escolha de um grupo de ações a serem executadas. As principais estruturas de
decisões são: if (se); else (senão).
A estrutura condicional em qualquer linguagem é utilizada de duas formas para escrever o
programa (Estrutura Condicional Simples e Condicional composta).
Simples:
É a estrutura que será repetida o teste condicional a cada decisão a ser tomada pelo
algoritmo ou programa.
Composta:
É a estrutura que fará o aproveitamento do teste condicional na decisão a ser tomada pelo
programa.
Exemplo 1:
Imagine um programa que determinado aluno somente estará aprovado se sua média for maior ou igual a 5.0, veja no exemplo do programa como ficaria.
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 16
C++ Builder ( Tela Gráfica ) ( Código )
Calcular Media Aritmética (Condicional simples)
Exemplo 2: C++ Builder ( Tela Gráfica ) ( Código ) (Concional composta)
Calcular Equação do 2° Grau
void __fastcall TForm1::Button1Click(TObject *Sender) { String situacao; float n1, n2, media; n1 = atof(Edit4->Text.c_str()); n2 = atof(Edit4->Text.c_str()); media = ( n1 + n2 ) / 2; if (media >=5.0) situacao = "Aprovado"; IF (media < 5.0) situacao = "Reprovado"; ListBox1->Items->Add("Aluno : " + Edit1->Text); ListBox1->Items->Add("Disciplina : " + Edit2->Text); ListBox1->Items->Add("Bimestre : " + Edit3->Text); ListBox1->Items->Add("Média : " + FloatToStr(media)); ListBox1->Items->Add("Situação : " + situacao); }
void __fastcall TForm1::Button1Click(TObject *Sender) { int a, b, c, d; float x1, x2; a = atoi(Edit1->Text.c_str()); b = atoi(Edit2->Text.c_str()); c = atoi(Edit3->Text.c_str()); d = pow(b, 2) - 4 * a * c; if ( d >= 0 ) { x1 = (-b + sqrt(d)) / (2 * a); x2 = (-b - sqrt(d)) / (2 * a); Edit4->Text = x1; Edit5->Text = x2; } else ShowMessage("Delta = " + IntToStr(d) + " < 0"); } void __fastcall TForm1::Button2Click(TObject *Sender) { Edit1->Text = ""; Edit2->Text = ""; Edit3->Text = ""; Edit4->Text = "";
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 17
5.1 EXERCÍCIOS
1) Receber um valor diferente para A, B e C, em seguida processe e mostre: Qual o maior
e o menor valor digitado.
2) Receber um valor diferente para A, B e C, em seguida processe e mostre: A, B e C na ordem crescente, independente da ordem digitada.
6. Estruturas Repetitivas em C++ Builder
6.1 Repetição com variável de controle em C++ Builder
A noção de percorrer uma série ordenada de coisas, realizando alguma tarefa com ou
sobre os elementos dessa série, é chamada de iteração (ou repetição). Toda linguagem de
programação oferece uma estrutura de looping com variável de controle definindo o número de
execuções do laço lógico.
Exemplo1:
Escrever os números impares de 1 a 100.
C++ Builder
Exemplo2:
Escrever seu nome 1000 vezes.
C++ Builder
{ int N; for (N = 1 ; N <= 100 ; N=N+2) ListBox1->Items->Add(N); }
{ int N; for (N = 1 ; N <= 1000 ; N=N+1) ListBox1->Items->Add(“Rufino”); }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 18
Exemplo3:
Escrever os números pares de 200 a 0.
C++ Builder
Além da utilização clássica que acabamos de ver, o comando de repetição For é muito
mais abrangente. Podemos ter mais de uma estrutura de repetição uma dentro da outra. Quando
isto acontece dizemos que temos estruturas de repetições aninhadas ou encadeada.
Exemplo 4:
Escrever a seguinte estrutura:
C++ Builder
{ int N; for (N = 200 ; N >= 0 ; N=N-2) ListBox1->Items->Add(N); }
{ int n, x; for (n = 1; n <= 5; n++) for ( x = 1; x <= 5; x++) ListBox1->Items->Add(IntToStr(n)+”. “+IntToStr(x)); }
1.1 4.1 1.2 4.2 1.3 4.3 1.4 4.4 1.5 4.5 2.1 5.1 2.2 5.2 2.3 5.3 2.4 5.4 2.5 5.5 3.1 3.2 3.3 3.4 3.5
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 19
6.2 EXERCÍCIOS
1) Elaborar as estruturas acima para calcular e exibir os N primeiros termos da
seqüência: 2, 4, 6, 8, ...
2) Elaborar as estruturas acima para calcular e exibir a todas as tabuadas de multiplicar de 1 a 10.
6.3 Repetição com a condição o início ou no final em C O comando de repetição while permite que um comando ou bloco de comandos seja
executado enquanto uma determinada condição for verdadeira. A condição pode ser verificada
no inicio de cada repetição, quando utilizamos o comando while, ou no final, quando utilizamos
do comando do...while.
1 x 1 = 1 1 x 2 = 2 1 x 3 = 3 1 x 4 = 4 1 x 5 = 5 1 x 6 = 6 1 x 7 = 7 1 x 8 = 8 1 x 9 = 9 1 x 10 = 10
2 x 1 = 2 2 x 2 = 4 2 x 3 = 6 2 x 4 = 8 2 x 5 = 10 2 x 6 = 12 2 x 7 = 14 2 x 8 = 16 2 x 9 = 18 2 x 10 = 20
3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 3 x 4 = 12 3 x 5 = 15 3 x 6 = 18 3 x 7 = 21 3 x 8 = 24 3 x 9 = 27 3 x 10 = 30
4 x 1 = 4 4 x 2 = 8 4 x 3 = 12 4 x 4 = 16 4 x 5 = 20 4 x 6 = 24 4 x 7 = 28 4 x 8 = 32 4 x 9 = 36 4 x 10 = 40
5 x 1 = 5 5 x 2 = 10 5 x 3 = 15 5 x 4 = 20 5 x 5 = 25 5 x 6 = 30 5 x 7 = 35 5 x 8 = 40 5 x 9 = 45 5 x 10 = 50
7 x 1 = 7 7 x 2 = 14 7 x 3 = 21 7 x 4 = 28 7 x 5 = 35 7 x 6 = 42 7 x 7 = 49 7 x 8 = 56 7 x 9 = 63 7 x 10 = 70
9 x 1 = 9 9 x 2 = 18 9 x 3 = 27 9 x 4 = 36 9 x 5 = 45 9 x 6 = 54 9 x 7 = 63 9 x 8 = 72 9 x 9 = 81 9 x 10 = 90
6 x 1 = 6 6 x 2 = 12 6 x 3 = 18 6 x 4 = 24 6 x 5 = 30 6 x 6 = 36 6 x 7 = 42 6 x 8 = 48 6 x 9 = 54 6 x 10 = 60
8 x 1 = 8 8 x 2 = 16 8 x 3 = 24 8 x 4 = 32 8 x 5 = 40 8 x 6 = 48 8 x 7 = 56 8 x 8 = 64 8 x 9 = 72 8 x 10 = 80
10 x 1 = 10 10 x 2 = 20 10 x 3 = 30 10 x 4 = 40 10 x 5 = 50 10 x 6 = 60 10 x 7 = 70 10 x 8 = 80 10 x 9 = 90 10 x 10 = 100
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 20
6.4 Repetição com o teste no inicio em C
O comando while teste a condição no início de cada iteração, repetindo o comando ou
bloco de comandos enquanto a condição for verdadeira.
Se a condição, logo no inicio, já for falsa, o comando (ou bloco) não será executado
nenhuma vez, pois o teste é feito antes da execução.
Exemplo1:
Escrever a soma dos 10 primeiros números pares.
C++ Builder
Exemplo2:
Escrever todos os múltiplos de 2,5082364789 e inferior a 31,34598736.
C++ Builder
6.5 Repetição com o teste no final em C
{ int x, soma; soma = 0; x = 1; while (x <= 10 ) { soma = soma + 2 * x; x = x + 1; } Edit1->Text = Soma; }
{ double m; m = 2.5082364789; while (x < 31.34598736 ) { ListBox1->Items->Add(m); m = m + 2.5082364789; } }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 21
O comando do...while testa a condição no final de cada iteração, repetindo o comando ou
bloco de comandos enquanto a condição for verdadeira.
Se a condição, logo no início, já for falsa, o comando (ou bloco) será executado pelo
menos uma vez, pois o teste é feito depois da execução.
Exemplo1:
Dados os valores A e B, inteiros, elaborar o programa em C++ Builder para exibir os números
pares entre a seqüência de A e B, inclusive.
C++ Builder
Exemplo2:
Calcular a soma e exibir o resultado dos N primeiros termos da seqüência: (1 + 2 + 3 + 4 + ...)
6.6 EXERCÍCIOS
1) Elaborar as estruturas acima para calcular exibir a soma dos N primeiras termos da seqüência:
{ int a, b; a = StrToInt(Edit1->Text); b = StrToInt(Edit2->Text); do { if ((a % 2) == 0) ListBox1->Items->Add(a); a++; } while (a <= b); }
{ int n, x, s; n = StrToInt(Edit1->Text); s = 0; x = 0; do { x++; s = s + x; } while (x < n); Edit2->Text = s; }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 22
1 + 3 + 5 + 7 + .... (Usar o teste no inicio)
2) Elaborar as estruturas acima para calcular e exibir o Produto dos N primeiros termos da seqüência: (Usar o teste no final)
1 * 2 * 3 * 4 * ... (Fatorial)
7. ARRANJOS
Arranjos, também conhecido como vetores ou matrizes, são agrupamentos de variáveis
do mesmo tipo, variáveis homogêneas, com o mesmo nome e diferenciadas por um ou mais
índices.
Diz-se que o arranjo é um vetor quando seus itens possuem uma única dimensão, um
único índice, e quando o arranjo for definido por duas dimensões, dois índices, costuma-se
referenciá-lo como matriz.
Vetor
A forma de declarar um vetor é:
TipoDeDado NomeDoVetor [QuantidadeDeItens];
Em termos práticos, esse tipo de variável significa que a simples declaração de um único
vetor do tipo inteiro com 5 itens equivale a 5 declarações de variáveis inteiro distintas.
Exemplo:
int Vet [5];
Vet 0 0 0 0 0
Indice 0 1 2 3 4
Equivale a:
int v0, v1, v2, v3, v4; ou int v0;
int v1;
int v2;
int v3;
int v4;
Exemplo1:
Suponha que você quer armazenar um nome de uma pessoa 7 vezes na memória usando vetor.
Solução 1: Solução 2:
C++ Builder
{ String nome[7]; nome*0+ = “Tolentina”; nome*1+ = “Tolentina”; nome*2+ = “Tolentina”; nome*3+ = “Tolentina”; nome*4+ = “Tolentina”; nome*5+ = “Tolentina”; nome*6+ = “Tolentina”; }
{ String nome[7]; int I; for I = 0 ; I < 7 ; I++) nome* I + = “Tolentina”; }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 23
Portanto, em qualquer uma das soluções na memória ficará assim:
nome Tolentina Tolentina Tolentina Tolentina Tolentina Tolentina Tolentina
Indice 0 1 2 3 4 5 6
Há ocasiões nas quais se deseja que o arranjo, ao ser criado, já tenha valores default
atribuídos a seus itens.
Exemplo:
int Vet[ 5 ] = { 16, 2, 77, 33, 1024 };
Vet 16 2 77 33 1024
Indice 0 1 2 3 4
Veja outro exemplo igual:
Into Vet[ ] = { 16, 2, 77, 33, 1024 };
Vet 16 2 77 33 1024
Indice 0 1 2 3 4
Veja outro exemplo diferente:
int Vet[ 5 ] = { 16, 2, 77 };
Vet 16 2 77 0 0
Indice 0 1 2 3 4
Veja este exemplo, um vetor de caracter:
String frase[ 42 ] = “Você tem muito o que aprender neste curso”;
É o que:
String frase[ 42 ] = { “V”, “o”, “c”, “ê”, “ “,”t”, “e”, “m”, “ “, “m”, “u”, “i”, “t”, “o”, “ “, “o”, “ “, “q”, “u”, “e”, “ “, “a”, “p”, “r”, “e”, “n”, “d”, “e”, “r”, “ “, “n”, “e”, “s”, “t”, “e”, “ “, “c”, “u”, “r”, “s”, “o”, “\0” };
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 24
O ultimo caractere de uma string é o elemento nulo “\0”.
Exemplo2:
Suponha que desejamos confeccionar uma cartela de um bingo que geralmente são
confeccionadas com valores de 1 a 75 números.
B I N G O
1 19 33 47 61
3 26 34 53 65
6 27 35 54 68
10 28 42 56 73
11 29 44 60 75
Podemos criar e armazenar um vetor inteiro da seguinte forma:
int cartela[25] = { 1, 3, 6, 10, 11, 19, 26, 27, 28, 29, 33, 34, 35, 42, 44, 47, 53, 54, 56, 60, 61, 65,
68, 73, 75 };
Ou assim:
int cartela[25];
cartela[0]=1 ; cartela[1]=3 ; cartela[2]=6 ; cartela[3]=10 ; cartela[4]=11;
cartela[5]=19 ; cartela[6]=26 ; cartela[7]=27 ; cartela[8]=28 ; cartela[9]=29;
cartela[10]=33 ; cartela[11]=34 ; cartela[12]=35 ; cartela[13]=42 ; cartela[14]=44;
cartela[15]=47 ; cartela[16]=53 ; cartela[17]=54 ; cartela[18]=56 ; cartela[19]=60;
cartela[20]=61 ; cartela[21]=65 ; cartela[22]=68 ; cartela[23]=73 ; cartela[24]=75;
Solução
{ int cartela[25] = {1, 3, 6, 10, 11, 19, 26, 27, 28, 29, 33, 34, 35, 42, 44, 47, 53, 54, 56, 60, 61, 65, 68, 73, 75}; String linha[5]; int I, L, x; ListBox1->Items->Add("B I N G O"); I = 0 ; x = 1 ; for (L = 0 ; L < 5 ; L++) { linha*L+ = “”; do { linha[ L ]=linha[ L ]+IntToStr(cartela[ I ])+" "; I = I + 5; x = x + 1; } while (x <= 5); I = I - 24; x = 1; } for (L = 0 ; L < 5 ; L++) ListBox1->Items->Add(linha[ L ]); }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 25
Exemplo3:
A Distribuidora de Bebidas Caranguejo Ltda atingiu em 2007, sua meta de venda mensal
conforme tabela abaixo. Através da meta atingida na tabela, ela precisa saber a média de
venda mensal em 2008, e o qual o valor e o mês, que a meta foi menor e maior. Faça um
programa em C++ mostrar os dados solicitados, usando o conceito de vetor.
Tabela de simulação:
MÊS VALOR DE VENDA
Janeiro R$ 180.000,00
Fevereiro R$ 200.000,00
Março R$ 195.000,00
Abril R$ 170.000,00
Maio R$ 285.000,00
Junho R$ 230.000,00
Julho R$ 250.000,00
Agosto R$ 215.000,00
Setembro R$ 207.000,00
Outubro R$ 225.000,00
Novembro R$ 240.000,00
Dezembro R$ 280.000,00
{ String mes[12] = {“Janeiro”,”Fevereiro”,”Março”,”Abril”, “Maio”,”Junho”,”Julho”,”Agosto”,”Setembro”,”Outubo”,”Novembro”,”Dezembro”}; float meta[12] = { 180000,20000,195000,170000,285000,230000,250000,215000,207000,225000,240000,280000};
float mvm, metamaior, metamenor; String mesMetamaior, mesMetamenor; int x; metamaior=meta[0] ; metamenor=meta[0]; for (x=0 ; x < 12 ; x++ ) { mvm = mvm + meta [x]; if (meta[x] > metamaior) { metamaior = meta[x]; mesMetamaior = mes[x]; } if (meta[x] < metamenor) { metamenor = meta[x]; mesMetamenor=mes[x]; } } mvm = mvm / 12; ListBox1->Items->Add(“Média mensal de vendas =”+FormatFloat(“###,###,##0.00”,mvm));
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 26
Matriz
Uma matriz nada mais é do que um vetor de vetores. A organização na memória é a
mesma que a de um vetor (uma seqüência contínua de elementos), mas a organização percebida
pelo programador dentro das linguagens de programação é diferente. Cada elemento de uma
matriz é individualizado por dois índices. O primeiro corresponde a linha, e o segundo
corresponde a coluna.
A forma de declarar uma matriz é:
TipoDeDado NomeDaMatriz [QuantidadeDeLinhas] [QuantidadeDeColunas];
Exemplo:
int Mat [2] [2];
Índices: (00) (01) (10) (11)
Equivale a:
int Mat0, Mat1, Mat2, Mat3; ou Mat [4] = {0, 0, 0, 0};
Exemplo1:
Suponha que você quer armazenar um nome de uma pessoa 10 vezes na memória usando matriz.
Solução 1:
C++ Builder
Solução 2:
Mat 0(00) 0(01)
0(10) 0(11)
{ String nome[2] [5]; nome*0+*0+ = “Florentina”; nome*0+*1+ = “Florentina”; nome*0+*2+ = “Florentina”; nome*0+*3+ = “Florentina”; nome*0+*4+ = “Florentina”; nome*1+*0+ = “Florentina”; nome*1+*1+ = “Florentina”; nome*1+*2+ = “Florentina”; nome*1+*3+ = “Florentina”; nome*1+*4+ = “Florentina”;
}
{ String nome[5] [2]; nome*0+*0+ = “Florentina”; nome*0+*1+ = “Florentina”; nome*1+*0+ = “Florentina”; nome*1+*1+ = “Florentina”; nome*2+*0+ = “Florentina”; nome*2+*1+ = “Florentina”; nome*3+*0+ = “Florentina”; nome*3+*1+ = “Florentina”; nome*4+*0+ = “Florentina”; nome*4+*1+ = “Florentina”; }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 27
Solução 3:
Portanto, a solução 1 e 3 na memória ficará assim:
nome Florentina(00) Florentina(01) Florentina(02) Florentina(03) Florentina(04) Florentina(10) Florentina(11) Florentina(12) Florentina(13) Florentina(14)
Índices: (00) (01) (02) (03) (04) (10) (11) (12) (13) (14)
Há ocasiões nas quais se deseja que o arranjo, ao ser criado, já tenha valores default
atribuídos a seus itens.
Exemplo1:
C++ Builder
String nome[2] [5] = {{"Florentina","Florentina","Florentina","Florentina","Florentina"},
{"Florentina","Florentina","Florentina","Florentina","Florentina"}};
Exemplo2:
Suponha que desejamos confeccionar uma cartela de um bingo que geralmente são
confeccionadas com valores de 1 a 75 números.
B I N G O
1 19 33 47 61
3 26 34 53 65
6 27 35 54 68
10 28 42 56 73
11 29 44 60 75
Podemos criar e armazenar uma matriz de inteiros da seguinte forma:
{ String nome[2] [5]; int L,C; for L = 0 ; I < 2 ; L++) for C = 0 ; I < 5 ; C++) nome*L+ *C+ = “Florentina”; }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 28
int cartela[5] [5] = {{ 1, 19, 33, 47, 61 },
{ 3, 26, 34, 53, 65 },
{ 6, 27, 35, 54, 68 },
{ 10, 28, 42, 56, 73 },
{ 11, 29, 44, 60, 75 }};
Ou assim:
int cartela[5] [5];
cartela[0][0]=1 ; cartela[0][1]=19 ; cartela[0][2]=33 ; cartela[0][3]=47 ; cartela[0][4]=61;
cartela[1][0]=3 ; cartela[1][1]=26 ; cartela[1][2]=34 ; cartela[1][3]=53 ; cartela[1][4]=65;
cartela[2][0]=6 ; cartela[2][1]=27 ; cartela[2][2]=35 ; cartela[2][3]=54 ; cartela[2][4]=68;
cartela[3][5]=10 ; cartela[3][1]=28 ; cartela[3][2]=42 ; cartela[3][3]=56 ; cartela[3][4]=73;
cartela[4][0]=11 ; cartela[4][1]=29 ; cartela[4][2]=44 ; cartela[4][3]=60 ; cartela[4][4]=75;
Solução
Exemplo 3
Suponha que queremos fazer um programa para compararmos a previsão do tempo em 5 cidades
do nosso país, na primeira semana do mês de maio/2008 todos os dias. Vamos usar o conceito de
vetor e matriz para resolver esta solução. Faça um programa em C++ para indicar qual a
temperatura e a cidade que está mais quente e qual a que está mais fria.
Tabela de simulação:
{
int cartela[5] [5] = {{ 1, 19, 33, 47, 61 }, { 3, 26, 34, 53, 65 }, { 6, 27, 35, 54, 68 }, { 10, 28, 42, 56, 73 }, { 11, 29, 44, 60, 75 }}; String linha[5]; int L, C;
ListBox1->Items->Add(“B I N G O”); for (L = 0 ; L < 5 ; L++) { linha*L+ = “”; for (C = 0 ; C < 5 ; C++) linha[ L ]=linha[ L ] + IntToStr(cartela[L ] [C]) + " "; } for ( L = 0 ; L < 5 ; L++) ListBox1->Items-Add(linha[ L ]); }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 29
Cidades Segunda Terça Quarta Quinta Sexta Sábado Domingo
Aracajú 20 27 26 30 32 31 26 Belém 30 32 31 29 29 30 27 Belo Horizonte 25 26 27 28 28 29 26 Boa Vista 35 37 35 27 31 28 29 Brasília 28 25 24 25 27 26 25
C++ Builder
{ float Temp[5][7]; String cid[5] = {"Aracajú", "Belém", "Belo Horizonte", "Boa Vista", "Brasilia"}; String dsem[7] = {"Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado", "Domingo"}; int L,C ; float tma, tme; String cidf, cidq, dia; Temp[0][0]=StrToFloat(Edit1->Text); Temp[0][1]=StrToFloat(Edit2->Text); Temp[0][2]=StrToFloat(Edit3->Text); Temp[0][3]=StrToFloat(Edit4->Text); Temp[0][4]=StrToFloat(Edit5->Text); Temp[0][5]=StrToFloat(Edit6->Text); Temp[0][6]=StrToFloat(Edit7->Text); Temp[1][0]=StrToFloat(Edit8->Text); Temp[1][1]=StrToFloat(Edit9->Text); Temp[1][2]=StrToFloat(Edit10->Text); Temp[1][3]=StrToFloat(Edit11->Text); Temp[1][4]=StrToFloat(Edit12->Text); Temp[1][5]=StrToFloat(Edit13->Text); Temp[1][6]=StrToFloat(Edit14->Text); Temp[2][0]=StrToFloat(Edit15->Text); Temp[2][1]=StrToFloat(Edit16->Text); Temp[2][2]=StrToFloat(Edit17->Text); Temp[2][3]=StrToFloat(Edit18->Text); Temp[2][4]=StrToFloat(Edit19->Text); Temp[2][5]=StrToFloat(Edit20->Text); Temp[2][6]=StrToFloat(Edit21->Text); Temp[3][0]=StrToFloat(Edit22->Text); Temp[3][1]=StrToFloat(Edit23->Text); Temp[3][2]=StrToFloat(Edit24->Text); Temp[3][3]=StrToFloat(Edit25->Text); Temp[3][4]=StrToFloat(Edit26->Text); Temp[3][5]=StrToFloat(Edit27->Text); Temp[3][6]=StrToFloat(Edit28->Text); Temp[4][0]=StrToFloat(Edit29->Text); Temp[4][1]=StrToFloat(Edit30->Text); Temp[4][2]=StrToFloat(Edit31->Text); Temp[4][3]=StrToFloat(Edit32->Text); Temp[4][4]=StrToFloat(Edit33->Text); Temp[4][5]=StrToFloat(Edit34->Text); Temp[4][6]=StrToFloat(Edit35->Text);
for (C = 0 ; C < 7 ; C++) { cidq=cid[0] ; cidf=cid[0]; tma = Temp[0][C] ; tme=Temp[0][C]; for (L = 0 ; L < 5 ; L++) { dia = dsem[C]; if (Temp[L][C] > tma) { tma = Temp[L][C]; cidq = cid[L]; } else if (L > 0 && Temp[L][C] == tma) cidq = cidq + "/" + cid[L]; if (Temp[L][C] < tme) { tme = Temp[L][C]; cidf = cid[L]; } else if (L > 0 && Temp[L][C] == tme) cidf = cidf + "/" + cid[L]; } ListBox1->Items->Add(dia); ListBox1->Items->Add("Maior Temp: “+FloatToStr(tma)+" -> "+cidq); ListBox1->Items->Add("Menor Temp: “+ FloatToStr(tme)+" -> "+cidf); } }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 30
6.7 EXERCÍCIOS ( VETOR / MATRIZ )
1) O departamento financeiro da Empresa “Só Cuscuz, Mingaus e Polenta Ltda” precisa
saber nos últimos dois anos, a média mensal, o mês que teve maior e menor venda de cada
ano, e qual a média dos dois anos de vendas. Elabore o programa em C++ para mostrar os
dados solicitados, usando o conceito de matriz, e vetores se necessário.
Ano Jan Fev Mar Abr Mai Jun Jul Ago Set Out Nov Dez 2007 50.000 60.000 65.000 70.000 55.000 75.000 97.500 72.000 68.000 90.000 95.000 97.000
2008 70.000 65.000 75.000 77.000 78.000 80.000 83.000 85.000 88.000 91.000 98.000 100.000
1) Dado o Gabarito de uma prova com 10 (dez) questões de um concurso, conforme
abaixo. A comissão de correção do concurso precisa de um programa que faça a
correção através da prova com o gabarito, para calcular quantos pontos o candidato
fez. Considere que, cada questão tem um valor de 10 pontos, e o conceito “Aprovado”
se o candidato atingir a pontuação maior ou igual a 60 pontos, caso contrário o conceito
será “Reprovado”. Considere também, na tabela o número {1} as alternativas corretas
e o número {0} as alternativas falsas. Use o conceito de matriz, e vetor, se necessário
para resolver esta solução.
1ª 2ª 3ª 4ª 5ª 6ª 7ª 8ª 9ª 10ª
A 1 0 0 0 0 0 0 1 1 0
B 0 0 0 0 0 1 0 0 0 0
C 0 0 1 0 1 0 0 0 0 0
D 0 1 0 0 0 0 0 0 0 1
E 0 0 0 1 0 0 1 0 0 0
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 31
7 PROCEDIMENTOS
A utilização de procedimentos permite que um conjunto de comandos possa ser usado várias
vezes dentro de um programa, sem a necessidade de reescrever o código várias vezes. Um bloco
de comandos é associado a um nome (nome do procedimento); sempre que for necessário
executar estes comandos, basta chamar o nome do procedimento. Linguagens como o DELPHI,
C++BUILDER e outras linguagens visuais, trabalham sempre com procedimento e funções.
Portanto, podemos aproveitar todo o nosso conhecimento e criarmos também nossos
procedimento e funções, caso necessite dentro dos nossos programas.
Exemplo1:
Lembrando a equação do segundo grau. Aplicaremos o conceito de Procedimentos. Veja:
C++ Builder
TForm1 *Form1; //------------ Variaveis Globais--------------------------------------- int delta; //------------ Procedimento------------------------------------------ void CalcularDelta(int a, int b, int c) { delta = pow(b,2) - 4 * a * c; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { int va, vb, vc; float x1, x2; va = atoi(Edit1->Text.c_str()); vb = atoi(Edit2->Text.c_str()); vc = atoi(Edit3->Text.c_str()); CalcularDelta(va, vb, vc) ; Edit4->Text = delta; if (delta < 0) ShowMessage("Nao existe raiz reais..."); else { x1 = (-vb + sqrt(delta)) / (2 * va); x2 = (-vb - sqrt(delta)) / (2 * va); Edit5->Text = x1; Edit6->Text = x2;
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 32
Exemplo2: Receber o Nome do Produto, Preço Unitário, Desconto em %, em seguida calcular e mostrar: O Nome do produto, valor do Desconto e o Valor do Produto com Desconto, usando o conceito de Procedimentos.
TForm1 *Form1; //------------ Variaveis Globais--------------------------------------- float ValorProduto, Desconto; //------------ Procedimento1----------------------------------------- void CalcularValor( float ValorUnit, float desc ) { Desconto = (ValorUnit * desc ) / 100; ValorProduto = ValorUnit – Desconto; } //------------ Procedimento2----------------------------------------- void LimparTela(void ) { Form1->Edit1->Clear(); Form1->Edit2->Clear(); Form1->Edit3->Clear(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { float vu, dc; String produto; produto = Edit1->Text; vu = atof(Edit2->Text.c_str()); dc = atof(Edit3->Text.c_str()); CalcularValor( vu, dc ) ; ListBox1->Items->Add(“Produto : “+produto); ListBox1->Items->Add(“Desconto: “+ FloatToStr(Desconto)); ListBox1->Items->Add(“Valor com Desconto: “+FloatToStr(ValorProduto)); LimparTela(); }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 33
Exemplo3:
O senhor Zequinha, mantém toda semana as mesmas cartelas e joga na Mega Sena. Ele joga toda semana 10 cartelas com os mesmos números. Para conferir ele vai a casa lotérica e pega os números sorteados a cada concurso. Ele confere através do programa abaixo, feito em C++ Builder, usando alguns recursos que já vimos em nossa disciplina (Vetor/Matriz/Repetições e Procedimentos). Ele digita apenas os números e o programa informa para ele quais os números sorteados em cada cartela que jogou. C++ Builder
TForm1 *Form1; //----------Variaveis Globais------------------------------------------------ int NumCartela[10]; String NumSort[10]; //---------------------------------------------------------------------------------- void CartelaMegaSena(int n1, int n2, int n3, int n4, int n5, int n6) { int cartela[10][6] = {{ 7, 13, 23, 32, 33, 42 }, { 2, 17, 33, 35, 36, 57 }, { 3, 21, 43, 44, 52, 53 }, {10, 13, 33, 47, 57, 60 }, { 7, 17, 43, 52, 53, 57 }, { 1, 10, 13, 17, 33, 47 }, { 9, 17, 18, 31, 38, 46 }, {11, 12, 25, 29, 44, 45 }, {21, 22, 23, 54, 58, 60 }, { 5, 15, 17, 39, 40, 43 }}; int L, C, ns; int nsort[6] = { n1, n2, n3, n4, n5, n6 }; for (L = 0 ; L < 10 ; L++) { NumSort[L] = ""; NumCartela[L] = L+1; ns = 0; while (ns <= 5) { for (C = 0 ; C < 6 ; C++) if (cartela[L][C] == nsort[ns]) { NumSort[L] = NumSort[L] + IntToStr(nsort[ns])+", "; } ns++; } } }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 34
8 FUNÇÕES
Uma função é um procedimento que retorna um valor (um resultado). Normalmente é um bloco
de comandos que executa uma tarefa específica, e após executá-la devolve o resultado das
operações realizadas. Este resultado pode ser atribuído a uma variável em qualquer parte do
programa principal. Tanto uma função, como um procedimento podem ser chamados (executados)
várias vezes, durante o funcionamento do programa.
Exemplo1:
Lembrando a equação do segundo grau. Aplicaremos o conceito de Funções. Veja:
//--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { int v1, v2, v3, v4, v5, v6; int x; v1 = atoi(Edit1->Text.c_str()); v2 = atoi(Edit2->Text.c_str()); v3 = atoi(Edit3->Text.c_str()); v4 = atoi(Edit4->Text.c_str()); v5 = atoi(Edit5->Text.c_str()); v6 = atoi(Edit6->Text.c_str()); CartelaMegaSena(v1, v2, v3, v4, v5, v6); for (x = 0 ; x < 10 ; x++) ListBox1->Items->Add("Cartela: "+IntToStr(NumCartela[x]) + "=>" + NumSort[x]); }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 35
C++ Builder
TForm1 *Form1; //------------ Função----------------------------------------- int CalcularDelta(int a, int b, int c) { int delta; delta = pow(b,2) - 4 * a * c; return delta; } void __fastcall TForm1::Button1Click(TObject *Sender) { int va, vb, vc, d; float x1, x2; va = atoi(Edit1->Text.c_str()); vb = atoi(Edit2->Text.c_str()); vc = atoi(Edit3->Text.c_str()); d = CalcularDelta(va, vb, vc) ; Edit4->Text = d; if (d < 0) ShowMessage("Nao existe raiz reais..."); else { x1 = (-vb + sqrt(d)) / (2 * va); x2 = (-vb - sqrt(d)) / (2 * va); Edit5->Text = x1; Edit6->Text = x2; } }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 36
Exemplo2:
Receber o Nome do Produto, Preço Unitário, Desconto em %, em seguida calcular e mostrar: O Nome do produto, valor do Desconto e o Valor do Produto com Desconto, usado o conceito de Funções.
Exemplo2:
C++ Builder
TForm1 *Form1; //------------ Função---------------------------------------------------- float CalcularValor( float ValorUnit, float desc ) { float ValorProduto; ValorProduto = ValorUnit - (ValorUnit * desc ) / 100; return ValorProduto; } //------------ Procedimento------------------------------------------ void LimparTela(void ) { Form1->Edit1->Clear(); Form1->Edit2->Clear(); Form1->Edit3->Clear(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { float vu, dc, vdc, nvp; String produto; produto = Edit1->Text; vu = atof(Edit2->Text.c_str()); dc = atof(Edit3->Text.c_str()); nvp = CalcularValor( vu, dc ) ; vdc = vu - nvp; ListBox1->Items->Add("Produto : "+produto); ListBox1->Items->Add("Desconto: "+ FloatToStr(vdc)); ListBox1->Items->Add("Valor com Desconto: "+FloatToStr(nvp)); LimparTela();
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 37
8.1 EXERCÍCIOS ( PROCEDIMENTOS / FUNÇÕES ) C++ Builder;
1) O Educandário Duquinha, no seu Curso Técnico de Informática, trabalha com o
sistema de avaliação por Competência. A Tabela abaixo mostra a forma de cada
conceito atribuído em suas avaliações. Elabore programa em C++ Builder para mostrar
os dados solicitados, usando o conceito de Procedimentos.
Conceito Nota
“E” >= 90%
“MB” >=80% e <90%
“B” >=70% e < 80%
“I” < 70%
E = “Excelente” ; MB= “Muito Bom” ; B = “Bom” ; I = “Insuficiente”
O programa deverá solicitar, o nome do aluno, a disciplina e 3 (três) notas, e em seguida
em um Procedimento, calcular a média aritmética, e em um outro Procedimento atribuir
o conceito conforme tabela. Como resultado final de retorno mostrar, o nome do aluno,
a média e o seu conceito.
2) A maioria dos cálculos de uma Folha de Pagamento é baseada em tabelas fornecidas
pelo Governo. Use as tabelas abaixo para desenvolver um programa simples, que como
resultado será a impressão de um Contracheque de um Funcionário. O programa
deverá solicitar o Nome do Funcionário, a Função e o Salário Bruto, Números de
Filhos. Uma Função calcula o INSS, outra calcula IRRF, outra calcula o Salário de
Família, e um Procedimento calcula o FGTS e outro limpar Campos. Como resultado
final mostrar:
====================Contracheque===============================
Funcionario: Fulano
Salário Bruto: 0,00
Número de Filhos: 0
====================
Desconto de INSS: 0,00
Desconto de IRRF: 0,00
Total de Desconto: 0,00
====================
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 38
Salário de Família: 0,00
====================
FGTS: 0,00
====================
SALARIO LIQUIDO: 0,00
=============================================================
TABELAS PARA CALCULOS
INSS
Salário Desconto
Até R$ 911,70 8%
De R$ 911,71 a R$ 1.719,50 9%
De R$ 1.519,51 a R$ 3.038,99 11%
IRRF
Salário Desconto Dedução
Até R$ 1.372,81 Isento
De R$ 1.372,82 a 1.743,25 25% R$ 205,2
> R$ 1.743,26 27% R$ 548,82
SALÁRIO DE FAMÍLIA
Salário Valar a Receber
Até R$ 472,43 R$ 24,23
De R$ 472,44 a 710,08 R$ 17,07
FGTS 8% do salário bruto (será depositado no Banco)
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 39
9. ENTENDO VALORES E PONTEIROS
O que são Valores e Ponteiros?
Quando se usa “*” e “&” ?
Valores:
São mais fácil de entender, veja:
{
int a = 5;
char ch = “x”;
}
Para nós é fácil de entender que “a” e igual ao valor 5 e “ch” é igual ao valor “x”. Más para
entender o que um ponteiro mais adiante, este definição de valores não é suficiente. Tempos
que “baixar o nível” um pouco e ver da perspectiva do compilador e/ou processador. Vocês
concordam que para o compilador/processador “a” e “ch”não faz sentido?. Para o
compilador/processador “a” e “ch” são endereço de memória. Esta é a chave de tudo!. São
lugares de memória que contém no caso de “a” um inteiro com valor 5 e no caso “ch” um
caractere com o valor “x”. Isto é muito importante. Enquanto nós (humanos) entendemos “a”
é igual a 5 e “ch” é igual ao caractere “x” , ele (o computador) entender:
Endereço Valor
a 0100 00
0101 00 5
0102 00
0103 05
ch 0104 78 “x”
Vamos entender a figura, cada linha representa um byte. A coluna da direita (Verde)
representa a memória em si, e a coluna da esquerda (Azul) representa o endereço de cada
byte da memória. A notação utilizada é a hexadecimal, o endereço (Azul) foi escolhido
aleatoriamente, más o fato deles serem seqüenciais, não é coincidência. Notar que o que nós
enxergamos como “a” o computador (neste exemplo) enxerga como o endereço 0100 e pelo
fato de “a” ser do tipo int, ele ocupa 4 bytes. O mesmo acontece com “ch”, o computador
enxerga como o endereço 0104 e por ser do tipo char ocupa somente um byte. Resumindo, o
endereço 0100 (“a”) da memória tem o inteiro 5 e o endereço 0104 (“ch”) da memória tem
78 (valor ASCII hexadecimal do caractere “x”).
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 40
Ponteiros:
Um ponteiro é um endereço de memória e não um valor. Talvez seja interessante fazermos
uma analogia entre ponteiro e um link. Ponteiro nos leva de uma posição de memória até a
outra como um link nos leva de um site até o outro. Ponteiro é basicamente isto. O resto é só
entender a sintaxe.
No C, ao se definir:
char letra; // cria variável do tipo char
...
letra = 'A'; // a variável letra armazena o caracter A
É reservada uma área na memória com o tamanho especificado pelo tipo da variável (char =
1 byte). Esta área é identificada no programa por um nome (letra), mas internamente ao
sistema, por um valor numérico, chamado endereço da variável.
O valor do endereço de memória não é escolhido pelo programador. O programa, em
execução, é que se encarrega de achar uma posição de memória livre no computador, e a
reserva para uso. Entretanto é possível e desejável, conhecer estes endereços. Veja a seguir a
declaração de uma variável, tipo ponteiro.
9.1 DECLARAÇÃO DE UM PONTEIRO
Para declarar e utilizar um ponteiro usa-se uma simbologia apropriada. O símbolo &(e-
comercial) se refere ao endereço de uma variável. O símbolo *(asterisco) declara um
ponteiro, e também serve para referenciar um conteúdo. A declaração é dada por:
tipo * nome_da_variável;
Assim, alterando a definição da variável letra do Exemplo acima, para o uso de ponteiro,
teremos (as linhas foram numeradas para explicar as linhas do trecho de programa):
Exemplo 1:
[1] char letra; // cria variável do tipo char
[2] char *pLetra; // variável do tipo ponteiro para char
[3] letra = 'A'; // a variável letra armazena o caracter A
[4] pLetra = & letra; // pLetra aponta para letra
Na linha [1] criou-se uma variável do tipo char para armazenar uma letra.
Na linha [2] está sendo declarado um ponteiro chamado pLetra do mesmo tipo de letra
(char). Sempre um ponteiro, deve ser do mesmo tipo da variável a ser apontada. O símbolo *
(asterisco) indica que a variável é um ponteiro.
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 41
Na linha [3] a variável letra (uma posição da memória) recebe o caractere 'A', ou seja, o
conteúdo a ser armazenado na área reservada para variável letra.
Na linha [4] o ponteiro pLetra recebe o endereço de memória da variável letra, ou seja, passa
a apontar para a variável letra. Usa-se o símbolo & (e-comercial) para acessar o endereço de
uma variável.
Se adicionarmos uma nova variável, aux, junto às definições de variáveis do exemplo:
char aux; // variável auxiliar do exemplo, acrescentarmos também a linha [5]:
[5] aux = *pLetra; // aux recebe o conteúdo de pLetra teremos o seguinte:
Na linha [5] a variável aux recebe o conteúdo da posição de memória apontada por pLetra,
ou seja 'A'.
Endereço Valor letra 0100 *pletra 0101 letra 0100 41 “A” pletra = &letra 0100 aux 0102 aux = *pLetra 0102 41 “A”
Programa em C++ Execução
{
char letra; letra 0100: 41
char *pletra; aux 0102: 0100: 41
letra = “A”;
pletra = &letra;
char aux;
aux = *pletra;
}
Portanto, em termos práticos, aux e letra acessam a mesma posição de memória.
Exemplo 2:
Dado o seguinte trecho de programa, qual o conteúdo das variáveis após a sua
execução?
{
int x = 1; // declara e atribui o valor 1em uma posição de memória
int y = 2; // declara e atribui o valor 2 em uma posição de memória
int *ip, *iy, *sxy ; // declaração de um ponteiro para inteiro
ip = &x; // o ponteiro ip recebe o endereço de x
y = *ip; // y recebe o conteúdo de x
*ip = 0; // x é zero
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 42
iy = &y; // o ponteiro iy recebe o endereço de y;
*sxy = *ip + *iy; // a posição de memória reservada para sxy recebe a soma do conteúdo de ip e iy
}
Veja o mapa de memória:
Memória Física
Então, no endereço reservado para „x‟ ficou armazenado o inteiro 0, no endereço reservado
para „y‟ ficou armazenado o inteiro 1 e no endereço reservado para „sxy‟ ficou o inteiro 1.
Exemplo 3:
Qual o valor da variável “y” e “z” após a execução do trecho de programa abaixo.
// associado ao evento clique de um botão
{
int x, y;
int *z;
x = atoi(Edit1->Text.c_str());
z = &y;
y = x + 1;
0100 00 00 0101 00 00 0102 00 00 0103 01 00 0104 00 00 0105 00 00 0106 00 00 0107 02 01 0108 00 00 0109 00 00 0110 00 00 0111 00 00 0112 00 00 0113 00 00 0114 00 00 0115 00 00 0116 00 00 0117 00 00 0118 00 00 0119 00 01
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 43
Edit2->Text = y;
Edit3->Text = *z;
}
Resposta: y e z é igual ao valor de x + 1.
Exemplo 4:
{
int x,y;
int *p1, *p2;
x = 1000;
p1 = &x;
p2 = p1;
ListBox1->Items->Add( IntToStr(p1));
ListBox1->Items->Add( IntToStr(p2));
ListBox1->Items->Add(*p1);
ListBox1->Items->Add(*p2);
}
Resposta: p1 e p2 recebem o endereço de “x”, e o conteúdo de p1 e p2 é 1000.
9.2 Aritmética de Ponteiros
Existem apenas duas operações aritméticas que podem ser usadas com ponteiros: adição e
subtração.
Exemplo: (Adição)
{
int numero[5] = {5, 7, 9, 10, 12};
int *ptrnumero; Memória
ptrnumero = &numero[0];
ListBox1->Items->Add(IntToStr(*ptrnumero++));
ListBox1->Items->Add(IntToStr(*ptrnumero++));
ListBox1->Items->Add(IntToStr(*ptrnumero++));
ListBox1->Items->Add(IntToStr(*ptrnumero++));
ListBox1->Items->Add(IntToStr(*ptrnumero++));
100 5 101 7 102 9 103 10 104 12
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 44
}
Exemplo: (Subtração)
{
String nome[2][2] = {{“ana”, “maria”,},
{“mário”, “kátia”}}; Memória
String *ptr;
ptr = &nome[1][1];
ListBox1->Items->Add(*ptr--);
ListBox1->Items->Add(*ptr--);
ListBox1->Items->Add(*ptr--);
ListBox1->Items->Add(*ptr--);
}
9.3 Função e Procedimento com ponteiros
O conteúdo visto de funções e procedimentos define a criação de programas grandes dividios
e pequenos módulos deixando assim o software mais ágil. Podemos também, introduzir
nestes módulos de programas o conceito de pronteiro. Sendo assim, se necessário o software
ganhará mais recursos agilidade na sua execução.
Exemplo: (Funções e Procedimentos com ponteiros)
O peso ideal de uma pessoa é calculado através de fórmulas já prontas. Para o
sexo feminino, calcula-se com a fórmula:
Pesoid = ( 62.1 * h ) – 44.7, e para o sexo masculino: Pesoid = ( 72.7 * h ) – 58.
Faça um programa que receba o Nome da pessoa, altura e o sexo. Caso o sexo
seja “F” feminino leve os dados necessários para uma Função, calcule o peso ideal
usando a fórmula e ao retornar, escreva o peso ideal feminino. Caso o sexo seja “M”
masculino. leve os dados para um Procedimento, calcule o peso ideal usando a
fórmula e ao retornar escreva o peso ideal masculino.
1000 ana 1001 maria 1002 mário 1003 kátia
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 45
// variável global para o procedimento
float peso_ideal;
// procedimento do usuário – calcular peso ideal femimino
void p_ideal_f(float *ptraltura)
{
peso_ideal = (62.1 * ( *ptraltura ) - 44.7);
}
// função do usuário – calcular peso ideal masculino
float *p_ideal_m(float *ptraltura)
{
float peso_ideal;
peso_ideal = (72.7 * ( *ptraltura ) - 58);
return &peso_ideal;
}
// procedimento do botão
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String sexo;
float altura, *peso_ideal_masc;
sexo = (Edit1->Text);
altura = atof(Edit2->Text.c_str());
if (sexo == "F")
{
p_ideal_f(&altura); // chamar o procedimento feminino.
Edit3->Text = peso_ideal;
}
if (sexo == "M")
{
peso_ideal_masc = p_ideal_m(&altura); // chamar a função masculino
Edit3->Text = *peso_ideal_masc;
}
}
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 46
9.4 Exercícios
1. Qual das instruções é correta para se declarar um ponteiro?
a) int _ptr; c) *int ptr;
b) int *ptr; d) *ptr;
2. Na expressão float *pont; o que é do tipo float?
a) a variável pont c) a variável apontada por pont
b) o endereço de pont d) nenhuma
3. Qual a maneira correta de atribuir o endereço de “p” ao ponteiro “q”?
a) q = p c) &q = p
b) *q = p d) q = &p
4. Assumindo que o endereço de “num” foi atribuído a um ponteiro “pnum”, quais das
seguintes expressões são verdadeiras?
a) num == &pnum c) pnum == *num
b) num == *pnum d) pnum == &num
5. Faça um programa que o usuário entre com dois valores qualquer. Uma função receber os
endereços dos valores digitados, a mesma função calcula a soma dos dois ponteiros e
devolve para ser impresso ao programa principal.
6. Elaborar um programa para calcular e exibir a Soma dos N primeiros termos da
seqüência:
O programa deverá receber a quantidade de termos e o valor de X, uma função recebe o endereço do valor digitado, calcula a soma dos termos e devolve o valor ao programa principal.
7. Considere o valor das vendas dos últimos 3 anos da Empresa Sucata Duquinha Ltda,
na tabela abaixo:
Ano J F M A M J J A S O N D
06 9 10 8 11 8 9 7 6 11 10 12 13
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 47
07 10 11 15 17 18 19 12 10 16 15 11 10
08 11 13 12 10 15 17 18 19 15 17 16 15
O senhor Duquinha é o dono da Empresa. Ele quer saber a média de vendas e o valor
do lucro total de todas suas vendas, durante os 3 (três) anos de atividade da empresa,
na tabela. Considere o lucro de 60% do total das vendas. Faça um programa que
declare os valores em uma matriz, um ponteiro caminha cada endereço de memória e
soma cada conteúdo armazenado, e no final mostrar a situação da empresa para o
senhor Duquinha.
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 48
9.5 Alocação de memória dinâmica
Até aqui, na declaração de um vetor, foi preciso dimensioná-lo. Isto nos obrigava a saber, de antemão, quanto espaço seria necessário, isto é, tínhamos que prever o número máximo de elementos no vetor durante a codificação. Este pré-dimensionamento do vetor é um fator limitante. Por exemplo, se desenvolvermos um programa para calcular a média das notas de uma prova, teremos que prever o número máximo de alunos. Uma solução é dimensionar o vetor com um número absurdamente alto para não termos limitações quando da utilização do programa. No entanto, isto levaria a um desperdício de memória que é inaceitável em diversas aplicações. Se, por outro lado, formos modestos no pré-dimensionamento do vetor, o uso do programa fica muito limitado, pois não conseguiríamos tratar turmas com o número de alunos maior que o previsto. Felizmente, a linguagem C oferece meios de requisitarmos espaços de memória em tempo de execução. Dizemos que podemos alocar memória dinamicamente. Com este recurso, nosso programa para o cálculo da média discutido acima pode, em tempo de execução, consultar o número de alunos da turma e então fazer a alocação do vetor dinamicamente, sem desperdício de memória. Uso da memória Informalmente, podemos dizer que existem três maneiras de reservarmos espaço de memória para o armazenamento de informações. A primeira delas é através do uso de variáveis globais (e estáticas). O espaço reservado para uma variável global existe enquanto o programa estiver sendo executado. A segunda maneira é através do uso de variáveis locais. Neste caso, como já discutimos, o espaço existe apenas enquanto a função que declarou a variável está sendo executada, sendo liberado para outros usos quando a execução da função termina. Por este motivo, a função que chama não pode fazer referência ao espaço local da função chamada. As variáveis globais ou locais podem ser simples ou vetores. Para os vetores, precisamos informar o número máximo de elementos, caso contrário o compilador não saberia o tamanho do espaço a ser reservado. A terceira maneira de reservarmos memória é requisitando ao sistema, em tempo de execução, um espaço de um determinado tamanho. Este espaço alocado dinamicamente permanece reservado até que explicitamente seja liberado pelo programa. Por isso, podemos alocar dinamicamente um espaço de memória numa função e acessá-lo em outra. A partir do momento que liberarmos o espaço, ele estará disponibilizado para outros usos e não podemos mais acessá-lo. Se o programa não liberar um espaço alocado, este será automaticamente liberado quando a execução do programa terminar. Apresentamos abaixo um esquema didático que ilustra de maneira fictícia a distribuição do uso da memória pelo sistema operacional
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 49
Alocação esquemática de memória Quando requisitamos ao sistema operacional para executar um determinado programa, o código em linguagem de máquina do programa será carregado na memória. O sistema operacional reserva também os espaços necessários para armazenarmos as variáveis globais (e estáticas) existentes no programa. O restante da memória livre é utilizado pelas variáveis locais e pelas variáveis alocadas dinamicamente. Cada vez que uma determinada função é chamada, o sistema reserva o espaço necessário para as variáveis locais da função. Este espaço pertence à pilha de execução e, quando a função termina, é desempilhado. A parte da memória não ocupada pela pilha de execução pode ser requisitada dinamicamente. Se a pilha tentar crescer mais do que o espaço disponível existente, dizemos que ela “estourou” e o programa é abortado com erro. Similarmente, se o espaço de memória livre for menor que o espaço requisitado dinamicamente, a alocação não é feita e o programa pode prever um tratamento de erro adequado (por exemplo, podemos imprimir a mensagem “Memória insuficiente” e interromper a execução do programa). Funções da biblioteca padrão Existem funções, presentes na biblioteca padrão stdlib, que permitem alocar e liberar memória dinamicamente. A função básica para alocar memória é malloc. Ela recebe como parâmetro o número de bytes que se deseja alocar e retorna o endereço inicial da área de memória alocada. Para exemplificar, vamos considerar a alocação dinâmica de um vetor de inteiros com 10 elementos. Como a função malloc retorna o endereço da área alocada e, neste exemplo,
Programa carregado
na memória.
Área reservada pelo
sistema.
Área alocada
dinamicamente
(função, variáveis
locais).
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 50
desejamos armazenar valores inteiros nessa área, devemos declarar um ponteiro de inteiro para receber o endereço inicial do espaço alocado. O trecho de código então seria: int *v; v = malloc(10*4); Após este comando, se a alocação for bem sucedida, v armazenará o endereço inicial de uma área contínua de memória suficiente para armazenar 10 valores inteiros. Podemos, então, tratar v como tratamos um vetor declarado estaticamente, pois, se v aponta para o inicio da área alocada, podemos dizer que v[0] acessa o espaço para o primeiro elemento que armazenaremos, v[1] acessa o segundo, e assim por diante (até v[9]). No exemplo acima, consideramos que um inteiro ocupa 4 bytes. Para ficarmos independentes de compiladores e máquinas, usamos o operador sizeof( ). v = malloc(10*sizeof(int)); Além disso, devemos lembrar que a função malloc é usada para alocar espaço para armazenarmos valores de qualquer tipo. Por este motivo, malloc retorna um ponteiro genérico, para um tipo qualquer, representado por void*, que pode ser convertido automaticamente pela linguagem para o tipo apropriado na atribuição. O comando para a alocação do vetor de inteiros fica então: v = (int *) malloc(10*sizeof(int)); A figura abaixo ilustra de maneira esquemática o que ocorre na memória:
Alocação dinâmica de memória. Se, por ventura, não houver espaço livre suficiente para realizar a alocação, a função retorna um endereço nulo (representado pelo símbolo NULL, definido em stdlib.h). Podemos cercar o erro na alocação do programa verificando o valor de retorno da função malloc. Por exemplo, podemos imprimir uma mensagem e abortar o programa com a função exit, também definida na stdlib. Exemplo:
v = (int*) malloc(10*sizeof(int));
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 51
if (v==NULL) { ShowMessage("Memoria insuficiente."); exit(1); /* aborta o programa e retorna 1 para o sist. operacional */ }
Para liberar um espaço de memória alocado dinamicamente, usamos a função free. Esta unção recebe como parâmetro o ponteiro da memória a ser liberada. Assim, para liberar o vetor v, fazemos: free (v); Só podemos passar para a função free um endereço de memória que tenha sido alocado dinamicamente. Devemos lembrar ainda que não podemos acessar o espaço na memória depois que o liberamos.
Exemplo 1: Alocar 10 posições de memória para armazenar 10 números inteiros.
//------------------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { int x, *v; v = (int*) malloc(10*sizeof(int)); if (v==NULL) { ShowMessage("Memoria insuficiente."); exit(1); /* aborta o programa e retorna 1 para o sist. operacional */ } else for (x=0 ; x< 10 ; x++) { v[x] = x; ShowMessage(v[x]); } free(v); } //------------------------------------------------------------------------------------------
Exemplo 2: Dado 3 valores tipo float (7.5, 9.0, 9.7). Alocar as posições de memória necessária para armazenar os valores e média.
// ------------------Botão------------------------------------------------------------- { float *n;
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 52
n = (float*) malloc(4*sizeof(float)); if (n==NULL) { ShowMessage("Memoria insuficiente."); exit(1); /* aborta o programa e retorna 1 para o sist. operacional */ } else { n[0] = 7.5 ; n[1] = 9.0 ; n[2] = 9.7 ; n[3] = (n[0] + n[1] + n[2]) / 3 ; ShowMessage(n[3]); free(n); } } //---------------------------------------------------------------------------
Exemplo 3: // Variáveis Globais--------------------------------------------------- String valor; int n, x, *v; // Botao Incluir-------------------------------------------------------- void __fastcall TForm1::IncluirClick(TObject *Sender) { n = atoi(Edit1->Text.c_str()); v = (int*) malloc(n*sizeof(int)); if (v==NULL) { ShowMessage("Memoria insuficiente."); exit(1); /* aborta o programa e retorna 1 para o sist. operacional */ } else for (x=0 ; x < n ; x++) { valor = InputBox("Alocação de memória", "Digite o valor", ""); v[x] = StrToInt(valor); } } // Imprimir--------------------------------------------------------------------- void __fastcall TForm1::ImprimirClick(TObject *Sender)
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 53
{ for (x=0 ; x < n ; x++) ListBox1->Items->Add(v[x]); } // Liberar memória------------------------------------------------------ void __fastcall TForm1::LbMemoriaClick(TObject *Sender) { free(v); } //---------------------------------------------------------------------------
9.6 Lista simplesmente encadeada A grande diferença da lista para as outras estruturas de dados, é que as listas não possuem critério de inclusão e remoção de dados. Uma lista encadeada tem necessariamente uma variável ponteiro apontando para o seu primeiro elemento. Essa variável será utilizada sempre, mesmo que a lista esteja vazia, e deverá apontar sempre para o início da lista (primeiro elemento). Caso esta primeira variável não seja atualizada corretamente (no caso da inclusão de um elemento na primeira posição), a lista poderá se perder na memória e não ser mais acessível. Um elemento da lista é composto de duas partes: a informação propriamente dita e uma conexão com o próximo elemento. São chamadas de simplesmente encadeadas porque possuem somente o endereço do seu próximo (próximo elemento).
Exemplo: struct celula { int dados; /* campo para os dados */ struct celula *proximaCelula; /* ponteiro para a proxima celula */ }; celula *aux; Uma lista encadeada é toda alocada dinamicamente. Sabemos que a memória alocada dinamicamente não possui um nome como acontece nas variáveis comuns, portanto, todas as listas devem possuir uma variável padrão, do tipo ponteiro, que vai apontar para o seu inicio.
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 54
Uma vez que o primeiro elemento será uma célula, e cada célula é uma estrutura, então a variável que apontará para o início da lista será um ponteiro de estrutura. A variável início mostrada na figura acima será então definida como: celula * inicio; /* ponteiro para uma estrutura Celula */ Uma vez que a lista não possui elementos ainda, então: inicio = NULL; Para uma lista vazia (sem células), a variável inicio possui valor NULL: Incluindo o primeiro elemento (primeira célula): celula aux; /* variavel auxiliar: ponteiro para uma estrutura Celula */ Para reservar memória para nova célula, utilizamos o comando malloc aux = (celula*) malloc (sizeof (Celula)); Temos então:
e precisamos atualizar os ponteiros para que a lista receba seu primeiro elemento. Sendo assim: 1) aux->proximaCelula = NULL; // atribui NULL ao campo proximacelula da célula apontada por aux. 2) inicio = aux; // copia o endereço de aux em inicio
Para inserir dados nesta primeira célula, podemos utilizar o ponteiro aux, que permanece apontando para a célula. aux->dados = 10; /*atribui o valor 10 ao campo dados da célula pontada por aux Obs: Cada célula de uma lista também é chamada de nó ou nodo
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 55
O programa a seguir cria uma lista com três nós, conforme exibida a abaixo Exemplo 1: // Estrutura global------------------------------------------------------------------ struct no /* nome da estrutura */ { int matricula; /* tipo da dado matrícula a ser alocada */ struct no *proximo; /* ponteiro que aponta para próxima cela célula */ }; no *inicio, *novo, *atual; /* variáveis ponteiro do tipo no */ // Botão – Insere na estrutura alocada---------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { // cria o primeiro registro (no 1) novo = (no*) malloc(sizeof (no)); /* aloca o nó na memória */ novo->matricula = 1000; /* atribui 1000 para a matrícula */ novo->proximo = NULL; /* nulo */
inicio = novo; /* inicio aponta para o primeiro nó */
atual = novo; /* atual recebe o endereço do nó alocado no momento */ // cria o segundo registro (no 1) novo = (no*) malloc(sizeof (no)); /* instancia o segundo nó */ novo->matricula = 1001; /* atribui 1001 para a matrícula */ novo->proximo = NULL; /* nulo */ atual->proximo = novo; /* nó anterior aponta para o segundo da lista */ atual = novo; /* atual recebe o endereço do nó alocado no momento */ // cria o terceiro registro (no 3) novo = (no*) malloc(sizeof (no)); /* instancia o terceiro nó */ novo->matricula = 1002; /* atribui 1002 para a matricula */ novo->proximo = NULL; /* nulo */ atual->proximo = novo; /* nó anterior aponta para o terceiro da lista */ atual = novo; /* atual recebe o endereço do nó alocado no momento */
inicio
1
matricula proximo
1 2 3
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 56
/* exibe os nós da lista */ atual = inicio; while (atual != NULL) { ListBox1->Items->Add(atual->matricula); atual=atual->proximo; } } //--------------------------------------------------------------------------- Exemplo 2: struct aluno { char nome[50]; int idade; struct aluno *proximo; }; aluno *inicio, *novo, *atual; // Aloca o nó na memória--------------------------------------------------------- void aloca(void) { novo = (aluno*) malloc(sizeof (aluno)); if (novo == NULL) { ShowMessage("Memoria insuficiente."); exit(1); } } // Procedimento Insere os dados na memória-------------------------------- void insere(void) { strcpy(novo->nome,Form1->Edit1->Text.c_str()); novo->idade = atoi(Form1->Edit2->Text.c_str()); }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 57
// Botao1 chama o procedimento alocaçao de memória e o procedimento Insere-------- void __fastcall TForm1::Button1Click(TObject *Sender) { aloca(); insere(); if (atual == NULL) { novo->proximo = NULL; /* nulo */ inicio = novo; /* inicio recebe o endereço do nó atual alocado */ atual = novo; /* atual recebe o endereço do nó atual alocado */ } else { novo->proximo = NULL; /* nulo */ atual->proximo = novo; /* nó anterior aponta para o próximo nó */ atual = novo; /* atual recebe o endereço do nó alocado no momento */ } } // Botal2 posiciona o no registro 1 e lista cada registro alocado-------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { /* exibe os nós da lista */ atual = inicio; while (atual != NULL) { ListBox1->Items->Add(atual->nome); ListBox1->Items->Add(atual->idade); atual=atual->proximo; } } //---------------------------------------------------------------------------
9.7 Lista Duplamente encadeada As listas duplamente encadeadas são aquelas que cada nó possui não só o endereço do nó anterior más também o endereço do próximo nó.
1 2 2
matricula proximo inicio
A M P A M P
fim
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 58
Exemplo : #define ALOCA (struct cliente *) malloc(sizeof(struct cliente)) // aloca o endereço na memória. struct cliente // define cliente como uma estrutura composta com os dados abaixo. { char nome[20]; // declara nome com 20 caracteres. char telefone[15]; // declara telefone com 15 caracteres. char email[30]; // declara o email com 30 caracteres. struct cliente *prox, *ant; // declara prox e ant como ponteiros para movimentar a estrutura. }; struct cliente *registro, *inicio, *ultimo, *pos; // declara todas as variaveis com ponteiro para o controle da estrutura criada. //------------------------------------------------------------------------- struct cliente *nova(void) // define uma função para nova do tipo estrutura cliente. { struct cliente *x; // declara x como o ponteiro para estrutura cliente. x = ALOCA; // chama a função definida aloca atribui o endereço a x. x->ant = registro; // o ponteiro x aponta para o registro anterior que recebe o registro atual. x->prox = NULL; // o ponteiro x aponta para o proximo registro que receber o nulo. return (x); // retorna o endereço de x para a linha que o chamou a função nova. } //------------------------------------------------------------------------- struct cliente* insere(struct cliente *pt) // declara a função insere do tipo estrutura cliente. { strcpy(pt->nome,Form1->Edit1->Text.c_str()); // copia o dado digitado para o endereço de nome.
strcpy(pt->telefone,Form1->Edit2->Text.c_str()); // copia o dado digitado para o endereço de telefone.
strcpy(pt->email,Form1->Edit3->Text.c_str()); // copia o dado digitado para o endereço de email. pt->prox = nova(); // o ponteiro pt aponta para o prox e executa a função nova. ultimo=pt->prox->ant; // o ultimo inserido, no o atual recebe o endereço do anterior. return (pt->prox); // retorna o endereço do proximo para a função que o chamou. } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { inicio = registro = ALOCA; // inicia as variaveis o primeiro endereço criado por aloca. } //--------------------------------------------------------------------------- void __fastcall TForm1::bInsereClick(TObject *Sender) { registro = insere(registro); // chama a função insere e recebe o endereço do proximo. Edit1->Text = ""; // limpa o campo edit1 Edit2->Text = ""; // limpa o campo edit2 Edit3->Text = ""; // limpa o campo edit3 }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 59
//--------------------------------------------------------------------------- void __fastcall TForm1::bApagaClick(TObject *Sender) { free(registro); // apaga todos as alocação de memoria ciada por alloc. Close(); // fecha o formulário. } //--------------------------------------------------------------------------- void __fastcall TForm1::bAnteriorClick(TObject *Sender) { pos = registro->ant; // recebe a posição do anterior. if (registro->ant != NULL) // verifica se ainda não é inicio da alocação. { Edit1->Text = pos->nome; // edit1 recebe de volta o nome alocado. Edit2->Text = pos->telefone; // edit2 recebe de volta o telafone alocado. Edit3->Text = pos->email; // edit3 recebe de volta o email alocado. registro = pos; // registro recebe a posição atual. } } //--------------------------------------------------------------------------- void __fastcall TForm1::bInicioClick(TObject *Sender) { pos = inicio; // posiciona no inicio da alocação. Edit1->Text = pos->nome; // edit1 recebe de volta o nome alocado. Edit2->Text = pos->telefone; // edit2 recebe de volta o telefone alocado. Edit3->Text = pos->email; // edit3 recebe de volta o email alocado. registro = pos; // registro recebe a posiçao do atual. } //--------------------------------------------------------------------------- void __fastcall TForm1::bUltimoClick(TObject *Sender) { pos = ultimo; // posiciona no ultimo registro. Edit1->Text = pos->nome; // edit1 recebe de volta o nome alocado. Edit2->Text = pos->telefone; // edit2 recebe de volta o telefone. Edit3->Text = pos->email; // edit3 recebe de volta o email. registro = pos; // registro recebe a posiçao do atual. } //--------------------------------------------------------------------------- void __fastcall TForm1::bProximoClick(TObject *Sender) { pos = registro->prox; // recebe a posição do proximo. if (registro->prox != NULL && registro != ultimo) // verifica se o proximo não é nulo e o registro atual é diferente do ultimo, criado e não utilizado. { Edit1->Text = pos->nome; // edit1 recebe de volta o nome alocado. Edit2->Text = pos->telefone; // edit2 recebe de volta o telefone. Edit3->Text = pos->email; // edit3 recebe de volta o email. registro = pos; // registro recebe a posição do atual. } }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 60
9.8 Pilhas Uma pilha é uma lista de variáveis do mesmo tipo (semelhantes a uma matriz, ou mesmo uma matriz), onde utilizamos o conceito de que "o primeiro que entra é o último a sair". Imaginemos um bloco de folhas. Normalmente utilizaremos primeiro a última folha do bloco ("a de cima"), enquanto que a primeira folha colocada ("a de baixo") será a última a ser utilizada. Outro exemplo, uma pilha de prato, o ultimo da pilha e o primeiro a ser usado. Nos exemplos a seguir serão utilizadas duas funções: push() e pop(). Usaremos push() para inserir elementos na pilha e pop() para sacá-los. Exemplo: Simulando uma pilha em ação na memória Ação Conteúdo da Pilha Push(A) A Pusb(B) BA Push(C) CBA Pop() BA Push(F) FBA Pop() BA Pop() A Pop() vazia Exemplo 1: O programa abaixa empilha e desempilha cinco valores inteiros na memória.
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 61
// Variaveis------------------------------------------------------------------------ int pilha[5],*p1,*to, *max, valor; // vetor, ponteiros e variaveis normais //Procedimento verificar se a pilha está cheia e empilha--------------------- void push(int i) // procedimento recebe um valor inteiro { if (p1 >= (to + 5)) // verifica se o poteiro atual é maior que o tamanho da pilha { ShowMessage("Pilha cheia... "); // mostra mensagem max = NULL; // recebe nulo quando a pilha encher } else { *p1 = i; // ponteiro recebe o valor digitado p1++ ; // caminha para próxima posição max = p1; // max recebe a posição atual do ponteiro } } //Função verificar se a pilha está vazia e retorna a posição desempilhar---- pop(void) // função sem parâmetro { if ((p1) == to) // verifica se o ponteiro já está no topo da pilha { ShowMessage("Pilha vazia... "); // mostra mensagem return(NULL); // retorna nulo } else { p1--; // ponteiro volta uma posição na memória return *(p1); // retorna o conteúdo do ponteiro atual } } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { p1 = pilha; // ponteiro “p1” e “to” recebe a primeira posição do vetor pilha to = p1; } // Procedimento botão empilhar------------------------------------------------------- { valor = atoi(Edit1->Text.c_str()); // variavel receber o valor digitado push(valor); //coloca o valor na pilha if (max != NULL) // verifica se o ponteiro “max” é nulo { ListBox1->Items->Add(valor); // escreve o valor colocado na pilha } }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 62
// Procedimento botão desempilhar ----------------------------------------------- { valor = pop(); // desempilha if (valor != NULL) // verifica se o valor é nulo { ListBox1->Items->Add(valor); // escreve o valor desempilhado *p1=NULL; // ponteiro recebe valor nulo } // Procedimento botão----------------------------------------------- { Close(); // fechar } //--------------------------------------------------------------------------- Exemplo 2: O programa empilha e desempilha valores com alocação de memória
// variaveis globaix------------------------------------------------------------------- char x,y,*px; // declaração de variaveis comuns e ponteiro // Procedimento prepara a posição para empilhar------------------------- void push( char i) // procedimento recebe o conteúdo de “x” { px++; // ponteiro caminha para primeira posiçao alocada *px=i; // ponteiro atual recebe o conteúdo da variavel “i” }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 63
//Procedimento prepara a posição para desempilhar------------------- pop(void) // função não recebe nenhum valor { px--; // ponteiro volta uma posição return *(px+1); // retorna a posição a ser desempilhada (após a segunda execução adiante uma posição)
} // Procedimento botão cria alocação e empilha-------------------------- { px = (char*) malloc(sizeof(char)); // aloca uma posição de memória if (px == NULL) // verifica se o ponteiro e nulo { ShowMessage("Memória Insuficiente!"); // escreve mensagem exit(1); // não deixa o sistema oparacional abortar em caso de memória insuficiente } ListBox1->Items->Add("Empilhou"); // escreve cabeçalho ListBox1->Items->Add("========"); // escreve cabeçalho x = 'a'; // atribui o valor ‘a’ a variavel “x” push(x); // coloca o valor na pilha ListBox1->Items->Add(x); // escreve o valor colocado na pilha x = 'b'; // atribui o valor ‘b ‘ a variavel “x” push(x); // coloca o valor na pilha ListBox1->Items->Add(x); // escreve o valor colocado na pilha } // Procedimento botão desempilhar---------------------------- { ListBox1->Items->Add("Desempilhou"); // escreve cabeçalho ListBox1->Items->Add("==========="); // escreve cabeçalho y = pop(); // desempilha o valor na posição atual *(p1+1) = NULL; //ponteiro recebe valor nulo ListBox1->Items->Add(y); // escreve o valor desempilhado y = pop(); // desempilha o valor na posição atual *(p1+1) = NULL; //ponteiro recebe valor nulo ListBox1->Items->Add(y); // escreve o valor desempilhado } // Procedimento Liberar alocação de memória----------------- { free(px); // libera as alocações de memória Close(); //fechar o programa }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 64
9.9 FILAS Uma fila é uma lista de variáveis do mesmo tipo (semelhantes a uma matriz, ou mesmo uma matriz), onde utilizamos o conceito de que "o primeiro que entra é o primeiro a sair". Imaginemos uma fila de um banco. Normalmente a primeira pessoa que chega é o primeiro que será atendido. Nos exemplos a seguir serão utilizadas duas funções: Inseri() e Remover(). Usaremos Inserir() para colocar elementos na fila e Remover() para tirá da fila.
Fila Simples: Simulando uma fila em ação na memória Ação Conteúdo da Pilha Inserir(A) A Inserir(B) AB Inserir(C) ABC Remover() BC Inserir(F) BCF Remover() CF Remover() F Remover() vazia Exemplo 1:
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 65
// Definindo o tamanho constante da Fila------------------------ #define MAX 3 // Variaveis Globais------------------------------------------------------ char *p[MAX], *ptatual; int spos,rpos ; //Procedimento Inserir na Fila--------------------------------------- void inserir(char *q) { if (spos==MAX) { ShowMessage("Fila Cheia"); ptatual = NULL; return; } p[spos]=q ; ptatual = q; spos++; } // Procedimento remover da Fila----------------------------------- void remover(void) { if (rpos==spos) { ShowMessage("Fila vazia"); return; } rpos++; p[rpos-1]=""; } // Botão Inserir----------------------------------------------------------- { inserir("A"); inserir("B"); inserir("C"); ShowMessage(“Dados estão Fila!!!”); } // Botão Remover ------------------------------------------------------- { int x; remover(); ListBox1->Items->Clear(); for (x=0 ; x < MAX ; x++) ListBox1->Items->Add(p[x]); }
Programação e Estrutura de Dados
_____________________________________________________________________________
_____________________________________________________________________________ CEFET - Curso Superior de Tecnologia em Sistemas para Internet - Prof. Pereira Página 66
// Botão Listar----------------------------------------------------------- { int x; ListBox1->Items->Clear(); for (x=0 ; x < 3 ; x++) ListBox1->Items->Add(p[x]); } // Botão Fechar---------------------------------------------------------- { Close(); }
Fila Circular: Dizemos que uma fila é circular quando implementamos os índices de uma fila simples para retornar ao início da matriz, em vez de termos uma para pelo programa.
Simulando uma fila circular em ação na memória Ação Conteúdo da Pilha Inserir(A) A Inserir(B) AB Inserir(C) ABC Remover() BC Inserir(F) BCF Remover() CF Remover() F Remover() vazia Inserir(A) A Inserir(B) AB Inserir(C) ABC Remover() BC Inserir(F) BCF Remover() CF Remover() F Remover() vazia Obs: No procedimento do exemplo anterior, atribua o valor “NULL” aos indices, e assim o programa reinicia a fila novamente em vez de para o programa. // Procedimento remover da Fila----------------------------------- void remover(void) { if (rpos==spos) { ShowMessage("Fila vazia"); spos = NULL ; rpos = NULL; // indice recebe o valor nulo, volta ao inicio da fila return; } rpos++; p[rpos-1]=""; // ponteiro na receber o valor nulo }
Top Related