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

while (x <= 10) { y = x * x. [Deitel 3. 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. } 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).de selecção simples (sem else) da instrução if. printf("%d\n". ++x. y). y). total).2. while (x <= 10) { total += x. ++x. } . return 0. y. ++y. printf("A idade é maior ou igual que 65\n").h> main() { int x = 1. int x = 1.1. total = 0. } b) d) 3. total. [Deitel 3. while (y > 0) { printf"%d\n". ++x. Introdução à programação estruturada 3. total += y. } c) While (x <= 100) total += x. else printf("A idade é menor que 65\n").13] O que escreve o programa seguinte? #include <stdio.

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

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

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

5.4. short e char? c) Escreva um programa que imprima uma tabela de factoriais dos números de 1 a 15. em vez do tipo int.. e os respectivos valores (com 3 casas decimais).. 1! 2 ! 3! (Sugestão: calcule cada termo a partir do termo imediatamente anterior.dois primeiros dígitos do ano (exemplo: 19) Y .. Escreva um programa para determinar as raízes da equação quadrática ax2+bx+c=0.(1 + L) * (M / 11)] mod 7 em que W . Exemplo: Introduza os coeficientes: 2. 2=Abril. sendo os coeficientes a. terminando quando é introduzido um número negativo. (Sugestão: utilize um ciclo for dentro de um ciclo while. 12=Fevereiro C .200+2. 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 + − + − +.4. [Deitel 3. 4. O dia da semana correspondente a uma data pode obter-se através da seguinte fórmula: W = [D + (26 * M .2 * C ..47. 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.dia do mês. O programa deve indicar se a equação tem 2 raízes reais diferentes... 3 5 7 9 11 1 1 1 + + +. o operador "/" refere-se ao quociente da divisão inteira..dia da semana: 0=domingo. etc. .. a) Escreva um programa que calcule e imprima o número de dias de um mês/ano indicado pelo utilizador. (Sugestão: utilize um único ciclo for. 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.) 4. usasse cada um dos seguintes tipos: long..522i e 0.2) / 10 + Y + (Y / 4) + (C / 4) .dois últimos dígitos do ano (exemplo: 98) D . Os anos bissextos são os anos múltiplos de 4 que não são múltiplos de 100.mês: 1=Março.) c) Série que dá o valor de e-x (com x real positivo previamente definido): 1− x x2 x3 + − +... 1=segunda. a começar em 1 L .) 4.6. 2 raízes reais iguais ou 2 raízes complexas conjugadas. enquanto que os anos 1998 e 1900 são comuns.) .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) ⋅ . Por exemplo. 11=Janeiro.200-2. 10=Dezembro=10. ⋅ 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.5 -1 16 Há 2 raízes complexas conjugadas: 0. M . e ainda os anos múltiplos de 400.3. (Sugestão: utilize a instrução switch. os anos 1996 e 2000 são bissextos.1 se o ano for bissexto e 0 se o ano for comum Nesta fórmula.522i 4. b e c fornecidos pelo utilizador.

4. Escreva um programa que imprima o número Romano equivalente a um número decimal entre 1 e 1000 introduzido pelo utilizador. else printf("%d é primo!\n". while (1) { printf("Introduza um inteiro positivo (0 termina): ").8.7. continue.n). &n). 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. scanf("%d".b) Escreva um programa que mostre no ecrã o calendário de um mês/ano indicado pelo utilizador.n). i * i <= n. 4. Um número é primo se apenas for divisível pela unidade e por si próprio. Restruture o seguinte código por forma a evitar o uso das instruções break e continue: int n. } for (i = 2. i++) if ( ! (n % i) ) break. a) Escreva um programa que leia um número e determine se é primo ou não. } . c) Escreva um programa que imprima todos os números primos inferiores a 10000. if (i * i <= n) printf("%d não é primo!\n". if (n < 0) { printf("Não aceita números negativos!\n"). Diz-se que um número a é divisível por um número b. b) Escreva um programa que imprima os 100 primeiros números primos. if (!n) break. i. se o resto da divisão inteira de a por b for zero.9.

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

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

scanf("%s". str). 1. O programa aceitará polinómios com grau desde 0 até 20. O número de apostas a gerar é dado pelo utilizador. .. printf("%d %d %d\n". 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. Suponha que foi definido: double d[2][10]. para k=n-1. a) Escreva uma função int lePolinomio(float coefs[]) para ler um polinómio. até um máximo de 20 apostas..1.6. a[3]). a[2]. basta acrescentar um 1 na coluna n e somar ao elemento da coluna k o elemento da coluna k-1.) 6. isto é.0001}. os valores de nCk para 0≤k≤n≤13.345.2. (Sugestão: Represente cada aposta por um vector de 6 números crescentes (compreendidos entre 1 e 49). float f[3] = {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.13. /* O utilizador introduz ola */ Suponha que foi definido: int a[3].01. 6. 1000..3. . [Deitel 6. e represente o conjunto de apostas por um vector de até 20 apostas. A função deve colocar os coeficientes no vector coefs e deve retornar o grau do polinómio.) 6.1. 9] = 2. 10.001. 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].4. Para calcular a linha seguinte (n). Escreva um programa para imprimir o triângulo de Pascal de altura 14. Escreva um programa para gerar várias apostas do totoloto todas diferentes entre si. a[1]. d[1. Pretende-se escrever uma programa para efectuar operações com polinómios. "Arrays" 6. 100.

por ordem não decrescente. 6. Sendo i o nº da linha e j o nº da coluna. a rainha da linha 1 está na coluna 1.7. Escreva um função maximos_locais que imprima todos os máximos locais e respectivas posições.5. Para representar uma solução do problema. 2.. Esta representação impede que duas rainhas estejam na mesma linha. e o utilizador tenta adivinhar a chave. 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. 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). por exemplo. 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). [Baseado em Deitel 6. grau. const float c) Escreva uma função float calculaPolinomio(int grau. atenda a que. para escrever um polinómio. sem que nenhumas duas rainhas estejam na mesma linha. A chave é gerada aleatoriamente pelo computador.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. 6. Pretende-se construir um programa que permite efectuar operações sobre matrizes quadradas.. (Sugestão: Para minimizar o número de operações em vírgula flutuante. Esta segunda expressão pode ser calculada "de dentro para fora". apresentando um menu do tipo: 1. 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 . 1. unsigned factores[32]) para decompor um número inteiro positivo n. .8. 3. No entanto. O número máximo de tentativas é 10.e. em factores primos.).) d) Escreva um programa para integrar e testar as funções anteriores. e as diagonais numeradas de 0 a 14. b) Escreva uma função para transpor uma matriz. use um vector int S[8]. Pretende-se escrever um programa para jogar mastermind (sem visual gráfico). A chave é uma sequência de 5 cores diferentes. Introduzir polinómio Mostrar polinómio Calcular valor de polinómio num ponto Terminar 6. Desta forma.. a0+a1x+a2x2+a3x3 = a0+(a1+(a2+(a3)x)x)x. Suponha que este vector é preenchido com os números 0. A cada tentativa do utilizador. não há duas rainhas na mesma coluna. 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).. 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. seguidos de um 0 no fim. d) Diz-se que um elemento de uma matriz é um máximo local se for superior a todos os seus vizinhos. 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. float x). etc. Escreva um programa com um pequeno menu que permita integrar e testar todas as funções escritas nas alíneas anteriores. Escreva uma função void factoresPrimos(unsigned n. entre 2 e 232-1. Os factores primos são colocados no vector factores[]. a) Escreva funções para ler e escrever uma matriz. 6.b) Escreva uma função void escrevePolinomio(int coeficientes[]). para calcular e retornar o valor de um polinómio num ponto x.6. considerando que qualquer elemento da matriz pode ser um máximo local. const float coefs[]. as duas diagonais correspondentes podem ser numeradas i+j e i+7-j. 7 (o que quer dizer que a rainha da linha 0 está na coluna 0. c) Escreva uma função para multiplicar duas matrizes e colocar o resultado numa terceira. Sugestão: Considere as linhas e colunas de um tabuleiro de xadrez numeradas de 0 a 7. As cores são representadas por números de 1 a 8. 4.

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

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

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

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

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

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

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

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

Sign up to vote on this title
UsefulNot useful