Program a Cao

Post on 10-Aug-2015

64 views 0 download

Transcript of Program a Cao

Introdução à Programação

Apresentação da Disciplina e

Conceitos Básicos de

Computadores

2

Objetivos

Aprender técnicas de programação que aumentem aqualidade de software e a produtividade nodesenvolvimento

Discutir conceitos de programação, ilustrando como osmesmos são representados na linguagem de programaçãoCDiscutir como programas podem ser adequadamenteescritos, estruturados e documentadosExplorar o ambiente de suporte a C, incluindo ferramentas ebibliotecasDiscutir princípios de engenharia e qualidade de software.Desenvolver, documentar e avaliar uma aplicação de médioporte em C

Resultados de Semestres Anteriores

3

2541%

23%

1017%

2439%

Resultados 2010-1

Reprovados

Reprovados por faltaAprovados

Aprovados por Media

Resultados de Semestres Anteriores

4

3548%

23%

2028%

1521%

Resultados 2010-2

Reprovados

Reprovados por faltaAprovados

Aprovados por Média

5

Análise de Resultados

No último ano, 133 alunos cursaram a disciplina69 aprovados (52% de aprovação)

Apenas 39 aprovados por média (29%)64 reprovados (48% de reprovação)

ConsequênciasDificuldade de conseguir vagas para cursar a disciplina denovoVária disciplinas dependem de IP

Atraso significativo no curso de ECPara os que conseguiram passar com dificuldade,problemas para acompanhar a disciplina de Algoritmos

Além de várias outras disciplinas que exigem que oaluno desenvolva programas (Infra de SW, Infra deComunicação, etc)

6

Como Ter Sucesso na Disciplina?

Estudo diárioSão 6 horas de aula por semana

Nenhuma disciplina tem tantas aulas por semana

Programação não se aprende somente olhando olivro e exemplos

Deve-se praticar exaustivamenteProgramação não é trivial para muitos, pois envolveraciocínio lógico para resolver problemas complexos ecodificar a solução em uma linguagem de programaçãoFacilidade de acesso a computadores

Aproveitar as aulas práticas e de exercíciosEscrever programas com alguém para esclarecer dúvidasajuda muito

7

Tópicos da Aula

Antes de aprender a programar, precisamos verconceitos básicos de Computação

Componentes de um computador

Como os diferentes componentes interagem

Representação das informações em computadores

8

Hardware e Software

Computador = Hardware + Software

Hardware

Parte física do computador

Chips, monitores, teclado, etc

Software

Programas (conjunto de instruções)

e dados

Editores de texto, navegadores,

sistemas operacionais, etc

9

Modelo de um computador

CPU

Unidade Central de Processamento

Memória Principal (RAM)

Armazenamento Secundário Dispositivos de

Entrada/Saída

Canal de Comunicação (Barramento)

Disco Rígido (HD), CD,DVD, PenDrive,etc Periféricos

10

CPU e RAM

CPU

Executa as instruções presentes nos programas

Memória Principal (RAM)

Armazena os programas e dados que estão sendo

usados pela CPU

CPU busca primeiramente programas e dados

residentes na memória

CPU também armazena dados na memória

11

Unidade Central de Processamento (1)

A CPU é o “cérebro do computador

Implementado em um chip chamado demicroprocessadorFaz continuamente 3 ações:

Busca

Busca instrução na

memória principal

Decodifica

Determina o que

é a instrução

Executa

Processa a

instrução

12

Unidade Central de Processamento (2)

Os componentes principais de uma CPU são:

Unidade de Lógica/Aritmética

Registradores

Unidade de Controle

Áreas pequenas de

armazenamento

Faz cálculos e toma

decisões

Coordena as etapas

do processamento

13

A velocidade de processamento de uma CPU é dado

pelo relógio (clock) do sistema

O clock gera um pulso eletrônico em intervalos

regulares

Estes pulsos coordenam as atividades da CPU

Velocidade da CPU é medida geralmente em Hertz

(Hz)

Unidade Central de Processamento (3)

14

Armazenando Dados (1)

Memórias são

divididas em várias

células de tamanhos

iguais

Cada célula é identificada

unicamente por um valor

numérico chamado de

endereço

9278

9279

9280

9281

9282

9283

9284

9285

9286

15

Armazenando Dados (2)

Cada célula pode

armazenar um valor de

tamanho máximo fixo

Valores que ultrapassam o

tamanho máximo de uma

célula são armazenados

em mais de uma célula

(células consecutivas)

9278

9279

9280

9281

9282

9283

9284

9285

9286

10011010

16

Também chamada de memória RAM

Random Access Memory

Acesso aos endereços de memória podem ser feita de

forma direta sem ter que passar por endereços

anteriores

Armazena dados e programas utilizados pelo

processador num dado instante

Quando o computador possui sistema operacional, este é

carregado na memória geralmente na hora em que o

computador é ligado

Memória Principal

17

Computadores atuais utilizam também pequenas memórias

cache para armazenar partes dos dados e programas que

estão na memória principal

Memória cache utiliza tecnologia que torna acesso aos

dados mais rápida

Evita acesso pelo barramento

Memória Principal

CPU Memória Principal (RAM)

Cache

18

Armazenamento Secundário

CPU

Memória Principal (RAM)

Armazenamento Secundário

CPU procura programa/dadosna RAM

Não encontrando, CPUprocura na memóriasecundária

Programa/dados sãotransferidos para RAM

Tipos de memória

para armazenamento

de longa duração de

dados/programas

19

Armazenamento Secundário

(Disco Rígido)

Dispositivo magnético

Partes que são gravadas são magnetizadas

20

Armazenamento Secundário

(Disco Rígido)

Informações são gravadas em setores

Uma trilha é composta por um conjunto de

setores

setor

trilha

21

Armazenamento Secundário

(CD/DVD )

Dispositivo óptico

Pequenos furos quando lidos por laser refletem

diferentemente do resto do CD

Furos representam 0´s e espaços representam 1´s

22

Memória RAM é mais rápida do que memórias

secundárias

Memória RAM é volátil

Informação é perdida quando não há corrente elétrica

Memórias secundárias não são voláteis

Memórias secundárias geralmente são mais baratas

que a memória RAM

Por serem mais baratas, geralmente a capacidade de

armazenamento é maior (Ex: Disco Rígido)

Memória RAM x Memória Secundária

23

Dispositivos de Entrada/Saída

CPU

Memória Principal (RAM)

Armazenamento Secundário Dispositivos de

Entrada/SaídaDispositivos para

facilitar a interação

do usuário

Interação do usuário pode mudar o fluxo de execução na CPU

24

Existem, basicamente, 2 formas de representar umainformação:Modo Analógico

Contínua, diretamente proporcional aos dados queconstituem a informaçãoTermômetro de mercúrio – Mercúrio sobe em um tuboproporcionalmente ao aumento da temperatura fora do tubo

Modo DigitalInformação é quebrada em pedaços e cada pedaço érepresentado separadamenteMúsica em um CD – o disco armazena números querepresentam amostras regulares (no tempo) de níveis devoltagens específicas do som

Representação de Informação

25

Analógico x Digital

Analógico

volt

tempo

3

8

11

74

1 2 3 4 5

Digital

8

11

7

43

1 2 3 4 5

26

Computadores armazenam toda informação deforma digital

NúmerosTextoGráficos e ImagensVídeoÁudioInstruções de programas

Para isto o computador digitaliza as informações, ouseja quebra a informação em pedaços

Informação Digital

27

Em um texto, cada caractere é armazenado comoum número, incluindo espaços, dígitos e pontuaçãoCaracteres maiúsculos e minúsculos têmnumerações diferentes

Representando Texto Digitalmente

O i , M u n d o!

79 105 44 32 77 117 110 100 111 33

28

Números Binários

Quando a informação é digitalizada, ela érepresentada e armazenada em memória usando osistema de numeração binária

Um dígito binário (0 ou 1) é chamado de bit

Um bit pode representar 2 estados possíveis (0 ou 1), assimcomo uma lâmpada que pode estar ligada (1) ou desligada(0)

Dispositivos que armazenam e manipulaminformação com representação binária (com 2estados possíveis) são mais confiáveis e baratos

29

Sistema de Numeração Binária (1)

No sistema de numeração decimal utilizamos osdígitos de 0 até 9 para representar qualquer número

No sistema binário, só podemos utilizar os dígitos 0 e1 para representar um número

Exemplo: Para representar o número nove emdecimal utilizamos o dígito 9, em binário ficaria 1001

1 0 0 11x 23 + 0 x 22 + 0 x 21 + 1 x 20

30

Sistema de Numeração Binária (2)

Sistema Decimal Sistema Binário (4 bits)10987654321

1010100110000111011001010100001100100001

31

Unidades de Medida

Um byte corresponde a 8 bits

Capacidade de armazenamento de dados de umamemória é medida em termos de bytes que ela podeguardar

KB 210

= 1024

MB 220

(>1 milhão)

GB 230

(>1 bilhão)

TB 240

(>1 trilhão)

Unidade Símbolo Número de Bytes

kilobyte

megabyte

gigabyte

terabyte

32

Categorias de Software

Sistema OperacionalControla todas as atividades do computadorFornece uma interface para que o usuário interaja com ocomputadorGerencia recursos computacionais tais como CPU,memória, dispositivos de E/S, etcWindows , Unix, Linux, Mac OS

AplicativosTermo genérico para qualquer outro tipo de softwareEditores de texto, jogos, navegadores, sistemas de controleaéreo, etc

Maioria dos softwares possuem uma interface gráfica(GUI)

33

Aplicativos e Sistema Operacional

CPU

Sistema OperacionalAplicativos Gerencia

recursos do

computador

34

Usuários e Sistema Operacional

CPU

Sistema OperacionalFornece uma

interface para que

o usuário acesse

os recursos de um

computador

35

Resumindo

Componentes básicos de um sistema computacionalHardware

CPU

Memória

Periféricos

Software

Categorias de software

Introdução à Programação

Conceitos Básicos de

Programação

2

Tópicos da Aula

Antes de aprender a programar, precisamos saber oque é um algoritmo

Definição de algoritmoUsando algoritmos para resolver problemas

Depois precisamos saber o que é programação

Definição de Programa

Linguagens de Programação

Como o computador consegue entender um programa

3

Conceito de Algoritmo

Um algoritmo é um conjunto ordenado finito de passos executáveis, não ambíguos , definindo um processo que tem um término

Um algoritmo representa a sequência de passosnecessários para realizar uma tarefa

Para realizar uma mesma tarefa podemos terdiferentes algoritmos

4

Algoritmo de Conversão de Celsius

para Farenheit

Um algoritmo é um conjunto ordenado finito de passosexecutáveis, não ambíguos , definindo um processo que tem um término

1. Divida o número 9 pelonúmero 5

2. Multiplique o resultado dopasso 1 pela temperatura emgraus Celsius dada

3. Some o número 32 aoresultado obtido no passo 2

1. Multiplique 9 pelatemperatura em grausCelsius dada

2. Divida o resultado do passo1 por 5

3. Some o número 32 aoresultado obtido no passo 2

Ordem diferente dos passos Algoritmos diferentes

5

Contra-exemplo de Algoritmo

1.Retire uma moeda do bolso e coloque sobre mesa2.Volte ao passo 1

Processo chega ao fim quando acaba as moedas do bolso

Um algoritmo é um conjunto ordenado finito de passos executáveis, não ambíguos , definindo um processo que tem um término

Nenhum passo indica sobre o procedimento a ser adotado quando acaba as moedas

Ambigüidade

6

Algoritmo para Preparar um Bolo

Misture os ingredientes

Unte forma com manteiga

Despeje a mistura na forma

Tem coco ralado?

Despeje coco na mistura

Deixe a forma no forno

Dourou?

Tire do forno

Sim

Não

Sim

Pode necessitar decisões ou repetir passos

Diferentes formas de apresentar um

algoritmo

Não

7

Usando Algoritmos para resolver

problemas

Problema: Torre de HanoiDeve-se transportar todos os discos da primeira haste até a

última obedecendo as seguintes regras:

1. Só pode ser deslocado um disco por vez (o do topo de uma haste)

2. Em nenhum momento um disco maior pode estar sobre um menor

8

Usando Algoritmos para resolver

problemas

Algoritmo para torre de Hanoi com 4 discos

9

Algoritmo para a Torre de Hanoi com 4

Discos

1 2 3

1.Mova disco 1 para haste 2

1 2 3

10

2.Mova disco 2 para haste 3

3.Mova disco 1 para haste 3

Algoritmo para a Torre de Hanoi com 4

Discos

11

4.Mova disco 3 para haste 2

5.Mova disco 1 para haste 1

Algoritmo para a Torre de Hanoi com 4

Discos

12

6.Mova disco 2 para haste 2

7.Mova disco 1 para haste 2

Algoritmo para a Torre de Hanoi com 4

Discos

13

8.Mova disco 4 para haste 3

9.Mova disco 1 para haste 3

Algoritmo para a Torre de Hanoi com 4

Discos

14

10.Mova disco 2 para haste 1

11.Mova disco 1 para haste 1

Algoritmo para a Torre de Hanoi com 4

Discos

15

12.Mova disco 3 para haste 3

13.Mova disco 1 para haste 2

Algoritmo para a Torre de Hanoi com 4

Discos

16

14.Mova disco 2 para haste 3

15.Mova disco 1 para haste 3

Algoritmo para a Torre de Hanoi com 4

Discos

17

Programação de Computadores

Programação consiste no ato de indicar como ocomputador (hardware) deve trabalhar ou realizarserviços

Quais são os serviços que um computador poderealizar?

Enviar mensagens eletrônicas, armazenar e recuperardados, realizar exames e cirurgias, jogar e muito outrascoisas

Para que o computador consiga realizar de fato estesserviços, deve-se escrever um programa

18

Programas

Programa pode ser definido como uma série deinstruções que indicam como o computador irárealizar os serviços

O programa deve definir a ordem em que asinstruções devem ser executadas pelo computador

Um computador, geralmente, possui muitosprogramas, que podem estar sendo executados aomesmo tempo

Como vimos, programas constituem o grupo desoftwares de um computador

Programa Software

19

Algoritmos X Programas

Algoritmo é abstrato

Independe de máquina e de linguagem deprogramação

Pode ser representado de várias formas

Pode ser feito por uma máquina ou um humano

Programa é uma implementação real doalgoritmo utilizando uma linguagem deprogramação

É executado por um computador

20

Algoritmos X Programas

Atores e computadores

Do mesmo jeito que um ator de cinema precisa do roteiro de um filme para

poder encená-lo, um computador precisa de um programa para poder realizar

algum serviço.

21

Fonte: http://whatisthematrix.warnerbros.com

Roteiro de Matrix

Personagens,papéis

Instruções, falas,a serem executadas pelos atores

22

Fonte: http://whatisthematrix.warnerbros.com

Um roteiro podeser executado mais de uma vez

Um ator pode exercer mais de um papel no mesmo filme, executando asinstruções de cada um deles

Roteiro de Matrix

23

Fonte: http://whatisthematrix.warnerbros.com

Roteiro de Matrix

Além do textoem linguagemnatural (inglês,português, etc.)o roteirista pode usar gravuras...

linguagemgráfica

24

Fonte: http://whatisthematrix.warnerbros.com

Roteiro de Matrix

...o queimportaé que a linguagemusada peloroteiristapossa ser entendida pelos atores

25

Fonte: http://whatisthematrix.warnerbros.com

Roteiro de Matrix

O roteiro definea ordem em queas ações, falas e instruções devemacontecer...

26

As observações sobre roteirosvalem também para programas...

Roteiros e programas

Um programa contém instruções a serem executadaspor um computadorQuando solicitado, um computador executa asinstruções de um dado programa

O computador executa o programa

Um programa pode ser executado mais de uma vezUm programa pode se comportar de maneira diferentenas várias execuções...

dependendo do comportamento dos usuários, outrosprogramas, hardware, etc.

27

Roteiros e programas

Um computador pode executar vários programas aomesmo tempoCópias de um mesmo programa podem serexecutadas em vários computadores ao mesmotempoPara executar um programa, o computador tem queter uma cópia do programa

O programa tem que ser instalado ou carregado nocomputador

Um programa define a ordem de execução das suasinstruções pelo computador

28

Roteiros e programas

Mas, na verdade, um roteiro pode ser visto como vários programas, um para cada personagem, deixando claro como os personagens devem interagir.

As observações sobre roteirosvalem também para programas...

29

Filmes e sistemas

Do mesmo jeito que a encenação de um roteiro por vários atores “gera” um filme,a execução de um ou mais programas que

interagem constitui, junto com o hardware associado, um sistema computacional.

Sistema = Programas em execução, interagindo + Hardware

30

Linguagens de Programação

Os programas têm que ser escritos em umalinguagem de programação:

uma linguagem que pode ser entendida pelo computador

31

uma linguagem que pode ser traduzida para a linguagem

entendida pelo computador

1001001010001110

a = 10;a = a + 1; ?

1001001010001110

Sintaxe e Semântica

Uma linguagem de programação define as palavras esímbolos que se pode usar para escrever um programa

Uma linguagem de programação emprega um conjuntode regras (sintaxe) que estabelece como palavras esímbolos podem ser agrupados de maneira a formarinstruções válidas de um programa

A semântica de uma instrução define o significadodesta instrução no programa

Um programa que é sintaticamente correto não énecessariamente logicamente (semanticamente)correto

32

Níveis de Abstração de Linguagens

Linguagens de programação variam de acordo com oseu nível de abstração

↑ conhecimento da máquina onde programa será executado↓nível de abstração

↓ conhecimento da máquina onde programa será executado↑nível de abstração

Linguagens podem ser classificadas em 4 níveis:

Linguagem de máquina

Linguagem de montagem (assembly)

Linguagem de alto nível (Java, C, Pascal, C++, etc)

Linguagem de 4ª geração (PL/SQL, NATURAL, MATLAB, etc)

33

Níveis de Abstração de Linguagens

Cada tipo de CPU tem sua linguagem de máquinaespecífica

Instruções codificadas em binário

Dependente da máquina

Linguagem assembly é dependente da máquina,porém utiliza palavras reservadas para codificarinstruções (mnemônicos)

Outros níveis são independentes de máquina efacilitam leitura e escrita dos programas por parte doser humano

Complexidade atual de programas exigem cada vez mais oemprego destas linguagens

34

Como o computador entende um

programa?

Cada tipo de CPU executa apenas uma linguagem demáquina particular

Deve-se traduzir um programa para a linguagem demáquina

Um compilador é um programa que traduz umprograma escrito (código fonte) em uma determinadalinguagem de programação para outra linguagem(linguagem destino)

Se a linguagem destino for a de máquina, o programa pode,depois de compilado, ser executado

Um interpretador é um programa que traduz instruçãopor instrução de um programa em linguagem demáquina e imediatamente executa a instrução 35

Compilação x Interpretação

36

Compilação

a = 10;a = a + 1; Compilador

1001001010001110

Código- fonte Código de máquina

a = 10;a = a + 1;

Interpretador10010010

Código- fonteCódigo de máquina

10001110

Interpretação

Compilação x Interpretação

Existem vários exemplos tanto de linguagensinterpretadas como de linguagens compiladas

A linguagem C é um exemplo de linguagem compilada

Java é uma linguagem de programação que utiliza umprocesso híbrido de tradução

O compilador Java traduz o código-fonte em um formatointermediário independente de máquina chamado bytecode

Interpretador Java específico da máquina onde irá rodar oprograma então traduz os bytecodes para linguagem demáquina e executa o código

37

Resumindo...

Conceitos Básicos de Programação

Algoritmos

Programa

Linguagens de Programação

Compilação x Interpretação

38

Introdução à Programação

Introdução a Linguagem C

Construções Básicas

2

Programa em C

#include <stdio.h>

int main ( ) {

float celsius ;float farenheit ;celsius = 30;farenheit = 9.0/5 *celsius + 32;printf (“30 graus celsius = %f graus farenheit”,farenheit);return 0;

}

#include

floatfloat

int mainPalavras

Reservadas

E ainda expressões...

celsiusfarenheit

printf

Identificadores criados pelo programador

Identificadores criados por terceiros (chamadas

de funções)

3

Tópicos da Aula

Hoje aprenderemos a escrever um programa em C,para isto veremos

Características da linguagemEstrutura de um programaCiclo de construção de um programa em CEstruturas básicas de uma linguagem de programação

Identificadores,Variáveis,Tipos de dados, Atribuição

Conceito de funções

Depois escreveremos um programa em um ambientede programação

Apresentação de um ambiente de programação

Executando um programa

4

Linguagem C - Características

Linguagem de programação de finalidadegeral criada por Dennis Ritchie em 1972

Criada para desenvolver o sistema operacionalUnixPadronizada em 1989 pela ANSITornou-se muito popular

Ela faz parte das linguagens denominadasimperativas

Ações que o computador deve executar sãoespecificadas como comandos que alteram oestado da memória

5

Linguagem C - Características

Combina o alto nível com o baixo nível,permitindo a manipulação direta de bits, bytese endereços de memória

Possui fluxos de controle e estruturas dedados presentes na maioria das linguagensimperativas

Agrupamento de comandosTomadas de decisões (if-else)Laços para permitir a repetição de comandos

6

Linguagem C - Características

Possui apenas 32 palavras-chaves(reservadas)Permite economia de expressão e geracódigos reduzidosPossibilita alocação dinâmica de memóriaPermite estruturar o software em módulos,arquivos fontes, bibliotecas

7

Linguagem C - Críticas

Dá-se muita liberdade ao programadorProgramas ininteligíveis, acesso direto àmemóriaNão há verificação de tipos e nem de limitesde arrays (veremos depois)

Simplifica o projeto do compilador CMensagens de erro muito vagas (limitação docompilador )

8

Estrutura de um Programa

Em C, a construção fundamental é a função:Um programa é constituído de uma ou mais funções

Uma destas funções deve ser a função main

O programa inicia sua execução na função main

Mas, o que é uma função?

É um conjunto de instruções para realizar uma ou mais tarefas que são agrupadas em uma mesma

unidade e que pode ser referenciada por um nome único

9

Estrutura de um Programa

Dentro de uma função pode haver:Declarações, expressões, chamadas de outras funções,comandos, etc

Uma função em C pode retornar algum valor, assim

como acontece com funções matemáticas

Inteiro, real, caractere, etc

Porém, uma função não precisa necessariamente

retornar um valor

Quando não retorna um valor, dizemos que a função é do

tipo void

10

Estrutura de um Programa

função 1

int main ()

{

}

Comandos,

declarações, chamada

de funções, etc

função 2

função n

return 0;

.

.

.

.

.

.

11

Exemplo de um Programa em C

#include <stdio.h>

int main()

{

int resultado;

resultado = 6 + 7;

printf(“%d”,resultado);

return 0 ;

} Chamada de função

Expressão aritmética

Declaração de variavel

Comando

12

Estrutura de uma Função

int multiplicacao (int p1, int p2)

{

int produto;

produto = p1 * p2;

return produto;

}

Assinatura da função

Corpo da

função

Uma função deve conter:Uma assinatura

Um corpo

13

Estrutura de uma Função

int multiplicacao (int p1, int p2)

{

int produto;

produto = p1 * p2;

return produto;

}

Lista de parâmetros

Assinatura de uma função deve informar:Tipo de valor retornado (se for o caso)

Nome

Lista de parâmetros formais (se houver)

Nome do parâmetro e tipo do parâmetro

Tipo retornado Nome

Parênteses

obrigatórios

14

Estrutura de uma Função

int multiplicacao (int p1, int p2)

{

int produto;

produto = p1 * p2;

return produto;

}

Corpo da

função

dentro das

chaves { }

Instruções devem ser separadas

por ponto e vírgula (;)

Corpo de uma função contém:Instruções

Declarações, comandos, expressões, etc

O comando return, caso o tipo de retorno seja diferente de

void

15

Funções de Bibliotecas

A linguagem C oferece um conjunto de funções jádefinidas que são organizadas em bibliotecas

Programador pode utilizar (chamar) estas funções no programaReduzem o tempo de desenvolvimento do programa

Algumas das funções oferecidas permitem:realizar operações de E/Smanipulação de caracteres (strings)aplicações matemáticas, etc.

16

Funções de Bibliotecas

Informações sobre as funções de bibliotecas sãoencontradas em vários arquivos

header files ou arquivos com extensão .h

Para usar estas bibliotecas, o programa deve indicar osnomes dos arquivos que as contêm

Estas bibliotecas são adicionadas ao programa usandoa diretiva de pré-processamento # include

Por exemplo: # include < stdio.h >Não possui ponto_e_vírgula ( ; )stdio.h é uma biblioteca que contém funções deentrada/saída, tal como a função printf que permitemostrar alguma mensagem no monitor

17

Outro Exemplo de Programa em C

#include <stdio.h>

int multiplicacao (int p1, int p2)

{

int produto;

produto = p1 * p2;

return produto;

}

int main ( )

{

int resultado;

resultado = multiplicacao(6,7);

printf(“6 vezes 7 eh %d”,resultado);return 0 ;

}

Inclui a biblioteca stdio

Chama função da biblioteca stdio

Chama a função multiplicacao

Argumentos da

função

18

Diretivas de Pré-Processamento

O pré-processador é um programa que examina oprograma fonte em C e executa certas modificaçõescom base em instruções chamadas de diretivas

Exemplos: include, define, etc

Uma diretiva deve vir precedida de #

Deve ser escrita em uma única linhaSe passar de uma linha deve-se usar a barra invertida (\) aofinal da linha e contiunuar na seguinte

Diretivas não fazem parte da linguagem CServem para auxiliar o desenvolvimento do programa fonte

19

Exemplo da Diretiva include

#include <stdio.h>

int multiplicacao (int p1, int p2)

{

int produto;

produto = p1 * p2;

return produto;

}

int main ( )

{

int resultado;

resultado = multiplicacao(6,7);

printf(“6 vezes 7 eh %d”,resultado);return 0 ;

}

Inclui a biblioteca stdio

Chama função da biblioteca stdio

20

Variáveis

Programas manipulam dados (valores) eesses dados são armazenados em variáveis

Uma variável é uma posição na memóriareferenciada por um identificador (nome)Uma variável deve ser declarada informandoo tipo de dado que ela armazenará e o nomedela

int total;

int count, temp, result;

Muitas variáveis podem ser criadas em uma declaração

tipo nome

21

Variáveis

Uma declaração de variável instrui ocompilador:

a reservar um espaço de memória suficiente paraarmazenar o tipo de dado declaradoo nome ao qual iremos referenciar esta posiçãode memória

Só após a declaração da variável, é que estapode ser referenciada (utilizada)Quando uma variável é referenciada noprograma, o valor armazenado nela éutilizado

22

Variáveis

Onde se declara variáveis?No corpo de uma função (variável local)

Recomenda-se que as declarações devariáveis sejam as primeiras instruções dafunção

Na lista de parâmetros de funçõesParâmetros formais

Fora das funções (variável global)

23

Declaração de Variáveis

#include <stdio.h>

int resultado;

int multiplicacao (int p1, int p2)

{

int produto;

produto = p1 * p2;

return produto;

}

int main () {

resultado = multiplicacao(6,7);

printf(“6 vezes 7 eh %d”,resultado);return 0 ;

}

Declaração de variáveis nos

parâmetros formais

Declaração de variável local

Declaração de

variável global

24

Atribuição

Um comando de atribuição modifica o valorarmazenado na variávelO operador de atribuição é o sinal de =

total = 55;

total = 65;

Variável total armazena

valor 55

Valor 65 sobrescreve o

valor armazenado antes

Só se deve atribuir a uma variável valores compatíveis com o tipo

declarado da variável

int total;

25

Inicialização de Variáveis

Uma variável pode ser inicializada com o comandode atribuição na hora de sua declaração

int total = 55; Inicializa total com valor

55

Declara variável total do tipo int

Em C, variáveis locais não são inicializadas automaticamente

26

Constantes

Uma constante é um identificador semelhante auma variável, exceto pelo fato de só poderarmazenar o mesmo valor durante toda suaexistênciaUma constante é declarada usando a palavrareservada const

Deve-se inicializar a constante no ato da suadeclaração

const float PI = 3.1416;

PI = 3.141618; Esse comando gera um

erro de compilação

Não se pode mudar o valor de uma constante

27

Constantes

São úteis para dar um significado maiscompreensível a determinados valores

Exemplo : PI é mais compreensível que o valor 3,1416

Facilitam a manutenção do programaCaso uma alteração no programa seja necessária queacarrete uma mudança no valor da constante e estaconstante seja referenciada em vários lugares do programa,só precisamos alterar o programa em um lugar

Explicitam formalmente que um determinado valornão pode ser alterado

Evitam erros de outros programadores

28

Constantes

É comum utilizar-se também a diretiva de pré-processamento define para definir constantes

#define PI 3.1416

int main() {

float raio = 5;

float area = PI*raio*raio;

float comp = 2*PI*raio;

return 0;

}

int main() {

float raio = 5;

float area = 3.1416*raio*raio;

float comp = 2*3.1416*raio;

return 0;

}

No pré-processamento, ocorre

a substituição

29

Linguagem C - Tipos de Dados

Cada dado possui associado a ele um tipo e podepossuir um qualificador

C possui 5 tipos básicos de dadochar: tipo caractere (tamanho de um byte)int: tipo inteiro (números sem parte decimal)float: tipo ponto flutuante de precisão simplesdouble: tipo ponto flutuante de precisão duplavoid: não possui valor

Mais utilizado para indicar que uma função não retornanenhum valor

Qualificadores: short, long, unsigned, signedPrecedem o tipo na declaração do tipo

Ex: unsigned int valor ;

30

Tipo Tamanho Representatividade

char 1 byte -128 a 127

unsigned char 1 byte 0 a 255

short int 2 bytes -32768 a 32767

unsigned short int 2 bytes 0 a 65535

long int (ou int) emambientes de 32 bits

4 bytes -2147483648 a 2147483647

unsigned long int 4 bytes 0 a 4294967295

Linguagem C - Tipos de Dados

O tipo de dado define o tamanho do dado e a formade armazenamento

Valores Inteiros e suas Representatividades

31

Tipo Tamanho Representatividade

float 4 bytes 3.4 X10-38 a 3.4 X1038

double 8 bytes 1.7 X 10-308 a 1.7X10308

long double 10 bytes 3.4 X 10-4932 a 3.4X104932

Valores Reais e suas Representatividades

Linguagem C - Tipos de Dados

32

Tipos de Dados Numéricos

Números com e sem sinalC permite que o programador defina se umavariável de tipo numérico deva ou não reservar obit de sinal (números negativos)Notação

signed tipo

unsigned tipo

Se nenhum modificador for indicado, o compiladorC reservará o bit de sinal

33

Tipo de Dados Caractere

Representado pelo tipo char

„a‟,‟b‟, „1‟, „\n‟ etcinternamente representa um código da tabelaASCIIASCII: na verdade aceita até 255 caracteres(unsigned char)

