• Nenhum resultado encontrado

a) Preencher um vetor com os números 0 a 10, e depois mostrar somente os elementos pares.

N/A
N/A
Protected

Academic year: 2021

Share "a) Preencher um vetor com os números 0 a 10, e depois mostrar somente os elementos pares."

Copied!
9
0
0

Texto

(1)

Instituto Federal de Santa Catarina - Câmpus Chapecó Ensino Médio Integrado em Informática - Módulo IV Unidade Curricular: Programação Estruturada Professora: Lara Popov Zambiasi Bazzi Oberderfer

Plano de Aula

Sexta-feira – Tarde – 23/08/2013

Objetivo:

• Revisar conceito de vetor, matrizes, função e ponteiros na linguagem C. • Introduzir o conceito de alocação dinâmica na memória e registros / structs.

Metodologia:

• Explicar junto com a turma o desenvolvimento dos seguintes exercícios (a). • Após cada exercício, os alunos poderão treinar com um exercício semelhante (b).

Conteúdo: 1. Vetor

a) Preencher um vetor com os números 0 a 10, e depois mostrar somente os

elementos pares.

b) Preencher um vetor com os valores referentes a idade de 30 alunos, verificar a

porcentagem de alunos com mesma idade ( 15, 16 e 17 anos).

2. Matrizes

a) Faça um programa que leia a matriz abaixo:

00 01 02 10 11 12 20 21 22

b) Faça um programa que leia duas matrizes, e imprima o resultado da soma de

cada elemento em uma 3a. Matriz, ao final mostre as 3 matrizes.

c) Pensando na ideia da matriz anterior, faça um programa de Jogo da Velha para

(2)

Sexta-feira – Tarde – 30/08/2013

3. Função

a) Criar uma função que retorna o seguinte: A função recebe 3 valores float

(n1,n2,n3) e retornar o (x*x)+y+z ou seja : O quadrado do 1º + a soma dos outros dois.

b) Escreva um programa em C que recebe via teclado: quantidade de litros, tipo de combustível ([A]lcool, [G]asolina ou [D]iesel) e o tipo de pagamento

([P]razo ou [V]ista). O programa deve calcular e imprimir na tela: total à prazo,

desconto e o total à vista. O programa termina quando o usuário digitar 'N' ou

'n' na pergunta "Continua [S/N]?".

Tela de execução: Valores:

Quantidade de litros? 50 <enter> Álcool à 1,23

Tipo de combustível [A]lcool, [G]asolina ou [D]iesel ? G Gasolina à 2,19 Tipo de pagamento [P]razo ou a [V]ista ? V Diesel à 1,46

Total à prazo (R$) : 109.50

Desconto (R$): 5.48 Desconto à vista: 5%

Total à vista (R$): 104.02 Continua [S/N]? N

4. Ponteiros

a) Faça um programa que some dois números através de ponteiros.

b) Faça um programa que realize as quatro operações matemáticas através de

(3)

Sexta-feira – Tarde – 06/09/2013

5. Alocação Dinâmica na Memória

As declarações abaixo alocam memória para diversas variáveis. A alocação é estática, pois acontece antes que o programa comece a ser executado:

char c; int i; int v[10];

Às vezes, a quantidade de memória a alocar só se torna conhecida durante a execução do programa. Para lidar com essa situação é preciso recorrer à alocação dinâmica de memória. A alocação dinâmica é gerenciada pelas funções malloc e free, que estão na biblioteca stdlib. Para usar esta biblioteca, é preciso dizer

#include <stdlib.h>

no início do programa.

Função malloc

A função malloc (abreviatura de memory allocation) aloca um bloco de bytes consecutivos na memória do computador e devolve o endereço desse bloco. O número de bytes é especificado no argumento da função. No seguinte fragmento de código, malloc aloca 1 byte:

char *ptr;

ptr = malloc( 1); scanf( "%c", ptr);

