P. 1
Exercícios Resolvidos Algoritmo 2

Exercícios Resolvidos Algoritmo 2

|Views: 901|Likes:
Publicado porpauloh_27

More info:

Published by: pauloh_27 on Sep 23, 2013
Direitos Autorais:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less

05/09/2015

pdf

text

original

Faculdade de Engenharia da Universidade do Porto

LICENCIATURA EM ENGENHARIA INFORMÁTICA E COMPUTAÇÃO INTRODUÇÃO À PROGRAMAÇÃO DE COMPUTADORES II - 1999/2000 EXERCÍCIOS João Pascoal Faria (jpf@fe.up.pt)

1. Introdução ao ambiente de programação
1.1. Siga o seguinte guião:
• Arranque o Microsoft Visual C++ 5.0 a partir de Start → Programs → Microsoft Visual C++ 5.0 → Microsoft Visual C++ 5.0. • Crie um novo projecto e espaço de trabalho ("workspace"), com a opção File → New ... → Projects, fornecendo os seguintes dados: Win32 Console Application Location = c:\temp (ou outro directório com permissão de escrita) Project name = ip2 (ou outro nome à sua escolha) √ Create new workspace • Crie um ficheiro com a opção File → New ... → File, fornecendo os seguintes dados: C++ Source File File name = c:\temp\ip2\ip2.c (ou outro nome) √ Add to project • Na janela de edição do ficheiro acabado de abrir, introduza o seguinte programa em C: #include <stdio.h> main() { printf("Ola!\n"); return 0; } • Crie o executável com a opção Build → Build ip2.exe • Corra o executável com a opção Build → Execute ip2.exe • Corra o executável fora do Visual C++, a partir do Windows Explorer e a partir da MS-DOS Prompt (o executável estará em c:\temp\ip2\debug\ip2.exe) • Experimente introduzir e executar outros programas apresentados nas aulas teóricas. • Explore à sua vontade o ambiente de trabalho do Visual C++!

1.2. No sistema operativo Linux, crie um ficheiro de texto ola.c com o mesmo conteúdo do exercício
anterior, usando um editor de texto à sua escolha ( emacs, vi, pico, etc.). Compile o programa com o comando:

gcc ola.c -o ola Execute o ficheiro executável ola criado por este comando.

2. Introdução à programação em C
2.1. [Deitel 2.7] Identifique e corrija os erros em cada uma das instruções seguintes (Nota: pode existir
mais do que um erro por instrução): a) b) c) d) e) f) g) h) i) j) scanf("%d", value); printf("O produto de %d e %d é %d\n", x, y); firstNumber + secondNumber = sumOfNumbers if (number => largest) largest == number; */ Programa para determinar o maior de três inteiros /* Scanf("%d", anInteger); printf("O resto da divisão de %d por %d é \n", x, y, x % y); if (x = y); printf(%d é igual a %d\n", x, y); printf("A soma é %d\n," x + y); Printf("O valor introduzido foi: %d\n, &value);

2.2. [Deitel 2.12] O que aparece escrito no ecrã, se é que é aparece alguma coisa, em resultado da
execução de cada uma das seguintes instruções em C? Suponha que x = 2 e y = 3. a) b) c) d) e) f) g) h) i) printf("%d", x); printf("%d", x + x); printf("x="); printf("x=%d", x); printf("%d = %d", x + y, y + x); z = x + y; scanf("%d%d", &x, &y); /* printf("x + y = %d", x + y); */ printf("\n");

2.3. [Deitel 2.15] Indique a ordem de avaliação dos operadores em cada uma das seguintes instruções
em C, e mostre o valor de x após a execução de cada uma das instruções. a) b) c) x = 7 + 3 * 6 / 2 - 1; x = 2 % 2 + 2 * 2 - 2 / 2; x = (3 * 9 * (3 + (9 * 3 / (3))));

2.4. [Deitel 2.19] Escreva um programa em C que leia 3 inteiros diferentes introduzidos pelo teclado, e
apresente no ecrã a soma, a média, o produto, o menor e o maior desses números. Use apenas a forma

y. ++x. while (x <= 10) { total += x.de selecção simples (sem else) da instrução if. Introdução à programação estruturada 3. total. y). total = 0. int x = 1. printf("%d\n". ++x. } c) While (x <= 100) total += x. [Deitel 3.13] O que escreve o programa seguinte? #include <stdio. while (y > 0) { printf"%d\n".h> main() { int x = 1.2. O diálogo deve aparecer no ecrã com o seguinte aspecto: Introduza três inteiros diferentes: 13 27 14 A soma é 54 A média é 18 O produto é 4914 O menor é 13 O maior é 27 3. while (x <= 10) { y = x * x. } printf("O total é %d\n".11] Identifique e corrija os erros em cada uma das alíneas seguintes (Nota: pode existir mais do que um erro por alínea): a) if (age >= 65). ++x. } b) d) 3. return 0. else printf("A idade é menor que 65\n").1. y). } . total). total += y. printf("A idade é maior ou igual que 65\n"). [Deitel 3. ++y.