char letra = „A‟; char letra = 65;

Instrução equivalente

34

Identificadores

Identificadores são palavras que oprogramador utiliza em programasConsiste de um ou mais caracteres.

o primeiro caractere deve ser letra ou "_”demais são uma combinação de letras, números e"_"Identificadores não podem começar com umdígito

Exemplo de identificadores válidos: _a, a3_,bom_diaExemplo de identificadores inválidos: 2a, a-b, a_ b

C é “case-sensitive”Os identificadores casa e CASA são diferentes

35

Identificadores

Identificadores podem ser:Nomes que o programador escolheu

Exemplo: nome de uma variável, função, constante, etc

Nomes que terceiros escolheramExemplo: nome de uma função de uma bibliotecautilizada

Palavras reservadas da linguagemNão podem ser usadas de outra formaExemplo: main, const, int, etc

36

Identificadores em C

#include <stdio.h>

int main ( ) {

float celsius ;float farenheit ;celsius = 30;farenheit = 9.0/5 *celsius + 32;printf (“30 graus celsius = %f graus farenheit”,farenheit);return 0;

}

#include

floatfloat

int mainPalavras

Reservadas

E ainda expressões...

celsiusfarenheit

printf

Identificadores criados pelo programador

Identificadores criados por terceiros (chamadas

de funções)

37

Executando de um Programa em C

Escrever o programa em um arquivo texto(código fonte)

Salvar o arquivo com a extensão .c

Compilar o programa fonte para gerar ocódigo executável (*.exe)

Um programa em C pode ser composto de várioscódigos fontes (vários arquivos .c)É comum a geração de um código objeto (*.obj ou*.o) para cada código fonte e a posterior geraçãodo código executável (linkedição)

38

Construção de Programas em C

EditorCodigo,

Palavras reservadas

Programafonte

Edição

ProgramaFonte

Compilador ProgramaObjeto

Compilação

ProgramasObjeto

ProgramaExecutável

Link-Edição

Adição /Localização de códigos objetos das bibliotecas

ProgramaFonte

Pré-processador

ProgramaFonte

ModificadoPré-processamento

39

Ambiente de Programação

Para acelerar o desenvolvimento de programas, écomum utilizar ambientes de programação ou IDEs(Integrated Development Environment)

Integra várias ferramentas em um único ambienteEditores de textoCompiladoresBibliotecasE muito mais ...

CodeBlocks, DevC++, Visual Studio, Eclipse etc

39

40

Resumindo ...

Características da linguagemEstrutura de um programaCiclo de construção de um programa em CEstruturas básicas de uma linguagem deprogramação

Identificadores,Variáveis,Tipos de dados, Atribuição

Conceito de funções

Introdução à Programação

Operadores, Expressões

Aritméticas e Entrada/Saída de

Dados

2

Programa em C

#include <stdio.h>

int main ( ) {

float celsius ;float farenheit ;celsius = 30;farenheit = 9.0/5 *celsius + 32;printf (“30 graus celsius = %f graus farenheit”,farenheit);

}

#include

floatfloat

mainPalavras

Reservadas

E ainda expressões

aritméticas...

celsiusfarenheit

printf

Identificadores criados pelo programador

Identificadores criados por terceiros (chamadas

de funções)

3

Tópicos da Aula

Hoje aprenderemos a escrever um programa em C quepode realizar cálculos

Conceito de expressãoTipos de Operadores em COperador de atribuiçãoOperadores aritméticos

Operadores especiais

Depois aprenderemos como utilizar funções deentrada/saída para escrever um programa

Funções de entrada

Funções de saída

4

Expressões

Uma expressão é uma combinação de um ou maisoperadores e operandos que geralmente realizaum cálculoA avaliação ou cálculo da expressão se fazobedecendo regras de associação e precedênciaestabelecidas na linguagem

O valor calculado pode não ser necessariamente umnúmero

Pode ser um caractere, cadeia de caracteres, etc

int total = 3 + 4/2 ;Expressão é avaliada e

o resultado é atribuído a

total que armazena

agora o valor 5Divisão (/ ) tem precedência

sobre soma (+)

5

Operadores em C

Categorias de operadores em CAtribuiçãoAritméticosEspeciaisRelacionaisLógicos

Hoje veremos estes 3 tipos de

operadores

6

Operador de Atribuição

Operador de AtribuiçãoPode ser usado em qualquer expressão válida emCRepresentado por =Forma geral:

<nome_da_variável> = <expressão> ;Ex.: x = 5 ;

Ação é executada da direita para a esquerda

5

x 5

7

Operador de Atribuição

Atribuição (Cont.)É usado para atribuir valores às variáveisNão é igual ao operador = de matemática

5 = a não faz sentido em C!

Valor da expressão é armazenado fisicamenteem <nome_da_variável>Múltiplas atribuições

Ex: x = y = z = 0

xyz0 0 0 0

8

Operadores Aritméticos

Operadores aritméticos unáriosUm só operandooperador operando

Sinal Ação Precedência- Troca de sinal 1ª

Ex.: -(a)

++ Incremento de 1 1ª

-- Decremento de 1 1ª

9

Operadores Aritméticos

Operadores aritméticos bináriosDois operandos

operando operador operando

Sinal Ação Precedência+ Adição 3ª- Subtração 3ª* Multiplicação 2ª/ Divisão 2ª

% Resto da Divisão 2ª(só para inteiros)

Operadores de incremento e decremento sãooperadores unários (usam um só operando)

O operador de incremento (++) soma 1 ao seuoperando

O operador de decremento (--) subtrai 1 de seuoperando

A instrução

contador++;

é funcionalmente equivalente a

contador = contador + 1;

Operadores de Incremento e

Decremento

10

Estes operadores podem ser empregados deforma pós-fixada ou pré-fixada

contador++; ou ++ contador;

Quando isolados têm comportamentosequivalentes

Quando fazem parte de expressões

maiores, eles podem ter comportamentosdiferentes

Operadores de Incremento e

Decremento

11

12

Operadores de Incremento e

Decremento

Pré-fixado : ++a ou --a

Incrementa (decrementa) de 1 o valor de a. Seaparece em uma expressão, o valor éincrementado (decrementado) antes do cálculo daexpressão

Pré: int soma = ++a + b

+ =

a b soma

5 2 86

13

Operadores de Incremento e

Decremento

Pós-fixado: a++ ou a--

Incrementa (decrementa) de 1 o valor de a. Seaparece em uma expressão, o valor éincrementado (decrementado) após o cálculo daexpressão

Pós: int soma = a++ + b

+ =ab soma

52 7

6

( )

Devem ser utilizadas com cuidado emexpressões maiores!

Operadores de Incremento e

Decremento

14

int contador = 3;

contador++;

++contador;

int valor = contador++;

valor = ++ contador;

contador agora armazena 4

contador agora armazena 5

valor agora armazena 5 e

depois contador é

incrementado para 6

contador é incrementado

para 7 e agora valor armazena

7

1515

Divisão e Resto da Divisão

Se ambos operandos da expressão aritméticaforem valores inteiros, o resultado será uminteiro (a parte decimal será descartada)Portanto

14/3 4

8/12 0

14%3 2

8%12 8

16

Operadores Aritméticos de Atribuição

É comum fazermos algum tipo de operação com umavariável e depois armazenar o valor da operação naprópria variável

Operadores aritméticos de atribuição facilitam codificaçãode expressões do tipo a = a op bForma geral

variavel op = expressão

x += 1; x = x + 1;

x *= k; x = x * k;

x -= 2; x = x - 2;

x /= 3; x = x / 3;

x %= 3; x = x % 3;

1717

Expressões Aritméticas

Uma expressão aritmética computaresultados numéricos e utiliza operadoresaritméticos combinados com operandosnuméricos

Variáveis, constantes, funções numéricasOrdem de precedência

Operadores unários (- , -- , ++ ) e FunçõesMultiplicação ( *), Divisão ( / ) e Módulo (% )Adição ( + ) e Subtração ( - )

Comandos Equivalentesa = a + 1; a += 1 ; a++ ; ++a ;

18

Operadores Aritméticos

int a , r ;

double b , c ;

a = 3.5 ;

b = a / 2.0 ;

c = 1/2 + b ;

r = 10 % a ;

Quais serão os valores das variáveis declaradas após a avaliação das expressões abaixo?

a=3 b=1.5 c=1.5 e r=1

Atribuição de Expressões aritméticas

Numa atribuição, a expressão aritmética éavaliada primeiro, para depois se atribuir oresultado da expressão à variável

Primeiro, a expressão do lado direito

do operador = é avaliado

Depois, o resultado é armazenado na

variável

answer = sum / 4 + MAX * lowest;

14 3 2

19

O lado direito e esquerdo de um comando deatribuição podem conter a mesma variável

Primeiro, 1 é adicionado aovalor original de contador

Depois o resultado é armazenado em contador

(sobrescrevendo o seu valor original)

contador = contador + 1;

Atribuição de Expressões aritméticas

int contador = 3;

4

20

21

Operadores Especiais

O operador & é utilizado para se obter oendereço da memória que a variávelrepresenta

Forma geral&variável

Um endereço de memória é visto como umnúmero inteiro sem sinal

22

Conversão de Tipos

Existem conversões automáticas de valores em umaavaliação de uma expressão quando operandospossuem tipos diferentes

Operando de tipo de menor tamanho é convertidoautomaticamente para o tipo de maior tamanho

Conversão é feita em área temporária da memória antes daavaliação da expressãoResultado é novamente convertido para o tipo da variável aesquerda da atribuição

int a = 3/2.0 + 0.5;

1. O inteiro 3 é convertido para real

2. Expressão é avaliada como 2.0,

3. Valor é convertido para um inteiro e atribuído a variável

Valor de a é 2

23

Operadores Especiais (Cast)

Algumas vezes a conversão automática dá resultadosnão desejadosDevemos então usar o operador de cast

Forma geral(tipo desejado) variável ou (tipo desejado) (expressão)Armazenamento de um valor real em um tipo de dado inteirogera erro ou perde-se precisão

int a = 3/2 + 0.5;

printf("a = %d",a); int a = ((float)3)/2 +0.5;

printf("a = %d",a);

a = 1

Usando cast

a = 2

24

Entrada de Dados

A função scanf

Usada para a entrada formatada de dadosPara cadeia de caracteres, a leitura é feita até oprimeiro espaço em branco, ou o return, ou o tab.Está definida na biblioteca “stdio.h”

Forma Geral: Tem duas partes:scanf (“expressão de controle”, lista de argumentos)

Expressão de controleCódigos de formatação, precedidos por %

25

Entrada de Dados

Códigos de Formatação

Código Função

%c ler um único caractere

%d ler um número inteiro

%f %e %g ler um número real (tipo float)

%lf %le %lg ler um número real (tipo double)

%s ler uma cadeia de caracteres

%u ler um inteiro sem sinal

%l ler um inteiro longo

26

Entrada de Dados

Lista de ArgumentosCada código de formatação deve corresponder auma variável de entrada, que deve serrepresentada com o operador de endereço

Operador de EndereçoUtilizado para permitir que o dado lido dodispositivo de entrada seja armazenado navariável correspondente. Ele retorna o endereçoda variável.

int a ;&a endereço da variável ascanf ( “ % d ” , &a ) ;

27

Entrada de Dados

Exemplo:

int main() {

char a, b, c ;

int n ; double x ;

scanf (“%c%c%c%d%lf ”,&a,&b,&c,&n,&x);

}

28

Entrada de Dados

#include “stdio.h“int main ( ) /* ler um valor numérico */{ float a;

scanf(“%f”,&a);.....

}

15.2

15.2a

29

Saída de Dados

A Função printfPermite a impressão formatada de números ecadeias de caracteres

Forma Geralprintf(“estruturas de controle”, lista de parâmetros)

Estruturas de ControleCaracteres especiaisCódigos de formatação precedidos por %

30

Saída de Dados

Formato Significado%c caracter%d inteiro %u inteiro sem sinal%e notação científica com e (7.12300e+00)%E notação científica com E (7.12300E+00)%f ponto flutuante decimal (7.12300)%g escolhe %e ou %f ,o menor dos 2 formatos%G escolhe %E ou %f ,o menor dos 2 formatos%s cadeia de caracteres%% imprime o caracter ‘%’

31

Exemplo E/S de Dados

Escreva um programa em C para ler 2 valores para

as variáveis A e B, efetuar a troca dos valores de

forma que a variável A passe a possuir o valor da

variável B e que a variável B passe a possuir o

valor da variável A. Apresentar os valores

trocados.

32

Exemplo E/S de Dados

#include “stdio.h”

int main( ){

int a , b, aux;

printf (“\nTroca de valores entre variáveis\n”);

printf (“\nEntre com o valor de A: ” );

scanf (“%d”, &a );

printf (“\nEntre com o valor de B: ”) ;

scanf (“%d”, &b );

aux = a ;

a = b ;

b = aux ;

printf (“A variável A agora vale: %d”, a ) ;

printf (“ \n”) ;

printf ( “A variável B agora vale: %d”, b ) ;

}

33

Resumindo ...

Conceito de expressãoTipos de Operadores em COperador de atribuiçãoOperadores aritméticos

Operadores especiaisEntrada/Saída

Funções de entrada

Funções de saída

Introdução à Programação

Expressões Booleanas e Comandos Condicionais

2

Comandos CondicionaisMisture os ingredientes

Unte forma com manteiga

Despeje a mistura na forma

Tem coco ralado?

Despeje coco na mistura

Deixe a forma no forno

Sim

Comandos Condicionais

Algoritmo para preparação de bolo

Instrução é executada se

uma determinada

condição for verdadeira

33

Tópicos da Aula

Hoje vamos acrescentar comportamentos maiscomplexos a programas

Tomada de decisão e Mudança de fluxo de controle

Expressões booleanas (lógicas)

Comandos Condicionais

if-else

switch

Operador condicional

Instruções de Controle

Toda linguagem de programação precisaoferecer pelo menos três formas básicas decontrole:

executar uma sequência de instruçõesrealizar testes para decidir entre açõesalternativasrepetir uma sequência de instruções

Hoje, aprenderemos a realizar testes para decidir quais instruções executar

4

Modificando Fluxo de Controle

A ordem de execução de um programa édenominado fluxo de controleExceto quando especificado de outra forma, a ordemde execução é linear, isto é uma instrução após aoutra em seqüenciaAlguns comandos em programação nos permitem:

Decidir se a execução de uma instrução deve ounão ser feita

Útil para que certas instruções só sejam executadassob determinadas condiçõesEsta tomada de decisão é baseada em expressõesbooleanas

5

Expressão Booleana

O resultado da avaliação de uma expressãobooleana é ou verdadeiro ou falso

Em C, NÃO existe o tipo de dado booleanVerdadeiro é representado como 1Falso é representado como 0

Uma expressão booleana é composta deoperandos booleanos (lógicos) e operadoresrelacionais e/ou lógicos

6

7

Operador Ação< menor que

> maior que

<= menor ou igual que

>= maior ou igual que

== igual a

!= diferente de

Resultado de Comparação

Falso ou Verdadeiro

4 < 5 é verdadeiro ( valor 1)

3 >= 10 é falso (valor 0)

Operadores Relacionais

São usados para fazer comparações

8

Operadores Lógicos (Booleanos)

Operador Ação&& E

|| Ou

! Negação

Resultado da Avaliaçãoint a , b ; int c = 23 ;int d = 27 ;a = ( c < 20 ) || ( d > c ) ; b = (c < 20 ) && ( d< c ) ;

São usados para combinar comparaçõesOperam sobre valores booleanos (0 ou 1)

Qual será o valor de a e b?

a = 1

b = 0

Expressões Booleanas

Operadores lógicos e expressões:x && y

x || y

!x

Operadores && e || são ditos short-circuitedOperandos da direita só são avaliados, senecessárioExistem os operadores bit a bit & e I

x e y são expressões booleanas

As expressões resultantessão booleanas, gerando

verdadeiro (1) ou falso (0)como resultado

da avaliação 9

Tabela Verdade

Uma tabela verdade contém todas ascombinações verdadeiro-falso de umaexpressão booleana

10

a b a && b a || b !a

verdadeiro verdadeiro verdadeiro verdadeiro falso

verdadeiro falso falso verdadeiro falso

falso verdadeiro falso verdadeiro verdadeiro

falso falso falso falso verdadeiro

11

Expressões Booleanas

Exemplos3 < 4 && 5 > 2 ! (3 > 7)

v v

v

5 < 4 || 7 > 2 ! (7 >= 10)

f v

v

f

v

f

v

Expressões Booleanas

{ ...

int b, c;

b = 1;

c = !b;

c = !(1 || b) && c;

b = c || !(!b);

...

}

Parênteses são usados para

evitar ambigüidades

Qual o valor de b neste

ponto?12

1 (verdadeiro)

int b, c;

b = 1 || 0;

c = 1 && b;

b = b == c;

Qual o valorde b aqui?

131 (verdadeiro)

Expressões Booleanas

Comandos Condicionais

Um comando condicional nos permiteescolher qual deve ser a próxima instruçãoexecutada em um programaA execução de uma determinada instruçãodepende de uma condição (expressãobooleana)A linguagem C oferece 3 tipos de comandoscondicionais:

if – elseswitchcomando ternário

14

O comando if-else

if (expressaoBooleana) {

comandos

} else {

outros comandos

}

Se a avaliação de expressaoBooleanaretornar verdadeiro, comandos são

executados , caso contrário, executa-se outros comandos

15

16

Exemplo do if-else#include <stdio.h>

int main ( )

{ float n1, n2, n3, m;

printf (“\nEntre com 3 notas ” ) ;

scanf (“%f %f %f”, &n1, &n2, &n3);

m = (n1 + n2 + n3 ) / 3 ;

if (m >= 7.0) {

printf (“\n Aluno aprovado. ”) ;

printf (“ Média igual a %f “ , m) ;

}else {

printf (“\n Aluno reprovado. ”);

printf (“ Média igual a %f “ , m) ;

}

return 0;

}

Variações do comando if-else

if (expressaoBooleana) {

comandos

}

if (expressaoBooleana)

comando;

if (expressaoBooleana)

comando;

else outroComando;

Se a avaliação daexpressãoretornar falso,não executa-se nada

O uso do bloco sóé necessário casoqueira-se executarmais de um comando

17

18

Exemplo – if sem else

#include <stdio.h>

int main ( )

{ int resposta ;

printf (“\n Qual o valor de 10 + 14? ”);

scanf (“%d”, &resposta);

if (resposta == 10 + 14)

printf (“\n Resposta correta ! ”);

return 0;

}else não é obrigatório

19

Exemplo – if-else com único comando

#include <stdio.h>

int main ( )

{ int num ;

printf (“\nDigite um número: ”);

scanf (“%d”, &num);

if (num < 0)

printf (“\n Número é negativo ! ”);

else

printf (“\n Número é positivo ! ”);

return 0;

}

Aninhando if-else

if (expressaoBooleana)

if (expressaoBooleana)

comando;

else outroComando;

O comando dentro do if ou elsepode ser outro if

20

if-else aninhado

Num aninhamento, o else é associado ao maisrecente if sem else

21

Exemplo if-else AninhadoExercício: O que está errado neste programa?

#include <stdio.h >

int main ()

{ int temp ;

printf (“\n Digite a temperatura: ” ) ;

scanf (“%d”, &temp) ;

if (temp < 30)

if (temp > 20)

printf (“\n Temperatura agradável ” ) ;

else printf (“\n Temperatura muito quente ” ) ;

return 0 ;

}

22

Exemplo if-else AninhadoExercício: Corrigindo o programa

#include <stdio.h >

int main ()

{ int temp ;

printf (“\n Digite a temperatura: ” ) ;

scanf (“%d”, &temp) ;

if (temp < 30)

if (temp > 20)

printf (“\n Temperatura agradável ” ) ;

else printf (“\n Temperatura muito quente ” ) ;

return 0 ;

}

{

else associado ao if certo

}

Encadeando comandos if-else

if (expressaoBooleana) {

comandos

} else if (expressaoBooleana‟) {

comandos‟

} else {

comandos‟‟

}

23

Tomando Múltiplas Decisões

O comando if-else é útil para a escolha deuma entre duas alternativasQuando mais de duas alternativas sãonecessárias, pode ficar deselegante utilizarvários if-else encadeados

Para estes casos o comando switch pode ser amelhor opção

24

switch(expressao) {

case rotulo1:

Comandos1

break;

case rotulo2:

Comandos2

break;

...

default:

Comandos

}

O Comando switch

Para executar um switch

Avalia-se expressao

Executa-se os comandosdo case cujo rótulo éigual ao valor resultanteda expressão

Executa-se os comandosde default caso o valorresultante não seja igual anenhum rótulo

switch(expressao) {

case rotulo1:

Comandos1

break;

case rotulo2:

Comandos2

break;

...

default:

Comandos

}

Restrições do Comando switch

O tipo de expressao

só pode ser :Inteiro ou caractere

Os rótulos sãoconstantes diferentesExiste no máximo umacláusula default (éopcional)Os tipos dos rótulos têmque ser o mesmo deexpressao

switch(expressao) {

case rotulo1:

Comandos1

break;

case rotulo2:

Comandos2

break;

...

default:

Comandos

}

Variações do Comando switch

Vários rótulos podemestar associados aomesmo comandoOs comandos break

são opcionais:Sem o break aexecução dos comandosde um rótulo continua noscomandos do próximo,até chegar ao final ou aum break

28

Exemplo de switchCalcular a diferença, o produto, o quociente ou a somade dois números, dependendo da operação escolhida eimprimir o resultado.

# include “stdio.h“

int main ()

{

char x;

float a, b ;

float result = 0.0;

printf (“\n Informe os 2 números e a operação ”);

scanf (“%f %f %c”, &a, &b, &x);

29

Exemplo de switch (cont..)

switch (x) {

case „+‟: result = a + b;

break;

case „-‟: result = a - b;

break;

case „*‟: result = a * b;

break;

case „/‟: result = a / b;

break;

default : printf(“\nOperador invalido”);

}

printf (“\nResultado igual a %f ”, result);

return 0 ;

}

30

if ( a > b ) {

maximo = a;

}

else {

maximo = b;

}

condição ? expressão1 : expressão2

maximo = a > b ? a: b;

Operador Condicional - ?

Forma Geral do ?

Substitui construções do tipo:

31

char a = „a‟, b = „b‟ ;/* b tem valor 98*/

int i = 1, j = 2 ;

double x = 7.07 ;

Expressão Valor

i == j ? a - 1 : b + 1

j % 3 == 0 ? i + 4 : x

j > 1 ? j - 1 : j + 1j % 3 != 0 ? i + 4 : x

Exercício: Considere as seguintes declarações

Comando Ternário de Decisão - ?

‘c’

7.07

15

3232

Resumindo ...

Necessidade de Mecanismos de Tomadas deDecisão em um Programa

Mudança de Fluxo de Controle

Expressões Booleanas

Comandos Condicionais em Cif-elseswitchOperador Condicional

Introdução à Programação

Funções e Escopo de Variáveis

Funções em C

2

FunçõesFunções constituem programas em C

33

Tópicos da Aula

Hoje vamos detalhar funções em C

Importância

Escrevendo funções

Comando return

Passagem de argumentos por valor

Execução de uma função

Depois iremos discutir o escopo de variáveis

Conceito de escopo

Diferentes tipos de variáveis

Local, global e estática

Importância de Funções para

Desenvolver Programas

Desenvolvimento de uma solução se torna mais fácil

quando quebramos esta solução em módulos

gerenciáveis

Quando estamos programando, podemos desenvolver

módulos separados, onde cada um é responsável por

uma certa parte da solução

Programação Modular

Em C, um módulo pode representado por uma função

ou um grupo de funções logicamente relacionadas

4

5

Funções em C

Permitem a construção de programas constituídos demódulos independentes

São trechos de programas que podem ser ativados

Pelo programa principal (função main)

Por outra função

Relembrando...

Uma função é um conjunto de instruções para realizar uma ou mais tarefas que são agrupadas em

uma mesma unidade e que pode ser referenciada por um nome único

6

Estrutura de uma Função

int multiplicacao (int p1, int p2)

{

int produto;

produto = p1 * p2;

return produto;

}

Lista de parâmetros

(pode ser vazia)

Tipo retornado Nome

Corpo da

função

7

Omitindo o Tipo Retornado

multiplicacao (int p1, int p2)

{

int produto;

produto = p1 * p2;

return produto;

}

Em C, caso o tipo retornado seja omitido, o compilador assume que a função retorna o

tipo int

8

Omitindo o Tipo Retornado

multiplicacaoReal (float p1, float p2)

{

float produto;

produto = p1 * p2;

return produto;

}Não vai retornar uma

multiplicação de números reais!

Evitar omitir tipo retornado dificulta entendimento

9

Retorno de uma Função

Uma função em C pode retornar algum valor, assim

como acontece com funções matemáticas

Inteiro, real, caractere, etc

Porém, uma função não precisa necessariamente

retornar um valor

Quando não retorna um valor, dizemos que a função é do

tipo void

Funções que Retornam Valores

int segundos(int hora, int min) {return 60 *(min + hora*60);

}

double porcetagem(double val,double tx) { double valor = val*tx/100;return valor;

}

Funções que retornam valores comoresultado usam o comando return

10

Comando return

Uma função que não tem valor para retornar

tem o tipo de retorno void

Neste caso, o uso do comando return é opcional

return expressão

11

Para executar este comando o computador:

avalia expressão, obtendo um valor

devolve este valor como resultado, terminando a

execução da função no qual ele se encontra

void imprimir(int valor) {printf(“%d”,valor);return;

}Pode ser omitido

Considerações sobre Funções

Uma definição de uma função especifica a

seqüência de instruções que serão

executadas (fluxo de controle) quando esta

função for chamada (invocada)

Quando uma função é chamada, o fluxo de

controle do programa pula para a função e

executa o código que está nela

12

Considerações sobre Funções

Quando a função termina de ser executada,

o fluxo de controle do programa volta para a

instrução logo após a chamada da função

Uma chamada a uma função pode ou não

retornar um valor

Depende da definição da função

13

minhaFuncao();

minhaFuncaomain

Programa

Fluxo de Controle de uma Função

14

minhaFuncao outraFuncao

outraFuncao();

Programa

minhaFuncao();

main

Fluxo de Controle de uma Função

15

Parâmetros e argumentos

Os parâmetros são nomes que aparecem na

declaração de uma função

16

Os argumentos são expressões que

aparecem na expressão de invocação da

função

imprimir(10);

void imprimir(int valor)

Parâmetros de uma Função

Quando uma função é chamada por outra, os

argumentos da chamada são copiados para os

parâmetros (formais) presentes no assinatura da

função

17

float media (float num1, float num2)

{

float result = (num1 + num2)/2;

return result;

}

int main() {

float valor = media (30,40);

}

Passagem de Argumentos

C permite a passagem de argumento por valor: o valor da expressão é

avaliado primeiro e depois passado para a função chamada

18

Passagem de Argumento por Valor

void incrementa(int x) {x = x + 1;printf(“%d”,x);

}

int main() {

int y = 1;

printf(“%d”,y);

incrementa(y);

printf(“%d”,y);

...

}

não alterao valor de

y

saída:1

saída:2

saída:1

19

Comunicação de dados entre funções é feita através de passagem

de argumentos

20

Ordem de Definição das Funções

Antes da função main

OU

Depois da função main desde que se declaresua assinatura antes da main

Onde uma função deve ser definida?

21

Definindo a Função Antes da main

#include <stdio.h>

int segundos(int hora, int min) {return 60 *(min + hora*60);

}

int main() {

int minutos,hora, seg ;

printf(“Digite a hora:minutos\n”);

scanf (“%d:%d”,&hora,&minutos) ;

seg = segundos(hora,minutos);

printf(“\n%d:%d tem %d segundos.”,hora,minutos,seg);

return 0 ;

}

Definição antes da main

#include <stdio.h>

int segundos(int hora, int min);

int main() {

int minutos,hora, seg ;

printf(“Digite a hora:minutos\n”);

scanf (“%d:%d”,&hora,&minutos) ;

seg = segundos(hora,minutos);

printf(“\n%d:%d tem %d segundos.”,hora,minutos,seg);

return 0 ;

}

int segundos(int hora, int min) {return 60 *(min + horas*60);

}

22

Definindo a Função Depois da main

Definição depois da main

Deve-se declarar antes a assinatura da função – Modo

alternativoint segundos (int,int)

Escopo de Variáveis

O escopo de uma variável define a área do programa

onde esta variável pode ser referenciada

Variáveis que são declaradas fora das funções

(inclusive da função main), podem ser referenciadas

por todas as funções do programa

São chamadas de variáveis globais

Variáveis que são declaradas dentro de uma função

só podem ser referenciadas dentro desta função

São chamadas de variáveis locais

23

Escopo de Variáveis

Pode existir uma variável local a uma função com

mesmo nome e tipo de uma variável global, neste caso

ao se referir ao nome da variável dentro da função,

estar-se-á acessando a variável local

24

#include <stdio.h>

int numero = 10;

int main(){

int numero = 4;

printf(“%d”,numero);}

Declaração de

variável local

Referência à

variável local

Será impresso o valor 4

25

Variáveis Globais

Podem ser usadas em qualquer parte do

código

Se não inicializadas explicitamente, C

inicializa com valores padrões

0 para tipos numéricos

Existem durante todo o ciclo de vida do

programa (ocupando memória)

26

Variáveis Globais

Normalmente são declaradas no início do

programa ou em arquivos do tipo header (*.h)

São declaradas uma única vez

Deve-se evitar o uso abusivo delas

Pode penalizar o consumo de memória

Pode dificultar a legibilidade do código

27

Uso de Variáveis Globais

#include <stdio.h>

int minutos,hora;

int segundos() {return 60 *(minutos + horas*60);

}

int main() {

int seg ;

printf(“Digite a hora:minutos\n”);

scanf (“%d:%d”,&hora,&minutos) ;

seg = segundos();

printf(“\n%d:%d tem %d segundos.”,hora,minutos,seg);

return 0 ;

}

Todas as funções “enxergam” as

variáveis minutose hora

Comunicação de dados entre funções agora é

feita através de variáveis globais

Variáveis Locais

São declaradas dentro de uma função

Só existem durante a execução da função

Não ocupam a memória durante toda a execução do

programa

Não são inicializadas automaticamente

Só são visíveis dentro da função

Outras funções não podem referenciá-las

Têm a mesma capacidade de armazenamento que as variáveis globais mas

28

Variáveis Locais

Caso uma função declare uma variável local,esta é criada a cada execução da função

29

int funcao( )

{

int a= 100;

a = a + 23;

return a;

}

Sempre retorna 123

Modificador static

Caso a variável local venha com o modificadorstatic, a variável é criada uma única vez

Armazena seu valor em várias execuções da mesmafunção