O endereço devolvido por malloc é do tipo "genérico" void *. O programador armazena esse endereço num ponteiro de tipo apropriado. No exemplo acima, o endereço é armazenado num ponteiro-para-char.

Para alocar um tipo-de-dado que ocupa vários bytes, é preciso recorrer ao operador sizeof, que diz quantos bytes o tipo especificado tem:

typedef struct {

int dia, mes, ano; } data;

data *d;

d = malloc( sizeof (data));

d->dia = 31; d->mes = 12; d->ano = 2008;

[As aparências enganam: sizeof não é uma função.]

Overhead. Cada invocação de malloc aloca um bloco de bytes consecutivos maior que o

solicitado: os bytes adicionais são usados para guardar informações administrativas sobre o bloco de bytes (essas informações permitem que o bloco seja corretamente desalocado, mais tarde, pela função free). O número de bytes adicionais pode ser grande, mas não depende do número de bytes solicitado no argumento de malloc. Não é recomendável, portanto, invocar malloc repetidas vezes com argumento muito pequeno. É preferível alocar um grande bloco de bytes e retirar pequenas porções desse bloco na medida do necessário.

(4)

Exercícios

1. Verificação do tamanho. Compile e execute o seguinte programa: typedef struct {

int dia, mes, ano; } data;

int main( void) {

printf( "sizeof (data) = %d\n", sizeof (data)); printf( "sizeof (data *) = %d\n", sizeof (data *)); return 0;

}

A memória é finita

Se a memória do computador já estiver toda ocupada, malloc não consegue alocar mais espaço e devolve NULL. Convém verificar essa possibilidade antes de prosseguir:

ptr = malloc( sizeof (data)); if (ptr == NULL) {

printf( "Socorro! malloc devolveu NULL!\n"); exit( EXIT_FAILURE);

}

A codificação frequente e repetida desse teste é cansativa para o programador e desvia a atenção do leitor. Por isso, vamos usar a seguinte versão alternativa de malloc:

void *mallocc( size_t nbytes) {

void *ptr;

ptr = malloc( nbytes); if (ptr == NULL) {

printf( "Socorro! malloc devolveu NULL!\n"); exit( EXIT_FAILURE);

}

return ptr; }

O parâmetro de mallocc é do tipo size_t. Em muitos computadores, size_t é equivalente a unsigned int. A função mallocc não está em nenhuma biblioteca e é desconhecida fora destas notas de aula. Ela é apenas uma abreviatura conveniente.

Função free

As variáveis alocadas estaticamente dentro de uma função desaparecem quando a execução da função termina. Já as variáveis alocadas dinâmicamente continuam a existir mesmo depois que a execução da função termina. Se for necessário liberar a memória ocupada por essas variáveis, é preciso recorrer à função free.

A função free libera a porção de memória alocada por malloc. O comando free( ptr) avisa o sistema de que o bloco de bytes apontado por ptr está livre. A próxima chamada de malloc poderá tomar posse desses bytes.

(5)

malloc; aplique free apenas ao bloco todo.

Convém não deixar ponteiros "soltos" (= dangling pointers) no seu programa, pois isso pode ser explorado por hackers para atacar o seu computador. Portanto, depois de cada free( ptr), atribua NULL a ptr:

free( ptr); ptr = NULL;

Atribuir um valor a um ponteiro que se tornou inútil é decididamente deselegante, mas não há como lidar com hackers de maneira elegante…

Para não cansar o leitor com detalhes repetitivos, estas notas não seguem a recomendação de segurança acima.

Vetores e matrizes

Eis como um vetor (= array) com n elementos inteiros pode ser alocado (e depois desalocado) durante a execução de um programa:

int *v; int n, i;

scanf( "%d", &n);

v = mallocc( n * sizeof (int)); for (i = 0; i < n; ++i)

scanf( "%d", &v[i]); for (i = n; i > 0; --i) printf( "%d ", v[i-1]); free( v);