Leia o enunciado do problema. 3. os seguintes números são capicuas: 12321. 45554 e 11611. a) Escreva um programa que leia um inteiro de 3 dígitos e determine se é ou não uma capicua. no caso em que x = 9 e y = 11. Note que o compilador de C ignora a "indentação". [Deitel 3.9). a) supondo que o fim da sequência é indicado pelo valor 0 (que já não faz parte da sequência). else printf("#####\n"). [Deitel 3. Formule o algoritmo usando pseudo-código e refinamento sucessivo "top-down". b) supondo que o comprimento da sequência é indicado previamente.3. 2.34] Escreva um programa que leia o comprimento do lado de um quadrado (entre 1 e 20) e escreva no ecrã um quadrado "oco" com asteriscos. } else { printf("#####\n"). (Sugestão: Use os operadores de divisão e módulo para separar o inteiro nos seus dígitos. } b) Para cada um dos exercícios seguintes (3. 3. o programa deve também imprimir o comprimento da sequência. 4. 555. Note também que o compilador de C associa um else ao if mais próximo.6. e determine e imprima a soma. a saída do programa deve ser: ***** * * * * * * ***** 3. . depure e execute o programa em C. printf("$$$$$\n").4 a 3. Escreva um programa em C. (Sugestão: Comece por aplicar as convenções habituais de "indentação". e no caso em que x = 11 e y = 9. if (x < 10) { if (y < 10) printf("*****\n").35] Uma capicua é um número ou um texto que se lê da mesma maneira de trás para a frente e da frente para trás. a média. deve proceder da seguinte forma: 1.) b) Generalize o programa da alínea (a) por forma a tratar inteiros com qualquer número de dígitos.4. No caso da alínea (a). Por exemplo. Escreva um programa em C que leia uma sequência de números inteiros. printf("$$$$$\n"). Por exemplo.31] Determine a saída produzida em cada uma das alíneas seguintes. se o comprimento dado for 5.) a) if (x < 10) if (y < 10) printf("*****\n"). 3.5. Teste. o menor e o maior dos números.3. a não ser que se indique outra coisa através de chavetas {}. [Deitel 3.

3.0001. Suponha que o utilizador introduz 100 A. x++) printf("%d\n". Escreva um programa que leia duas horas do dia no formato hhmm. scanf("%d". [Deitel 3. Exemplo: Introduza a primeira hora no formato hhmm: 1845 Introduza a segunda hora no formato hhmm : 0620 A soma é: 1 0105 Sugestões: Ler cada hora do dia para um inteiro. usar a instrução: printf("%. x >= . o quociente e o resto da divisão inteira por 100 dão as horas e os minutos. x). e calcule e imprima a respectiva soma no formato d hhmm.42] Escreva um programa que leia o raio de um círculo (do tipo float) e calcule e imprima o diâmetro. charVal = getchar(). intVal. respectivamente. e determine se esses valores poderiam representar as medidas dos lados de um triângulo.8.) 4. switch (value % 2) { case 0: printf("Inteiro par\n"). x += 2) printf("%d\n". } c) O código seguinte deve ler um inteiro e um caracter e imprimir os dois.7f\n".14159 para π. &intVal). em que hh indica as horas (de 0 a 23) e mm os minutos (de 0 a 59). 3. b) O código seguinte deve imprimir se um dado inteiro é par ou ímpar: e) O código seguinte deve imprimir os inteiros ímpares de 999 até 1: . 3. Controlo de programa 4. x >= 1.000001) printf("%. o perímetro e a área do círculo. x >= 1.44] Escreva um programa que leia três valores positivos do tipo float. d) for (x = . Para escrever um inteiro n (representando horas ou minutos) em 2 casas preenchidas com zeros à esquerda. com 2 casas decimais. Use o valor 3. for (x = 999. (Sugestão: Não é possível construir um triângulo com um lado maior do que a soma dos outros dois.9. em que d é o número de dias (0 ou 1).n). x). x). charVal). printf("Inteiro: %d\nCaracter: %c\n". [Deitel 3.2d". case 1: printf("Inteiro ímpar\n"). [Deitel 4.7. x += .5 a)-g)] Encontre e corrija os erros em cada uma das alíneas seguintes: a) For (x = 100.1.000001.

[Deitel 4.b): #include <stdio. } While (contador < 100). /* mas por ordem inversa. contador += 2. 14. 18. } return 0 4. total += x. /* Nesta altura. scanf("%f".f) O código seguinte deve imprimir os inteiros pares de 2 até 100: contador = 2. " não é uma capicua\n"). 2. 4.2. n). " é uma capicua\n") else printf(n. 2. contador). 3. 13. while n > 0. x++).h>. do m = m * 10 + aux mod 10 while aux / = 10. 5. Do { if (contador % 2 == 0) printf("%d\n". int m = 0. 8. 7 b) 3. -10 . h) O programa seguinte pretende responder à questão 3. if (m = n) printf(n.6. 6. x <= 150. -4. 23 c) 20. main { int n. m deve ter os mesmos digitos que n. g) O código seguinte deve somar os inteiros de 100 até 150 (suponha que total é inicializado com 0): for (x = 100. int aux = n.7] Escreva instruções for para imprimir cada uma das seguintes sequências de valores: a) 1. 8. do printf("Introduza um inteiro positivo: ").

2 raízes reais iguais ou 2 raízes complexas conjugadas. 1! 2 ! 3! (Sugestão: calcule cada termo a partir do termo imediatamente anterior.dois primeiros dígitos do ano (exemplo: 19) Y . 2=Abril..2 * C . 10=Dezembro=10.. etc.. o operador "/" refere-se ao quociente da divisão inteira... a começar em 1 L . ⋅ 1 n! = 1 (para n =0) (para n ≥1) a) Escreva um programa que leia repetidamente números inteiros não-negativos e calcule e imprima o seu factorial.) b) Qual é o maior número cujo factorial é calculado correctamente pelo programa da alínea (a)? Porquê? E se.4. [Deitel 3.6. (Sugestão: utilize um único ciclo for. usasse cada um dos seguintes tipos: long. short e char? c) Escreva um programa que imprima uma tabela de factoriais dos números de 1 a 15. Os anos bissextos são os anos múltiplos de 4 que não são múltiplos de 100.4. 12=Fevereiro C . os anos 1996 e 2000 são bissextos. (Sugestão: utilize um ciclo for dentro de um ciclo while.dia do mês. 1=segunda. Exemplo: Introduza os coeficientes: 2.. b e c fornecidos pelo utilizador.) 4.) 4.3. e os respectivos valores (com 3 casas decimais).522i 4. M .) c) Série que dá o valor de e-x (com x real positivo previamente definido): 1− x x2 x3 + − +.1 se o ano for bissexto e 0 se o ano for comum Nesta fórmula.522i e 0...200-2. 11=Janeiro.14] O factorial de um número n não-negativo é denotado por n! e é definido da seguinte forma: n! = n ⋅ (n-1) ⋅ (n-2) ⋅ . enquanto que os anos 1998 e 1900 são comuns. Utilize a função sqrt da biblioteca de funções matemáticas para calcular a raiz quadrada de um número em vírgula flutuante. .dia da semana: 0=domingo. Por exemplo.mês: 1=Março.(1 + L) * (M / 11)] mod 7 em que W .dois últimos dígitos do ano (exemplo: 98) D . a) Escreva um programa que calcule e imprima o número de dias de um mês/ano indicado pelo utilizador. sendo os coeficientes a. 4.. Escreva instruções for para calcular a soma dos primeiros n termos (com n inteiro previamente definido) de cada uma das séries seguintes: a) Série que dá o valor da constante matemática π: 4− 4 4 4 4 4 + − + − +.200+2.5 -1 16 Há 2 raízes complexas conjugadas: 0.. Escreva um programa para determinar as raízes da equação quadrática ax2+bx+c=0. e ainda os anos múltiplos de 400.) . O dia da semana correspondente a uma data pode obter-se através da seguinte fórmula: W = [D + (26 * M .2) / 10 + Y + (Y / 4) + (C / 4) . O programa deve indicar se a equação tem 2 raízes reais diferentes.47. em vez do tipo int. 1! 2 ! 3! b) Série que dá o valor da constante matemática e: 1+ (Sugestão: calcule cada termo a partir do termo imediatamente anterior.. terminando quando é introduzido um número negativo. (Sugestão: utilize a instrução switch.5. 3 5 7 9 11 1 1 1 + + +.

Escreva um programa que imprima o número Romano equivalente a um número decimal entre 1 e 1000 introduzido pelo utilizador. continue. scanf("%d". c) Escreva um programa que imprima todos os números primos inferiores a 10000. Restruture o seguinte código por forma a evitar o uso das instruções break e continue: int n.9. i. if (i * i <= n) printf("%d não é primo!\n". i++) if ( ! (n % i) ) break. Um número é primo se apenas for divisível pela unidade e por si próprio. } .7. else printf("%d é primo!\n". 4.n). Diz-se que um número a é divisível por um número b. if (!n) break. Exemplo: Mês (1 a 12): 2 Ano (com 4 dígitos): 1999 Dom Seg Ter Qua 1 2 3 7 8 9 10 14 15 16 17 21 22 23 24 28 Qui 4 11 18 25 Sex 5 12 19 26 Sab 6 13 20 27 4. &n). if (n < 0) { printf("Não aceita números negativos!\n").n). b) Escreva um programa que imprima os 100 primeiros números primos. 4. } for (i = 2. a) Escreva um programa que leia um número e determine se é primo ou não. i * i <= n.b) Escreva um programa que mostre no ecrã o calendário de um mês/ano indicado pelo utilizador. while (1) { printf("Introduza um inteiro positivo (0 termina): "). se o resto da divisão inteira de a por b for zero.8.

(float) x). arredonda x para as centésimas (isto é.1. Escreva uma função double round(double x. retornando o valor arredondado. b) c) d) register auto int x = 7. Inclua essa função num programa de teste que pede ao utilizador valores de x e n. e) double square(double number) { double number. x = y.45678.. [Deitel 5. f) int sum(int n) { if (n == 0) return 0. unsigned n) que arredonda um número em vírgula flutuante ( x) para um certo número de casas decimais ( n). . e imprime o valor de round(x.2.5. int x. a instrução: y = floor(x * 100 + 0. terminando quando o utilizador introduz x=0. int randomNumber = srand(). printf("%f\n". Por exemplo. para 2 casas decimais). float y = 123. } return number * number.. .11] A função floor pode ser usada para arredondar um número em vírgula flutuante para um certo número de casas decimais.50] Encontre os erros existentes em cada um dos seguintes segmentos de programas e explique como os corrigiria: a) float cube(float). } 5. cube(float number) { return number * } /* protótipo */ /* definição */ number * number. [Deitel 5. Funções 5.n) com um número suficientemente grande de casas decimais. else return n + sum(n).5) / 100.