Evita uso de variáveis globais

30

int funcao( )

{

static int a= 100;

a = a + 23;

return a;

}

Inicializa apenas uma vez

1ª vez que função for chamada retorna 123

2ª vez retorna 146

31

Armazenamento das Variáveis

Código do programa

Variáveis Globais e Estáticas

Memória livre

Pilha de execução de funções

Onde são armazenados na memória os diferentes tipos de variáveis?

Pilha de execução armazena variáveis locais das funções

Quando acaba a execução da

função, espaço ocupado pelas suas

variáveis é liberado

32

Pilha de Execução de Funções

#include <stdio.h>

int segundos(int hora, int min) {int seg;seg = 60 *(min + hora*60);return seg;

}

int main() {

int minutos = 30,hora = 1, seg ;

seg = segundos(hora,minutos);

printf(“\n%d:%d tem %d segundos.”,hora,minutos,seg);

return 0 ;

}

Considere o seguinte código:

33

1 – Início do programa:pilha vazia

2 – Declaração de variáveis: minutos,hora,seg

3 – Chamada da função:cópia do argumento

4 – Declaração da variávellocal: seg

5 – Final da avaliação da expressão

6 – Retorno da função:desempilha

Pilha de Execução de Funções

<mainminutos

hora301

seg -

<main <main30

1-

minutoshoraseg <segundos

min

hora 130

<main301-

minutoshoraseg <segundos

min

hora 130

-seg 4500

<main301-

minutoshoraseg <segundos

min

hora 130

seg

minutoshora

301

seg 4500

<main

34

Macros Semelhantes a Funções

Pré-processador e Macros

Diretiva de Definição com Parâmetros

São chamadas de Macros

Exemplo

define MAX(a,b) ((a) > (b) ? (a):(b))