(A propósito, veja observação sobre vetores e endereços em outra página.) Do ponto de vista conceitual (mas apenas desse ponto de vista) o comando

v = mallocc( 100 * sizeof (int));

tem o mesmo efeito que a alocação estática

int v[100];

A propósito, convém lembrar que não permite escrever "int v[n]", a menos que n seja uma constante, definida por um #define.

Matrizes bidimensionais são implementadas como vetores de vetores. Uma matriz com m linhas e n colunas é um vetor cada um de cujos m elementos é um vetor de n elementos. O seguinte fragmento de código faz a alocação dinâmica de uma tal matriz:

int **A; int i;

A = mallocc( m * sizeof (int *)); for (i = 0; i < m; ++i)

A[i] = mallocc( n * sizeof (int));

(6)

A[i][j].

Exercícios

2. Escreva uma função que receba um caractere c e transforme c em uma cadeia de ,caracteres, ou seja, devolva uma cadeia de caracteres de comprimento 1 tendo c como único elemento.

3. Escreva um programa que leia um número inteiro positivo n seguido de n números inteiros e imprima esses n números em ordem invertida. Por exemplo, ao receber

5 222 333 444 555 666 o seu programa deve imprimir 666 555 444 333 222

O seu programa não deve impor limitações sobre o valor de n.

6. Tipos Estruturados / Registros / Structs

Um registro é uma coleção de várias variáveis, possivelmente de tipos deferentes. Na linguagem C, registros são conhecidos como STRUCTS.

O exemplo abaixo declara um registro data com três campos inteiros:

struct {

int dia; int mês; int ano; } data;

É indicado que se coloque sempre o nome do registro, outra forma de representar:

struct dma { int dia; int mês; int ano; };

struct data x; /* um registro x do tipo data */

Para atribuição de valores nos campos de um registro, temos:

x.dia = 23; x.mes = 08; x.ano = 2013;

struct data x; /* um registro x do tipo data */

Exemplo: A função abaixo recebe a data de início de um evento e a duração do evento em dias. Ela devolve a data de fim do evento.

(7)

struct dma fim_evento (struct dma datainicio, int duracao) { struct dma datafim;

. . . . . . datafim.dia = ... datafim.mes = ... datafim.ano = ... return datafim; }

O código foi omitido porque é um tanto enfadonho: deve levar em conta a existência de meses com 31 dias, de meses com 30 dias, com 29 dias etc. Eis como essa função poderia ser usada:

int main( void) { struct dma a, b; int d;

scanf( "%d %d %d", &a.dia, &a.mes, &a.ano); scanf( "%d", &d);

b = fim_evento( a, d);

printf( "%d %d %d\n", b.dia, b.mes, b.ano); return EXIT_SUCCESS;

}

Exercícios

1. Complete o código da função fim_evento acima.

2. Escreva uma função que receba dois structs do tipo dma, cada um representando

uma data válida, e devolva o número de dias que decorreram entre as duas datas.

3. Escreva uma função que receba um número inteiro que representa um intervalo de

tempo medido em minutos e devolva o correspondente número de horas e minutos (por exemplo, converte 131 minutos em 2 horas e 11 minutos). Use uma struct como a seguinte: struct hm { int horas; int minutos; }; Structs e ponteiros

Cada registro tem um endereço na memória do computador. (Você pode imaginar que o endereço de um registro é o endereço de seu primeiro campo, mas essa detalhe é irrelevante.) É muito comum usar um ponteiro para guardar o endereço de um registro.

Dizemos que um tal ponteiro aponta para o registro. Por exemplo,

struct dma *p; /* p é um ponteiro para registros dma */ struct dma x;

p = &x; /* agora p aponta para x */

(*p).dia = 31; /* mesmo efeito que x.dia = 31 */

[Cuidado! A expressão *p.dia, que equivale a *(p.dia), tem significado muito diferente de (*p).dia .] A expressão p->mes é uma abreviatura muito útil para a expressão