'C'. 1 Conforme o leitor já deve ter reparado. contar o número de vezes que sai cada uma das faces.5. . as centenas (nada.. . que retorna 1 se n for primo e 0 no caso contrário. Escreva uma versão recursiva da função mdc(x.7. utilizável em todas as alíneas. Refaça o exercício 4. 5. a) Escreva uma função mdc(x. para imprimir 6 centenas em romano. basta dividir n pelos números de 2 a (int)sqrt(n).y) directamente a partir destas propriedades. C. para imprimir em romano. Por exemplo.3.31] Escreva um programa que simule o lançamento de uma moeda.0)=x. ou IX).. ou CM). II.8 (programa para imprimir o número Romano equivalente a um número decimal entre 1 e 1000). sem argumentos. se n fôr par (≥2)..5. o itálico é usado para expressões matemáticas. ou XC) e as unidades (nada.4. x1 = x. XX. de acordo com o peso do dígito (milhares.. x40 pode ser calculado com apenas 6 multiplicações em vírgula flutuante (e mais algumas operações aritméticas com inteiros. usando um ciclo for. a) Escreva uma implementação iterativa desta função. char letra5. No entanto. . Por sua vez. unsigned n) que retorne o valor de xn. 5.. Note que. Pretende-se implementar uma função double PotenciaNatural(double x. o programa deve imprimir Cara ou Coroa. seguindo a definição acima. 'M'). 1 c) Desenvolva uma versão não recursiva da função mdc(x. X. escrevendo uma função int primo(int n). char letra1. O programa deve efectuar 100 lançamentos.y)=mdc(y. 'D'. e o Courier bold para código C. . O 1º argumento recebido por esta função é o dígito decimal.y) capaz de calcular o maior divisor comum de dois inteiros. bastaria invocar para_romano(6.42] O maior divisor comum (mdc) de dois inteiros x e y é o maior inteiro que divide tanto x como y (com resto 0). Escreva uma implementação recursiva da função PotenciaNatural tirando partido destas fórmulas. dividindo o programa em funções para imprimir os milhares (nada ou M). o número de operações em vírgula flutuante pode ser drasticamente reduzido se atendermos a que: xn = [xn/2]2. b) É sabido que mdc(x. [Deitel 5. O programa principal deve chamar uma função separada cara_ou_coroa. x0 = 1 Por exemplo. xn = x⋅[x(n-1)/2]2.29. centenas. que só recebe 0 ou 1). Para cada lançamento....7. [Deitel 5.6.x mod y) e mdc(x. b) Uma implementação directa desta função gasta n-1 multiplicações em vírgula flutuante. 5. muito mais rápidas). sem recorrer à biblioteca de funções matemáticas. 5. I. que retorna 0 para cara e 1 para coroa. Cada uma destas funções deve receber como argumento um número entre 0 e 9 (excepto a função para imprimir os milhares. Refaça o exercício 4. para verificar se n é primo.. c) Existe uma implementação iterativa (simples) que tire partido das propriedades indicadas na alínea anterior? 5. Os argumentos seguintes indicam os caracteres a usar. e imprimir os resultados. de 0 a 9. se n for ímpar (≥3) x2 = x⋅x. dezenas ou unidades). cada uma destas funções deve ser implementada através de uma única chamada a uma função mais genérica com o seguinte protótipo: void para_romano(int digito. char letra10). as dezenas (nada.y) tirando partido das propriedades referidas em b).

) 6. O programa deve produzir um resultado do seguinte tipo (os cabeçalhos de linhas e colunas são dispensáveis): n\k* 12 13 0 1 2 3 4 5 6 7 8 9 10 11 ********************************************************************* ****** 0 * 1 1 * 1 1 2 * 1 2 1 3 * 1 3 3 1 4 * 1 4 6 4 1 5 * 1 5 10 10 5 1 6 * 1 6 15 20 15 6 1 7 * 1 7 21 35 35 21 7 1 8 * 1 8 28 56 70 56 28 8 1 9 * 1 9 36 84 126 126 84 36 9 1 10 * 1 10 45 120 210 252 210 120 45 10 1 11 * 1 11 55 165 330 462 462 330 165 55 11 1 12 * 1 12 66 220 495 792 924 792 495 220 66 12 1 13 * 1 13 78 286 715 1287 1716 1716 1287 715 286 78 13 1 (Sugestão: Utilize um vector para guardar os valores da linha corrente.0001}. [Deitel 6. "Arrays" 6. Escreva um programa para imprimir o triângulo de Pascal de altura 14. 1000.. Escreva um programa para gerar várias apostas do totoloto todas diferentes entre si.001. str).345. 100. Pretende-se escrever uma programa para efectuar operações com polinómios. . a[2]. isto é. scanf("%s".13. d[1. e represente o conjunto de apostas por um vector de até 20 apostas. até um máximo de 20 apostas.. 1. a[1]. a) Escreva uma função int lePolinomio(float coefs[]) para ler um polinómio.3. O número de apostas a gerar é dado pelo utilizador. A função deve colocar os coeficientes no vector coefs e deve retornar o grau do polinómio.6. . /* O utilizador introduz ola */ Suponha que foi definido: int a[3]. 6. 9] = 2.) 6. 10. Suponha que foi definido: double d[2][10]. a)-d)] Encontre os erros existentes em cada um dos seguintes segmentos de programas: a) b) c) d) Suponha que foi definido: char str[3].1. a[3]). Para calcular a linha seguinte (n). os valores de nCk para 0≤k≤n≤13.1.2.4.01. O programa aceitará polinómios com grau desde 0 até 20. (Sugestão: Represente cada aposta por um vector de 6 números crescentes (compreendidos entre 1 e 49). para k=n-1. printf("%d %d %d\n".. float f[3] = {1. basta acrescentar um 1 na coluna n e somar ao elemento da coluna k o elemento da coluna k-1. Cada polinómio será representado por um vector com os coeficientes em vírgula flutuante e por um inteiro sem sinal com o grau do polinómio.

Escreva um programa com um pequeno menu que permita integrar e testar todas as funções escritas nas alíneas anteriores. const float coefs[]. No entanto. seguidos de um 0 no fim. Sendo i o nº da linha e j o nº da coluna. 6. Pretende-se construir um programa que permite efectuar operações sobre matrizes quadradas. 3. Suponha que este vector é preenchido com os números 0. use um vector int S[8]. grau. entre 2 e 232-1.). float x).e.. as duas diagonais correspondentes podem ser numeradas i+j e i+7-j.8.. Esta representação impede que duas rainhas estejam na mesma linha.. const float c) Escreva uma função float calculaPolinomio(int grau. Escreva uma função void factoresPrimos(unsigned n. por ordem não decrescente. estão todas as rainhas na mesma diagonal! O problema inicial pode agora ser formulado da seguinte forma: encontrar uma permutação deste vector de 8 números em que não fiquem duas rainhas . O número máximo de tentativas é 10. considerando que qualquer elemento da matriz pode ser um máximo local. A chave é gerada aleatoriamente pelo computador. (Sugestão: Para minimizar o número de operações em vírgula flutuante.b) Escreva uma função void escrevePolinomio(int coeficientes[]). a) Escreva funções para ler e escrever uma matriz. [Baseado em Deitel 6. em que S[i] indica a coluna (entre 0 e 7) em que se encontra a rainha que se encontra na linha i (entre 0 e 7).) d) Escreva um programa para integrar e testar as funções anteriores. e o utilizador tenta adivinhar a chave. d) Diz-se que um elemento de uma matriz é um máximo local se for superior a todos os seus vizinhos. Os factores primos são colocados no vector factores[]. c) Escreva uma função para multiplicar duas matrizes e colocar o resultado numa terceira. por exemplo. sem que nenhumas duas rainhas estejam na mesma linha. 2. a0+a1x+a2x2+a3x3 = a0+(a1+(a2+(a3)x)x)x. 7 (o que quer dizer que a rainha da linha 0 está na coluna 0. Para representar uma solução do problema. O computador deve ainda assinalar as tentativas inconsistentes com as pontuações obtidas nas tentativas anteriores (uma tentativa é inconsistente se as pontuações anteriores se alterarem no caso da chave ser substituída por essa tentativa). Pretende-se escrever um programa para jogar mastermind (sem visual gráfico). na mesma coluna ou na mesma diagonal)? Escreva um programa para achar pelo menos uma solução (ou todas as soluções) para este problema. em factores primos.26] O problema das oito rainhas pode ser formulado da seguinte forma: é possível colocar oito rainhas num tabuleiro de xadrez sem se atacarem mutuamente (i. Escreva um função maximos_locais que imprima todos os máximos locais e respectivas posições. . 1. Desta forma. b) Escreva uma função para transpor uma matriz. No 1º caso é necessário achar a "reunião" dos factores primos e no 2º caso é necessário achar a "intersecção" dos factores primos. A chave é uma sequência de 5 cores diferentes. etc. Sugestão: Considere as linhas e colunas de um tabuleiro de xadrez numeradas de 0 a 7. 6. Introduzir polinómio Mostrar polinómio Calcular valor de polinómio num ponto Terminar 6. 6. a rainha da linha 1 está na coluna 1.7. Esta segunda expressão pode ser calculada "de dentro para fora". o computador responde com a respectiva pontuação (número de cores certas no sítio certo e número de cores certas no sítio errado). unsigned factores[32]) para decompor um número inteiro positivo n. Use depois esta função para achar o mmc (menor múltiplo comum) e o mdc (maior divisor comum) de pares de números dados pelo utilizador. 4. A cada tentativa do utilizador. e as diagonais numeradas de 0 a 14. para calcular e retornar o valor de um polinómio num ponto x. para escrever um polinómio. apresentando um menu do tipo: 1. As cores são representadas por números de 1 a 8.6.5.. não há duas rainhas na mesma coluna. atenda a que.

