Programação 23/24 S2
Teste
Informações gerais
Regras
- Podem consultar a folha de consulta previamente distribuida - em formato físico.
- Pode resolver o teste a lápis.
- A resolução do teste é individual.
- Não podem sair da sala durante o teste.
- Além do material estritamente necessário para resolver o teste, não podem ter mais nada em cima da mesa.
Cotação
- [5 valores] - Parte 1
- Cada pergunta vale 1 valor
- Repostas erradas descontam 25% do seu valor
- Pergunta com 1 resposta, resposta errada desconta 0.25 valores
- Pergunta com 2 respostas, cada resposta errada desconta 0.125 valores
- etc.
- [14 valores] - Parte 2
- [2.5 valores] - Problema 1
- [2.5 valores] - Problema 2
- [5 valores] - Problema 3
- [5 valores] - Problema 4
Parte 1
Pergunta 1 (1 resposta)
//funcao para a media
int func(int n, int array[n]) {
int soma = 0;
for (int i = 0; i < n; i++) {
soma += array[i];
}
return soma / n;
}
Esta função:
- Devolve a média dos elementos de um array de inteiros de tamanho
n
. - Não compila porque o tamanho do array não pode ser passado como argumento.
- Não compila porque porque não há salvaguarda para prevenir divisão por 0.
- Devolve calcula a soma dos elementos de um array de inteiros de tamanho
n
.
Pergunta 2 (2 respostas)
Esta função pretende devovler o produto dos elementos de um array de inteiros de tamanho n
. A função:
- Não está correcta porque não devolve nenhum valor.
- Está bem implementada.
- Não está correcta porque não tem chavetas
{ }
no ciclofor
. - Não está correcta porque a variável
total
não está inicializada corretamente inicializada.
Pergunta 3 (1 resposta)
No final da execução do seguinte código, qual é o valor da variável x? (1 resposta)
- 0
- 1
- 2
- 10
- Nenhuma das respostas anteriores.
Pergunta 4 (1 resposta)
Considera o seguinte programa:
int main() {
int array[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
for (int i=0; i<10; i++) {
val = array[i];
if (i % 2 == 0) val += i;
printf("%d ", val);
}
}
Output do programa:
- 1 1 2 1 3 1 4 1 5 1
- 1 1 2 1 3 1 4 1 5 1
- 1 2 3 4 5 6 7 8 9 10
- 1 1 3 1 5 1 7 1 9 1
Pergunta 5 (1 resposta)
Considera o seguinte programa:
typedef struct
{
int x;
int y;
char c; // c=0 inativo, c=1 ativo
} Ponto;
typedef struct
{
int n;
Ponto pontos[100];
} Pontos;
void filter(Pontos pontos, int n) {
for (int i = 0; i < n; i++)
if (pontos.pontos[i].y < pontos.pontos[i].x)
pontos.pontos[i].c = 0;
}
Escolhe a resposta correcta:
- A função filter não altera o array original, porque recebe uma cópia do registo
Pontos
, e não um apontador para oPontos
original. - A função filter muda o array original de forma a que todos os pontos abaixo da diagonal principal y=x fiquem inactivos.
- A função filter muda o array original de forma a que todos os pontos acima da diagonal principal y=x fiquem inactivos.
- A função não faz nada porque o ciclo não tem chavetas
{ }
. - Nenhuma das respostas anteriores.
Parte 2
Problema 1
Considera as 2 variantes de um programa que incrementa os valores de uma matriz.
typedef struct { float valores[100][100]; int ncols, nrows; } Matriz; Matriz incrementa_matriz1(Matriz m) { for (int i = 0; i < m.nrows; i++) { for (int j = 0; j < m.ncols; j++) { m.valores[i][j]++; } } return m; } int programa1() { Matriz m = = {{{0}}, 3, 3}; // matriz 3x3 com zeros incrementa_matriz1(m); // imprimir matriz for (int i = 0; i < m.nrows; i++) { for (int j = 0; j < m.ncols; j++) printf("%f ", m.valores[i][j]); printf("\n"); } } void incrementa_matriz2(Matriz * m) { for (int i = 0; i < m->nrows; i++) { for (int j = 0; j < m->ncols; j++) { m->valores[i][j]++; } } } int programa2() { Matriz m = = {{{0}}, 3, 3}; // matriz 3x3 com zeros incrementa_matriz2(&m); // imprimir matriz for (int i = 0; i < m.nrows; i++) { for (int j = 0; j < m.ncols; j++) printf("%f ", m.valores[i][j]); printf("\n"); } }
- O output das duas funções (
programa1
eprograma2
) é o mesmo (Sim/Não)? [1.5 val]- Escreve o output de cada um dos programas (se forem iguais, basta escrever de um deles).
- Qual é a vantagem de passar o registo
Matriz
por referência como noprograma2
, invés de por valor como noprograma1
? [1 val]
Problema 2
- Considera o seguinte código.
#include <stdio.h>
#include <string.h>
#define MAX_STRINGS 100
char *nomes_proprios[] = {
"Maria", "Joao", "Ana", "Pedro", "Carla", "Jose",
"Margarida", "Miguel", "Sofia", "Ricardo"
};
void print_com_filtro_char(int n_strings, char nomes[n_strings][MAX_STRINGS], char c1, char c2) {
for (int i = 0; i < n_strings; i++)
if (nomes[i][0] == c1 || nomes[i][strlen(nomes[i])-1] == c2)
printf("%s\n", nomes[i]);
}
int main() {
print_com_filtro_char(5, nomes_proprios, 'M', 'a');
return 0;
}
- [1 val] Indica o output do programa na consola.
- [1.5 val] Explica o que o programa está a fazer.
Problema 3 - Cálculo dos limites para histograma
- Escreve uma função chamada
calcular_limites
que recebe- um array de reais (
vals
) e o seu tamanho (n
); - um array de reais (
limites
) e o seu tamanhon_bins+1
;
- um array de reais (
- O objetivo da função é delimitar os intervalos dos valores de
vals
emn_bins
intervalos. - Para isso é necessário percorrer todo o especto de valores de
vals
em intervalos regulares, e.g.- para
vals[] = {-5, 1, -2, 3, 6, 15}
(valores podem não estar ordenados!) en_bins = 4
; limites
seria{-5, 0, 5, 10, 16}
;- porque o valor minimo é -5, o valor máximo é 15, e como queremos 4 intervalos, dividimos \frac{max - min}{n\_bins} = 5 para obter a largura de cada um dos n\_bins+1=5 intervalos;
- como os intervalos são fechados à esquerda e abertos à direita, somamos 1 ao valor máximo para garantir que o último intervalo inclui o valor máximo;
- se “desenrolarmos” o vetor
limites
, teríamos os seguintes intervalos [-5, 0[, [0, 5[, [5, 10[, [10, 16[.
- para
Problema 4 - Histograma
- Escreve uma função chamada
calcular_histograma
que devolve um inteiro e recebe- um array de reais (
vals
) e o seu tamanho (n
); - um apontador de registo do tipo
Histograma
. Este registo tem os seguintes campos:- o número de intervalos do histograma (
n_bins
); - um array de inteiros (
counts
) para contar o número de elementos que existe em cada intervalo- o conteúdo útil deste vetor ocupa
n_bins
elementos; - assume-se que este vetor não foi previamente inicializado;
- o conteúdo útil deste vetor ocupa
- um array de reais (
limites
) para indicar os limites de cada intervalo de valores- o conteúdo útil deste vetor ocupa
n_bins+1
elementos;
- o conteúdo útil deste vetor ocupa
- um inteiro
limites_init
que indica se os limites já foram calculados (1) ou não (0);
- o número de intervalos do histograma (
- um array de reais (
- O objetivo da função é calcular o histograma dos valores do vetor
vals
. - Um histograma conta o número de elementos que se encontram em cada intervalo de valores (definido pelo vetor
limites
), e.g.- para
vals[] = {-5, 1, -2, 3, 6, 15}
- e
limites[]
seria{-5, 0, 5, 10, 16}
- e
counts
seria{2, 2, 1, 1}
, porque há 2 elementos em [-5,0[, 2 em [0,5[, 1 em [5,10[ e 1 em [10,16[.
- para
- Se os limites ainda não foram calculados, a função devolve 1. Caso contrário, devolve 0.