(8)

(*p).mes :

p->mes = 8; /* mesmo efeito que (*p).mes = 8 */ p->ano = 1998;

Registros podem ser tratados como um novo tipo-de-dados. Por exemplo, typedef struct dma data;

data x; data *p; p = &x;

TYPEDEF

A sintaxe de typedef é fácil. Primeiro, escreva uma declaração de uma variável do tipo desejado. Por exemplo,

int *ptri;

declara uma variável ptri (do tipo ponteiro-para-inteiro). Agora escreva "typedef" antes da declaração:

typedef int *ptri;

Com isso, ptri passa a ser o nome de um novo tipo (idêntico ao tipo ponteiro-para-inteiro). Esse tipo pode ser usado para declarar novos ponteiros-para-inteiros, como p e q:

ptri p, q; Outro exemplo: struct { int x; int y; } ponto;

declara uma variável ponto (que é um par ordenado de inteiros). Preceda a declaração de um typedef:

typedef struct { int x;

int y; } ponto;

Agora ponto passa a ser o nome de um novo tipo (idêntico a par ordenado de inteiros). Esse tipo pode ser usado para declarar novos pontos:

ponto a, b;

Exercícios

4. Defina um registro empregado para guardar os dados (nome, sobrenome, data de

nascimento, RG, data de admissão, salário) de um empregado de sua empresa. Defina um vetor de empregados para armazenar todos os empregados de sua empresa.

5. Um racional é qualquer número da forma p/q, sendo p inteiro e q inteiro não nulo.

É conveniente representar um racional por um registro: typedef struct {

int p, q; } racional;

(9)

Vamos convencionar que o campo q de todo racional é estritamente positivo e que o máximo divisor comum dos campos p e q é 1. Escreva

• uma função reduz que receba inteiros a e b e devolva o racional que representa a/b;

• uma função neg que receba um racional x e devolva o racional −x; • uma função soma que receba racionais x e y e devolva o racional que

representa a soma de x e y;

• uma função mult que receba racionais x e y e devolva o racional que representa o produto de x por y;

• uma função div que receba racionais x e y e devolva o racional que representa o quociente de x por y;

Referências:

• ASCENCIO, Ana F. G.; CAMPOS, Edilene A. V. de. Fundamentos da programação de computadores. 2ª ed. São Paulo: Pearson Pratice Hall, 2007.

• MIZRAHI, Victorine V. Treinamento em Linguagem C. 2ª ed. São Paulo: Pearson Pratice Hall, 2008.

Referências

Documentos relacionados

Consta na Av.35 desta matrícula que nos autos da Ação de Execução Trabalhista, Processo nº 00015075320125150027, em trâmite na 1ª Vara do Trabalho da Comarca de

Este artigo tem por finalidade mostrar a utilização da ferramenta de Planejamento Estratégico Análise Swot, e sua importância para alcançar a excelência no desenvolvimento

Nos tempos atuais, ao nos referirmos à profissão docente, ao ser professor, o que pensamos Uma profissão indesejada por muitos, social e economicamente desvalorizada Podemos dizer que

Na imagem abai- xo, por exemplo, as dimensões e o posicionamento dos personagens (Tio Sam e Cardoso) traduzem, em linguagem simples, o desnível geopolítico existente entre Brasil

The process of implementation of the Forest Code is inherently a redefinition of the bundle of property rights to land, in which there is currently a mismatch between de facto and

Tendo como parâmetros para análise dos dados, a comparação entre monta natural (MN) e inseminação artificial (IA) em relação ao número de concepções e

Quando contratados, conforme valores dispostos no Anexo I, converter dados para uso pelos aplicativos, instalar os aplicativos objeto deste contrato, treinar os servidores

O sentido de ambiente saudável de trabalho se apresenta através do sentido de desenvolvimento do trabalhador dado pelas condições de trabalho que constituem a produção da