int main() {

float v = 4.5 ;

float c = MAX(v,3.0) ;

O compilador verá:

int main() {

float v = 4.5 ;

float c = ((v)>(3.0)?(v):(3.0)) ;

35

Pré-processador e Macros

Macros definidas incorretamente

Uso de macros deve ser feito com cautela!

#define DIF(a,b) a - b

int main(){

printf(“%d”,4 * DIF(5,3));

return 0 ;

}

Saída é 17 e não 8

#define PROD(a,b)( a * b )

int main(){

printf(“%d”,PROD(3 + 4,2));

return 0;

}

Saída é 11 e não 14

Macros Semelhantes a Funções

3636

Resumindo ...

Funções

Importância

Escrevendo funções

Comando return

Passagem de argumentos por valor

Execução de uma função

Escopo de variáveis

Conceito de escopo

Diferentes tipos de variáveis

Local, global, estática

Introdução à Programação

Estruturas de Repetição

Repetição de Comandos…

int somatorio(int n) {

int soma = 0;

int i = 0;

soma = soma + i;

i++;

soma = soma + i;

i++;

soma = soma + i;

...

}

Faz esta seqüência de comandos n vezes

n

i

i0

E haja copy&paste!

2

33

Tópicos da Aula

Hoje, aprenderemos a usar estruturas derepetição para programas mais complexos

Necessidade de estruturas de repetição

Apresentação do conceito de laço (loop)

O comando for

O comando while

O comando do-while

Diferenças entre os comandos de repetição

Veremos também, como podemos alterar o

fluxo de laços

Comandos break e continue

44

Necessidade de Estruturas de Repetição

Na resolução de problemas em programação,

freqüentemente, precisamos repetir uma mesma

seqüência de comandos várias vezes

Na maioria dos casos, não sabemos de antemão

quantas vezes a seqüência de comandos será repetida

A linguagem de programação deve fornecer uma

estrutura (comando) que permita a execução repetida

de mesma seqüência de comandos

Evita esforço do programador

Permite que o programador não tenha que saber quantas

vezes o comando será executado

55

Estruturas de Repetição

Permite repetir diversas vezes um comando ou

seqüência de comandos

Cada repetição de um comando ou seqüência de comandos é

denominada de iteraçãoSão geralmente conhecidos como loops(laços)

Da mesma forma que comandos condicionais, são

controladas por expressões booleanas

C oferece 3 tipos de estruturas(comandos) de

repetição:O laço for

O laço while

O laço do-while

O Comando for

for (i = 0; i < valor; i = i+1)

corpo

Executa corpo um número específico de vezes:

valor vezes

Neste exemplo, na primeira execução de corpo, o

valor de i é 0

O valor de i é incrementado após cada execução de

corpo

Variável i deve ser declarada antes de se utilizar o

comando for

Variável de controle

6

A Forma Geral do Comando for

inicialização e incremento podem ser

praticamente quaisquer comandos

condição pode ser qualquer expressão booleana

inicialização geralmente inicializa a variável

de controle do for

incremento geralmente incrementa a variável for

for(inicialização;condição;incremento)

corpo

7

Fluxo de Controle do Laço for

comando

true

condiçãoavaliada

incremento

inicialização

false

8

for ( inicialização ; condição ; incremento )

comando;

Examinando o Comando for

A inicialização

é executada uma só vez

antes do laço começar

O comando é

executado enquantocondição for verdadeira

O incremento é executado ao fim de

cada iteração

9

Cabeçalho do for

Entendendo o Comando for

int somatorio(int n) {

int valor;

int soma = 0;

for (valor = 0; valor <= n; valor++)

soma = soma + valor;

return soma;

}

Variável valor é inicializada com 0

A cada iteração, valor é incrementado em 1

10

Comando será realizado enquanto valor for menor ou igual a n

int somatorio(int n) {

int valor;

int soma = 0;

for (valor = 0; valor <= n; valor++)

soma = soma + valor;

return soma;

}

Entendendo o Comando for

Se n for menor do que0, nãose executa o corpo do for

11

É executado depois do for

Entendendo o Comando for

int somatorio(int n) {

int soma = 0;

int valor;

for (valor = 0; valor <= n; valor++){

soma = soma + valor;

printf(“Soma Parcial:%d\n”,soma);

}

printf(“Soma Total:%d”,soma);

return soma;

}

Corpo do for pode ser composto por bloco de comandos

12

Modificando o Incremento do for

int somatorio(int n) {

int soma = 0;

int valor;

for (valor = n; valor>= 0; valor--){

soma = soma + valor;

printf(“Soma Parcial:%d\n”,soma);

}

printf(“Soma Total:%d”,soma);

return soma;

}

13

valor agora é decrementado

Modificando o Incremento do for

int somatorioPares(int n) {

int soma = 0;

int valor;

for (valor = 0; valor <= n; valor = valor + 2){

soma = soma + valor;

printf(“Soma Parcial:%d\n”,soma);

}

printf(“Soma Total:%d”,soma)

return soma;

}

14

valor agora é incrementado em 2

Pode-se colocar qualquer tipo de expressão na

parte de incremento do comando for

Variações do Comando for

Cada expressão no cabeçalho de um laço for loop

é opcional

Se a inicialização é omitida, nenhuma inicialização é

feita

Se a condição é omitida, a condição é considerada

sempre verdadeira e o laço continua para sempre

(laço infinito)

Se o incremento é omitido, nenhuma operação é

realizada ao final da iteração do laço

15

O Comando for sem Condição, etc.

for(;;valor++)

corpo

16

for(;valor < n; valor++)

corpo

for(;;)

corpo

Repetição infinita: cuidado!

17

Mais Variações do Comando for

Teste condicional não precisa ser baseado na variável

de controle

#include <stdio.h>

#include <conio.h>

int main ( ) {

int i ;

/* atribui um valor inicial a ch*/

char ch = „a‟ ;

for(i = 0; ch != „q‟;i++){

printf (“\nPasso:%d”,i) ;

ch = getche() ;

}

}

condição não é

baseada na

variável de

controle

18

Mais Variações do Comando for

Parte de incremento não precisa incrementar variável

de controle

Comando for pode vir sem corpo

#include <stdio.h>

#include <conio.h>

int main ( ) {

char ch;

for(ch = getche(); ch!=„q‟;ch = getche());

printf (“\nValor q encontrado”) ;

} Incremento

pode ser outro

tipo de

expressão

Não tem corpo

O comando while

Executa corpo várias vezes até que a

avaliação da expressão retorne falso

A condição é avaliada de novo após cadaexecução de corpo

Não executa corpo nenhuma vez, se de

início a avaliação da condição retorna falso

while (condição)

corpo

19

Fluxo de Controle do Laço while

comando

true

condiçãoavaliada

false

20

int somatorio(int n) {

int soma = 0;

int valor = 0;

while ( valor <= n ){

soma = soma + valor;

valor++;

}

return soma;

}

Entendendo o comando while

Se n for negativo, não seexecuta o corpo do while

21

É executado quando o while termina, quando a condição for falsa

int somatorio(int n) {

int soma = 0;

int valor = 0;

while ( valor <= n ){

soma = soma + valor;

valor++;

}

return soma;

}

Entendendo o comando while

Inicialização da variável de controle é feita fora do laço while

22

Incremento da variável de controle é feita no corpo do laço while

int somatorio(int n) {

int soma = 0;

int valor = 0;

while ( valor <= n ){

soma = soma + valor;

}

return soma;

}

Laço Infinito com o Comando while

23

Se valor não é incrementado, este comando será executado infinitas vezes

O Comando for e o Comando while

for(inicialização;condição;incremento)

corpo

inicialização;

while(condição) {

corpo;

incremento;

}

equivale a ...

24

O Comando for e o Comando while

for(;;)

corpo

while(1) {

corpo;

}

equivale a ...

25

do {

corpo

} while(condição)

O Comando do-while

Executa corpo, pelo menos uma vez, até

que a avaliação da condição retorne falso

A condição é avaliada de novo após cadaexecução de corpo

26

true

condição

avaliada

comando

false

Fluxo de Controle do Laço do-while

27

int somatorio(int n) {

int soma = 0;

int valor = n;

do {

soma = soma + valor;

valor--;

} while ( valor >= 0 )

return soma;

}

Entendendo o comando do-while

Se n for negativo, o corpodo do-while é executado pelo menos uma vez

28

É executado quando o do-while termina, quando a condição for falsa

Comportamento alterado: cuidado!

do {

corpo

} while(condição)

Os Comandos do-while e while

corpo;

while(condição)

corpo;

Equivalente a ...

29

3030

Laços Aninhados

Laços podem ser aninhados da mesma forma

que comandos condicionais

O corpo de um laço pode conter outro laço

Para cada iteração do laço externo, o laço

interno é completamente executado

3131

Laços Aninhadosint somatorioDoSomatorio(int n, int vezes) {

int soma = 0, somatorio =0;

int valExt;

for (valExt = 0; valExt < vezes; valExt++ ){

int valInt = 0;

while (valInt <= n) {

soma = soma + valInt;

valInt++;

}

somatorio = somatorio + soma;

}

return somatorio;

} A cada iteração do for,o laço while é executado

3232

Considerações sobre Laços

Os 3 tipos de laços são funcionalmente

equivalentes

Portanto podem ser usados indiscriminadamente

Os laços for e while são executados 0 ou

muitas vezes

O laço do-while é executado 1 ou muitas

vezes

33

O Comando breakForma Geral do comando break

Tem dois usos distintos

Para forçar o término de um laço de repetição (do-while, for

ou while)

Para terminar um case do comando switch

Quando o comando break é encontrado dentro de

um laço de repetição:

instrução é imediatamente finalizada

próxima instrução após a estrutura de repetição é executada

Deve ser usado com cautela

Reduz legibilidade

Pode levar a erros de lógica

break;

O Comando break

int somatorio(int n) {

int soma = 0;

int valor;

for (valor = 0; ; valor++){

soma = soma + valor;

if (valor == n)

break;

printf(“Soma Parcial:%d\n”,soma);

}

printf(“Soma Total:%d”,soma)

return soma;

}

Este comando não será executado quando valor = = n

34

O Comando continue

Termina a execução da iteração atual de umloop (for,while,do-while) e volta ao

começo deste loop

Todos os comandos que seriam executadosapós o continue são descartados

continue

Forma Geral do comando continue

35

36

Comando de Desvio - continuePara os comandos while e do-while, ocontinue causa:

a realização imediata do teste da condição

correspondente

continuidade do processo de repetição dependendo

do resultado do teste

Para o comando for , o continue causa:

incremento da variável de controle do laço de

repetição

execução do teste para verificação da condição

continuidade do processo de repetição dependendo

do resultado do teste

O Comando continue

void imprimeNumerosAteCinco() {

int valor;

for (valor = 0; valor <= 5; valor++){

if (valor == 4)

continue;

printf(“%d “,valor);

}

}

Controle pula para o incremento e este comando não será executado quando valor = = 4

37

A saída desta função será: 0 1 2 3 5

O Comando continue

void imprimeNumerosAteCinco() {

int valor = 0;

while (valor <= 5){

if (valor == 4)

continue;

printf(“%d”,valor);

valor++;

}

}

Controle pula para o teste e função tem execução infinita quando valor = = 4

38

A saída desta função será: 0 1 2 3 ...

laço infinito

3939

Resumindo ...

Estruturas de RepetiçãoNecessidade de estruturas de repetição

Conceito de laço (loop)

Tipos de laço em C

O comando for

O comando while

O comando do-while

Laços Aninhados

Diferenças entre os comandos de repetição

Comandos para alterar o fluxo de laços

break e continue

Introdução à Programação

Recursão

Recursão

decoraçãoSubstantivo feminino. 1.Ato ou efeito de decorar

Recursão

2

decorarVerbo transitivo direto. 1.Guarnecer com adorno(s); dispor formas e cores em; ornamentar, embelezar;2.Realçar, avivar, adornar;

Fonte: Dicionário Aurélio

33

Tópicos da Aula

Hoje, aprenderemos a usar uma técnica deprogramação chamada de recursão

Conceito de Recursão

Definições Recursivas

Casos Base e Geral

Programando Recursivamente

Recursão X Laço

44

Recursão

Uma definição recursiva de um conceito consiste emutilizar o próprio conceito na definição

Ex: fat(n) = n * fat(n-1)

Definições recursivas em linguagem natural não são,geralmente, muito úteis

Contudo, em outras situações, uma definição recursivapode ser a mais apropriada para explicar um conceito

Recursão é uma técnica de programação que podefornecer soluções elegantes para determinadosproblemas

Mas, antes, deve-se aprender a pensar recursivamente!

55

Definições Recursivas: Lista

Considere a seguinte lista de números

24, 88, 40, 37

Podemos definir uma lista de números como:

Uma LISTA é um: número

ou um: número vírgula LISTA

Resumindo: uma LISTA é definida ou como um único número, ou como um número seguido de

uma vírgula seguida de uma LISTA

Utilizamos LISTA para sua própria definição

66

Definições Recursivas: Lista

88, 40, 37

A parte recursiva da definição de LISTA é utilizada diversas vezes, até que se possa

utilizar a parte não recursiva

24

37

,

40, 3788,

3740,

número vírgula LISTA

Parte recursiva da definição de

LISTA

Parte não recursiva da definição de

LISTA

77

Definições Recursivas: Fatorial

Fatorial de um número N (N!), que é inteiro epositivo, é definido como a multiplicação detodos os inteiros compreendidos entre 1 e N(inclusive)

Podemos definir fatorial recursivamente:

0! = 1

N! = N x (N-1)!

Mais uma vez, utilizamos fatorial para sua própria definição

5!

5 * 4!

4 * 3!

3 * 2!

2 * 1!

1 * 0!

1

Definições Recursivas: Fatorial

2

6

24

120

1

8

99

Caso Base e Caso Geral

Toda definição recursiva deve ter uma parterecursiva e outra não recursiva

Se não houver a parte não recursiva, ocaminho recursivo nunca termina

Gera uma recursão infinita

Similar a um laço infinito

Denomina-se de caso base, a parte nãorecursiva da definição, enquanto o caso geralé a parte recursiva

Uma função em C pode chamar ela mesmaFunção recursiva

O código de uma função recursiva deve tratar o caso

base e o caso geral

Cada chamada da função cria novos parâmetros e

variáveis locaisCria-se uma nova instância da função

Como em qualquer chamada de função, assim que a

função termina sua execução, o controle retorna para a

função que a chamou (que neste caso, é outra

instância da mesma função)

Programação Recursiva

1111

Exemplo de Função Recursiva:

Fatorial

int fatorial(int n) {

int resultado;

if (n == 0)

resultado = 1;

else

resultado = n * fatorial(n - 1);

return resultado;

} Caso Geral

Caso Base

1212

Chamando Função Recursiva: Fatorial

int main() {

int fat = fatorial(2);

printf(“Fatorial de 2 é %d”,fat);

return 0;

}

13

1 – Chamada da função:cópia do argumento

4 – Retorno da 3a chamada:cálculo da expressão

Pilha de Execução de Funções

Recursivas

<main-2

-

fat

resultadon <fatorial

<main-2

-

fat

resultadon <fatorial

<fatorial’

resultado

n 1-

<main-2

-

fat

resultadon <fatorial

<fatorial’

resultado

n 1-

<fatorial’’

resultadon 0

1

<main-2

-

fat

resultadon <fatorial

<fatorial’

resultado

n 11

<main-2

2

fat

resultadon <fatorial

<main2fat

2 – Chamada recursiva:cópia do argumento

3 – Chamada recursiva:cálculo da expressão

5 – Retorno da 2a chamada:cálculo da expressão

5 – Retorno da 1a chamada

14

Usando Recursividade para resolver

problemas

Problema: Torre de HanoiDeve-se transportar todos os discos da primeira estaca até

a última obedecendo as seguintes regras:

1. Só pode ser deslocado um disco por vez (o do topo de uma estaca)

2. Em nenhum momento um disco maior pode estar sobre um menor

15

Resolvendo Recursividade o Problema

da Torre de Hanoi

Solução: Torre de Hanoi1. Mover n – 1 discos da estaca Origem para a Temporária2. Mover o disco n da estaca Origem para a Destino3. Mover n – 1 discos da estaca Temporária para a Destino

1616

Torre de Hanoi

void mover(int n, char orig, char temp, char dest) {

if (n == 1)

printf("Mova o disco 1 da estaca %c para a estaca

%c\n",orig,dest);

else {

mover (n-1,orig,dest,temp);

printf("Mova o disco %d da estaca %c para a estaca

%c\n",n,orig,dest);

mover(n-1,temp,orig,dest);

}

}

Caso Geral

Caso Base

1717

Pontos Chave de uma Solução

Recursiva

Definir o problema em termos recursivos

Definir o caso geral

Determinar o caso base

Definir uma solução de modo que a cada

chamada recursiva, podemos nos aproximar do

caso base

1818

Recursão x Laço

Não é porque existe uma solução recursiva, que

sempre devemos usá-la

Soluções iterativas (com laço) são geralmente mais

eficientes

Soluções recursivas geralmente demandam mais poder de

processamento e memória

Porém, soluções utilizando recursão podem ser mais

elegantes e mais compreensíveis que soluções

iterativas equivalentes

Programador deve analisar caso a caso qual é a melhor

técnica a aplicar para a resolução do problema

1919

Resumindo ...

Recursão

Conceito

Exemplos de definições recursivas

Casos Base e Geral

Programando Recursivamente

Recursão X Laço

Introdução à Programação

Armazenamento de Grande Quantidade de Informação –

Usando Vetores

Armazenando Grande Quantidade de

Informação

Como armazenar tanta

informação?

2

Vetores !

33

Tópicos da Aula

Hoje, aprenderemos como armazenar grandequantidade de informação

Necessidade de armazenamento

Utilização de muitas variaveis

Manipulação incremental das informações

Aprenderemos a utilizar vetoresConceito

Criação

Inicialização

Acesso

Limites de um vetor

Passagem de vetores como argumentos

Vetores bidimensionais (matrizes)

44

Necessidade de Armazenamento

Sistemas armazenam informações para que possamposteriormente acessá-las e manipulá-las

Maioria dos sistemas requer o armazenamento degrande quantidade de valores do mesmo tipo

Mesmas operações para manipular estes valores

Ex: processamento de imagens

Milhões de imagens e cada imagem composta de milhõesde pixels

No desenvolvimento de um programa, devemos definirestruturas e mecanismos para armazenar e manipularesta grande quantidade de informação

5

Calculando a Média Aritmética

n

x

m

n

i

i 1

A média aritmética de um conjunto de valores é

dada pela seguinte expressão

66

Como Armazenar Grande Quantidade

de Informações?

Até agora, vimos construções de programaçãoque permitem guardar uma única informaçãode cada vez

Variável e constante

Neste caso, a solução seria criar uma variávelpara cada valor que desejamos armazenar

Não é uma boa solução, porém hoje veremos comopodemos trabalhar com esta alternativa

77

Tentativa com Muitas Variáveis

#include <stdio.h>

int main() {

float numero1, numero2;

float media;

printf(“Digite 2 numeros:\n”);

scanf(“%f %f”, &numero1,&numero2);

media = (numero1 + numero2)/2;

printf(“\nA media eh %f\n”,media);

return 0;

}

2 variáveis para armazenar números

Limitação: Só permite média de 2 números

88

Tentativa com Muitas Variáveis

#include <stdio.h>

int main() {

float numero1, numero2, numero3;

float media;

printf(“Digite 3 numeros:\n”);

scanf(“%f %f %f”, &numero1,&numero2,&numero3);

media = (numero1 + numero2 + numero3)/3;

printf(“\nA media eh %f\n”,media);

return 0;

}Trecho de código depende da quantidade de números

suportados

3 variáveis para armazenar números

Limitação: Só permite média de 3 números

99

Problemas com Uso de Muitas

Variáveis

Dificuldade de lidar com mudança do númerode informações que devem ser armazenados

Acrescentar ou remover variável

Muitas vezes requer modificações em várias linhasde código

#include <stdio.h>

int main() {

int qtdNumeros;

int contador = 0;

float numero;

float media = 0.0;

printf(“Digite quantidade de numeros:\n”);

scanf(“%d”, &qtdNumeros);

while (contador < qtdNumeros) {

scanf(“%f”,&numero);

media = media + numero;

contador++;

}

media = media/qtdNumeros;

printf(“\nA media eh %f\n”,media);

return 0;

}

1010

Outra Estratégia: Manipulação

Incremental da Informação

Variável que guarda a quantidade de números

entrados

Permite média de quantidade variada de números

Cada número entrado é armazenado na variável numero

#include <stdio.h>

int main() {

int qtdNumeros;

int contador = 0;

float numero;

float media = 0.0;

printf(“Digite quantidade de numeros:\n”);

scanf(“%d”, &qtdNumeros);

while (contador < qtdNumeros) {

scanf(“%f”,&numero);

media = media + numero;

contador++;

}

media = media/qtdNumeros;

printf(“\nA media eh %f\n”, media);

return 0;

}

1111

Outra Estratégia: Manipulação

Incremental da Informação

Código independe da quantidadede números que serão utilizados

na média

Contudo perdemos informação sobre cada número digitado!

1212

Problemas com Manipulação

Incremental de Informação

Perda de informação sobre os valoresindividuais que foram armazenados

No exemplo, sabemos apenas qual foi o somatóriodos valores inseridos e não quais valores foraminseridos

Limita a utilização da informação armazenadaNo exemplo, se quiséssemos utilizar os mesmosdados para uma operação diferente (ex:multiplicação), não conseguiríamos

1313

Necessidade de Vetores

Precisamos de alguma estrutura dearmazenamento que:

armazene vários valores de um determinado tipo

permita que os valores sejam acessados de formasimples

9.0 7.5 6.3 8.8 9.8 10.0 Vetores !

Vetores

Vetor ou array é um tipo de dado utilizado para

representar um conjunto de valores

homogêneos utilizando um único nome

Define uma estrutura que armazena valores de

um determinado tipo

Um vetor é declarado usando

tipo nome[tamanho];

No ato da declaração, devemos especificar o

tamanho (dimensão) do vetor

Vetores têm tamanho fixo depois de criados

14

Vetores

0 1 2 3 4 5 6 7 8 9

notas

notas[0]notas[1]...notas[9]

float notas[10];

Índices do vetor

Cada elemento do vetor é referenciado através doíndice do vetor

Índice começa em 0 e vai até tamanho -1

4 9 8 6 3 7 8 2 9 5

Acessando Elementos de Vetores

Um determinado elemento do vetor pode ser

acessado usando o nome do vetor seguido do índice

do elemento entre colchetes ([ ])

A expressão notas[2] se refere ao valor 8 (3º

elemento do array)

16

A expressão notas[2] representa um local para

armazenar um inteiro e pode ser utilizada da mesmaforma que uma variável do tipo inteiro

notas

notas[2]

10 9 8 7

#include <stdio.h>

int main() {

int qtdNumeros,contador = 0;

float numeros[2000];

float media = 0.0;

do{

printf(“Quantidade de numeros? (< 2000):\n”);

scanf(“%d”, &qtdNumeros);

} while (qtdNumeros <= 0 || qtdNumeros > 2000);

while (contador < qtdNumeros) {

scanf(“%f”,&numeros[contador]);

media = media + numeros[contador];

contador++;

}

media = media/qtdNumeros;

printf(“\nA media eh %f\n”,media);

return 0;

} 17

Calculando a Média com Vetores

Vetor que guarda números entrados

Números podem ser acessados

individualmente

18

int v[10];

v 104

144 É reservado um espaço de memória

contínuo

Acessa o primeiro elemento de vv[0]

Acessa o último elemento de vv[9]

Vetores na Memória

Aloca espaço para 10 valores

inteiros, referenciados por v

v [10]Mas: Está errado !

Checando os Limites dos Vetores

Ao utilizar o índice para referenciar um elemento do

vetor, este índice deve permitir o acesso a um

elemento válido ( em um endereço da memória

alocado para o vetor)

Índice deve variar de 0 a tamanho -1

C não avisa quando o limite de um vetor é excedido!

Se o programador transpuser o fim do vetor durante a

operação de atribuição, os valores serão armazenados emoutros dados ou mesmo no código do próprio programa

19

O programador tem a responsabilidade de verificar o limite do vetor!

Checando os Limites dos Vetores

São comuns, erros de programação no uso

de vetores dentro de laços

Deve-se prestar atenção na parte de teste do laço

20

int main() {

int pares[20];

int i,somaPares = 0;

for (i = 0; i <= 20; i++) {

pares[i] = 2 * i ;

somaPares = somaPares + pares[i];

}

...

}Teste deveria ser i < 20

Por causa do teste errado, esta linha gerará um erro

21

Inicializadores de vetores são representados da

seguinte forma: {expressões},onde

expressões representam expressões de tipos

válidos separadas por vírgulas

Vetores podem ser inicializados na declaração

Inicializando Vetores

int v[5] = {5,10,15,20,25} ;

ou simplesmente:

int v[]= {5,10,15,20,25};

Vetores só podem ser inicializados no ato da declaração!

Opções de Inicialização de Vetores

22

No caso de utilizar inicializadores de vetores,note que:

Quando não especificado o tamanho, o compiladoraloca espaço suficiente para armazenar todos osvalores contidos na inicialização

Quando o tamanho for especificado e houver a listade inicialização

Se há menos inicializadores que o tamanhoespecificado, os outros serão zero

Mais inicializadores que o necessário implica emum warning

Quando o vetor não for inicializado, o tamanho deve ser especificado na

declaração !

Passando Vetores como Argumentos

de FunçõesUm vetor pode ser passado como argumentopara uma função

Parâmetro da função deve ser do tipo tipo[]

Ao passar um vetor para uma funçãopodemos modificar o conteúdo deste vetordentro da função

Passa-se na verdade o endereço do vetor namemória (veremos em breve!)Modificar um elemento do vetor ou incluir um novoelemento

Podemos passar também um elemento emparticular de um vetor para uma função

Parâmetro deve ser to tipo tipo

23

#include <stdio.h>

float media(int n, float num[]){

int i;

float s = 0.0;

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

s = s + num[i] ;

return s/n ;

}

int main(){

float numeros[10] ;

float med;

int i ;

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

scanf (“%f”, &numeros[i]) ;

med = media(10, numeros ) ;

...

}24

Passando Vetores como Argumentos

para Funções

Parâmetro do tipo vetor de float

Passando o vetor numeroscomo argumento

#include <stdio.h>

void incrementar(int n,float num[], float valor){

int i;

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

num[i] = num[i] + valor ;

}

int main(){

float numeros[10] ;

int i ;

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

scanf (“%f”, &numeros[i]) ;

incrementar( 10,numeros,1.5) ;

...

}

25

Passando Vetores como Argumentos

para Funções

Modificando o conteúdo do vetor passado como

argumento

#include <stdio.h>

int reprovado(float nota, float media){

if ( nota < media)

return 1;

else

return 0;

}

int main(){

float notas[] = {6.5,5.0,7.5,9.4,3.8};

int i ;

for(i = 0; i < 5; i++){

if (reprovado(notas[i],7.0) == 1)

printf(“Aluno %d: REPROVADO\n”,i);

else

printf(“Aluno %d: aprovado\n”,i);

}

...

}26

Passando Elementos de Vetores como

Argumentos

Passando um único elemento do vetor para

uma função

27

Um vetor unidimensional armazena uma lista deelementos

Um vetor bidimensional pode ser visto como umamatriz com linhas e colunas

Em C, um vetor bidimensional é um vetor de vetores

Vetores Bidimensionais

int matriz[9][6];

uma

dimensãoduas

dimensões

28

Inicializando Matrizes

A inicialização de uma matriz também pode ser

feita das seguintes formas:

float mat[4][3]={{5.0,10.0,15.0},{20.0,25.0,30.0} ,

{35.0,40.0,45.0},{50.0,55.0,60.0}}

float mat[4][3] = {5.0, 10.0, 15.0, 20.0, 25.0, 30.0,

35.0, 40.0,45.0, 50.0,55.0,60.0}

float mat [][3]= {5.0, 10.0, 15.0, 20.0, 25.0, 30.0,

35.0,40.0,45.0,50.0,55.0,60.0}

Deve ser passada a segunda dimensão

Percorrendo Matrizes

int main() {

int i,j;

int matriz[2][2]={{1,2},{5,6}};

for (i=0;i<2;i++){

for (j=0;j<2;j++){

printf("%d ",matriz[i][j]);

}

printf("\n");

}

return 0;

}Laços aninhados para

percorrer matriz

Saída: 1 2

5 6

Passando Matrizes como Argumentos

de Funções

Uma matriz pode ser passada como

argumento para uma função

Parâmetro da função deve ser do tipo

tipo[][tamanho colunas]

A linguagem C exige que a segundadimensão seja especificada

30

Passando Matrizes como Argumentos

void imprimeMatriz(int linhas, int mat[][2]) {

int i,j;

for (i=0; i < linhas; i++){

for (j=0;j < 2; j++){

printf("%d ",mat[i][j]);

}

printf("\n");

}

}

Deve ser especificada pelo menos a segunda dimensão

3232

Resumindo ...

Armazenamento de grande quantidade deinformação

Necessidade de armazenamento

Problemas

Utilização de muitas variaveis

Manipulação incremental das informações

VetoresConceito

Declaração

Inicialização

Acesso

Limites de um vetor

Passagem de vetores como parâmetros

Vetores bidimensionais (matrizes)

Introdução a Programação

Strings (Vetor de Caracteres)

2

Tópicos da Aula

Hoje aprenderemos a manipular vetores decaracteres (Strings)

Caracteres em CEntrada/Saída de caracteresFunções que manipulam caracteresVetores de caracteres (Strings)

InicializaçãoStrings constantesEntrada/Saída de StringsFunções de Manipulação de Strings

3

Caracteres

Em C, o tipo char :é usado para representar caracterespode armazenar valores inteiros (em 1 byte),representando assim, 256 valores distintosUma constante char é escrita entre aspas simples

char letraA = „A‟;

char letraC;

letraC = „C‟;

printf ( “ %c %c ”, letraA , letraC) ;

4

Caracteres

São representados internamente na memóriado computador por códigos numéricos

A correspondência entre os caracteres e os seuscódigos numéricos é feita por uma tabela ASCIINa tabela ASCII:

os dígitos são codificados em seqüênciaas letras minúsculas e maiúsculas tambémformam dois grupos sequenciais

char letraA = 65; /* letra A*/

char letraC;

letraC = 67;

printf ( “%c %c ”, letraA , letraC) ;

5

0 1 2 3 4 5 6 7 8 930 sp ! “ # $ % & ‘40 ( ) * + , - . / 0 150 2 3 4 5 6 7 8 9 : ;60 < = > ? @ A B C D E70 F G H I J K L M N O80 P Q R S T U V W X Y90 Z [ \ ] ^ _ ` a b c100 d e f g h i j k l m110 n o p q r s t u v w120 x y z { | } ~

Tabela ASCII

6

Impressão de CaracteresPodem ser impressos de duas formasdiferentes usando o printf:

char lc = 97 ;

printf(“%d %c”,lc,lc);

char la = „a‟ ;

printf(“%d %c”,la,la );

Saída: 97 c Saída: 95 a

Existe a função putchar da biblioteca stdio.hque permite a impressão de um caractere

char la = „a‟; /* ou la = 97; */

putchar(la);

7

Leitura de CaracteresLeitura de caracteres com a função scanf

char a ;

scanf(“%c”,&a );

char a ;

/* sem brancos */

scanf(“ %c”,&a );

OU

Existe a função getchar da biblioteca stdio.hque permite a leitura de um caractere

char a ;

a = getchar();

8

Leitura de CaracteresFunção scanf e getchar obriga que a tecla <enter> sejapressionada após a entrada dos dadosExistem funções para ler dados sem esperar pelo<enter> em C para ambientes Windows:

Função getche – definida em conio.h

Lê um caractere e o exibe na tela

char letra ;

letra = getche();

Função getch – definida em conio.hLê um caractere e não o exibe na tela (invisível)

char letra ;

letra = getch();

9

Escrevendo Funções que Manipulam Caracteres

Pode-se tirar proveito da codificação seqüencialda tabela ASCII

Escrevendo programas que usam a tabelaA função abaixo verifica se um dado caractere é umdígito entre ‘ 0 ’ e ‘ 9 ’

int digito (char c){

int ehDigito;

if(( c >= „0‟)&&(c <= „9‟)) {

ehDigito = 1;

} else{

ehDigito = 0;

}

return ehDigito;

}

10

Função para converter uma letra em maiúscula

char maiuscula(char c){

char maiusc;

if((c >= „a‟)&&(c <= „z‟)) {

maiusc = c – „ a ‟ + ‟ A ‟ ;

}

return maiusc ;

}

Escrevendo Funções que Manipulam Caracteres

Testa se é minúscula

Diferença entre qualquer caracter minúsculo e a letra ‘a’ é a mesma do equivalente maiúsculo e a

letra ‘A’

11

Vetor de Caracteres (String)É representada por um vetor do tipo char e terminadaobrigatoriamente, pelo caractere nulo ‘ \0 ’O especificador de formato %s da função printf permiteimprimir uma cadeia de caracteresA partir do endereço para o primeiro caractere, asfunções processam caractere a caractere até que ‘\0’seja encontrado

int main(){

char cidade[4];

cidade[0]=„R‟;

cidade[1]=„I‟;

cidade[2]=„O‟;

cidade[3]=„\0‟;

printf(“%s”,cidade);

}

12

Inicialização de StringsInicialização do vetor de caracteres na declaração

int main(){

char cidade[]={´R‟,‟I‟,‟O‟,„\0‟} ;

printf (“%s\n”,cidade );

}

Inicialização do vetor na declaração através da escritados caracteres entre aspas duplas

int main(){

char cidade[]= “RIO”;

printf(“%s\n”,cidade);

}

Caractere nulo é representado implicitamente

13

Declarando Strings

char s2[] = “Rio de Janeiro”;

Representa um vetor com 15 elementos

char s3[81];

Representa um vetor de no máximo, 80 elementos

char s4[81] = “Rio”;

Representa um vetor de no máximo 80 elementos,mas com um valor inicial já atribuído

printf("Uma string constante!\n");

printf(“Eu moro em %s ",“Recife");

Constantes do Tipo String

São criados strings contantes na memória

R

e

c

i

f

e

\0

100

101

102

103

104

105

106

Constantes do Tipo String

ERRADOchar capital[7];

capital = “Recife";

Declaração da constante do tipo vetor de caracteres capital

Já foi atribuido um endereco à constante capital (endereço inicial do vetor)

Tentativa de atribuir endereço da constante “Recife”à constante capital

Constantes do Tipo String

CORRETOchar capital[7] = “Recife";

Declaração da constante do tipo vetor de caracteres capital

Vetor de caracteres inicializado com as letras que fazem parte de Recife

R

e

c

i

f

e

\0

100

101

102

103

104

105

106

A constante capital armazena o valor inicial da String (100)

17

Impressão de StringsEspecificador %s na função printf deve serutilizado

char cidade [81] = “Recife”;

printf(“%s”, cidade );

Função puts de stdio.h pode ser utilizadotambém para imprimir strings

char cidade [81] = “Recife”;

puts(cidade);

18

Leitura de StringsEspecificador %s na função scanf capturasomente uma seqüência de caracteres nãobrancos

Limitação: somente nomes simples podem ser lidos

char cidade [81];

scanf (“%s”, cidade );

Um caracter branco pode ser um:espaço ( ‘ ’ )caractere de tabulação ( ‘ \ t ’ )caractere de nova linha ( ‘ \ n ’ )

& não é necessário pois cidade já armazena um

endereço (endereço inicial do vetor)

19

Permitindo Ler Mais de um Nome com o scanf

A função acima lê uma seqüência de caracteresaté que seja digitado um <enter>A inclusão do espaço antes de % descartamespaços em brancos que precedem o nome

char cidade [81] ;

scanf(“ %[^\n]”, cidade) ;

O caracter ^ informa que o caracter \n não

pode ser lido

20

Limitando Tamanho da String com o scanf

Para limitar o número máximo de caracterescapturados:char cidade [81] ;

scanf (“ %80[^\n]”, cidade ) ;

No máximo, 80 caracteres são lidos

Cuidado!

Leitura de uma string maior do que a capacidade declarada invadirá espaço de

memória não reservada

21

Usando gets para Leitura A função gets de stdio.h pode também serutilizada para ler strings

Lê a string até encontrar um ‘\n’

VantagensLê nomes compostosSintaxe mais simples

DesvantagemNão tem como limitar quantidade de caractereslidos

char cidade [81];

gets(cidade);

22

Funções de Manipulação de Strings

void imprime (char s[]) {

int i;

for (i = 0; s[i] != „\0‟; i++) {

printf (“%c“,s[i]) ;

}

printf (“\n”);

}

Função análoga

void imprime (char s[]) {

printf ("%s“,s);

printf (“\n”);

}

Imprime caracter a caracter

23

Calcula o comprimento da cadeia

int comprimento (char s[]) {

int i ;

int n = 0 ;

for (i = 0 ; s[i] != „\0‟; i++) {

n++ ;

}

return n ;

}

Função análoga definida em string.h:strlen (char* str) ;

Funções de Manipulação de Strings

Equivalente a char[]

24

void copia (char dest[], char orig[] ){

int i;

for ( i = 0 ; orig[i] != „\0‟; i++) {

dest[i] = orig[i];

}

/* fecha a cadeia copiada */

dest[i] = „\0‟;

}

Função análoga definida em string.h:strcpy (char* dest , char* orig) ;

Copia os elementos do 2º parâmetro no 1ºSupõe que o 2º parâmetro tem espaço suficiente

Funções que Fazem Cópias de Strings

Funções que manipulam Strings assumem que toda String

termina com o „\0‟

Copiando Strings

CORRETOchar capital[7];

char cidade[7];

strcpy(capital,”Recife”);

strcpy(cidade,capital);

Para copiar Strings deve-se utilizar uma função que faz a cópia!

ERRADOchar capital[7];

capital = “Recife";

Não se usa atribuição para copiar uma String na constante do tipo String capital

26

Cadeia de Caracteres

void concatena (char dest[], char orig[]) {

int i = 0 ; int j ;

while (dest[i] != „\0‟){

i++ ;

}

for (j = 0; orig[j] != „ \0 ‟; j++){

dest[i] = orig[j];

i++;

}

dest[i] = „\0‟;

}

Função análoga definida em string.h:strcat (char* dest , char* orig) ;

Concatena as duas cadeias e o resultado é atribuído ao1º parâmetro

Funções que Concatenam Strings

Acha o final da String destino

Copia elementos

Fecha a String destino

Outras Funções para Strings

Definidas em string.h:strcmp(char *str1,char *str2);

Retorna um inteiro positivo se str1 é lexicamenteposterior que str2; zero se as duas são idênticas; enegativo se str1 é lexicamente anterior que str2

strncpy(char *dest,char *origem, int n)

Copia n caracteres de origem para destinostrncat(char *dest,char *origem, int n);

Concatena n caracteres da origem em destino

2828

Vetor de Strings

Vetor de Strings equivale a um vetor de vetoresMatrizCada linha da matriz corresponde a uma string

Útil quando queremos armazenar uma coleçãode strings

2929

Exemplo de Vetor de Strings#define MAX 50 ;

int main (){

int i , numAlunos ;

char alunos[MAX][121] ;

do {

printf( “Digite o numero de alunos:\n”) ;

scanf (“%d”,&numAlunos);

} while ( numAlunos > MAX );

for (i = 0; i < numAlunos; i++) {

gets(alunos[i]) ;/* Lê uma string*/

}

return 0 ;

} Cada posição do vetor guarda uma String

30

Resumindo ...

Caracteres em CEntrada/SaídaFunções que manipulam caracteres

Vetores de caracteres (Strings)InicializaçãoStrings constantesEntrada/SaídaFunções de Manipulação de Strings

Introdução à Programação

Programação e Fatores de

Qualidade

22

Qualidade de Software

Quero que você escrevarapidamente um sistema defolha de pagamento quefuncione corretamente, que sejarobusto e que seja rápido. Ah!Pretendo lançar uma outraversão deste mesmo programa,daqui a uns 6 meses.

Sem problema,chefe.

Ferrou!

33

Tópicos da Aula

Hoje aprenderemos alguns fatores dequalidade de software

Fatores de qualidade externosFatores de qualidade internos

Depois aprenderemos algumas técnicas paramelhorar alguns fatores de qualidade de umprograma

ComentáriosPadrões de CodificaçãoPapel da endentação em um programaAlgumas dicas para melhorar a eficiência de umprograma

4

Impacto econômico e social do

software de qualidade

Disponibilidade de serviços essenciaishome banking

telefoniaSegurança de pessoassistemas de monitoramento de pacientessistemas de controle de tráfego aéreofreios ABS

5

Competitividade das empresasMelhores produtos a um menor custoAtração de novas empresas para a regiãoInvestimentos na regiãoArrecadação de impostos

O impacto na prática

66

Crise de Software

Nas 3 primeiras décadas da Computação, apreocupação maior era hardware

Custo de processamento e armazenamento de dadosDesafio atual é melhorar qualidade e custo dosoftwareProblemas

25% dos projetos são canceladosO tempo e custo de desenvolvimento é bem maior do que oestimado

em 53% dos projetos75% dos sistemas não funcionam como planejadoA manutenção e reutilização são difíceis e custosasA produtividade dos profissionais da área de software nãotem acompanhado a demanda por seus serviços

7

Causas da Crise de Software

EssênciasComplexidade crescente dos sistemasDificuldade e custos de formalização

Uma linha de código do sistema de controle delançamento do ônibus espacial da NASA custa1.000 dólares!

Essências não podem ser evitadas

8

Dificuldade de Formalização

9

Causas da Crise de Software

AcidentesMá qualidade das linguagens, ferramentas emetodologiasProblemas gerenciais (pessoas, riscos, etc.),políticos, e organizacionaisPouca comunicação entre o cliente e odesenvolvedorManutenção de software, geralmente não éconsiderada como parte do ciclo de software

Acidentes PODEM ser evitados!!!

1010

Fatores de Qualidade de Software

Qualidade de software é uma combinação devários fatoresEstes fatores podem ser classificados em:

Fatores ExternosQualidades percebidas pelos usuários de um softwareUsuários incluem: usuário final e aquela pessoa quecontratou o desenvolvimento do softwareEx: corretude, eficiência, reusabilidade, etc

Fatores InternosQualidades percebidas somente por profissionais desoftware que têm acesso ao código do softwareEx: modularidade, legibilidade, etc

11

Robustez

11

Alguns Fatores Externos

Corretude é a capacidade do software executar deforma correta todas as tarefas que foram pedidasnos requisitos e especificação do software

Especificação

Corretude

Robustez é a capacidade do software funcionar,mesmo em situações não previstas na especificação

É o complemento de corretude

1212

Alguns Fatores Externos

Extensibilidade é a facilidade em que o softwarepode ser alterado para que atenda novas exigênciasda especificação

Software está em constante mudança≈70% de custo do software é a fase de manutençãoMudanças de requisitos são responsáveis por ≈ 50% dasatividades de manutenção

Reusabilidade é a capacidade que o software temde ser usado em novas aplicações.

Este uso pode ser de partes do software ou dele todoGrande impacto no tempo de desenvolvimento de softwareMenor tempo de desenvolvimento é importante parasucesso do software

1313

Alguns Fatores Externos

Eficiência é a capacidade do software de otimizar autilização dos recursos de hardware

Muitas vezes requer um bom conhecimento do hardwareonde o software será executadoPode tornar a implementação do software dependente demaisda plataforma alvo

Facilidade de Uso é uma qualidade que diz respeito afacilidade com que usuários com diferentes perfisconseguem aprender a utilizar o software e resolver osproblemas desejados

Engloba também o aprendizado de instalação, operação emonitoramentoRepresenta economia para a empresa que utiliza o softwareem relação aos custos de treinamento

14

Outros Fatores Externos

PortabilidadeEscalabilidadeIntegridade e segurançaCompatibilidadeTestabilidade

1515

Alguns Fatores Internos

Um software é modular se ele é construído àpartir de elementos autônomos conectados

Modularidade Reusabilidade e Extensibilidade

Legibilidade de um programa é a facilidadecom que profissionais de software conseguementender o código do programa

Documentação é importantePadrões de codificação devem ser seguidosLegibilidade Reusabilidade e Extensibilidade

1616

Algumas Considerações sobre

Qualidade

Fatores internosFatores externosSoftwares são utilizados em aplicações dos maisdiversos domíniosFreqüentemente, não se pode obter todos os fatoresde qualidade

Diferentes fatores podem ser conflitantesEx: Freqüentemente para aumentar a eficiência, código doprograma deve ser mais específico a uma plataforma, oque diminui a reusabilidade e/ou portabilidade do código

1717

Algumas Considerações sobre

Qualidade

Cabe ao desenvolvedor avaliar quais

fatores são mais importantes

de acordo com a aplicação

O que foi que aconteceu? Eu pisei no freio e ele demorou um século para ser acionado

Eu ouvi dizer que este sistema novo de controle de freio, pelo menos, é mais reusável

1818

Comentando um Programa

Um programa deve ser bem documentadoDocumentação externa para usuáriosDocumentação no próprio programa

Aumenta a legibilidade

Comentário é um mecanismo oferecido pelas linguagens de programação que permite que o programador expresse em linguagem natural a lógica pensada para escrever um programa ou

um trecho de programa

1919

Comentando um Programa

Usa-se o termo inline documentation paracomentários em um programaDevem ser incluídos para explicar o propósitodo programa e algumas partes deleComentários não afetam o funcionamento doprograma

São ignorados na hora da execução

Dica: Comente o código enquanto o estiver escrevendo, senão há uma forte probabilidade

de não o fazer depois

2020

Comentários em C

Em C para incluir comentários:Usa-se /* e */

Pode conter múltiplas linhas

/* Este tipo de comentário só termina

quando o asterisco barra é encontrado */

Não se pode colocar os símbolos decomentário dentro de um comentário

/* Este tipo de comentário /*só termina*/

quando o asterisco barra é encontrado */

2121

Comentários em C

// Este é um comentário de uma linha

Precedido de //

Isto ocorre porque a maioria das IDEs suportamC++

Este tipo de comentário é aceito em C++

Comentários de uma linha usando // sãoaceitos pela maioria dos ambientes deprogramação (IDEs)

2222

Reuso de Código

Reusabilidade é um fator importante paraacelerar o desenvolvimento de um sistemaReuso pode se dar de várias formas:

Função inteiraUma função chama outra função

Trechos de programa ou funções

2323

Reuso de Código

Existem muitas técnicas existentes parareutilizar código ou pelo menos aumentar opotencial de reusoUma “técnica” infelizmente muito difundida é ocopy & paste

Solução rápida e “boa” para quem não quer pensarSolução péssima para a manutenção do sistema

Se uma alteração for requerida, esta também deverá serpropagada por todos os trechos repetidosSe um bug for encontrado, terá de ser corrigido em todosos outros códigos repetidos

Melhor do que isto é usar Refactoring

2424

Refactoring

Refactoring consiste em uma série de técnicas quereestruturam o código do software, aumentando opotencial de reuso, extensibilidade e legibilidade

O comportamento do software continua o mesmo, só muda aestruturaMuito difundido entre metodologias de desenvolvimento desoftware orientadas a objetos

Porém, muitas técnicas podem ser aplicadas a programasdesenvolvidas em linguagens como C

Exemplos de refactoring:Generalizar uma função com parâmetrosTransformar um trecho de codigo em uma função

25

Padronização de Codificação

Quanto mais fácil for o entendimento(legibilidade) do código do sistema, maisprodutiva será a equipe de desenvolvimentoFreqüentemente as pessoas que escrevem ocódigo não são as mesmas que o mantém

Pode haver dificuldades de entendimento entre asdiferentes pessoas que trabalham sobre o mesmocódigo

Atrasa o desenvolvimento do sistema

26

Padronização de Codificação

Um padrão de codificação visa minimizar essesproblemas

Estabelece regras, definindo como o código deveser escrito para favorecer a impessoalidade doprogramaFacilita a integração de novos desenvolvedores aoambiente de desenvolvimento

Em C, não existe um padrão internacionalaceito de codificação

Empresas geralmente estabelecem um próprio

Porém, veremos os padrões mais utilizados em C

27

Nomenclatura de Contantes e

Variáveis

A princípio, identificadores não devem serabreviados

Quando o fizer, usar bom senso para que não seperca expressividadeUsar bom senso para que nome da variável ouconstante não fique grande demais

Focar no que a variável ou a constanterepresentam

Recomenda-se colocar o identificador de umaconstante em letras maiúsculas

Se houver mais de uma palavra, as palavrasseguintes devem ser separadas com o caracter deunderscore ( _)

28

Nomenclatura de Contantes e

Variáveis

Recomenda-se colocar o identificador de umavariável começando com letra minúscula

Se houver mais de uma palavra, as palavrasseguintes devem começar com maiúscula ouserem separadas com o caracter de underscore (_)

Para nome de variáveis locais querepresentam contadores, pode-se colocarapenas uma letra do alfabetofor (i = 0; i < 5; i++) /*Aceitável */

Exemplos de Constantes e Variáveis

quantidadeAutores /*Bom */

Variável para representar a quantidade de autores deum livro

qtdAutores /* Aceitável */

qtdAut /* Inaceitável */

variavelQueArmazenaQuantidadeDeAutores /*Ruim*/

29

Constante para representar o número de vagas dadisciplina de IP

VAGAS_IP = 60 /*Bom */

Vg_Ip = 60 /*Inaceitável */

30

Nomenclatura de Funções

Identificadores não devem ser abreviadosRecomenda-se colocar o nome começando letraminúscula

Se houver mais de uma palavra, as palavras seguintes devemcomeçar com maiúscula ou serem separadas com o caracterde underscore (_)

Não se deve colocar nomes misturando palavras delínguas diferentesMuitas vezes, coloca-se na primeira palavra um verbono infinitivo representando a utilidade da função

Ex: imprimirPrimos(int comeco, int fim)

Muitas vezes se coloca um nome igual ao nome deuma função matemática

Ex: fatorial(int n)

31

Importância da Endentação

Como sabemos, o compilador C ignora espaços etabulaçõesPorém, para aumentar a legibilidade do código é muitoimportante se preocupar com sua endentação

Torna mais claro o que será feito dentro de comandoscondicionais e laçosTorna mais claro o limite de funções

if (total > MAX)

printf ("Erro!!");

contador++;

if (total > MAX)

printf ("Erro!!");

contador++;

32

Que trecho de código é mais claro?int divisao(int dividendo, int divisor){int i, resultado = 0;

if (divisor != 0)

for(i = dividendo; i >= divisor ; i = i - divisor)

resultado++;

return resultado;

}

int divisao(int dividendo, int divisor){

int i, resultado = 0;

if (divisor != 0)

for(i = dividendo; i >= divisor ; i = i - divisor)

resultado++;

return resultado;

}

33

Algumas Dicas para Melhorar

Eficiência

Evitar o uso de variáveis globaisOcupam memória durante toda a execução doprograma

Não declarar variaveis que não serãoutilizadasNão declarar variáveis com tipos que ocupammais memória quando a aplicação nãotrabalha com valores muito grandes

Aritmética de inteiros é mais rápida do quearitmética de ponto flutuante (reais)

34

Algumas Dicas para Melhorar

Eficiência

Sempre que puder privilegiar soluçõesiterativas sobre as recursivas

Pode diminuir uso da memóriaPode economizar tempo de processamento

Evitar executar todas as iterações de um laçoquando não é necessário

Economiza tempo de processamento

35

Exemplo de Melhoria de Eficiência

Evita um teste desnecessario

se o numero for

maior do que 100

int existeNumeroPrimoEntre(int inicio, int fim){

int i, existe = 0;

for(i = inicio; i <= fim;i++){

/*Considere que exista uma função que diz se um num é primo*/

if (numeroPrimo(i) == 1) {

existe = 1;

}

}

return existe;

}

Mesmo achando um numero

primo, continua laço

36

Exemplo de Melhoria de Eficiênciaint existeNumeroPrimoEntre(int inicio, int fim){

int i, existe = 0;

for(i = inicio; i <= fim && existe == 0;i++){

/*Considere que exista uma função que diz se um num é primo*/

if (numeroPrimo(i) == 1) {

existe = 1;

}

}

return existe;

}Evita continuação do laço

quando encontra numero primo

37

Algumas Dicas para Melhorar

Eficiência

Quando usar comandos condicionais, analisarse certos caminhos podem realmente serexecutados

Elimine caminhos que nunca podem serexecutados

Quando o programa tiver muitos if testandouma mesma variavel, verificar se não émelhor colocar alguns else para evitar testesdesnecessários

38

Exemplo de Melhoria de Eficiênciavoid maiorQue100(int numero){

if (numero > 100){

printf(“%d eh maior que 100”,numero);

}

if (numero <= 100) {

printf(“%d nao eh maior que 100”,numero);

}

}

void maiorQue100(int numero){

if (numero > 100){

printf(“%d eh maior que 100”,numero);

} else {

printf(“%d nao eh maior que 100”,numero);

}

}

Evita um teste desnecessario

se o numero for

maior do que 100

3939

Referências Adicionais

Crise do softwareSoftware„sChronic Crisishttp://www.cin.ufpe.br/~if669/files/MaterialDeEnsino/Referencias/SoftwareChronicsCrisis/SciAmSept1994.html

Fatores de QualidadeBertrand Meyer. Object-Oriented Software Construction.Segunda Edição. Prentice Hall, 1988

Otimização de código Chttp://www.abarnett.demon.co.uk/tutorial.html#ARRAY

Práticas que NÃO devem ser seguidasProgramação Orientada a Gambiarrahttp://desciclo.pedia.ws/wiki/Programação_Orientada_a_Gambiarras

4040

Resumindo ...

Fatores de qualidade de softwareFatores de qualidade externosFatores de qualidade internos

Técnicas para melhorar alguns fatores de qualidade deum programa

Comentários

Refactoring

Endentação

Melhorando a eficiência

Introdução a Programação

Ponteiros e Passagem de Argumentos por Referência

Tópicos da Aula

Hoje aprenderemos a manipular endereços de

memória ou ponteiros

Variáveis e Endereços

Conceito de Ponteiro

Operadores de Ponteiros

2

Ponteiros e Funções

Passagem de Argumentos por Referência

Importância de uso de ponteiros

Aritmética de Ponteiros

Variáveis e Endereços

Memória abstrata (Como vemos a memória):

{x→→→→5, y→→→→9, z→→→→‘a’}

Memória concreta:

Associações:

Id→→→→Valor

Associações:

{x→→→→13, y→→→→72, z→→→→00}

Memória de fato:

{00→→→→‘a’,...,13→→→→5,

72→→→→9,...,99→→→→undefined}

Id→→→→Endereço

Endereço→→→→Valor

Ponteiros

Toda variável tem um endereço ou uma

posição associados na memória

Este endereço é visto como um ponteiro

(ou apontador), uma referência para a(ou apontador), uma referência para a

posição de memória de uma variável

Ponteiros fornecem um modo de acesso à

variável sem referenciá-la diretamente

Um endereço pode ser armazenado em

uma variável do tipo ponteiro (ponteiro

variável)

Ponteiro Variável

Um ponteiro variável é uma variável que contém

o endereço de outra variável

valor1V endereço4

endereço5

Memória

P = endereço da variável V

valor1

endereço4P

V

endereço1

endereço2

endereço3

endereço4

P aponta para V

Declarando Variáveis do Tipo Ponteiroem C

int b; Declara uma variável de nome b que pode armazenar

valores inteiros

Para declarar uma variável do tipo ponteiro:

6

int* p; Declara uma variável de nome p que pode armazenar um endereço de memória

para um inteiro

Forma Geral:tipo* variavel

Operador &

Operador unário que fornece o endereço deuma variável

Forma Geral:&variavel

Variável de tipo ponteiro para int *p;

int v;

p = &v;

ERRADO!

Não pode ser aplicado a expressões ouconstantes

Ex: x = &3;

Variável p de tipo ponteiro para inteiro recebe endereço da variável v de tipo inteiro

Operador de Indireção *

Quando aplicado a uma variável do tipo

ponteiro, acessa o conteúdo do endereço

apontado por ela

Forma Geral:*variavel

3

endereço4p

v

endereço1

endereço2

endereço3

endereço4

endereço5

int *p;

int v = 3;

p = &v;

*p = 4;

*variavel

4

Usando Ponteiros

int i, j;

int *ip;

i = 12;

A variável ip armazena um ponteiro para um inteiro

O endereço de i é armazenado em i = 12;

ip = &i;

j = *ip;

*ip = 21;

O endereço de i é armazenado em ip

O conteúdo da posição apontada por ip é armazenado em j

O conteúdo da posição apontada por ip passa a ser 21

Usando Ponteiros

int i,j ;

int *ip ;112

12

ip

1)

j

i

108

104---

i = 12 ;

2)

112ip

j

i

108

104

--

ip = &i ;

112ip

3)

j

i

108

10412

-104

12

j = *ip;

*ip = 21;112ip

4)

j

i

108

10412

104

21

Manipulando Ponteiros

int main () { /* função principal */

int a , *p ;

p = &a ;

*p = 2 ;

printf (“%d”,a);

return 0 ;

}Imprime o valor 2

int main () { /* função principal*/

int a,b,*p ;

a = 2 ;

*p = 3 ;

b = a +( *p );

printf(“%d”,b);

return 0;

}

Imprime o valor 2

Erro típico de manipulação de ponteiros –ponteiro não inicializado!

Funções e Ponteiros

Retorno explícito de valores não permite transferir

mais de um valor para a função que chama

# include <stdio.h>

void somaprod(int a, int b, int c, int d) {

c = a + b ;

d = a * b ;

}

12

int main () {

int s,p ;

somaprod(3,5,s,p) ;

printf(“Soma = %d e Produto = %d \n”,s,p);

return 0 ;

}

Esse código não funciona como esperado !

A Passagem de Argumentos em C é por valor...

int a,b;

a = 8;

b = 12;

swap(a,b);

A chamadada funçãonão afeta os valores de a e b

Copia os valores que estão em a e b para parâmetros x e y

void swap(int x, int y){

int temp;

temp = x;

x = y;

y = temp;

}

parâmetros x e y

int a,b;

a = 8;

b = 12;

swap(&a,&b);

A chamadada funçãoafeta os valores de a e b

Copia os endereços de a e b para parâmetros px e py

Mas C Permite a Passagem por Referência

void swap(int* px, int* py){

int temp;

temp = *px;

*px = *py;

*py = temp;

}

parâmetros px e py

Passagem por Referência em C

int a,b ;

a = 8;

b = 12

112

1)

b

a

108

1048

12

-

main>

104

108swap(&a,&b) ;

2)

112swap>

b

a

108

104main>

px

py

temp

8

12

-

8

*px = *py;

*py = temp;

4)

112swap>

b

a

108

104main>

px

py

temp

104

108

8

8

128

temp = *px;

3)

112swap>

b

a

108

104main>

px

py

temp

8

12

104

108

12

Como uma função pode alterar variáveis de

quem a chamou?

1) função chamadora passa os endereços dos

valores que devem ser modificados

Passando endereços para uma função

2) função chamada deve declarar os endereços

recebidos como ponteiros

16

Usando Passagem por Referência para Função SomaProd

# include “stdio.h”

void somaprod(int a,int b,int* p, int* q){

*p = a + b ;

*q = a * b ;

}

Passagem por

17

int main (){

int s , p ;

somaprod (3 , 5 , &s , &p) ;

printf(“Soma= %d e Produto = %d \n”,s,p);

return 0 ;

}

Passagem por Referência

Por que ponteiros são usados ?

Possibilitar que funções modifiquem os

argumentos que recebem

Manipular vetores e strings - útil para passar