a) int *numero. 0. p[1]. printf("%c%s %s %s\n". for (p = v. 5. y. *p. 1. 4}. Apontadores 7.2. 3. *p). printf("%d\n".14. 0}. *p = x. 4. sizeof(nomes) / sizeof(char *)). ++*p1. 2. int a[4] = {0. size--) (*f)(*v++). n / 100. int size. *p). 7. x.2f\n". x. 11. *p. size>0. a)-g)] Indique e corrija. "José". 2. 90}. *p1.0). 17. Utilize vectores para marcar as diagonais ocupadas. float x = 3.2f %.1. } 7. *numero). o erro existente em cada um dos seguintes segmentos de programa. p++) printf("%d\n". void forall(int *v. **nomes. *p2 = *p1. *(a+3)). Note que há 8! = 40320 permutações possíveis. *(p+2). printf("%d %d %d %d\n". y. *p2). nomes[0]+1. 3}. *p. se possível. 19. mostra). forall(v. O que imprime cada um dos seguintes segmentos de programa? a) int x = 1. uma solução possível é {3. printf("%d %d %d %d ". 5. } main() { b) c) d) e) f) int v[4] = {57. 6. *p = &x. void (*f)(int)) { for ( . [Deitel 7. 80. *(nomes+1). 7. return 0. 1. 7. int v[] = {1.na mesma diagonal. nomes[2]). char *nomes[] = {"João". *p2. p2 = &y. sizeof(nomes). "Joaquim"}. . Por exemplo. printf("%. a[0]. p1 = &x. 13. } void mostra(int n) { printf("%5. *p1.6. printf("%d %d\n". 2. p = a.2f%%\n". 63.

2. por exemplo o do meio.1. decrementar j 1. int contador. y. char *s. p2[2] = 'e'. ordenar sub-array entre a posição i e a última posição. int *x.2. p1[2] = 'e'. 1. incrementar i 1. s++) printf("%c ". c) d) e) f) g) h) 7. inclusivé. Passo de partição: 1. ordenar o sub-array entre a primeira posição e a posição j. intPtr = realPtr. ou seja: 2. float xPtr = &x. void *genericPtr = numPtr.2.2.1. inclusivé.2. trocar v[i] com v[j]. incrementar i e decrementar j Passo recursivo: Efectuar o passo 1 para cada um dos sub-arrays (esquerdo e direito) não ordenados.2. com valores ≤x do lado esquerdo e valores ≥x do lado direito. resultado. i 8 9 2 5 j 6 1 3 7 2.1.2. s). float x = 19.2. *s != '\0'. resultado = *genericPtr + 7. da seguinte forma: 1. [Wirth] O Quicksort (também designado método de ordenação por partição) é um método de ordenação de arrays muito eficiente que se baseia num algoritmo recursivo do seguinte tipo: 1.3. *s).34.2.3.3.2. char s[] = "ola". xPtr). desde que o seu comprimento seja maior do que 1.3. Enquanto v[i] < x. Escolher um elemento arbitrário (x) do array (v) não ordenado. Se j > primeira posição do array. Partir o array em dois sub-arrays.b) float *realPtr. const char * p1 = s. printf("%f\n". A figura seguinte ilustra o passo 1 do algoritmo. Inicializar i = primeira posição do array 1. short *numPtr. Inicializar j = última posição do array 1. char s[] = "isto é um array de caracteres". Se i ≤ j. char * const p2 = s. 2. x 4 j < i 3 1 x ≤ 2 4 5 6 9 x ≥ 8 7 . printf("%s\n".1. Se i < última posição do array.3. for ( . Enquanto v[j] > x. Enquanto i ≤ j fazer: 1. x = y. long *intPtr.3.

o elemento da coluna j da linha i tem um offset de m*i+j posições em relação ao elemento da 1ª coluna da 1ª linha."DOIS" . Generalizar as funções anteriores (acrescentado ou modificando argumentos se necessário) para trabalhar com labirintos de qualquer dimensão. dezenas e centenas por extenso: char *unidades [] = {"ZERO". A função deve substituir 0 por X ao longo do caminho percorrido. .. "DUZENTOS". . e deve marcar a entrada com E e a saída com S (caso exista saída). consiste em "seguir sempre pela direita". . tendo como argumentos a matriz de caracteres a ser preenchida com 0's e 1's. "DEZ". . "UM" ..5. "NOVECENTOS"}. Um método simples para encontrar a saída garantidamente (não necessariamente pelo caminho mais curto).. e) 7. Escreva uma função void numExtenso(unsigned n). numa matriz com m colunas. por extenso. (Sugestão: Atenda a que. . a) Escreva uma função atravessaLabirinto para atravessar um labirinto 8 x 8..25] A seguinte matriz de 0's e 1's representa um labirinto de 8 x 8 (com o trajecto entre a entrada e a saída realçado a bold): → 1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 0 1 1 0 0 1 0 1 0 1 1 1 1 1 0 1 0 1 1 1 0 0 0 1 0 1 1 1 0 → 1 1 1 1 1 Os 1's representam as paredes. recebendo como argumentos o endereço do primeiro elemento e o número de elementos do array a ordenar.) d) Escreva um programa para integrar e testar as funções anteriores. A função deve receber como argumento a matriz de caracteres que descreve o labirinto. numExtenso(2432) deve produzir: DOIS MIL QUATROCENTOS E TRINTA E DOIS Sugestão: Utilize arrays de strings para guardar as designações das unidades. para escrever no ecrã um número n. 7. c) Escreva uma função imprimeLabirinto para imprimir um labirinto.4. b) Escreva uma função geraLabirinto para gerar aleatoriamente um labirinto 8 x 8 (não necessariamente com saída). "NOVENTA"}. . char *dezenas [] = {"". A função deve ter o seguinte protótipo: void quicksort (int *v. e apontadores para receber a linha e coluna de entrada. c) Escreva e teste uma versão alternativa da função quicksort...a) Escreva uma função recursiva quicksort para ordenar um array de inteiros pelo método exposto. A função deve receber como argumentos a matriz de caracteres que descreve o labirinto. Se o labirinto não tiver nenhuma saída. "VINTE". "CEM". int size). acaba por se voltar à posição de partida. recebendo como argumentos os endereços do primeiro e do último elemento do array a ordenar. não necessariamente quadrados. entre 0 e 9999."DEZANOVE"}. bem como a linha e coluna de entrada (na fronteira do labirinto). b) Escreva um pequeno programa para testar a função anterior. [adaptado de Deitel 7. . char *centenas [] = {"". Por exemplo.

(Sugestão: Use a função strcat.5.) . "DEZEMBRO"}.6. (Sugestão: Guarde as palavras a eliminar num array de strings e use as funções strtok. Escreva uma função int contaOcorrências(char *s1. dataExtenso(27. int mes. O protótipo da novo função será: void numExtenso(unsigned n.7. "FEVEREIRO". 8. char *str) com o objectivo oposto da função anterior. "DA". é usado o cifrão ( $) para separar os escudos dos tostões e centavos e é usado o ponto ( . Escreva um função int identificadorValido(char *str) que verifica se uma string (str) contém um identificador válido. Escreva um programa para ler nomes do "standard input" (um nome em cada linha. Escreva uma função void formataMontante(double montante. uma letra seguida de zero ou mais letras ou dígitos. "JANEIRO".7. (Sugestão: Use as funções gets e puts. char *normPtr) para normalizar um nome (apontado por nomePtr) da seguinte forma: as minúsculas são convertidas para maiúsculas.. Usando a função do problema anterior.1. strcmp. isto é. "DO". usando a função do problema anterior.) 8. em vez de o escrever no ecrã.4. escreva uma função void dataExtenso(int dia.4.2.1998) deve produzir: VINTE E SETE DE MARÇO DE MIL NOVECENTOS E NOVENTA E OITO Escreva um pequeno programa para testar esta função. com 256 caracteres no máximo) e imprimir os nomes normalizados correspondentes no "standard ouput". Considere que cada palavra do nome não tem mais de 40 caracteres. Por exemplo. O nome normalizado é colocado no array de caracteres apontado por normPtr. sequências de vários espaços ou tabs entre duas palavras são substituídos por um único espaço.) 8.. toupper e strcat. Na string.) 8. Exemplos: -1. Escreva uma função double converteMontante(char *str) para converter uma string com um montante em dinheiro para double. "DOS" e "E". Sugestão: Utilize um array de strings para guardar as designações dos meses por extenso: char *meses[] = {"". espaços ou tabs no início ou no fim são suprimidos. 8. "DAS".6. char *s2) para contar o número de ocorrências não sobrepostas da string s1 na string s2. (Sugestão: Use as funções isalpha e isalnum. por forma a escrever o número por extenso numa string.) para separar grupos de 3 dígitos.) 8.3. (Sugestão: Use a função strstr. O montante pode ser precedido do sinal menos (-). O programa deve terminar quando aparece uma linha vazia. . Escreva uma função void normalizaNome(char *nomePtr. (Sugestão: Use a função isdigit.. são removidas as palavras "DE". char *str) .000$00 67.) 8. Refaça a função numExtenso() do exercício 7. para escrever no ecrã uma data por extenso.5. int ano).718$30 14$50 . Caracteres e cadeias de caracteres (strings) 8.

Suponha que. Escreva um programa que copie caracteres do "standard input" para o "standard output".2. Se o número for introduzido com o ponto decimal ou com o "E" da notação exponencial. lê-o para um long. Estruturas. */ struct data le_data(void). Retorna a estrutura que descreve a data. bem como as sequências de caracteres começadas em "//" e terminadas com o caracter de mudança de linha. /* indica qual o campo usado na união */ union number_value value. /* Compara duas datas. DOUBLE}. }. Senão. igual ou menor do que a 2ª data (d2). se definem os seguintes tipos de dados e protótipos de funções: enum number_types {LONG. suprimindo as sequências de caracteres começadas em "/*" e terminadas em "*/" (início e fim de comentário em C).8. 0 ou –1 conforme a 1ª data (d1) é maior. */ . }. /* Escreve uma data no "standard output".9. union number_value { long l_value. Usando essa variante. double d_value. 9. (Sugestão: Use as funções getchar e putchar. 8. escreva um programa que leia várias linhas do "standard input". para implementar uma calculadora capaz de trabalhar com números inteiros ou em vírgula flutuante. no mesmo formato entendido por "le_data". typedef struct number NUMBER. Retorna 1.3 (ver Resposta a exercícios seleccionados). ano. e escreva as mesmas linhas ordenadas alfabeticamente no "standard output". struct number { enum number_types type. no formato dia/mês/ano. enumerações e manipulação ao bit 9.1. Escreva uma variante da função quicksort do exercício 7. até um máximo de 50 linhas de 80 caracteres. */ int compara_datas(struct data d1. /* Lê um número do "standard input". Suponha que se define o seguinte tipo de estrutura para representar datas: struct data { int dia. */ void escreve_data(struct data d). Implementa e teste as seguintes funções: /* Lê uma data do "standard input". Retorna a estrutura com o tipo e o valor lido. }.) 9. para ordenar um array de strings em vez de um array de inteiros.8. lê-o para um double. com o mês de 1 a 12 e o ano com 4 dígitos. mes. struct data d2). uniões.

em vez de dois vectores. */ int conta_dias_trab(unsigned dias_trab). /* Soma dois números inteiros ou em vírgula flutuante e retorna a estrutura com o tipo e o valor resultante. separados por um ou mais espaços ou "tabs". */ void write_number(NUMBER num). usando dois inteiros.1. em que o i-ésimo bit a 1 (0) significa que o funcionário compareceu (faltou) ao trabalho no dia i (1≤i≤n. Suponha que as notas obtidas pelos alunos a um teste se encontram num ficheiro de texto "notas. unsigned dias_trab). codifica e retorna os dias de comparência ao trabalho de um dado funcionário num dado mês. Comece por escrever instruções ou expressões para activar (colocar a 1).NUMBER read_number(void).4. . usando a notação apropriada ao tipo. NUMBER num2). /* Imprime os dias de comparência ao trabalho de um dado funcionário num dado mês. char *mes. /* Conta os dias de comparência ao trabalho de um dado funcionário num dado mês (irrelevantes para o caso). int n_dias_mes). A 1ª linha do ficheiro tem o número de alunos que compareceram ao teste. Escreva também uma instrução para desactivar todos os bits. Cada um das restantes linhas do ficheiro tem o nome do aluno e a nota respectiva. 9. char *mes. desactivar (colocar a 0) e testar (retornando 1 ou 0) o i-ésimo bit de uma variável a do tipo unsigned. */ unsigned le_dias_trab(char *nome_func. 10. */ NUMBER add_numbers(NUMBER num1.º de dias do mês). void add_numbers(const NUMBER *numPtr1. A nota é indicada por um inteiro entre 0 e 20. A assiduidade de um funcionário num mês pode ser codificada num inteiro de 32 bits sem sinal (unsigned). com i entre 0 e 31. e operações bit-a-bit para tratar as duas diagonais. Senão. NUMBER *sumPtr). Se pelo menos um dos números for do tipo double. Refaça o exercício 6. b) Implementa versões alternativas das funções anteriores. baseadas nessa representação: /* Lê. 9.dat". void write_number(const NUMBER *numPtr). const NUMBER *numPtr2.8 (ver exercícios resolvidos). Manipulação de ficheiros 10. o resultado é do tipo double.3. o resultado é do tipo long. /* Escreve o número descrito por "num" no "standard output". Os protótipos passam a ser: void read_number(NUMBER *numPtr). usando apontadores para estruturas em vez de estruturas na chamada das funções. */ void escreve_dias_trab(char *nome_func. Implemente e teste as seguintes funções. a) Implementa e teste as funções anteriores.

o fim dos dados é geralmente sinalizado com Ctrl-D em UNIX e com Ctrl-Z em DOS/WINDOWS. 20). As linhas de entrada devem ser guardadas em memória numa lista ligada usada como pilha ("last in first out"). Sugestão: Use as funções gets(s) e puts(s). 10. A função gets retorna NULL quando encontra o fim dos dados de entrada (EOF). Listar o conteúdo do ficheiro Inserir um novo artigo no fim do ficheiro Procurar um artigo pelo nome Procurar um artigo pela posição no ficheiro Modificar os dados do último artigo procurado Terminar Antes de terminar. Seguidamente. O ficheiro é constituído por registos do seguinte tipo: struct artigo { char nome_artigo [40]. 6.dat".2. Por uma questão de generalidade. Cada linha do ficheiro tem a nota e o número de alunos com essa nota. . 1.2.dat" a partir do ficheiro "notas. 11. char unidade_medida [10]. .. Escreva um programa que construa o ficheiro "histograma. Suponha que as linhas de entrada não têm mais de 1000 caracteres. Cada artigo é descrito por uma estrutura do seguinte tipo: struct artigo { char nome_artigo [40].dat" com dados de artigos em stock. Cada nó da lista deve conter dois campos: um apontador para o nó seguinte. o programa deve criar o ficheiro vazio. 11. }. o programa deve perguntar ao utilizador os nomes dos ficheiros no início da sua execução. Quando se introduzem dados pelo teclado. O programa deve começar por abrir o ficheiro. um apontador para uma string (array de caracteres terminado em '\0') alocada dinâmicamente contendo uma linha lida do standard input. /* string */ float preco_unitario. 4.1. char unidade_medida [10]. 2.2) Escreva um programa para efectuar a manutenção de uma lista de artigos. 3.. No caso do ficheiro não existir. com o número de ocorrências de cada nota (0. deve apresentar um menu com as seguintes opções: 1. 2. o programa deve fechar o ficheiro. pretende-se construir um ficheiro de texto "histograma. Escreva um programa para efectuar a manutenção de um ficheiro binário "artigos. (baseado em 10.. }. Estruturas de dados dinâmicas 11.A partir dessas notas. /* string */ float quantidade_em_stock. separados por um espaço. /* string */ float preco_unitario.dat". Escreva um programa que lê um conjunto de linhas do standard input e as escreve de volta no standard output por ordem inversa. /* string */ float quantidade_em_stock. 5.

Procurar um artigo pelo nome (pergunta o nome do artigo e mostra os respectivos dados) 12. A lista deve estar ordenada por nome de artigo. 9. . Listar (imprime o conteúdo da lista em formato tabular) Inserir um artigo (pergunta os dados do artigo e insere na lista) Eliminar um artigo pelo nome (pergunta o nome do artigo.A lista de artigos deve ser representada em memória por uma lista ligada. mostra os dados actuais. No ínico do programa a lista está vazia. mostra os dados actuais e pede os novos dados) 11. 8. o programa deve libertar a memória ocupada pela lista. O programa deve apresentar um menu com as seguintes opções: 7. Terminar Antes de terminar. Cada nó da lista deve ter uma estrutura do tipo indicado acima e um apontador para o nó seguinte. Não podem existir dois artigos com o mesmo nome. Modificar um artigo (mantendo o nome) (pergunta o nome do artigo. pede confirmação e só depois o elimina da lista) 10.

You're Reading a Free Preview

Descarregar
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->