vetores como parâmetrovetores como parâmetro

Criar estruturas de dados mais complexas,

como listas encadeadas, árvores binárias etc.

18

Operações com Ponteiros

int main( ) {

int x=5, y=6;

int *px, *py;

px = &x;

py = &y;

if (px < py)

printf(“py-px = %u\n”,py-px);

else

px e py armazenam endereços para

inteiros

else

printf(“px-py = %u\n”,px-py);

return 0;

} Resultado: diferença entre endereços

dividido pelo tamanho em bytes de um

inteiro

Saída será:

Se px = 65488 e py = 65484

Testes relacionais >=,<=, <, >, ==, sãoaceitos em ponteiros

A diferença entredois ponteiros será

Operações com Ponteiros

Saída será:px - py = 1

A diferença entredois ponteiros serádada na unidade dotipo de dado apontado

Operações com Ponteiros

int main( ) {

int x=5, y=6;

int *px, *py;

px = &x;

py = &y;

printf(“px = %u\n”,px);

printf(“py = %u\n”,py);

py++;

Podemos utilizar operador de

incremento com py++;

printf(“py = %u\n”,py);

py = px+3;

printf(“py = %u\n”,py);

}

incremento com ponteiros

Podemos fazer aritmética de ponteiros

Operações com ponteiros

O incremento de um ponteiro acarreta na

movimentação do mesmo para o próximo

valor do tipo apontado

Ex: Se px é um ponteiro para int com valor 3000,

depois de executada a instrução px++, o valor dedepois de executada a instrução px++, o valor de

px será 3004 e não 3001 !!!

Obviamente, o deslocamento varia de

compilador para compilador dependendo do

número de bytes adotado para o referido tipo

22

Resumindo...

Ponteiros

Conceito

Operadores de Ponteiros

Ponteiros e Funções

Passagem de Argumentos por Referência

23

Quando usar ponteiros

Operações com Ponteiros

Introdução a Programação

Ponteiros e Vetores

2

Tópicos da Aula

Hoje aprenderemos que existe uma forte

relação entre ponteiros e vetores

Associação entre ponteiros e vetores

Ponteiros constantes x Ponteiros variáveis

Passagem de ponteiros invés de vetores para

funções

Comando sizeof

3

Considere a declaração:

O símbolo v

Representa o vetor

É uma constante que representa seu endereço

inicial

Aponta para o primeiro elemento do vetor

Associação entre Vetores e Ponteiros

int v [10] ;

4

Ponteiros e Vetores (matrizes)

Em C existe um relacionamento muito forte

entre ponteiros e vetores

O compilador entende todo vetor e matriz como

ponteiros, pois a maioria dos computadores é capaz

de manipular ponteiros e não vetores

Qualquer operação que possa ser feita com índices

de um vetor pode ser feita com ponteiros

O identificador de um vetor representa um endereço,

ou seja, um ponteiro

5

Como vimos, C permite aritmética de ponteiros

Se tivermos a declaração

Podemos acessar elementos do vetor através

de aritmética de ponteiros

Ponteiros e Vetores

Aponta para (igual ao endereço do) primeiro

elemento do vetorv + 0

Aponta para o segundo elemento do vetorv + 1

Aponta para o último elemento do vetorv + 9

Portanto: &v[i]↔(v + i) v[i]↔ *(v + i)

int v [10] ;

6

Representando Ponteiros e Vetores na Memória

100

101

102

103

104

105

106

107

108

109

110

111

6

10

7

v + 2 &v[2] 108

*(v + 2) v[2] 7

Memória int v[] = {6,10,7};

v + 1 &v[1] 104

*(v + 1) v[1] 10

v &v[0] 100

*v v[0] 6

7

Ponteiros e Vetores

int a[10];

int *pa;

pa = &a[0];

pa = a;

Vetores podem ser tratadoscomo ponteiros em C!

*pa a[0] pa[0]

*(pa+i) a[i]

pa[i] *(a+i)

a+i &a[i]

Expressões Equivalentes!

pa = &a[0];

pa = a;

8

Usando Notação de Ponteiros para Vetores

int main( ) {

int nums[ ] = {1, 4, 8};

int cont;

for(cont=0; cont < 3; cont++) {

printf(“%d\n,nums[cont]);

}

}

int main( ) {

int nums[ ] = {1, 4, 8};

int cont;

for(cont=0; cont < 3; cont++) {

printf(“%d\n,*(nums + cont));

}

}

Versão com Ponteiro

Versão com Vetor

9

Ponteiros Constantes x Ponteiros Variáveis

int main( ) {

int nums[ ] = {1, 4, 8};

int cont;

for(cont=0; cont < 3; cont++) {

printf(“%d\n,*(nums++));

}

}

Declaração de uma constante do tipo ponteiro para inteiros (ponteiro constante)

Tenta incrementar endereço armazenado na constante nums e atualizar a constante com

novo endereço

Errado!

10

Ponteiros Constantes x Ponteiros Variáveis

int main( ) {

int nums[ ] = {1, 4, 8};

int* pnums = nums;

int cont;

for(cont=0; cont < 3; cont++) {

printf(“%d\n,*(pnums++));

}

}

Declaração de uma variável do tipo ponteiro para inteiros (ponteiro variável)

Incrementa endereço armazenado na variável pnums e atualiza a variável com

novo endereço

Certo!

11

int a[10];

int *pa;

pa = a;

Ponteiros Constantes x Ponteiros Variáveis

int a[10];

int *pa;

a = pa;

Atribui a uma variável um novo

endereço: CERTO!

Atribui a uma constante um novo endereço: ERRADO!

#include <stdio.h>

float media(int n, float num[]){

int i;

float s = 0.0;

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

s = s + num[i] ;

return s/n ;

}

int main(){

float numeros[10] ;

float med;

int i ;

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

scanf (“%f”, &numeros[i]) ;

med = media(10, numeros ) ;

...

}12

Passando Vetores como Argumentos para Funções

Parâmetro do tipo vetor de float

Endereço inicial do vetor é passado como argumento

#include <stdio.h>

float media(int n, float* num){

int i;

float s = 0.0;

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

s = s + num[i] ;

return s/n ;

}

int main(){

float numeros[10] ;

float med;

int i ;

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

scanf (“%f”, &numeros[i]) ;

med = media(10, numeros ) ;

...

}13

Passando Ponteiros invés de Vetores como Argumentos para Funções

Parâmetro do tipo ponteiro para float

Endereço inicial (ponteiro) do vetor é passado como

argumento

14

Passando Ponteiros como Argumentos de Funções

Considere a seguinte assinatura de função:

void incrementa(int n, int* v)

Pergunta: Parâmetro v é um ponteiro para um vetor de inteiros ou para uma variável do tipo inteiro?

Resposta 1: Não tem como saber

Resposta 2: É indiferente. Podemos considerar um ponteiro para uma variável do tipo inteiro como um ponteiro para um vetor com um só elemento

15

Comando sizeof

Forma Geral:

Informa o número de bytes de um dado tipo ou variável

em tempo de compilaçãoExemplo:

int d = sizeof(float); d armazena o valor 4

sizeof(tipo) ou sizeof(variavel)

16

Usando sizeof para Determinar Tamanho de Ponteiros e Vetores

int main() {

int num[ ]={1,2,3};

int numElementos = sizeof(num)/sizeof(int);

printf ("Tamanho = %d\n", sizeof(num));

printf ("Num elementos = %d\n", numElementos);

}

int main() {

int num[ ]={1,2,3};

int* num2 = num;

int numElementos = sizeof(num2)/sizeof(int);

printf ("Tamanho = %d\n", sizeof(num2));

printf ("Num elementos = %d\n", numElementos);

}

Qual é o o numero de elementos?

Qual é o o numero de elementos?

3

1

17

Resumindo ...

Relação entre ponteiros e vetores

Ponteiros constantes x Ponteiros variáveis

Passagem de ponteiros invés de vetores para

funções

Comando sizeof

Introdução a Programação

Ponteiros e Strings, Alocação

Dinâmica

2

Tópicos da Aula

Hoje aprenderemos que a relação entre

ponteiros e strings

Ponteiros para strings X Vetores de Caracteres

Vetores de ponteiros para strings

Também veremos como alocar espaço de memória em

tempo de execução

Conceito de Alocação Dinâmica

Importância

Funções em C para alocação dinâmica

Usando alocação dinâmica para criar vetores e

matrizes dinâmicas

3

Ponteiros e Strings

Uma string é um vetor de caracteres

Vimos que s armazena o endereço inicial do

vetor

Portanto, podemos manipular strings com

ponteiros

char s [10] ;

4

Ponteiros e Strings

ERRADOchar capital[7];

capital = “Recife";

Declaração da constante do tipo vetor de caracteres capital

Já foi atribuido um endereco à constante capital (endereço inicial do vetor)

Tentativa de atribuir endereço da constante “Recife”à constante capital

5

Ponteiros e Strings

CORRETOchar capital[7] = “Recife";

char* cidade;

cidade = “Recife”;

Declaração da constante do tipo vetor de caracteres capital

Vetor de caracteres inicializado com as letras que fazem parte de Recife

Atribuição do endereço da constante “Recife”à variável cidade

6

Inicialização de Strings Através de

Ponteiros

int main() {

char *salute=“saudacoes”;

puts(++salute);

return 0;

}

int main() {

char salute[] =“saudacoes”;

puts(++salute);

return 0;

}

Estes dois códigos executariam da mesma forma?

Imprime audacoes (sem s): ponteiro

variável

Erro de compilação: tentativa de modificar

ponteiro constante

7

Passando Ponteiros para Strings para

FunçõesNa biblioteca string.h, existem várias funções que

têm como parâmetros ponteiros para strings

Exemplos:

char* strcpy(char* dest, char* origem);

int strcmp(char* s1, char* s2);

Podemos passar como argumentos, tanto ponteiros

para strings ou vetores de caracteres(strings)

int main() {

char *salute=“saudacoes”;

char saudacao[10];

strcpy(saudacao,salute);

return 0;

}

8

Vetores de Strings x Vetores de

Ponteiros para Strings

Quando queremos armazenar um conjunto de

strings podemos:

Usar um vetor de strings

Vetor bidimensional (matriz) de caracteres

Usar um vetor de ponteiros para strings

Usando Vetor de Strings (Matriz de

Caracteres)

int main(){

int cont;

int entra=0;

char nome[40];

char list[4][7]= {“Carlos”, “Ana”, “Pedro”, “Andre”};

printf (“Digite seu nome:”);

gets(nome);

for (cont=0; cont < 4; cont++){

if (strcmp(list[cont],nome) == 0)

entra=1;

}

if (entra == 1)

printf (“Você pode entrar.”);

else

printf (“Você não pode entrar.”);

return 0;

}

Programa verifica se um nome entrado pelo usuário pertence a um

vetor inicializado de strings

Cuidado para que as strings não excedam as

colunas da matriz!

Usando Vetores de Ponteiros para

Strings

int main(){

int cont;

int entra=0;

char nome[40];

char* list[4]= {“Carlos”, “Ana”, “Pedro”, “Andre”};

printf (“Digite seu nome:”);

gets(nome);

for (cont=0; cont < 4; cont++){

if (strcmp(list[cont],nome) == 0)

entra=1;

}

if (entra == 1)

printf (“Você pode entrar.”);

else

printf (“Você não pode entrar.”);

return 0;

}

Programa verifica se um nome entrado pelo usuário pertence a um vetor

inicializado de ponteiros para strings

Despreocupação com tamanho das strings

11

Inicialização de um Vetor de Strings x

Vetor de ponteiros para Strings

C a r l o s\0A n a\0P e d r o\0A n d r e\0

0 1 2 3 4 5 6list[0]

list[1]

list[2]

list[3]

Versão Vetor de Strings

list[0]

list[1]

list[2]

list[3]

Versão Vetor de Ponteiros

C a r l o s\0A n a\0P e d r o\0A n d r e\0

Desperdício de Memória!

int main(){

int cont;

int entra=0;

char nome[40];

char list[4][10];

for (cont=0; cont < 4; cont++){

printf(“\nEntre com mais um convidado:\n”);

gets(list[cont]);

}

return 0;

}

Programa pede para o usuário preencher um vetor de strings

Cuidado para que as strings não excedam as

colunas da matriz!

Outro Exemplo Usando Vetor de

Strings

int main(){

int cont;

int entra=0;

char nome[40];

char* list[4];

for (cont=0; cont < 4; cont++){

printf(“\nEntre com mais um convidado:\n”);

gets(list[cont]);

}

}

Programa pede para o usuário prencher um vetor de ponteiro para

strings

ERRADO!

Outro Exemplo Usando Vetor de

Ponteiro de Strings

Tenta armazenar string em endereço (INVÁLIDO)

apontado por list[cont]

14

Alocação de Memória

Quando declaramos uma variável, o compilador

reserva (aloca) um espaço na memória

suficiente para armazenar valores do tipo da

variável

Alocação estática (em tempo de compilação)

int var ;

char s1 [10];

char* s2;

Aloca espaço para 1 int

Aloca espaço para 10 char

Aloca espaço para 1 endereço

15

Modos de alocar espaço em memória:

Estaticamente

Variáveis globais (e estáticas): O espaço reservado

para a variável existe enquanto o programa estiver

sendo executado

Variáveis locais: O espaço existe enquanto a

função, que declarou a variável, estiver sendo

executada.

Dinamicamente

Requisitar memória em tempo de execução: O

espaço alocado dinamicamente permanece

reservado até que seja explicitamente liberado

pelo programa

Alocação Dinâmica

16

Função básica para alocar memória é malloc

presente na biblioteca stdlib.h

Recebe como argumento um número inteiro sem

sinal que representa a quantidade de bytes que se

deseja alocar

Retorna o endereço inicial da área de memória

alocada.

Alocação Dinâmica em C

void* malloc(unsigned qtdBytes);

17

Aloca somente a quantidade de memórianecessária

Exemplo:

Alocação Dinâmica em C com malloc

int *v ;

v = malloc (10 * 4) ;

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 (4O

bytes)

18

Uso do comando sizeof para ter independência de

plataforma de desenvolvimento

Exemplo:

int *v ;

v = malloc(10 * sizeof (int)) ;

Função malloc retorna um ponteiro genérico, para

qualquer tipo, representado por *void

Faz-se a conversão para o tipo apropriado usando o operador

de molde de tipo (cast)

v = (int *) malloc(10 * sizeof(int));

Alocação Dinâmica em C com malloc

19

Erro na Alocação

Se não houver espaço livre suficiente pararealizar a alocação, a função malloc retorna

um endereço nulo

É representado pelo símbolo NULL

É uma boa prática de programação testar se a

alocação foi bem sucedida para evitar erros de

execução

20

Liberando Espaço Alocado

Uso da função free para liberar espaço de

memória alocada dinamicamente

Recebe como parâmetro o ponteiro da memória a

ser liberada

O espaço de memória fica livre para ser alocado

futuramente pelo próprio programa ou outro

programa

Recomenda-se liberar espaço de memória

previamente alocado que não é mais necessário

Evita desperdício

void free(void* endereco);

21

Memória e Alocação Dinâmica

Código do programa

Variáveis Globais e Estáticas

Memória livre

1) Declaração: int *v ;

v -

Código do programa

Variáveis Globais e Estáticas

Memória livre

2) v=(int*)malloc(10*sizeof (int));

v 504

40 bytes504

Abre-se espaço na pilha para o ponteiro (variável local)

Reserva-se o espaço de memória da área livre e atribui o endereço à v

#include <stdio.h>

int main() {

int qtdNumeros,contador = 0;

float numeros[2000];

float media = 0.0;

do{

printf(“Quantidade de numeros? (< 2000):\n”);

scanf(“%d”, &qtdNumeros);

} while (qtdNumeros <= 0 || qtdNumeros > 2000);

while (contador < qtdNumeros) {

scanf(“%f”,&numeros[contador]);

media = media + numeros[contador];

contador++;

}

media = media/qtdNumeros;

printf(“\nA media eh %f\n”);

return 0;

} 22

Usando Alocação Estática para

Calcular Média com Vetores

Declaração estática do tamanho do vetor limita

aplicação

Tamanho pode ser insuficiente ou grande demais (desperdício)

23

Vetores Dinâmicos

Declaração de vetores implicam em alocação estática

de memória

Com alocação dinâmica, podemos criar algo como

um vetor cujo tamanho é decidido em tempo de

execução, ou seja um vetor dinâmico

Para tal, usaremos variáveis do tipo ponteiro que

receberão os endereços iniciais do espaço alocado

dinamicamente

Com o endereço inicial, podemos navegar pelo vetor

int main() {

int qtdNumeros,contador = 0;

float* numeros;

float media = 0.0;

do{

printf(“Quantidade de numeros?:\n”);

scanf(“%d”, &qtdNumeros);

} while (qtdNumeros <= 0);

numeros = (float*) malloc(qtdNumeros*sizeof(float));

if (numeros == NULL) {

printf(“Memoria insuficiente”);exit(1);

}

while (contador < qtdNumeros) {

scanf(“%f”,&numeros[contador]);

media = media + numeros[contador];

contador++;

} /* continua */

} 24

Usando Alocação Dinâmica para

Calcular Média com Vetores Dinâmicos

Ponteiro recebe endereço de espaço

alocado dinamicamente (vetor dinâmico)

Tamanho do vetor é determinado pelo usuário

25

Podemos mudar o espaço de memória alocado

previamente de forma dinâmica

Para isso, podemos utilizar a função realloc

Recebe endereço do bloco de memória alocado previamente

Recebe como argumento um número inteiro sem sinal que

representa a quantidade de bytes que se deseja alocar

Retorna o endereço inicial da área de memória alocada

Se endereço retornado for diferente do passado como

parâmetro, conteúdo do bloco original é copiado para

novo endereço

Função Realloc

void* realloc(void* ptr,unsigned qtdBytes);

int main() {

int qtdNumeros = 5,contador = 0;

char resposta;

float media = 0.0;

float* nums;

nums = (float*) malloc(qtdNumeros*sizeof(float));

if (nums == NULL) {

printf(“Memoria insuficiente”);exit(1);

}

printf(“Programa calcula media de 5 numeros.”);

printf(“Deseja mais/menos? (s/n)\n”);

scanf(“%c”,&resposta);

if (resposta == „s‟) {

do {

printf(“Quantidade de numeros?:\n”);

scanf(“%d”, &qtdNumeros);

} while (qtdNumeros <= 0);

nums = (float*) realloc(nums,qtdNumeros*sizeof(float));

/* continua */

} 26

Usando Realloc

Vetor é alocado dinamicamente

Tamanho do vetor muda dinamicamente

27

Vetores e Alocação Dinâmica

Vetores Locais e Funções

float* prod_vetorial (float* u , float* v) {

float p[3] ;

p[0] = u [ 1 ] * v [ 2 ] – v [ 1 ] * u [ 2 ] ;

p[1] = u [ 2 ] * v [ 0 ] – v [ 2 ] * u [ 0 ] ;

p[2] = u [ 0 ] * v [ 1 ] – v [ 0 ] * u [ 1 ] ;

return p ;

}

A variável retornada é declarada localmente. Por isso, sua área de memória deixa de ser válida

quando a função termina.

ERRADO! – Endereço local é retornado

28

Vetores e Alocação Dinâmica

Vetores Locais e Funções

Forma Correta:

float* prod_vetorial (float* u , float* v) {

float* p = (float*) malloc(3 * sizeof(float)) ;

p[0] = u [ 1 ] * v [ 2 ] – v [ 1 ] * u [ 2 ] ;

p[1] = u [ 2 ] * v [ 0 ] – v [ 2 ] * u [ 0 ] ;

p[2] = u [ 0 ] * v [ 1 ] – v [ 0 ] * u [ 1 ] ;

return p ;

}

CERTO! – Endereço alocado dinamicamente fica disponível até que

seja liberado explicitamente

29

Criando Matrizes Dinâmicas

Deve-se usar um ponteiro para ponteiro

Pode-se pensar em uma matriz dinâmica comoum vetor de ponteiros

Cada elemento do vetor contém o endereço inicial deuma linha da matriz (vetor-linha)

Para alocar uma matriz com malloc, é preciso fazer aalocação do vetor de ponteiros e, em seguida, decada vetor-linha

Da mesma forma, a liberação da memória é feita empartes

int** matriz;

Ponteiro para ponteiro

30

31

Representando Matrizes Dinâmicas na

Memória

100

101

102

103

104

105

106

107

300

408

Memória

int** m;

6

300

10

304

7

408

11

412

Vetor Linha

m

Ponteiro (endereço inicial do vetor linha)

100

6 10

7 11

Matriz m

Alocando uma Matriz Dinâmica

int main () {

int linhas, colunas,i,j;

printf(“Numero de linhas e colunas da matriz:\n");

scanf("%d %d",&linhas,&colunas);

float** mat ;

mat = (float**) malloc(linhas * sizeof(float*));

for (i = 0 ; i< linhas ; i++) {

mat[i]= (float*) malloc(colunas * sizeof(float)) ;

}

printf("\n Digite os elementos da matriz:\n");

for(i=0; i< linhas; i++) {

for(j=0; j< colunas; j++) {

printf("Elemento [%d][%d] = ",i,j);

scanf("%f",&mat[i][j]);

printf("\n");

}

}

/* continua */

Alocando vetor de ponteirosAlocando

vetores-linha

Liberando uma Matriz Dinâmica

void liberaMatriz (int** mat, int linhas) {

int i,j;

for(i=0; i< linhas; i++) {

free(mat[i]);

}

free(mat);

}

Libera primeiro cada vetor

linha

Libera depois vetor de ponteiros

void imprimeMatriz(int linhas, int** mat) {

int i,j;

for (i=0; i < linhas; i++){

for (j=0;j < 2; j++){

printf("%d ",mat[i][j]);

}

printf("\n");

}

}

Parâmetro do tipo ponteiro para ponteiro de int

Acesso usando notação de ponteiro:

*(*(mat+i)+j)

Passando Matrizes Dinâmicas como

Argumentos

Cuidado na Assinatura da Função

void imprimeMatriz(int linhas, int** mat) {

int i,j;

for (i=0; i < linhas; i++){

for (j=0;j < 2; j++){

printf("%d ",mat[i][j]);

}

printf("\n");

}

}

int main() {

int matriz[][2] = {{6,10},{7,11}};

imprimeMatriz(2,matriz);

return 0;

}

Parâmetro do tipo ponteiro de ponteiro de int

Endereço da matriz estática passada como argumento

Erro de Execução!

Cuidado na Assinatura da Função

void imprimeMatriz(int linhas, int mat[][2]) {

int i,j;

for (i=0; i < linhas; i++){

for (j=0;j < 2; j++){

printf("%d ",mat[i][j]);

}

printf("\n");

}

}

int main() {

int matriz[][2] = {{6,10},{7,11}};

imprimeMatriz(2,matriz);

return 0;

}

Parâmetro do tipo vetor de vetores de int

Parâmetro deve indicar número de colunasCerto!

37

Resumindo ...

Relação entre ponteiros e strings

Ponteiros para strings X Vetores de

Caracteres

Vetores de ponteiros para strings

Alocação Dinâmica

Uso

Funções em C para alocação dinâmica

Usando alocação dinâmica para criar vetores

e matrizes dinâmicas

Introdução a Programação

Tipos Estruturados de Dados

2

Tópicos da AulaHoje aprenderemos a trabalhar com tipos dedados mais complexos

Tipos Primitivos x Tipos EstruturadosConceito de Tipos EstruturadosImportânciaTipos Estruturados em C (struct)Declaração de structsVariáveis do tipo structOperações com estruturasComando typedefPassando Estruturas para FunçõesEstruturas Aninhadas

3

Tipos Estruturados

C oferece tipos primitivos que servem pararepresentar valores simples

Reais (float, double), inteiros (int), caracter(char)

C oferece também mecanismos para estruturardados complexos nos quais as informações sãocompostas por diversos campos

Tipos Estruturados !

Tipos Estruturados

NomeEndereçoTelefone

IdadeData de Nascimento

Peso Altura

stringstringinteirointeirointeirofloatfloat

Cadastro Pessoal

Agrupa conjunto de tipos de dados distintos sob umúnico nomePodemos criar varios objetos na memória de umdeterminado tipo estruturado

Estruturas ou Registros Nome do tipo estruturado

Membro do tipo estruturado

Tipos Estruturados em C (struct)

NomeEndereçoTelefone

IdadeData de Nascimento

Peso Altura

Cadastro Pessoalstruct cadastro_pessoal {

char nome[50];

char endereço[100];

int telefone;

int idade;

int nascimento;

float peso;

float altura;

};

Forma Geral:

struct nome_do_tipo {

declaração de variável 1 ;

declaração de variável n ;

};

6

Importância de Tipos EstruturadosConsidere um ponto representado por duascoordenadas: x e ySem mecanismos para agrupar as duascoordenadas:

int main() {

float x ;

float y ;

}

Não dá para saber que estas variáveis

representam coordenadas de um

ponto

7

Importância de Tipos Estruturados

Uma estrutura em C serve para agrupar diversas variáveis dentro de um único contexto

struct ponto {

float x ;

float y ;

};

8

Declarando Variáveis do Tipo Ponto

A estrutura ponto passa a ser um tipoEntão, podemos declarar uma variável destetipo da seguinte forma:

struct ponto {

float x ;

float y ;

};

int main() {

struct ponto p ;

...

}

A variável é do tipo struct ponto

9

Acessando Membros do Tipo Ponto

Membros de uma estrutura são acessados via o operador de acesso ( “.” )

Para acessar as coordenadas:

p . x = 10.0 ;p . y = 5.0 ;

struct ponto {

float x ;

float y ;

};

int main() {

struct ponto p ;

p.x = 0.0;

p.y = 7.5;

...

}

O nome da variável do tipo struct ponto deve vir antes do “.”

10

Utilizando oTipo Estruturado Ponto

*/ programa que captura e imprime coordenadas*/

#include <stdio.h>

struct ponto {

float x ;

float y ;

} ;

int main (){

struct ponto p ;

printf(“\nDigite as coordenadas do ponto (x,y)”) ;

scanf (“%f %f”, &p.x , &p.y ) ;

printf(“O ponto fornecido foi:(%f,%f)\n”,p.x, p.y);

return 0 ;

} variável p não precisa de parênteses

11

Onde Declarar um Tipo Estruturado?

Geralmente, declara-se um tipo estruturado foradas funções

Escopo da declaração engloba todas as funções nomesmo arquivo fonte

Pode-se, também, declarar tipos estruturadosdentro de funções

Neste caso, escopo do tipo estruturado é na função

12

Declarando oTipo Estruturado Fora das Funções

struct ponto {

float x ;

float y ;

} ;

struct ponto alteraPonto(float x, float y){

struct ponto q;

q.x = x;

q.y = y;

return q;

}

int main (){

struct ponto p ;

printf(“\nDigite as coordenadas do ponto (x,y)”) ;

scanf (“%f %f”, &p.x , &p.y ) ;

p = alteraPonto(8,9);

...

}

Funções podem usar o tipo estruturado

declarado acima

Declarado fora das funções

13

Declarando oTipo Estruturado Dentro de uma Função

void leCoordenadas(float* x, float* y){

struct ponto {

float x ;

float y ;

};

struct ponto q;

scanf (“%f %f”, &q.x , &q.y ) ;

*x = q.x;

*y = q.y;

}

int main (){

struct ponto p ;

printf(“\nDigite as coordenadas do ponto (x,y)”) ;

leCoordenadas(&p.x , &p.y ) ;

...

}

Outra função NÃOenxerga a

declaração do tipo estruturado

Declarado dentro da função

alteraPonto

Errado !

14

Outras Formas de Declarar Tipos Estruturados e Variáveis

Pode-se declarar um tipo estruturado e umavariável deste tipo de diferentes formasstruct ponto {

float x ;

float y ;

} p;

struct {

float x ;

float y ;

} p;

Declara-se tipo e variável numa expressão só

Declara-se tipo SEM NOME e variável numa

expressão só

Cuidado com legibilidade !

15

Inicializando Variáveis de TiposEstruturados

Uma variável de um tipo estruturado pode ser inicializada com uma estrutura com o auxílio do abre-fecha parênteses( “{” e “}” )

struct pessoa {

char nome[60] ;

int idade ;

};

int main() {

struct pessoa p = {“Ana”, 30};

...

}

Inicialização da variável p do tipo struct pessoa

Deve-se inicializar os membros na ordem correta

16

Atribuição de EstruturasA estrutura armazenada por uma variável de um tipo estruturado pode ser atribuída a outra variável deste mesmo tipo estruturado

struct pessoa {

char nome[60] ;

int idade ;

};

int main() {

struct pessoa p1,p2;

p1 = {“Ana”, 30};

p2 = p1;

...

}

Atribuição de uma estrutura para a

variável p1 (Errado)

Atribuição da estrutura contida em p1 para p2

17

Outras Operações com Estruturas

struct ponto {

float x ;

float y ;

};

int main() {

struct ponto p3;

struct ponto p1 = {0.0, 4.5};

struct ponto p2 = {1.0,2.5};

p3 = p1 + p2;

printf(“O x e y do novo ponto é:%f,%f,p3.x,p3.y);

return 0;

}

Não podemos somar estruturas inteiras

Como escrever um programa que imprime a soma das coordenadas de dois pontos?

Errado !

18

Outras Operações com Estruturas

struct ponto {

float x ;

float y ;

};

int main() {

struct ponto p3;

struct ponto p1 = {0.0, 4.5};

struct ponto p2 = {1.0,2.5};

p3.x = p1.x + p2.x;

p3.y = p1.y + p2.y;

printf(“O x e y do novo ponto é:%f,%f”,p3.x,p3.y);

return 0;

}

Temos que somar membro a membro

Como escrever um programa que imprime a soma das coordenadas de dois pontos?

Certo !

19

Usando typedef

O comando typedef permite criar novosnomes para tipos existentes

Criação de sinônimos para os nomes de tiposÉ útil para abreviar nomes de tipos ou tiposcomplexos

Forma Geral:

typedef tipo_existente sinonimo;

20

Usando typedef

struct pessoa {

char nome[60] ;

int idade ;

};

typedef struct pessoa Pessoa;

int main() {

Pessoa p = {“Ana”, 30};

...

}

Tipo existente

Novo nome

Simplificou declaração do tipo de variável

Após a definição de novos nomes para os tipos, pode-se declarar variáveis usando estes nomes

21

Usando typedef

Podemos combinar typedef com declaraçãodo tipo estruturado

typedef struct pessoa {

char nome[60] ;

int idade ;

} Pessoa;

int main() {

Pessoa p = {“Ana”, 30};

...

} Criação de tipo e criação de sinônimo

22

Passagem de Estruturas para Funções

Considere a função abaixo:

void imprimePonto ( struct ponto p ){

printf(“O ponto fornecido foi:(%f,%f)\n”,p.x,p.y);

}

Assim como podemos passar tipos primitivos comoargumentos para uma função, podemos passarestruturas

23

Passagem de Estruturas para Funções

*/ programa que captura e imprime coordenadas*/

#include <stdio.h>

typedef struct ponto {

float x ;

float y ;

} Ponto;

void imprimePonto(Ponto q) {

printf(“O ponto fornecido foi:(%f,%f)\n”,q.x, q.y);

int main (){

Ponto p ;

printf(“\nDigite as coordenadas do ponto (x,y)”) ;

scanf (“%f %f”, &p.x , &p.y ) ;

imprimePonto(p);

return 0 ;

}

Passa a estrutura armazenada em pcomo argumento

24

Retornando Estruturas

Considere a função abaixo:struct ponto alteraPonto(float x, float y ){

struct ponto q;

q.x = x;

q.y = y;

return q;

}

Assim como uma função pode retornar um valor de umtipos primitivo, uma função pode retornar umaestrutura

25

Retornando Estruturastypedef struct ponto {

float x ;

float y ;

} Ponto;

Ponto alteraPonto(float x, float y){

Ponto q;

q.x = x;

q.y = y;

return q;

}

int main (){

Ponto p ;

printf(“\nDigite as coordenadas do ponto (x,y)”) ;

scanf (“%f %f”, &p.x , &p.y ) ;

p = alteraPonto(8,9);

...

}

Variável p recebe a estrutura

retornada por alteraPonto

26

Tipos Estruturados Mais Complexos

Aninhamento de estruturasMembros de uma estrutura podem ser outrasestruturas previamente definidasExemplo:

typedef struct ponto {

float x ;

float y ;

} Ponto;

typedef struct circulo {

Ponto centro;

float raio;

} Circulo;

Tipo estruturado Circulo tem como um dos membros um

Ponto

27

Usando os Tipos Ponto e Circulo

float distancia ( Ponto p , Ponto q ){

float d = sqrt((q.x – p.x )*(q.x – p.x)+

(q.y – p.y)*(q.y – p.y)) ;

return d ;

}

int interior ( Circulo c , Ponto p ){

float d = distancia ( c.centro , p ) ;

return ( d <= c.raio ) ;

}

Função que calcula a distância entre 2 pontos

2

12

2

12 )()( yyxxd

Função que determina se um ponto está no círculo

Passa para distancia uma estrutura Ponto que é membro da estrutura

Circulo

28

Resumindo …

Tipos EstruturadosStructsOperações com EstruturasComando typedefPassando Estruturas para FunçõesEstruturas Aninhadas

Introdução a Programação

Ponteiros para Estruturas,

Outros Tipos de Estruturas

2

Tópicos da AulaHoje aprenderemos a trabalhar com ponteirospara estruturas

Ponteiros para estruturasAlocação dinâmica de estruturasPassagem por referência de estruturasVetores de estruturas x Vetores de ponteiros paraestruturas

Aprenderemos também que existe outrosformas de tipos estruturados em C

Tipo União (Union)Tipos Enumerados (Enum)

3

Usando Ponteiro para EstruturasPodemos ter variáveis do tipo ponteiro paraestruturas

struct ponto {

float x ;

float y ;

};

int main() {

struct ponto q;

struct ponto* p ;

p = &q

...

}

A variável p armazena o

endereço de uma estrutura

Acessando os Membros Através do Ponteiro

Os membros de uma estrutura são acessadosusando seu nome seguido do operador ponto

Podemos acessar os membros do mesmo jeito utilizando ponteiros?

struct ponto {

float x ;

float y ;

};

int main() {

struct ponto q;

struct ponto* p = &q;

p.x = 7.0;

...

}

Não !

Não podemos acessar membros de uma estrutura via ponteiro desta

forma

5

Para acessar os membros de uma estrutura por meio de um ponteiro, existem 2 formas:

Usando o operador * seguido da variável dentro de parênteses

Precisa de parênteses para variável p, senão o compilador entenderia como*(p.x)- Errado!

Acessando os Membros Através do Ponteiro

(*p).x = 7.0;

Usando o operador ->

p->x = 7.0;

6

A alocação dinâmica de estruturas é feita de forma similar a como é feito com tipos primitivos

Alocação Dinâmica de Estruturas

struct pessoa {

char nome[32] ;

int idade ;

double peso;

};

int main() {

struct pessoa* p;

p = (struct pessoa*) malloc(sizeof(struct pessoa));

strcpy(p->nome,”Ana”);

p->idade = 30;

...

}

Aloca espaço na memória para uma estrutura que contém um vetor de 32 caracteres (32

bytes), um inteiro (4 bytes) e um double (8 bytes)

7

Alocação Dinâmica de Estruturas

struct paciente {

float* vTemperatura ;

struct pessoa individuo;

};

typedef struct paciente Paciente;

int main() {

Paciente* p;

p = (Paciente*) malloc(sizeof(Paciente));

p->individuo.idade = 30;

strcpy(p->individuo.nome,”Ana”);

p->vTemperatura = (float*) malloc(5 * sizeof(float));

p->vTemperatura[0] = 37.5;

} Aloca espaço na memória para uma estrutura que contém um ponteiro para float (4 bytes), e

uma estrutura pessoa (44 bytes)

Aloca espaço na memória para um vetor

com 5 inteiros

8

Passagem de Estruturas para Funções

Cópia da estrutura na pilha não é eficienteÉ mais conveniente passar apenas o ponteiro daestrutura

void captura ( struct ponto p ) {

printf( “Digite as coordenadas do ponto (x,y):” ) ;

scanf ( “%f %f ”, &p.x, &p.y ) ;

}

int main() {

struct ponto p;

captura(p);

...

}

Valores da estrutura não podem ser modificados

9

Uma função para imprimir as coordenadas

Uma função para ler as coordenadasvoid captura ( struct ponto *p ) {

printf( “Digite as coordenadas do ponto (x,y):” ) ;

scanf ( “%f %f ”, &p->x, &p->y ) ;

}

Passagem de Ponteiros para Estruturas para Funções

void imprime ( struct ponto* p ){

printf(“O ponto fornecido foi:(%f,%f)\n”,p->x,p->y);

}

Permite modificar o valor da variável p

10

struct ponto {

float x ;

float y ;

} ;

void imprime ( struct ponto* p ){

printf(“O ponto fornecido foi:(%f,%f)\n”,p->x,p->y);

}

void captura ( struct ponto* p ) {

printf( “Digite as coordenadas do ponto (x,y):” ) ;

scanf ( “%f %f ”, &p->x, &p->y ) ;

}

int main (){

struct ponto p ;

captura(&p);

imprime(&p);

}

Passagem de Ponteiros para Estruturas para Funções

11

Vetores de EstruturasPodemos utilizar vetores de estruturasConsidere o cálculo de um centro geométrico de umconjunto de pontos

n

y

yn

x

x

n

i

i

n

i

i 11 e

struct ponto centrogeometrico(int n,struct ponto* v){

int i ;

struct ponto p = { 0.0 , 0.0 } ;

for ( i = 0 ; i < n ; i++ ){

p.x += v[i].x ;

p.y += v[i].y ;

}

p.x /= n ;p.y /= n ;

return p ;

}

Endereço inicial do vetor de pontos

Acessando coordenada x do i-ésimo ponto do vetor v

12

Vetores de Ponteiros para EstruturasSão úteis quando temos de tratar um conjuntode elementos complexos

Exemplo: Vetores de alunos

Matricula: número inteiro ;Nome: cadeia com 80 caracteres ;Endereço: cadeia com 120 caracteres ;Telefone: cadeia com 20 caracteres ;

Em C podemos representar aluno:

struct aluno {

int mat ;

char nome [81] ;

char end [121] ;

char tel [ 21 ] ; } ;

typedef struct aluno ALUNO ;

13

Se usarmos um vetor com um número máximode alunos:

#define MAX 100

ALUNO tab[MAX];

Tipo ALUNO ocupa pelo menos 227(=4+81+121+21)bytesSe for usado um número de alunos inferior aomáximo estimado, a declaração de um vetor dessaestrutura representa um desperdício significativo dememóriaUma solução é:

Vetores de Ponteiros para Estruturas

#define MAX 100

ALUNO* tab[MAX];

14

#define MAX 100

struct aluno {

int mat ;

char nome [81];

char end [121] ;

char tel [21] ;

} ;

typedef struct aluno ALUNO;

ALUNO* tab[MAX];

void inicializa (int n,ALUNO** tab){

int i ;

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

tab [i] = NULL ;

}

Usando Vetores de Ponteiros para Estruturas

Todas as posições do vetor de ponteiros guardam endereços nulos

15

void preenche(int n,ALUNO **tab ){

int i;

for ( i = 0; tab[i]!= NULL && i < n; i++ );

if (i < n) {

tab[i]= ( ALUNO*) malloc (sizeof(ALUNO));

printf (“\nEntre com a matricula:”);

scanf (“%d”, &tab[i]->mat) ;

printf (“\nEntre com o nome:”) ;

scanf (“%80[^\n]”, tab[i]->nome) ;

printf (“\nEntre com o endereco:”) ;

scanf (“%120[^\n]”, tab[i]->end) ;

printf (“\nEntre com o telefone:”) ;

scanf (“%20[^\n]”, tab[i]->tel) ;

} else {

printf(“Vetor cheio\n”);

}

}

Usando Vetores de Ponteiros para Estruturas

Espaço alocado para um novo aluno e endereço é armazenado no vetor

16

void retira(int n,ALUNO** tab,int i ) {

if ( i >= 0 && i < n) {

if (tab[i] != NULL) {

free(tab[i]);

tab[i] = NULL;

}

} else {

printf(“Indice fora do limite do vetor\n”);

}

}

Usando Vetores de Ponteiros para Estruturas

17

void imprime(int n,ALUNO** tab,int i ){

if ( i >= 0 && i < n) {

if (tab[i]!= NULL){

printf (“Matricula: %d\n”,tab[i]->mat);

printf (“Nome: %s\n”,tab[i]->nome);

printf (“Endereço: %s\n”,tab[i]->end);

printf (“Telefone: %s\n”,tab[i]->tel);

}

} else {

printf(“Indice fora do limite do vetor\n”);

}

}

Usando Vetores de Ponteiros para Estruturas

18

void imprime_tudo(int n,ALUNO** tab){

int i;

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

imprime(n,tab,i);

}

Usando Vetores de Ponteiros para Estruturas

19

int main(){

ALUNO *tab[10];

inicializa(10,tab);

preenche(10,tab);

preenche(10,tab);

preenche(10,tab);

imprime_tudo(10,tab);

retira(10,tab,0);

retira(10,tab,1);

retira(10,tab,2);

return 0 ;

}

Usando Vetores de Ponteiros para Estruturas

20

Tipos Estruturado enum

O tipo estruturado enum (enumeração) consistede um conjunto de constantes inteiras, em quecada uma delas é representada por um nomeUma enumeração é uma forma mais elegantede organizar constantes

Dá-se um contexto ao conjunto de constantesUma variável de um tipo enumerado pode assumirqualquer valor listado na enumeração

21

Definindo uma enum

Forma Geral :

enum dias_semana {

domingo, segunda, terca, quarta,

quinta, sexta, sabado };

Exemplo:

enum nome_do_tipo {

constante1, constante2,constante n

};

22

Valores das Constantes Definidas em uma enum

Internamente, o compilador atribui valoresinteiros a cada constante seguindo a ordem emque elas são definidas, começando de 0, depois1, etc

Portanto:enum dias_semana {

domingo, segunda, terca, quarta,

quinta, sexta, sabado };

sabado == 6

segunda == 1

domingo == 0

23

Valores das Constantes Definidas em uma enum

No entanto, o programador pode atribuirdiretamente os valores inteiros desejados

enum dias_semana {

domingo = 1, segunda, terca, quarta,

quinta, sexta, sabado };

sabado == 7

segunda == 2

domingo == 1

24

Usando enums

enum dias_semana {

domingo, segunda, terca, quarta, quinta, sexta,

sabado

};

typedef enum dias_semana DIAS;

int dia_util(DIAS dia) {

int ehUtil = 0;

if (dia >= segunda && dia <= sexta) {

ehUtil = 1;

}

return ehUtil;

} Função verifica se um dia passado como

argumento é útil ou não

25

Tipo Estruturado UnionAssim como uma struct, uma union agrupa umconjunto de tipos de dados (que podem ser distintos)sob um único nome

Diferentemente de uma struct, uma union

armazena valores heterogêneos em um mesmo espaçode memória

Apenas um único membro de uma union pode estararmazenado em um determinado instante

A atribuição a um membro da union sobrescreve o valoranteriormente atribuído a qualquer outro membro

Utiliza-se em casos onde se quer otimizar uso de memória

26

Definindo uma Union

Forma Geral :

union numero {

char str[32];

int inteiro ;

double real;

};

Exemplo:

union nome_do_tipo {

declaração de variável 1 ;

declaração de variável n ;

};

27

Union x Structunion numero {

char str[32];

int inteiro ;

double real;

};

struct pessoa {

char nome[32];

int idade ;

double peso;

};

4 bytes

nome -32 bytes

idade -4 bytespeso - 8 bytes

44 bytes na memória (soma

do tamanho das variáveis)

str, inteiro

e real -32 bytes

32 bytes na memória (maior variável - str)

28

Manipulando uma Union

Declaração de variável

union numero num;

Acesso aos membros de uma unionDiretamente ( Operador “ . ” ):

Via um ponteiro (Operador “ -> ” ):

num.inteiro = 60;

union numero num;

union numero* pnum = &num;

pnum->real = 60.5;

29

Cuidado ao Acessar Membros de Unions

union numero {

char str[32];

int inteiro ;

double real;

};

typedef union numero NUMERO;

int main(){

NUMERO num;

strcpy(num.str,"Joao");

num.real = 45.7;

num.inteiro = 70;

printf("num.inteiro = %d\n",num.inteiro);

printf("num.real = %lf\n",num.real);

printf(“num.str = %s\n",num.str);

return 0;

}

num.inteiro = 70

num.real = ?????

num.str = ??????

O que será impresso nas 3 linhas da área demarcada?

Comportamento imprevisível!

Introdução a Programação

Arquivos

2

Tópicos da Aula

Hoje aprenderemos a persistir dadosConceito de arquivosImportância de persistênciaModos de acesso de arquivos em COperações em arquivosFunções de leitura/escrita em modo binário

2

3

Arquivos

Um arquivo representa um elemento deinformação armazenado em memóriasecundária (disco)

Características:Informações são persistidasAtribui-se nomes aos elementos de informação(arquivos e diretórios),em vez de endereços dememóriaAcesso às informações são mais lentos

4

Persistência... pra quê?

Não perder os dados no fim da execução deum programa

Memória temporária(volatil)principalMais rápida e cara

Memória permanentesecundáriamais lenta e barata

Para melhorar velocidade de acesso, a cadaacesso, transfere-se trechos maiores doarquivo para espaços da memória (buffers)

4

55

Modos de Acesso a Arquivos em C

Dois modos de acesso:Texto e Binário

Arquivo Texto:

0 1 2 3 4

Arquivo Binario:

0 1 2 3 4

Informação persistidaString

Inteiros

66

Modo Texto

É interpretado como uma seqüência decaracteres agrupadas em linhasLinhas são separadas por um caractere denova linha

Vantagens:Pode ser lido facilmente por uma pessoaEditado por editores de texto convencionais

DesvantagensCodificação dos caracteres pode variar (ASCII, UTF-8, ISSO-8859, etc)Arquivos tendem a ser maiores (todas os dados sãoconvertidos para caracteres)

77

Modo Binário

Dados são armazenados da mesma forma quesão armazenados na memória principal

Vantagens:Facilmente interpretados por programasMaior velocidade de manipulaçãoArquivos são, geralmente, mais compactos

Desvantagens:Difícil de serem entendidos por pessoasDependentes da máquina onde foram gerados

88

Operações em Arquivos

AberturaSistema Operacional (SO) encontra arquivo pelonomePrepara buffer na memória

LeituraSO recupera trecho solicitado do arquivoParte ou todo trecho pode vir do buffer

99

Operações em Arquivos

EscritaSO altera conteúdo do arquivoAlteração é feita primeiro no buffer para depois sertransferida para o disco

FechamentoInformação do buffer é atualizada no discoÁrea do buffer utilizada na memória é liberada

1010

Abertura de Arquivos em C

Operações de manipulação de arquivos em Cse encontram, geralmente, na stdio.hFunção de Abertura

Nome

Nome do arquivoFILE

Tipo estruturado que representa uma abstração doarquivo

modo

r - Indica leituraw – Indica escritaa – Indica escrita ao final do existentet – Indica modo textob – Indica modo binário

FILE* fopen(char* nome,char* modo);

11

Abrindo arquivos

FILE *fptr; /* ponteiro para arquivo */

fptr = fopen(“arqtext.txt”, “w”);

nome do arquivo

Tipo de abertura

“r” Abrir arquivo texto para leitura. O arquivo deve estar presente no disco

“w” Abrir arquivo texto para gravação. Se o arquivo existir ele será destruído e reinicializado. Se não existir, será criado

“a” Abrir um arquivo texto para gravação. Os dados serãoadicionados no fim do arquivo existente, ou cria um novo

Modo t pode ser omitido

12

Abrindo arquivos

FILE *fptr; /* ponteiro para arquivo */

fptr = fopen(“arqtext.txt”, “w+”);

Tipo de abertura

“r+” Abrir arquivo texto para leitura e gravação. O arquivo deve existir e pode ser atualizado.

“w+” Abrir arquivo texto para leitura e gravação. Se o arquivo existir ele será destruído e reinicializado. Se não existir, será criado.

“a+” Abrir um arquivo texto para atualização e para adicionar dados no fim do arquivo existente, ou cria um novo

13

Abrindo arquivos

FILE *fptr; /* ponteiro para arquivo */

fptr = fopen(“arqtext.txt”, “wb”);

Tipo de abertura“rb” Abrir arquivo binário para leitura. O arquivo deve

estar presente no disco“wb” Abrir arquivo binário para gravação. Se o arquivo existir

ele será destruído e reinicializado. Se não existir, serácriado

“ab” Abrir um arquivo binário para gravação. Os dados serãoadicionados no fim do arquivo existente, ou cria um novo

14

Abrindo arquivos

FILE *fptr; /* ponteiro para arquivo */

fptr = fopen(“arqtext.txt”, “wb+”);

Tipo de abertura“rb+” Abrir arquivo binário para leitura e gravação. O

arquivo deve existir e pode ser atualizado.“wb+” Abrir arquivo binário para leitura e gravação. Se o

arquivo existir ele será destruído e reinicializado. Se não existir, será criado.

“ab+” Abrir um arquivo binário para atualização e para adicionar dados no fim do arquivo existente, ou cria umnovo

1515

Observações sobre Abertura de

Arquivos em C

SO mantém um “cursor” que indica a posiçãode trabalho no arquivoSe não for possível a abertura, a função fopenretorna NULL

1616

Fechamento de Arquivos

Após leitura/escrita do arquivo, devemos fechá-loFunção de fechamento

Retorna 0 se o arquivo foi fechado com sucesso

int fclose(FILE* fp);

1717

Leitura (Modo Binário)

p é o endereço de memória em que vai ser armazenado oque for lidotam é o tamanho em bytes de cada elemento lidonelem é o número de elementos de tamanho tam lidosRetorna a quantidade de bytes lidos com sucesso (tam *nelem)

int fread(void* p,int tam,int nelem,FILE* fp);

1818

Escrita (Modo Binário)

p é o endereço de memória cujo conteúdo deseja-se salvarem arquivotam é o tamanho em bytes de cada elemento escritonelem é o número de elementos de tamanho tam escritosRetorna a quantidade de bytes escritos com sucesso (tam *nelem)

int fwrite(void* p,int tam,int nelem,FILE* fp);

1919

Verificando o Final do Arquivo

Em operações de leitura do arquivo, é comumverificarmos se o final do arquivo já foi atingidoFunção de verificação de fim de arquivo

Retorna 1 se o fim do arquivo foi atingidoRetorna 0 caso contrário

int feof(FILE* fp);

2020

Usando fwrite na Escrita

#include <stdio.h>

typedef struct ponto {

float x,y;

} Ponto;

int main () {

int i,n;

Ponto p;

FILE* fp = fopen(“arquivo”, “wb”);

if (fp == NULL) {

printf(“Erro na abertura do arquivo.\n”);

exit(1);

}

printf(“Digite numero de pontos a gravar\n”);

scanf(“%d”,&n);

for (i = 0; i < n; i++) {

scanf(“%d %d”,&p.x,&p.y);

fwrite(&p, sizeof(Ponto), 1, fp);

}

fclose(fp);

}

Programa que salva n pontos em um arquivo binário

Gravando cada ponto entrado pelo usuario usando fwrite

2121

Usando fread na Leitura

#include <stdio.h>

int main () {

int i,n;

Ponto p;

FILE* fp = fopen(“arquivo”, “rb”);

if (fp == NULL) {

printf(“Erro na abertura do arquivo.\n”);

exit(1);

}

while(!feof(fp)){

fread(&p, sizeof(Ponto), 1, fp);

printf(“Ponto lido: (%d,%d)”,p.x,p.y);

}

fclose(fp);

}

Programa que lê todos os pontos armazenados em um arquivo binário

Lê cada ponto e guarda na variável p

Testa se o fim do arquivo já foi atingido

2222

Leitura/Escrita de Blocos de Dados

As funções fread/fwrite permitem ler/escrevergrandes blocos de dados em um arquivo

Um dos parâmetros indica qual é a quantidade dedados de um determinado tipo a ser lido/escrito

Portanto podem ser úteis para ler/escreverestruturas ou vetores em um arquivo numaúnica chamada de função

2323

Usando fwrite na Escrita

#include <stdio.h>

typedef struct ponto {

float x,y;

} Ponto;

void salva (char* arquivo, int n, Ponto* vet) {

FILE* fp = fopen(arquivo, “wb”);

if (fp == NULL) {

printf(“Erro na abertura do arquivo.\n”);

exit(1);

}

fwrite(vet, sizeof(Ponto), n, fp);

fclose(fp);

} Função que salva um vetor de pontos em um arquivo binário

Número de pontos do vetor

2424

void carrega (char* arquivo, int n, Ponto* vet) {

FILE* fp = fopen (arquivo, “rb”);

if (fp == NULL) {

printf(“Erro na abetura do arquivo.\n”);

exit(1);

}

fread (vet, sizeof(Ponto), n, fp);

fclose(fp);

}

Função que recupera um vetor de pontos de um arquivo binário

Usando fread na Leitura

2525

Usando as Funções Definidas

Anteriormenteint main() {

Ponto *entrada, *saida; int nPontos, cont,pos ;

FILE *arquivo;

char nome_arquivo[121];

printf(“Digite o nome do arquivo:\n”);

scanf(“%120s”,nome_arquivo);

printf(“\nDigite o número de pontos:\n”);

scanf(“%d”,&nPontos);

entrada = (Ponto *) malloc(nPontos*sizeof(Ponto));

for (cont = 0; cont < nPontos;cont++) {

printf(“Digite coordenadas x,y:\n”);

scanf(“%f%f”,&entrada[cont].x,&entrada[cont].y);

}

/* continua */ Programa que salva e recupera um vetor de pontos em um arquivo binário

2626

salva(nome_arquivo, nPontos, entrada);

do {

printf(“Digite agora a posição do ponto que

deseja ver: \n”);

scanf(“%d”,&pos);

} while (pos > nPontos || pos<=0 );

saida = (Ponto *) malloc (nPontos*sizeof(Ponto));

carrega(nome_arquivo, nPontos, saida);

printf(“O ponto na posicao %d é {%f,%f}\n”, pos,

saida[pos-1].x, saida[pos-1].y);

}

Usando as Funções Definidas

Anteriormente

Gravando os pontos no arquivo

Lendo os pontos do arquivo

Introdução a Programação

Manipulando Arquivos em

Modo Texto

2

Tópicos da Aula

Hoje aprenderemos funções de manipulaçãode arquivos texto

Funções de leitura em modo textoFunções de escrita em modo textoConsiderações sobre a utilização de operaçõesde leitura/escrita em modo texto e binário

Aprenderemos também algumas funções queservem para posicionar o cursor no arquivo

Exemplos de uso

2

33

Leitura (Modo Texto)

A cada operação de leitura, os dadoscorrespondentes são transferidos para amemória e o cursor avança e aponta para opróximo dadoExiste em C a função fscanf para leituraformatada de dados de um arquivo modo texto

Similar a scanfLê de um arquivo passado como parâmetro em vezde somente da entrada padrão (teclado)Pode ler também da entrada padrão (arquivo stdin)

44

Leitura com fscanf

Retorna número de dados lidos com sucessofp é o ponteiro para o arquivoformato equivale aos códigos de formatação (iguais aodo scanf)end_variaveis corresponde a lista de endereços devariáveis que armazenarão os dados lidos do arquivo

int fscanf(FILE* fp, char* formato,end_variaveis)

55

Leitura com fscanf

A cada operação de leitura, os dadoscorrespondentes são convertidos de caracterespara o tipo (formato) especificado em fscanf

Portanto, arquivo deve ter sido previamentegravado em modo texto

Se gravado em modo binário, a função tenta mapearos dados lidos para caracteres para depois fazer aconversão para o tipo especificado

66

Usando fscanf para Leitura (Modo

Texto)

#include <stdio.h>

int main() {

FILE *fp;

char primeiraPalavra[121];

fp = fopen(“teste.txt”,”r”);

if (fp == NULL) {

printf(“Impossível abrir arquivo”);

exit(1);

}

fscanf(fp, “%120s”,primeiraPalavra);

printf(“A primeira palavra do arquivo teste.txt

é: %s\n”,primeiraPalavra);

fclose(fp);

return 0;

}

Lê uma string do arquivo apontado por fp de até 120 caracteres e armazena

em primeiraPalavra

77

Constante EOF

A constante (simbólica) EOF indica o fim dearquivo

Definida no arquivo stdio.h

Ela NÃO é um caracterÉ um inteiro que indica fim de arquivoGeralmente um valor negativo

NÃO é um valor presente no arquivoÉ um valor retornado por funções de leituraindicando fim de arquivo ou erro de leitura

88

Outras Funções de Leitura (Modo Texto)

Lê um caractere de um arquivoRetorna o código do caractere lidoRetorna EOF se fim do arquivo for alcançado

s é a cadeia de caracteres que armazenará o que for lidon é o número máximo de caracteres a serem lidosLê uma seqüencia de caracteres até que ‘\n’ sejaencontrado ou que n caracteres tenham sido lidosRetorna ponteiro para a cadeia s

int fgetc(FILE* fp);

char* fgets(char* s, int n, FILE* fp);

99

Usando fgetc para a Leitura

#include <stdio.h>

int main() {

FILE *fp; int c;int nCaracteres = 0, nLinhas = 0;

fp = fopen(“teste.txt”,”r”);

if (fp == NULL) {

printf(“Impossível abrir arquivo”);

exit(1);

}

while ((c = fgetc(fp)) != EOF) {

if (c == „\n‟) nLinhas++;

else nCaracteres++;

}

printf(“Caracteres:%d,Linhas:%d\n”,nCaracteres,nLinhas);

fclose(fp);

return 0;

}

Programa conta número de caracteres e conta o número de

linhas de um arquivo

Lê caractere e ainda verifica se chegou no

fim do arquivo

1010

int main() {

FILE *fp;

int achou = linhaOcorrencia = 0;

char palavra[121], linha [121];

printf (“Digite a palavra:\n”);

scanf(“ %120[^\n]”,palavra);

fp = fopen(“teste.txt”,”r”);

if (fp == NULL) {

printf(“Impossível abrir arquivo”);exit(1);

}

while (fgets(linha,121,fp) != NULL && !achou) {

linhaOcorrencia++;

if (strstr(linha,palavra) != NULL)

achou = 1;

}

fclose(fp);

printf(“Ocorrências de %s = %d\n”, palavra,nOcorrencias);

}

Programa informa linha da ocorrência de uma palavra em um arquivo com linhas (maximo 120 caracteres)

Usando fgets para a Leitura

Lê uma linha e armazena em linha

Utiliza função strstr de string.h para saber se palavra é substring de linha

1111

Escrita (Modo Texto)

A cada operação de escrita, os dados sãogravados na memória e posteriormente nodisco, e o cursor avança apontando para aproxima posição do arquivo:Existe em C a função fprintf para escritaformatada de dados em um arquivo modo texto

Similar a printfEscreve em um arquivo passado como parâmetroem vez de somente na saída padrão (monitor)Pode escrever também na saída padrão (arquivostdout)

1212

Escrita com fprintf

Retorna número de dados escritos com sucessofp é o ponteiro para o arquivoformato equivale aos códigos de formatação (iguais aodo printf)variaveis corresponde a lista de variáveis, cujosconteúdos serão escritos no arquivo

int fprintf(FILE* fp, char* formato,variaveis)

1313

Escrita com fprintf

A cada operação de escrita, os dadoscorrespondentes são convertidos do tipo(formato) especificado em fprintf paracaracteresSe arquivo aberto em modo binário , dados sãogravados também como caracteres

1414

#include <stdio.h>

int main() {

FILE *fp;

char palavra[121];

fp = fopen(“teste.txt”,”w”);

if (fp == NULL) {

printf(“Impossível abrir arquivo”);

exit(1);

}

printf (“Digite a palavra:\n”);

scanf(“ %120[^\n]”,palavra);

fprintf(fp,“%s\n”,palavra);

fclose(fp);

return 0;

}

Usando fprintf para Escrita (Modo

Texto)Programa escreve uma palavra de no

máximo 120 caracteres em um arquivo

1515

Outras Funções de Escrita (Modo Texto)

Escreve um caractere em um arquivoRetorna o código do caractere escrito

s é a cadeia de caracteres que será escritaRetorna ponteiro para a cadeia s

int fputc(FILE* fp, char c);

char* fputs(char* s,FILE* fp);

1616

int main() {

FILE *e; FILE *s;

int caractere; char nome_entrada[121];

printf (“Digite o nome do arquivo de entrada:\n”);

scanf(“%120s”, nome_entrada);

e = fopen(nome_entrada,”r”);

if (e== NULL) {

printf(“Impossível abrir arquivo de entrada”);exit(1);

}

s = fopen(strcat(nome_entrada,”_maiuscula”),”w”);

if (s== NULL) {

printf(“Impossível abrir arquivo de saida”);exit(1);

}

while ((caractere = fgetc(e)) != EOF)

fputc(toupper(caractere),s);

fputs(“\nArquivo Convertido!”,s);

fclose(e); fclose(s);

return 0;}

Programa lê um arquivo e gera outro com todas as letras convertidas para maiusculas

Usando fputs e fputc para Escrita

Usuário fornece o nome do arquivo

Converte caractere a caractere e escreve no

arquivo

1717

Operações de Leitura/Escrita

(Modo Texto x Modo Binário)

As operações de leitura/escrita em modo textopermitem uma visualização melhor do resultadoPara operações que envolvem estruturas ouvetores, operações em modo binário sãomenos trabalhosasConsidere a estrurura abaixo:

struct aluno {

char nome [60];

int mat;

char sexo;

};

1818

int main() {

FILE *arq;

struct aluno aluno1, copia;

strcpy(aluno1.nome,”Jose”);

aluno1.mat = 1;

aluno1.sexo = „M‟;

arq = fopen(“arquivoAluno1.txt”,”w+”);

if (arq== NULL) {

printf(“Impossível abrir arquivo de entrada”);exit(1);

}

fprintf(arq,“%s\n%d\n%c”,aluno1.nome,aluno1.mat,aluno1.sexo);

rewind(arq);

fscanf(arq,"%s %d %c", copia.nome,&copia.mat,&copia.sexo);

return 0;

}

Usando Operações de Leitura/Escrita

(Modo Texto)

Escreve membro a membro da estrutura

Lê membro a membro da estrutura

Programa escreve e lê uma estrutura em/de um arquivo

Volta para inicio do arquivo

1919

int main() {

FILE *arq;

struct aluno aluno1, copia;

strcpy(aluno1.nome,”Jose”);

aluno1.mat = 1;

aluno1.sexo = „M‟;

arq = fopen(“arquivoAluno1.bin”,”wb+”);

if (arq== NULL) {

printf(“Impossível abrir arquivo de entrada”);

exit(1);

}

fwrite(&aluno1,sizeof(Aluno),1,arq);

rewind(arq);

fread(&copia,sizeof(Aluno),1,arq);

return 0;

}

Usando Operações de Leitura/Escrita

(Modo Binário)

Escreve toda a estrutura

Lê toda a estrutura

Programa escreve e lê uma estrutura em/de um arquivo

2020

Funções Utilitárias

Retorna a posição atual do cursor do arquivoCorresponde a distancia em bytes em relação ao começodo arquivo

long ftell(FILE* fp);

Devem ser utilizadas com cautela em arquivos no modotexto, pois nem sempre o posicionamento do cursor vaiser o desejado

Certas plataformas podem colocar caracteres de formataçãonão visíveis que podem alterar o tamanho do arquivo (númerode bytes)

2121

Funções Utilitárias

Utilizada para posicionamento do cursor em um arquivodist é o número de bytes em relação a origemorigem é uma posição do cursor do arquivo em bytes(SEEK_CUR – posição corrente; SEEK_SET – início doarquivo; SEEK_END – final do arquivo)Retorna a nova posição do cursor

long fseek(FILE* fp,long dist,int origem);

void rewind(FILE* fp);

Utilizada para posicionamento do cursor no início doarquivo

2222

Funções Utilitárias

Ponto le_ponto (FILE* fp, int i) {

Ponto p;

fseek (fp, i*sizeof(Ponto), SEEK_SET);

fread(&p, sizeof(Ponto), 1, fp);

return p;

}

int tamanho_arquivo (FILE *fp) {

int tamanho;

fseek (fp, 0, SEEK_END);

tamanho =ftell (fp);

return tamanho;

}

Função que recupera o i-ésimo ponto armazenado em um arquivo

Função que retorna o tamanho do arquivo em bytes

23

Resumindo ...

Funções de leitura em modo textofscanffgetsfgetc

Funções de escrita em modo textofprintffputsfputc

Quando utilizar operações de leitura/escrita em modotexto e binárioPosicionamento dos cursores em arquivos

23

Introdução a Programação

Listas Encadeadas

Tópicos da Aula

Hoje aprenderemos que existem, além de

vetores, estruturas de dados dinâmicas que

podem armazenar coleções de dados

Estruturas Dinâmicas e Vetores

Conceito de listas encadeadas

Listas Encadeadas x Vetores

Funções de manipulação de listas encadeadas

Variações de listas encadeadas

2

3

Vetores

Declaração de vetor implica na especificação de seu

tamanho

Não se pode aumentar ou diminuir tamanho

Outra alternativa no uso de vetores é alocar

dinamicamente o espaço necessário e guardar

endereço inicial do vetor

Porém, depois de determinado o tamanho do vetor,

não podemos liberar posição de memória arbitrária

Possível desperdício ou falta de memória!

4

Estruturas Dinâmicas

Uma estrutura de dado dinâmica consiste em

uma estrutura que pode aumentar ou diminuir

de tamanho de acordo com a necessidade da

aplicação (do programador)

Evita desperdício e/ou falta de memória

Programador é encarregado de requisitar e

liberar espaços de memória explicitamente

Uso de alocação dinâmica

Requer mais esforço por parte do programador!

5

Listas Encadeadas

Uma lista encadeada é uma estrutura dinâmica que

pode ser utilizada para armazenar um conjunto de

dados

Junto a cada elemento deve-se armazenar o

endereço para o próximo elemento (elementos

encadeados)

Elemento + ponteiro = nó da lista

Diferentemente de vetores, elementos geralmente não são

armazenados em espaços contíguos de memória

Caso não exista próximo elemento, o ponteiro para o

próximo elemento é NULL

6

Listas Encadeadas

Para cada novo elemento inserido na lista, aloca-se

um espaço de memória para armazená-lo

Para remover elemento deve-se liberar o endereço

de memória reservado para armazenar o elemento

O acesso aos elementos é sempre seqüencial

Não se pode garantir que os elementos ocuparão um

espaço de memória contíguo (não se pode localizar

elementos com base em um deslocamento constante)

7

Listas Encadeadas x Vetores

Listas Encadeadas

+ Uso eficiente da memória

- Complexidade de manipulação da estrutura

- Informação deve ser guardada em uma estrutura

que guarda também um endereço (requer mais

memoria por informação armazenada)

Vetores

+Simplicidade no acesso (manipulação) aos

elementos da estrutura

- Desperdício ou falta de memória

- Menor Flexibilidade

8

Representação de Listas Encadeadas

info1

primeiro

struct lista {

int info ; /* info pode ser de qualquer tipo */

struct lista* prox;

} ;

typedef struct lista Lista ;

p

r

o

x

info2

p

r

o

x

info3

Informação armazenada no nó da

lista

Armazena o endereço do próximo nó

Armazena endereço

nulo

fim

9

Representando Listas Encadeadas na

Memória

info3

NULL

info2

112

124

info1100

104

108

112

116

120

124

128

Memória

Lista* inicio;

inicio

100

info

prox

info1

inicio

p

r

o

x

info2

p

r

o

x

info3

10

Inserção de Elementos em Listas

Encadeadas

Diferentes formas de inserir um elemento na

lista:

No começo

Mais simples

No fim

Neste caso deve-se percorrer a lista toda

11

Inserindo Elementos no Início de

Listas Encadeadas

/* inserção início da lista */

Lista* lst_insere(Lista* inicio,int i){

Lista* novo = (Lista*) malloc(sizeof(Lista));

novo->info = i ;

novo->prox = inicio ;

return novo ;

}

info1

inicio

info2 info3 info4

Novo

Endereço do começo da

listaRetorna endereço inicial atualizado

12

Inserindo Elementos no Fim de Listas

Encadeadas

/* inserção fim da lista */

Lista* lst_insere(Lista* inicio,int i){

Lista* novo = (Lista*) malloc(sizeof(Lista));

novo->info = i ;

novo->prox = NULL ;

if (inicio == NULL){

inicio = novo;

} else {

Lista* p = inicio;

while (p->prox != NULL){

p = p->prox;

}

p->prox = novo;

}

return inicio ;

}

Se lista estiver vazia, inicio vai guardar endereço de novo

Senão temos que percorrer lista até último nó, para fazê-lo

apontar para novo

13

Usando Função de Inserção de Listas

Encadeadas

int main() {

Lista* inicio;

inicio = NULL;

inicio = lst_insere(inicio,23); /* insere 23 */

inicio = lst_insere(inicio,45); /* insere 45 */...return 0 ;

}

Não esquecer de atualizar a variável que guarda endereço

inicial da lista a cada inserção!

Variavel que armazena endereço inicial da lista deve ser inicializada com NULL!

14

Imprimindo Listas Encadeadas

void lst_imprime(Lista* inicio){

Lista* p; /*variável auxiliar para percorrer a

lista */

for(p = inicio; p != NULL; p = p->prox){

printf ( “info = %d\n ”, p->info ) ;

}

}

Laço para percorrer todos os nós da lista

15

Verificando se a Lista Está Vazia

/* função vazia: retorna 1 se vazia ou 0 se não

vazia */

int lst_vazia(Lista* inicio){

if (inicio == NULL)

return 1;

else

return 0;

}

/* versão compacta da função lst_vazia */

int lst_vazia ( Lista* inicio ){

return(inicio == NULL) ;

}

16

Buscando um Elemento em Listas

Encadeadas

Lista* lst_busca(Lista* inicio,int v){

int achou = 0;

Lista* p = inicio ;

while (p != NULL && !achou) {

if (p->info == v)

achou = 1 ;

else

p = p->prox;

}

return p;

}

Retorna o endereço do primeironó que contém o elemento

buscado

Se não achou elemento, retorna o endereço nulo!

17

Removendo Elementos de Listas

Encadeadas

Dois casos devem ser tratados para a remoção de

um elemento da lista

info1

inicio

info2 info3 info4

Remoção do primeiro elemento da lista

info1

inicio

info2 info3 info4

Remoção de um elemento no meio da lista

18

Removendo Elementos de Listas

EncadeadasLista* lst_retira(Lista* inicio,int v){

Lista* ant = NULL; /* guarda elemento anterior */

Lista* p = inicio;

while(p != NULL && p->info != v){

ant = p ;

p = p->prox ;

}

/* verifica se achou o elemento */

if (p != NULL) {

if (ant == NULL)

inicio = p->prox;

else

ant->prox = p->prox;

free(p) ;

}

return inicio ;

}

Procura elemento na lista,guardando

endereço do anterior

Retorna endereço inicial da lista

Elemento no inicio, retira elemento do início

Retira elemento do meio

19

Liberando Listas Encadeadas

void lst_libera(Lista* inicio){

Lista* p = inicio ;

while(p != NULL ) {

Lista* t = p->prox;

free(p); /* libera a memória apontada por “p”*/

p = t; /* faz “p” apontar para o próximo */

}

}

Guarda o endereço do próximonó para poder libera-lo na

próxima iteração

20

Comparando Listas Encadeadas

int lst_igual(Lista* lst1,Lista* lst2){

Lista* p1 ;

Lista* p2 ;

int igual = 1

for(p1 = lst1,p2 = lst2; p1!=NULL && p2!=NULL && igual;

p1=p1->prox,p2=p2->prox){

if(p1->info!= p2->info )

igual = 0;

}

return(p1 == p2 && igual) ;

}

Se os elementos testados forem iguais, deve-se ainda ver se p1 e p2 apontam para NULL (tamanhos

das listas iguais)

21

Utilizando Funções de Manipulação de

Lista de Inteiros

#include <stdio.h>

#include “lista.h“

int main() {

Lista * ls ; /* declara uma lista não iniciada */

ls = NULL; /*inicia lista vazia */

ls = lst_insere(ls,23); /* insere o elemento 23 */

ls = lst_insere(ls,45); /* insere o elemento 45 */

ls = lst_insere(ls,56); /* insere o elemento 56 */

ls = lst_insere(ls,78); /* insere o elemento 78 */

lst_imprime(ls); /* imprime: 78 56 45 23 */

ls = lst_retira(ls,78);

lst_imprime(ls); /* imprime: 56 45 23 */

ls = lst_retira(ls,45);

lst_imprime(ls); /* imprime: 56 23 */

lst_libera(ls);

return 0 ;

}

22

Listas podem variar quanto ao:Tipo de encadeamento

Simples

Circulares

Duplas

Circulares e Duplas

Conteúdo

Tipos Primitivos

Tipos Estruturados

Variações de Listas Encadeadas

Já vimos anteriormente

2323

Listas Circulares

lista

info1 info3info2

Estrutura do nó da lista é idêntica a da lista

simplesmente endadeada

Não há noção de primeiro e último nó da lista

Para saber se toda lista foi percorrida deve-se

guardar o endereço do primeiro nó a ser lido e

comparar com o endereço do nó que está sendo lido

2424

Imprimindo uma Lista Circular

void lcirc_imprime (Lista* inicio) {

Lista* p = inicio; /* faz p apontar para o nó inicial */

/* testa se lista não é vazia*/

if (p != NULL){

do {

printf(“%d\n”,p->info);

p = p->prox;

} while (p != inicio);

}

A condição de parada do laço é quando o nó a ser percorrido for igual ao nó

inicial

25

Lista duplamente encadeada

inicio

info1 info3info2

Permite percorrer a lista em dois sentidos

Cada elemento deve guardar os endereços do

próximo elemento e do elemento anterior

Facilita percorrer a lista em ordem inversa

Retirada de elemento cujo endereço é conhecido se

torna mais simples

Acesso ao nó anterior para ajustar encadeamento não

implica em percorrer a lista toda

info4

26

Estrutura de Listas Duplamente

Encadeadas

inicio

struct lista2 {

int info ;

struct lista2* prox;

struct lista2* ant;

} ;

typedef struct lista2 Lista2 ;

Armazena o endereço do próximo nó fim

info1

p

r

o

x

a

n

t

info1

p

r

o

x

info1

a

n

t

Armazena o endereço do nó anterior

2727

inicio

info1 info3info2

novo

Inserindo Elementos no Início de

Listas Duplamente Encadeadas

Lista2* lst2_insere (Lista2* inicio, int v) {

Lista2* novo = (Lista2*) malloc(sizeof(Lista2));

novo->info = v; novo->prox = inicio;

novo->ant = NULL;

/* verifica se lista não está vazia */

if (inicio != NULL)

inicio->ant = novo;

return novo;

}

Inserção no começo da lista

2828

inicio

info1 info3info2

novo

Inserção no fim da lista

Inserindo Elementos no Fim de Listas

Duplamente Encadeadas

2929

Inserindo Elementos no Fim de Listas

Duplamente Encadeadas

Lista2* lst2_insere (Lista2* inicio, int v) {

Lista2* novo = (Lista2*) malloc(sizeof(Lista2));

novo->info = v; novo->prox = NULL;

if (inicio == NULL) {

novo->ant = NULL;

inicio = novo

} else {

Lista2* p;

while (p->prox != NULL) [

p = p->prox;

}

p->prox = novo;

novo->ant = p;

}

return inicio;

}

Se lista estiver vazia, endereço do nó anterior a

novo é NULL

Senão temos que fazer com que o último nó aponte para novo e nó anterior de

novo seja o antigo último nó

30

Lista2* lst_busca (Lista2* lista, int v)

{

Lista2* p;

int achou = 0

for (p = lista; p != NULL && !achou; p = p->prox)

if (p->info == v)

achou = 1;

return p;

}

Buscando um Elemento em Listas

Duplamente Encadeadas

Mesma lógica aplicada a listas simplesmenteencadeadas

31

Removendo Elementos de Listas

Duplamente EncadeadasTrês casos devem ser tratados para a remoção de

um elemento da lista

Remoção de um elemento no meio da lista

info1

inicio

info2 info3 info4

info1

inicio

info2 info3 info4

Remoção de um elemento do fim da lista

info1

inicio

info2 info3 info4

Remoção do primeiro elemento da lista

32

Lista2* lst2_retira (Lista2* inicio, int v) {

Lista2* p = busca(inicio, v);

if (p != NULL){

if (inicio == p)

inicio = p->prox;

else

p->ant->prox = p->prox;

if (p->prox != NULL)

p->prox->ant = p->ant;

free(p);

}

return inicio;

}

Removendo Elementos de Listas

Duplamente Encadeadas

Usando a função de busca

Retira elemento do começo da lista

Retira do meio

Só acerta o encadeamento do ponteiro para o anterior se NÃO for o último

elemento

33

lista

info1 info3info2

Lista Circular Duplamente

Encadeada

Permite percorrer a lista nos dois sentidos, a

partir de um ponteiro para um elemento

qualquer

3434

void l2circ_imprime_inverso (Lista2* lista){

Lista2* p = lista;

if (p != NULL)

do {

p = p->ant;

printf(“%d\n”, p->info);

} while (p != lista);

}

Imprimindo no Sentido Inverso com

um Lista Circular Duplamente

Encadeada

Avança para o nó anterior

35

typedef struct retangulo {

float b; /* base */

float h; /* altura */

} Retangulo;

Lista de Tipos Estruturados

Uma lista pode ser composta de elementos estruturados

Considere o tipo Retangulo

OU

typedef struct lista {

Retangulo info;

struct lista *prox;

} Lista;

Podemos definir uma lista cujos nós contenham ou um

retângulo ou um ponteiro para um retângulo

typedef struct lista {

Retangulo* info;

struct lista *prox;

} Lista;

36

Lista* insere (Lista* inicio,float b, float h) {

Lista *novo;

novo = (Lista*)malloc(sizeof(Lista));

novo->info.b = b;

novo->info.h = h;

novo->prox = inicio

return novo;

}

Inserindo um Nó em uma Lista de

Tipos Estruturados

Nó da lista contém um retângulo

37

Inserindo um Nó de uma Lista de Tipos

Estruturados

Lista* insere (Lista* inicio,float b, float h){

Retangulo *r;

r = (Retangulo*) malloc(sizeof(Retangulo));

Lista* novo = (Lista*)malloc(sizeof(Lista));

r->b = b;

r->h = h;

novo->info = r;

novo->prox = inicio;

return novo;

}

Nó da lista contém um ponteiro para um retângulo

Espaço para a estrutura Retangulo deve também ser

alocado

Introdução a Programação

Tipos Abstratos de Dados –Implementando Pilha e Fila

Abstração

2

Abstração é o processo ou resultado

de generalização por redução do

conteúdo da informação de um

conceito ou fenômeno observável,

normalmente para reter apenas a

informação que é relevante para um

propósito particular.

Fonte: Wikipedia

Tópicos da Aula

Hoje aprenderemos que existe uma forma dedefinir um tipo de dado pelas suas operações

Conceito de Tipo Abstrato de DadoDois Tipos Abstratos de Dados: Pilha e Fila

Depois aprenderemos como implementar Pilhas eFilas

Implementação de Pilha usando VetorImplementação de Pilha usando ListaImplementação de Fila usando Lista

3

44

Tipo Abstrato de Dado

Um Tipo Abstrato de Dado (TAD) é umconjunto organizado de informações e asoperações que podem atuar sobre estasinformações

Define um novo tipo de dado

Um TAD é definido indiretamente pelasoperações que podem atuar nele e os efeitosdestas operações

Exemplo de TAD: Pilha

Operações sobre Pilha (Livros) : inserção no topo eremoção no topoTipo é definido pelo comportamento

Conjunto de operações sobre o tipo

5

InserçãoRemoção

Exemplo de TAD: Fila

Operações sobre Fila (Pessoa) : inserção no fim eremoção no começo

6

RemoçãoInserção

77

TAD x Estrutura de Dado

O TAD é a descrição lógica de um dado e a estruturade dado é a descrição real

TAD (Tipo Abstrato de Dados) é a “figura lógica” dosdados e operações que manipulam os elementoscomponentes dos dados

Estrutura de Dados é a implementação real dos dadose algoritmos que manipulam os elementos dos dados

TAD descrição das funcionalidades

Estrutura de Dado implementação

8

Objetivos deTADs

Abstrair (esconder) de quem usa um determinado tipo,a forma concreta com que ele foi implementado

O cliente utiliza o TAD de forma abstrata, apenas com basenas funcionalidades oferecidas pelo tipo (interface)

Desacoplar a implementação do uso, facilitando amanutenção e aumentando o potencial de reuso do tipocriado

99

Implementando um TAD

As operações definem a interface de um TAD

Um código implementa corretamente um TADdesde que obedeça o que está sendo definidona interface do TAD

10

Tipos Abstratos de Dados em C

Em C:Arquivos-fontes que agrupam funções afins sãogeralmente denominados de MódulosEm programas modulares, cada módulo deve sercompilado separadamente e depois “linkados” paragerar executávelQuando módulo define um novo tipo de dado e oconjunto de operações para manipular dados destetipo, dizemos que o módulo representa um TipoAbstrato de Dado (TAD)

11

Implementando TADs em C

Geralmente a interface de um TAD é descrita em Cnos arquivos .hO cliente só precisa dar um “include” no .h quecontém a interface do TAD

Ao cliente também é dado o arquivo objeto (.o) com aimplementação do TAD

Esconde (Abstrai) a implementaçãoA interface de um TAD contém as assinaturas dasfunções que ele oferece e contém a definição do tipode dado

Funciona como um “manual de uso” do tipo que está sendodefinido

1212

Pilha é um tipo abstrato de dados onde:Inserção e remoção de elementos no topo dapilhaO primeiro elemento que sai é o último que entrou(LIFO)Operações básicas: push (empilhar) e pop(desempilhar)

Definição de Pilha

1313

Funcionamento da pilha

topotopo

topotopo

empilha(a)

a

empilha(b)

ab

empilha(c)

ab

c

desempilha()

ab

cc

1414

Exemplo de Uso: Pilha de Execução de Funções

#include “stdio.h”

int fat ( int n ) ;

int main () {

int n = 5, r ;

r = fat(n) ;

printf ( “ Fatorial = %d \n ”, r ) ;

return 0 ;

}

int fat ( int n ){

int f=1 ;

while(n != 0) {

f *= n ;

n-- ;

}

return f ;

}

1515

1 – Início do programa:pilha vazia

main>

2 – Declaração de variáveis: n,r

main>5n

r -

3 – Chamada da função:empilha variáveis

main>5n

r -5fat>

n

4 – Final do laço

main>5n-0fat> n

r

f 120

5 – Retorno da função:desempilha

main>5n

120fat>

r

Pilha de Execução

Acesso às variáveis queestão na função do topo

1616

Interface do tipo Pilha

Criar pilha vazia;Inserir elemento no topo(push)Remover elemento dotopo (pop)Verificar se a pilha estávaziaLiberar a estrutura depilha

Em C/* pilha.h */

typedef struct pilha Pilha;

Pilha* pilha_cria();

void pilha_push(Pilha* p,float v);

float pilha_pop(Pilha* p);

int pilha_vazia(Pilha* p);

void pilha_libera(Pilha* p);

1717

Implementação do tipo Pilha

Existem várias implementações possíveis deuma pilha. Podem diferir da natureza doselementos, maneira como são armazenadose operações disponíveisIremos estudar 2 tipos de implementação:

Utilizando VetorUtilizando Lista Encadeada

1818

Implementando Pilha com Vetor

Estrutura que representa pilhadeve ser composta por um vetorpara armazenar os elementos eo número de elementosarmazenadosVantagem

Simplicidade

DesvantagensDeve-se saber de antemão onúmero máximo de elementosDesperdício de espaço de memória

#define N 50

struct pilha {

int n;

float vet[N];

};

1919

Pilha* pilha_cria ()

{

Pilha* p = (Pilha*) malloc(sizeof(Pilha));

p->n = 0;

return p;

}

Implementando Pilha com Vetor

Função de CriaçãoAloca estrutura dinamicamente

Inicializa com 0 elementos

2020

void pilha_push (Pilha* p, float v) {

if (p->n < N) {

p->vet[p->n] = v;

p->n++;

} else {/* capacidade esgotada */

printf(“Capacidade da pilha estourou.\n”);

}

}

Implementando Pilha com Vetor

Função de Inserção Verifica se tem espaço disponível

Insere na próxima posição livre e incrementa o número

de elementos da pilha

2121

float pilha_pop (Pilha* p)

{

float v;

if (pilha_vazia(p)) {

printf(“Pilha vazia.\n”);

exit(1);

}

v = p->vet[p->n-1];

p->n--;

return v;

}

Implementando Pilha com Vetor

Função de Remoção Verifica se a pilha está

vazia

Topo está na posição n - 1

Remoção se dá pelo decremento do número de elementos (próximo push

sobrescreverá antigo topo)

2222

int pilha_vazia (Pilha* p) {

return (p->n==0);

}

Implementando Pilha com Vetor

Função que testa se pilha está vazia

void pilha_libera (Pilha* p) {

free(p);

}

Função que libera memória alocada para apilha

2323

/* Função que informa o elemento do topo */

float pilha_topo (Pilha* p) {

return (p->vet[p->n – 1]);

}

Implementando Pilha com Vetor

Outras Funções Utilitárias

/* Função que imprime os elementos da pilha

void pilha_imprime (Pilha* p) {

int i;

for (i=p->n-1; i>=0; i--)

printf(“%f\n”, p->vet[i]);

}

2424

Implementando Pilha com Lista

Estrutura que representa pilhadeve ser composta por umponteiro para o primeiro nó dalista que armazena oselementosVantagens

Otimização da memóriaTamanho irrestrito

DesvantagemComplexidade na manipulação delistas

typedef struct lista{

float info;

struct lista *prox;

} Lista;

struct pilha {

Lista *topo;

};

2525

Pilha* pilha_cria () {

Pilha* p = (Pilha*) malloc(sizeof(Pilha));

p->topo = NULL;

return p;

}

Implementando Pilha com Lista

Função de CriaçãoLista(topo) é inicializada com NULL

2626

void pilha_push (Pilha* p, float v) {

Lista* novo = (Lista*) malloc(sizeof(Lista));

novo->info = v;

novo->prox = p->topo;

p->topo = novo;

}

Implementando Pilha com Lista

Função de Inserção

Elemento é inserido no começo da lista – topo

aponta para o começo da lista

2727

float pilha_pop (Pilha* p) {

Lista* t;

float v;

if (pilha_vazia(p)) {

printf(“Pilha vazia.\n”);

exit(1); /* aborta programa */

}

t = p->topo;

v = t->info;

p->topo = t->prox;

free(t);

return v;

}

Implementando Pilha com Lista

Função de Remoção

Elemento é realmente removido, topo é

atualizado

2828

int pilha_vazia (Pilha* p) {

return (p->topo == NULL);

}

Implementando Pilha com Lista

Função que testa se pilha está vazia

void pilha_libera (Pilha* p) {

Lista* q = p->topo;

while (q!=NULL) {

Lista* t = q->prox;

free(q);

q = t;

}

free(p);

}

Função que libera memória alocada para apilha

Deve-se liberar todos os elementos da lista primeiro

2929

/* Função que informa o elemento do topo */

float pilha_topo (Pilha* p) {

return (p->topo->info);

}

Implementando Pilha com Lista

Outras Funções Utilitárias

/* Função que imprime os elementos da pilha

void pilha_imprime (Pilha* p) {

Lista* q;

for (q=p->topo; q!= NULL; q = q->prox)

printf(“%f\n”, q->info);

}

30

Definição de Fila

Fila é um tipo abstrato de dados onde:Inserção de elementos se dá no final e aremoção no inícioO primeiro elemento que entra é o primeiroque sai (FIFO)Ex de uso : fila de impressão

31

Funcionamento da Fila

início

1- insere(a)

2- insere(b)

a

b

c

fim

a

início

fim

3- insere(c)fim

ba

início

4- retira( )

início

b

fim

ca

32

Interface do tipo Fila

Em C/* fila.h */

typedef struct fila Fila;

Fila* fila_cria();

void fila_insere(Fila* f,float v);

float fila_retira(Fila* f);

int fila_vazia(Fila* f);

void fila_libera(Fila* f);

Criar uma fila vaziaInserir um elemento nofimRetirar o elemento doinícioVerificar se a fila estávaziaLiberar a fila

33

Implementando Fila com ListaEstrutura que representa filadeve ser composta por 2ponteiros para a lista quearmazena os elementos.

Um aponta para o primeiroelemento e o outro para o últimoelemento

typedef struct lista{

float info;

struct lista *prox;

} Lista;

struct fila {

Lista *ini;

Lista *fim

};

info1 info3info2

ini fim

34

Fila* fila_cria ( ) {

Fila* f = (Fila*) malloc(sizeof(Fila));

f->ini = f->fim = NULL;

return f;

}

Implementando Fila com Lista

Função de Criação

ini e fim são inicializados com NULL

35

void fila_insere (Fila* f, float v) {

Lista* novo = (Lista*) malloc(sizeof(Lista));

novo->info = v;

novo->prox = NULL; /* novo nó passa a ser o

último */

if (!fila_vazia(f)) /* verifica se a fila não

estava vazia */

f->fim->prox = novo;

else

f->ini = novo;

f->fim = novo;

}

Implementando Fila com Lista

Função de Inserção

Se a fila estava vazia novo elemento passa a ser o começo da fila

Novo elemento sempre é o último da fila

36

float fila_retira (Fila* f) {

Lista* t;

float v;

if (fila_vazia(f)) {

printf("Fila vazia.\n"); exit(1);

}

t = f->ini;

v = t->info;

f->ini = t->prox;

if (f->ini == NULL)

f->fim = NULL;

free(t);

return v;

}

Implementando Fila com ListaFunção de Remoção

Se a fila ficou vazia, deve-se atualizar

ponteiro para o fim

37

int fila_vazia (Fila* f) {

return (f->ini == NULL);

}

Implementando Fila com Lista

Função que testa se a fila está vazia

void fila_libera (Fila* f) {

Lista* q = f->ini;

while (q!=NULL) {

Lista* t = q->prox;

free(q);

q = t;

}

free(f);

}

Função que libera memória alocada para afila

Deve-se liberar todos os elementos da lista primeiro

38

/* Função que informa o primeiro elemento da fila

*/

float fila_primeiro (Fila* f) {

return (f->ini->info);

}

Implementando Fila com Lista

Outras Funções Utilitárias

/* Função que imprime os elementos da fila

void fila_imprime (Fila* f) {

Lista* q;

for (q=f->ini; q!=NULL; q =q->prox)

printf(“%f\n”, q->info);

}

Introdução à Programação

Conceitos Básicos de

Orientação a Objetos

2

Tópicos da Aula

Aprenderemos fundamentos do paradigma orientado

a objetos, mas antes veremos o que é paradigma

Conceito de paradigma

Diferentes paradigmas na computação

Depois veremos o que é orientação a objetos

Conceitos de orientação a objetos

Programação orientada a objetos x Programação imperativa

Estrutura de um programa orientado a objetos em C++

Construtores

Criação de objetos

Exemplo de aplicação orientada a objetos

Paradigmas de Programação

Linguagens de programação são baseadas em

vários conceitos:

Tipos de dados, variáveis e armazenamento, controle,

abstração de dados, abstração procedural, sistema de

tipos,etc

Diferentes seleções dos conceitos definem o estilo

de programação ou Paradigma

Afeta a forma de pensar em como escrever um programa

A forma como estes conceitos são agrupados em

uma linguagem de programação definem que

paradigma é suportado por esta linguagem

Paradigmas de Programação

Podemos encontrar 6 grandes paradigmassuportados pelas linguagens de programação:

Imperativo

Uso de comandos, variáveis e procedimentos

Primeiras linguagens de programação são desteparadigma

Ex: Fortran, Pascal, C, etc

Orientação a Objetos

Uso de classes, objetos, herança, polimorfismo,maior abstração de dados, encapsulamento(implementação)

Evolução do paradigma imperativo

Ex: Smalltalk, C++, Eiffel, Java, C#, etc

Paradigmas de Programação

Funcional

Uso de expressões e funções, ausência de

variáveis e comandos

Ex: ML, Haskell

-- Exemplo em Haskell

-- type

factorial :: Integer -> Integer

-- using recursion

factorial 0 = 1

factorial n = n * factorial (n - 1)

Paradigmas de Programação

Lógico

Relações lógicas entre entradas e saídas,

asserções

Ex: Prolog, Mercury

/* Exemplo em Prolog */

mother_child(trude, sally). /* fato */

father_child(tom, sally).

father_child(tom, erica).

sibling(X, Y) :- parent_child(Z, X), parent_child(Z, Y).

parent_child(X, Y) :- father_child(X, Y). /* clausula*/

parent_child(X, Y) :- mother_child(X, Y).

?- sibling(sally, erica).

Yes

Paradigmas de Programação

Concorrente

Execução concorrente de processos, abstração de

controle de sincronização (inter-processos, acesso

a recursos, etc)

Ex: Occam, Java, Concurrent C, etc

Scripting

Sistema de tipos dinâmica, abstração de

processamento de Strings, suporte a interfaces

gráficas

Ex: Python, Java Script, Tcl, HTML

O que é Orientação a Objetos?

É considerar que tudo é um objeto:

Os sistemas são objetos

Os dados manipulados e comunicados entre os

sistemas são objetos

Cada parte de um sistema (sub-sistema) é um objeto

Os dispositivos eletrônicos são objetos

A interface com o usuário é um objeto, composto de

vários outros objetos...

8

Objeto

Podemos definir objeto como uma entidade

que possui:

Estado

Características ou propriedades do objeto

Comportamento

Operações que o objeto pode realizar

O comportamento pode examinar ou alterar o

estado de um objeto

9

Objeto DVD

Fonte: http://www.amazon.com

O estado atual do DVD; o que eleestá fazendo...

As operações que oDVD pode executar

10

ComportamentoNúmeroSaldo

21.342-7875,32

Crédito

Débito

Operações que umaconta pode executar

O estado atual da conta

11

Objeto Conta Bancária

Estados do Objeto Conta

NúmeroSaldo

21.342-7875,32

Crédito

NúmeroSaldo

21.342-7875,32

Crédito

Débito

Crédito(20)

12

NúmeroSaldo

21.342-7875,32

Crédito

NúmeroSaldo

21.342-7895,32

Crédito

Débito

Comportamento neste caso mudou o estado do

objeto conta

Classe

Classe é um agrupamento de objetos que têm

propriedades comuns e podem realizar as

mesmas operações

É uma definição que descreve como objetos

pertencentes à classe são estruturados

internamente (quais propriedades e operações

o objeto possui)

Classe é um conceito e o objeto é uma

instância deste conceito

Portanto, podemos ter vários objetos

pertencentes a mesma classe

13

Classe x Objeto

NúmeroSaldo

21.342-7875,32

Crédito

NúmeroSaldo

11.056-x1000,32

Crédito

Débito 14

Múltiplos objetos podem ser criados à partir da mesma

classe

NúmeroSaldo

Crédito Débito

NúmeroSaldo

21.342-7875,32

Crédito

NúmeroSaldo

875,32

Crédito

Débito

21.342-7

Classe Conta

Objeto conta1 Objeto conta2

Classe e Tipo

Tipo é um conjunto de valores relacionados que

são capazes de realizar as mesmas operações

Ex: inteiro, caractere, Conta, Banco, etc

Uma classe define um tipo: o tipo cujos

elementos são objetos com as mesmas

propriedades e comportamento

15

Atributo e Método (1)

Atributo representa alguma propriedade do

objeto

O conjunto de atributos de um objeto determina

o estado do objeto

Um atributo pode conter um valor simples tal

como um número real ou até outro objeto

Método representa uma operação que um

objeto pode fazer

O conjunto de métodos de um objeto determina

o comportamento do objeto

16

NúmeroSaldo

21.342-7875,32

Crédito

Débito

17

Atributo e Método (2)

Atributosda conta

Comportamento

Métodos de umaconta

Relações entre Objetos

Geralmente, um software é construído a partir de vários

objetos (classes) que se relacionam

As relações de Cliente e Herança são essenciais para

a construção de programas

Classe B é Cliente de classe A, se todo objeto de tipo B

contiver informação sobre um ou mais objetos do tipo A

Classe B é Herdeira de classe A, se B representa uma

versão especializada de A

Métodos e os atributos da classe A se tornam, também, parte

da classe B

Características e comportamento de A são passadas para B

18

Relação Cliente

NúmeroSaldo

21.342-7875,32

CréditoCria nova Conta

Transferência

Objeto Banco1

19

NúmeroSaldo

21.342-7875,32

Crédito

NúmeroSaldo

21.342-7895,32

Crédito

Débito

Objeto do tipo Banco têm vários objetos do tipo

Conta Banco é cliente de Conta

Banco do Brasil

Nome

Conta1

Conta

Conta1

Conta

Conta1

Conta

Objeto Conta1

Relação Herança

20

Classe Poupança é uma versão especializada de Conta

Métodos e atributos são herdados

Classe Conta

Saldo

Crédito Débito

Número

Saldo

Crédito Débito

Número Juros

Classe Poupança

Utilizando OO para Desenvolver

Programas

Desenvolvimento de uma

solução se torna mais fácil

quando quebramos esta solução

em módulos gerenciáveis

Quando estamos programando,

podemos desenvolver módulos

separados, onde cada um é

responsável por uma certa parte

da solução

Programação Modular

OO facilita a programação

modular

Módulos são as classes e objetos21

Algumas Considerações sobre OO

Orientação a Objetos Modularidade

Reusabilidade

Extensibilidade

Classe é uma entidade que combina 2 conceitos:

Módulo e Tipo

Módulo é um conceito sintático, pois a decomposição do

sistema em módulos afeta somente a forma como o programa

é escrito, não a funcionalidade dele

Tipo é um conceito semântico, pois o tipo influencia

diretamente a execução do sistema, definindo a forma dos

objetos que são criados e manipulados pelo sistema em tempo

de execução

22

OO e Linguagens de Programação

Linguagens OO têm em objetos e classes seus

elementos fundamentais para construção de programas

Estruturas da linguagem permitem mapeamento direto dos

conceitos de OO

Porém, é possível fazer um programa OO em uma

linguagem não OO

É possível, também, fazer um programa que não seja OO em

uma linguagem OO

23

Conceito de Orientação a Objetos é independente da linguagem de

programação

Linguagem C++

Criada por Bjarne Stroustrup em 1983

Pode ser vista quase como uma extensão da linguagem

C para dar suporte a OO

Embora quase tudo escrito em C seja compatível com C++,

certos comandos podem ter comportamento diferente em C++

Dá suporte a vários conceitos de OO:

Classe, Herança,Polimorfismo, Encapsulamento

Ainda oferece suporte a tratamento de exceções e tipos

genéricos

Sintaxe da linguagem Java foi inspirada em C++

24

Um Programa Imperativo...

Contém

Uma função principal, por onde começa aexecução do programa

Várias funções auxiliares, para modularizar, dividir

o código em partes

Importação de bibliotecas de funções

Pode ainda conter:

Definição de tipos estruturados

26

Um Programa Orientado a Objetos ...

Tem a classe como a sua construçãofundamental :

Um programa é constituído de uma ou mais classes

Que podem ter sido importadas de uma bibliotecade classes

Uma classe contém um ou mais atributos e métodos

Um método é composto de instruções

Ao Invés de Estruturas, Classes!

Define um tipo, com funções que

operam sobre este tipo

Estrutura

Função 1

Função 2

Função 3

Estrutura

Função 1

Função 2

Função 3

Classe

Programação Imperativa x

Programação OO

Programação Imperativa tem como elementos

principais os procedimentos (funções)

Programação OO tem como elementos

principais as classes

Estrutura + funções = classe

Programação OO ainda utiliza :

Herança

Encapsulamento

Polimorfismo

28

Veremos depois!

Implementando o Tipo Conta com

Programação Imperativa

Primeiro passo é definir um tipo estruturado

Conta

29

struct Conta{

double saldo;

char numero[11];

char agencia[11];

};

Implementando as Funções do Tipo

Conta

Depois se define as funções que operam sobre

o tipo Conta

creditar

debitar

getSaldo

criaConta 30

void creditar(struct Conta *c ,double v){

c->saldo = c->saldo + v;

}

Passa-se estrutura (ou endereço de estrutura) como parâmetro

Implementando as Funções do Tipo

Conta

31

void debitar(struct Conta *c,double v){

if (v <= c->saldo)

c->saldo = c->saldo - v;

}

double getSaldo(struct Conta *c){

return c->saldo;

}

Implementando as Funções do Tipo

Conta

32

struct Conta* criaConta(char *num, char* ag) {

struct Conta *retorno;

retorno = (struct Conta *)

malloc (sizeof(struct Conta));

if (retorno == NULL){

printf(“Erro na alocação de memória!”)

} else {

strcpy(retorno->numero, num);

strcpy(retorno->agencia, ag);

retorno->saldo = 0;

}

return retorno;

}

Alocando dinamicamente uma estrutura

Usando o Tipo Conta em Programação

Imperativa

33

int main() {

struct Conta *conta1;

conta1 = criaConta(“1234-5”,”007-x”);

if (conta1 == NULL){

printf(“Erro na alocação de memória!”)

} else {

creditar(conta1,300);

printf(“Saldo da conta = %lf\n”,getSaldo(conta1));

debitar(conta1,200);

printf(“Saldo da conta = %lf\n”,getSaldo(conta1));

}

return 0;

}

Implementando o Tipo Conta com

Programação OO (C++)

Primeiro passo é definir a classe Conta

Atributos e Métodos34

class Conta{

private:

double saldo;

char numero[11];

char agencia[11];

public:

void creditar(double v);

void debitar(double v);

double getSaldo();

Conta(char* num, char* ag);

};

Atributos

Métodos

Construtor

Implementando os Métodos do Tipo

Conta

35

void Conta::creditar(double v){

saldo = saldo + v;

}

Indica que método faz parte da classe Conta

Não precisa passar objeto como parâmetro!

saldo é um atributo que foi definido na classe Conta

Implementando os Métodos do Tipo

Conta

36

void Conta::debitar(double v){

if (v <= saldo)

saldo = saldo - v;

}

double Conta::getSaldo(){

return saldo;

}

Construtor

Tipo especial de método que é chamado no ato de

criação de um objeto da classe desejada

Importante para fazer algumas inicializações no objeto

Uma classe pode ter mais de um construtor

O que diferencia um construtor do outro é a ordem e/ou tipo

e/ou quantidade de parâmetros

Em C++, deve ter o mesmo nome da classe

Não possui tipo de retorno

Não é obrigatório definir um construtor

Existe em C++ um construtor default sem parâmetros

37

Implementando o Construtor do Tipo

Conta

38

Conta::Conta(char *num, char* ag) {

strcpy(numero, num);

strcpy(agencia, ag);

saldo = 0;

}

Usando o Tipo Conta em Programação

OO

39

#include <iostream>

using namespace std;

int main() {

Conta *c;

c = new Conta(“1234-5”,”007-x”);

if (c == NULL){

printf(“Erro na criação do objeto!”)

} else {

c->creditar(300);

cout<<"Conta tem saldo = " << c->getSaldo() << endl;

c->debitar(200);

cout<<"Conta tem saldo = " << c->getSaldo() << endl;

}

return 0;

}

Comando para criar objeto de uma classe em tempo de execução (dinamicamente)

Para chamar método a partir de uma referência para um objeto

Comando para imprimir na

tela

40

Criação Dinâmica de Objetos

Em linguagens OO, escrevemos programas

utilizando objetos

Mas, primeiro, temos que criá-los...

Para criar um objeto em C++ dinamicamente

utilizamos o comando new

new Conta(...);

Palavra reservada

ordenando a criação

de um objeto

Construtor do objeto a ser

criado

Avaliação do operador new

Cria um objeto da classe NomeDaClasse e

armazena na sua memória

Inicializa os atributos deste objeto usando o

construtor desta classe

Devolve como resultado da avaliação uma referência

(endereço da memória) para o objeto criado

Para avaliar uma expressão do tiponew NomeDaClasse();

o computador...

41

Criando um objeto dinamicamente...

new Conta(“12-3”,11-2”);

4. Devolve o endereço

como resultado da avaliação42

1. Cria o objeto

na memória

2. Inicializa o

objeto

12-3 11-2

id275

3. Associa um

endereço ao

objeto

12-3 11-2

Construtores e new

new NomeDaClasse(argumentos)

O número, ordem e tipos dos argumentos

determina o construtor 43

Podemos ter mais de um construtor para um

determinado objeto

A escolha do construtor para inicializar os atributos é

determinada pela lista de argumentos, entre

parênteses

Referências para objetos

A referência funcionacomo a identidade do objeto

O objeto

id305

A referênciapara o objeto

44

Todo acesso e manipulação é feito indiretamente,

através de uma referência (endereço) para o objeto

Quando declaramos uma variável do tipo de um

determinado objeto, ela não armazena o objeto e sim

uma referência para um objeto daquele tipo

Conta* conta1 = new Conta(“12-3”,”11-2”);

conta1 armazena este valor

Referências e identidade de um objeto

id305

id309

id312

Objetos diferentes, mas com o mesmoconteúdo (clones)

Referênciasdiferentes objetos diferentes

45

12-3 11-2

12-3 11-2

11-5 12-4

46

Considerações sobre Criação de

Objetos

Os valores dos atributos (estado) de um

objeto podem mudar durante a execução de

um programa, mas isso não afeta a

identidade do objeto

O ato de criar um objeto é chamado de

instanciar um objeto de uma determinada

classe

47

Criação Estática de Objetos

C++ permite também a criação estática (em tempo

de compilação) de objetos

No ato da declaração de uma variável do tipo de uma

classe, objeto é criado

Na declaração deve-se passar argumentos do construtor

Conta c(“12-3”,”11-2”);

Tipo da variável c é Conta

Argumentos do construtor

Usando Criação Estática de Objetos do

Tipo Conta

48

#include <iostream>

using namespace std;

int main() {

Conta c(“1234-5”,”007-x”);

c.creditar(300);

cout<<"Conta tem saldo = " << c.getSaldo() << endl;

c.debitar(200);

cout<<"Conta tem saldo = " << c.getSaldo() << endl;

return 0;

}

Declaração para instanciar objeto em tempo de compilação

Utiliza-se operador “.” para utilizar os métodos do objeto

criado estaticamente

Introdução à Programação

Encapsulamento e Herança

2

Tópicos da Aula

Hoje, aprenderemos conceitos mais avançadosde Orientação a Objetos

EncapsulamentoUsando modificadores de acesso em C++

HerançaImportânciaUtilização em C++Herança múltipla

Um objeto pode ser visto de duas formasdiferentes:

InternamenteDetalhes de atributos e métodos da classe que odefine

ExternamenteServiços que um objeto fornece e como esteobjeto interage com o resto do sistema (ainterface do objeto)

Encapsulamento (Information Hiding)

A visão externa de um objeto encapsula omodo como são fornecidos os serviços

Isto é, esconde os detalhes (internos) deimplementação do objeto (information hiding)

Encapsulamento (Information Hiding)

Um objeto (chamado neste caso de cliente) pode usaros serviços fornecidos por um outro objeto

Contudo, um cliente não deve precisar saber os detalhes deimplementação destes métodos

Mudanças no estado (atributos) de um objeto devemser feitas pelos métodos do objeto

Para permitir uma maior independência entre osobjetos,o acesso direto aos atributos de um objeto porum outro objeto deve ser restrito ou quase impossível

Encapsulamento (Information Hiding)

Um objeto pode ser visto como uma “caixa preta”,onde os detalhes internos são escondidos dosclientesClientes acessam o estado do objeto, através dosmétodos oferecidos

Métodos

Dados

Cliente

Encapsulamento (Information Hiding)

Em C++, o encapsulamento é possível através do usoapropriado de modificadores de acesso

Modificadores são palavras reservadas que especificamcaracterísticas particulares de um conjunto de métodos ou deatributos

Modificadores de acesso variam de acordo com avisibilidade que se quer oferecer ao clientePodem ser:public,protected ,private,friend

Modificadores de Acesso

Membros da classe que recebem o modificador public,podem ser acessados por qualquer outra classe

Devem ser utilizados para métodos que definem a interface daclasseNão deve ser utilizado para os atributos, excetuando-se o casoonde queremos declarar uma constante

Membros que recebem o modificador private, sópodem ser acessados por membros da classe ou classes(ou funções) “amigas” (friends)

Devem ser utilizados para atributos e métodos auxiliares

Modificadores de Acesso

public private

Atributos

MétodosFornecem serviços

para os clientesAuxiliam outros

métodos da classe

Preservam

encapsulamento

Violam

encapsulamento

Modificadores de Acesso

class Conta {

private:

string numero;

string agencia;

double saldo;

public:

void creditar (double valor);

void debitar(double valor);

double getSaldo();

string getNumero();

string getAgencia();

Conta(string num, string ag);

protected:

void setSaldo(double valor);

}

Classe Conta e Modificadores de

Acesso

10

Parte privada

Parte pública

Parte protegida

Membros de uma superclasse que recebem omodificador private, não podem ser acessadosnem pelas subclasses

Se colocar public e o membro for um atributo, o princípiodo encapsulamento é violado

Membros com o modificador protected são visíveispelas subclasses e pelas classes (ou funções)“amigas”

Modificadores de Acesso

Em C++, o modificador friend pode ser colocadoantes de um método ou (uma classe) declaradodentro de uma classe

O método “amigo” (ou classe “amiga”) não pertence a classena qual está declaradoInforma que o método “amigo” (ou classe “amiga”) podeacessar os membros privados e protegidos da classe naqual está declarado

Modificadores de Acesso

void creditarBonus(Conta* c, double v) {

if (c->saldo > 10000)

c->saldo = c->saldo + v;

}

class Conta {

private:

string numero;

string agencia;

double saldo;

public:

void creditar (double valor);

...

friend void creditarBonus(Conta* c,double v);

};

Classe Conta e Modificador de Acesso

Friend

13

Parte privada

Função (método) amiga

Função amiga que não pertence à classe acessa parte privada da classe

Membros de uma classe, que não recebem modificadorde acesso, tem visibilidade private

Na redefinição de métodos herdados, o modificador deacesso não deve ser trocado por um mais restrito

No entanto, podem ser trocados por modificadoresmenos restritos

Modificadores de Acesso

class PoupancaD {

private:

string numero;

string agencia;

double saldo;

public:

void creditar (double valor);

void debitar(double valor);

void renderJuros(double taxa);

}

Classes de Poupanças e Contas:

Descrições

class Conta{

private:

string numero;

string agencia;

double saldo;

public:

void creditar (double valor);

void debitar(double valor);

}

Parte diferente das descrições

Partes idênticas das descrições

15

Classe de Bancos: Assinatura

class BancoD {

public:

void cadastrarConta(Conta* c){}

void cadastrarPoupanca(PoupancaD* p){}

...

} Métodos diferentes para manipular contas e poupanças

16

Problemas

Duplicação desnecessária de código:A definição de PoupançaD é uma simplesextensão da definição de ContaClientes de Conta que precisam trabalhar tambémcom PoupançaD terão que ter código especialpara manipular poupanças

Falta refletir relação entre tipos do “mundoreal”

17

Subtipos e Subclasses

Poupança

Conta

18

Herança

Necessidade de estender classesAlterar classes já existentes e adicionarpropriedades ou comportamentos pararepresentar outra classe de objetosCriar uma hierarquia de classes que “herdam”propriedades e comportamentos de outra classe edefinem novas propriedades e comportamentos

19

Herança

Herança permite que novas classes possam serderivadas de classes existentesA classe existente é chamada de classe pai (mãe) ousuperclasseA classe derivada é chamada de classe filha ousubclasseSubclasse herda as características da superclasse

Herda os atributos e métodos

Estabelece a relação de é- um

A subclasse é uma versão especializada da superclasse

20

Importância de Herança

ComportamentoObjetos da subclasse comportam-se como os objetos dasuperclasse

SubstituiçãoObjetos da subclasse podem ser usados no lugar de objetosda superclasse

Reuso de CódigoDescrição da superclasse pode ser usada para definir asubclasse

Extensibilidadealgumas operações da superclasse podem ser redefinidasna subclasse

21

#include “Conta.h”

class Poupanca: public Conta {

public:

void renderJuros(double taxa);

Poupanca(string num,string ag):Conta(num,ag){}

}

22

Classe de Poupanças: Assinatura

Indica que a classe Poupanca herda de

Conta

Indica que o construtor de Poupanca utiliza o construtor de Conta

para inicializar atributos

#include “Poupanca.h”

void Poupanca::renderJuros(double taxa) {

creditar(getSaldo() * taxa);

}

23

Classes de Poupanças:

Implementação

So precisa implementar o método renderJuros, o resto é

herdado!

Herança e Construtores

Construtores não são herdadosEmbora, freqüentemente, precisamos doconstrutor da superclasse para a definição dosconstrutores das subclassesNecessários para inicializar os atributos que sãoherdados da superclasse

Devemos portanto definir construtores paraas subclasses

24

Herança Múltipla

Herança múltipla permite que uma classeseja derivada de mais de uma classe

25

Carro

puxarFreiodeMao()

acelerar()

Barco

jogarAncora()

acelerar()

CarroAnfibio

Qual versão do método acelerar é herdada por CarroAnfibio?

Herança múltipla faz com que subclassesherdem atributos e métodos das suassuperclasses

Pode haver colisões de nomes de atributos emétodos

Ao contrário de Java, C++ dá suporte aherança múltipla

Na hora de utilizar o método, usamos o operador

de resolução de escopo para dizer a qualmétodo estamos nos referindo

26

Herança Múltipla e C++

int main() {

CarroAnfibio ca;

ca.Carro::acelerar();

ca.Barco::acelerar();

...

}

class CarroAnfibio: public Carro,Barco {

...

};

Herança Múltipla em C++

27

Herda das superclasses Carro e Barco

Usando operador de resolução de escopo para determinar qual versão do método

acelerar deve ser usado

Introdução à Programação

Polimorfismo, Cast e Dynamic

Binding

2

Tópicos da Aula

Hoje, aprenderemos conceitos mais avançadosde Orientação a Objetos

PolimorfismoConceitoObtendo polimorfismo através de HerançaCastRedefinição e sobregarga de métodos

Dynamic Binding (Ligação Dinâmica)

Polimorfismo

A palavra polimorfismo significa “assumirmuitas formas”

Uma referência polimórfica é uma variávelque pode armazenar referências (ponteiros)para objetos de tipos diferentes em intervalosde tempo diferentes

3

Polimorfismo

Um método chamado através de umareferência polimórfica pode tercomportamentos diferentes entre umachamada e outra

Polimorfismo em C++ pode se dar através deherança

4

Polimorfismo via Herança

PolimorfismoUma conta pode ser

Uma poupançaUma conta especial

Herança permite a substituição do supertipo pelosubtipo no código

Onde é permitido o supertipo, o subtipo pode serutilizadoVariável de supertipo pode em um determinado instantedo tempo guardar uma referência (ponteiro) para umainstância de um subtipo

5

public class Banco {

...

public:

void cadastrar(Conta* conta);

...

}

6

Classe de Bancos: Assinatura

Subtipos: Substituição

...

Banco banco;

banco.cadastrar(new Conta("21.345-7“,”123-4”));

banco.cadastrar(new Poupanca("1.21.345-9“,”123-4”));

7

Podemos cadastrar poupanças

Podemos cadastrar contas

Mesmo método pode ser aplicado a Conta e Poupanca

Subtipos: Substituição

...

Conta* conta;

conta = new Poupanca(“21.342-7”,”123-4”);

conta->creditar(500.87);

conta->debitar(45.00);

...

8

Herança permite a substituição do supertipopelo subtipo no código

Onde é permitido o supertipo, o subtipo pode serutilizado

Subtipos: Substituição

...

Poupanca* p;

p = new Conta(“21.342-7”,”123-4”);

p->creditar(500.87);

p->debitar(45.00);

...

9Cuidado! A recíproca não é verdadeira.

Substituição e Casts

Nos contextos onde objetos do tipo Contasão usados pode-se usar objetos do tipoPoupancaNos contextos onde objetos do tipoPoupanca são usados pode-se usar variáveisdo tipo Conta que armazenam referências(endereços) para objetos do tipo Poupanca,desde que se faça o uso explícito de casts

dinâmicos

10

Subtipos: Utilizando Casts Dinâmicos

...

Conta* c;

c = new Poupanca("21.342-7“,”123-4”);

...

c->renderJuros(0.01);

...(dynamic_cast<Poupanca*>(c))->renderJuros(0.01);

11

Cast

Gera erro de compilação

Redefinição de Métodos

Uma subclasse pode redefinir (override) ummétodo herdado da superclasse

O novo método deve ter a mesma assinaturado método da superclasse, mas pode ter umcorpo diferente

Semântica dos métodos redefinidos deve serpreservada

12

class ContaEspecial: public Conta {

private:

double limiteCredito;

public:

void debitar(double valor);

ContaEspecial(string num,string ag, double taxa):

Conta(num,ag){limiteCredito = taxa;}

...

};

void ContaEspecial::debitar(double valor) {

double saldo = getSaldo();

if (valor <= (saldo + limiteCredito)) {

setSaldo(saldo – valor);

}

} 13

Classe ContaEspecial: Redefinindo debitar

Método existente em Conta é redefinido em

ContaEspecial

Redefinição de Métodos

Visibilidade dos métodos redefinidos deve serpreservada

Em C++, é possível aumentar a visibilidade de um métodoDiminuir a visibilidade pode gerar um erro de compilação

É possível acessar a definição dos métodos dasuperclasse usando operador de resolução deescopo

14

class Pai {

public:

void x(){

...

};

}

class Filha:public Pai{

public:

// Redefinindo x

void x(){

Pai::x();

...

};

}

Sobrecarga de Métodos

Sobrecarga (overloading) de método é oprocesso de dar a um método múltiplasdefiniçõesIsto quer dizer que somente o nome dométodo não é suficiente para determinar qualo método que se deseja utilizarA assinatura de cada método overloaded

deve ser únicaO que vai diferenciar os métodos é o número, tipoe ordem dos parâmetros

Não podem somente ser diferenciados pelo tipo deretorno 15

Sobrecarga de Métodos

Construtores são comumente overloaded

Útil para permitir várias formas de inicialização de um objeto

O compilador checa qual é o método que está sendochamado, analisando os parâmetros

16

class Conta{

...

public:

Conta(string num, string ag, double valor);

Conta(string num, string ag);

}

Conta::Conta(string num, string ag) {

numero = num;

agencia = ag;

}

Conta::Conta(string num,string ag, double valor) {

numero = num; agencia = ag;

saldo = valor;

}

Conta* conta = new Conta(“2”,”3”, 50);

Chamada

Sobrecarga x Redefinição

Sobrecarga trata múltiplos métodos com omesmo nome, mas assinaturas diferentesRedefinição trata de dois métodos, um nasuperclasse e outro na subclasse, quepossuem a mesma assinaturaSobrecarga permite que se defina umaoperação similar em diferentes formas paradiferentes parâmetrosRedefinição permite que se defina umaoperação similar em diferentes formas paradiferentes tipos de objeto

17

class Conta {

...

public:

void debitar(double valor);

...

};

void Conta::debitar(double valor) {

if (valor <= saldo) {

saldo – valor;

}

}

Binding de Métodos: debitar de

Conta e ContaEspecial

18

class ContaEspecial: public Conta {

...

public:

void debitar(double valor);

};

void ContaEspecial::debitar(double valor) {

double saldo = getSaldo();

if (valor <= (saldo + limiteCredito)) {

setSaldo(saldo – valor);

}

}

Duas versões de debitar

...

Conta* ca;

ca = new ContaEspecial(“21.342-7”,”123-4”,1000);

ca->creditar(500);

ca->debitar(600);

cout << ca->getSaldo()<<endl;

ca = new Conta(“21.111-7”,”123-4”);

ca->creditar(500);

ca->debitar(600);

cout << ca->getSaldo()<<endl;

...

19

Binding de Métodos

Qual versão de debitar é utilizada?

Binding

Uma chamada de um método dentro docódigo deve ser ligada (associada) àdefinição do método chamadoAssocia-se o método chamado aoendereço de memória que contém adefinição do método

Se esta ligação (binding) é feita em tempode compilação, então sempre a chamada dométodo será ligada ao mesmo método

Static Binding

20

Se a ligação da chamada de método a suadefinição correspondente for em tempo deexecução, então o método chamado dependedo objeto referenciado

Dynamic Binding ou Late Binding

Portanto, se existir dois métodos com o mesmonome e tipo(definição e redefinição), em Java, ocódigo é escolhido dinamicamente

Escolha é feita com base na classe do objetoassociado à variável destino da chamada do método

Linguagens como Java, Eiffel e Smalltalkutilizam dynamic binding como padrão

21

Dynamic Binding

Binding em C++

C++, C# e Delphi utilizam static binding comopadrão

Para se utilizar dynamic binding deve-se informarexplicitamente que um método pode ser ligado emtempo de execução

22

...

Conta* ca;

ca = new ContaEspecial(“21.342-7”,”123-4”,1000);

ca->creditar(500);

ca->debitar(600);

cout << ca->getSaldo()<<endl;

ca = new Conta(“21.111-7”,”123-4”);

ca->creditar(500);

ca->debitar(600);

cout << ca->getSaldo()<<endl;

...

23

C++: Padrão Static Binding

Qual versão de debitar é utilizada?

Será utilizada o método debitar definido em Conta

class Conta {

...

public:

virtual void debitar(double valor);

...

};

void Conta::debitar(double valor) {

...

}

Dynamic Binding em C++

24

class ContaEspecial: public Conta {

...

public:

void debitar(double valor);

};

void ContaEspecial::debitar(double valor) {

...

}

Deve-se utilizar a palavra virtual antes do método

da superclasse que vai ter dynamic

binding

...

Conta* ca;

ca = new ContaEspecial(“21.342-7”,”123-4”,1000);

ca->creditar(500);

ca->debitar(600);

cout << ca->getSaldo()<<endl;

ca = new Conta(“21.111-7”,”123-4”);

ca->creditar(500);

ca->debitar(600);

cout << ca->getSaldo()<<endl;

...

25

Dynamic Binding em C++

Qual versão de debitar é utilizada?

Em tempo de execução é decidida qual versão de debitar deve ser utilizada