Exercícios de arrays (vetores e matrizes) em C

Reunimos 13 exercícios, do iniciante ao avançado, que usam arrays. Vão do básico de arrays unidimensionais até arrays bidimensionais (matrizes), ordenação e busca binária. Escreva seu código no navegador e clique em "Corrigir": ele é executado com gcc de verdade em várias entradas e a saída é verificada.

Como usar estes exercícios
  1. Leia o enunciado e o exemplo de execução e escreva seu código no campo abaixo
  2. Clique em "▶ Executar" para testar com a sua própria entrada
  3. Clique em "✔ Corrigir" para verificar a saída com várias entradas preparadas
  4. Travou? Abra a "Dica". Resolveu? Compare com "Solução e explicação"
Regras da correção
  • Imprima a saída exatamente como no exemplo. Não imprima mensagens pedindo a entrada, como "Digite um número"
  • Espaços no fim das linhas e linhas em branco no final são ignorados
  • Seu código é salvo automaticamente neste navegador

Obs.: Executar e Corrigir enviam seu código ao Wandbox, um serviço externo e gratuito de compilação, que o executa com gcc.

13 exercícios (Iniciante 4 · Intermediário 5 · Avançado 4)

Arrays (13 exercícios)

A01 Iniciante

Exercício 1. Mostrar em ordem inversa

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 100) e na 2ª linha N inteiros, e mostre-os em uma linha, separados por espaço, na ordem inversa à da entrada.
Exemplo de execução (a entrada está sublinhada)
5 3 1 4 1 5 5 1 4 1 3
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 4 entradas preparadas.
Primeiro leia tudo repetindo scanf("%d", &a[i]); com for (i = 0; i < n; i++). Para mostrar, comece em i = n - 1 e volte até 0 com i--.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    for (int i = n - 1; i >= 0; i--) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}
Explicação: Os índices de um array com N elementos vão de 0 a N−1. Começando em i = n, você lê a[n], que fica fora do array (acesso fora dos limites é comportamento indefinido e pode mostrar lixo sem dar erro). A condição de término também precisa ser i >= 0, senão a[0] não é mostrado.
A02 Iniciante

Exercício 2. Soma e média

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 100) e na 2ª linha N inteiros (cada um entre −1000 e 1000) e mostre a soma e a média. A média deve ser mostrada com duas casas decimais.
Exemplo de execução (a entrada está sublinhada)
5 1 2 3 4 5 Soma: 15 Média: 3.00
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Inicialize a variável da soma, sum, com 0 e repita sum += a[i]; N vezes. Para a média, divida convertendo um dos lados para double: (double)sum / n.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i];
    }
    printf("Soma: %d\n", sum);
    printf("Média: %.2f\n", (double)sum / n);
    return 0;
}
Explicação: Com sum / n a operação é uma divisão entre inteiros e a parte decimal é descartada (5 / 3 dá 1). Escrevendo (double)sum / n, sum é convertido para double antes da divisão, e você obtém 1.666…. Já (double)(sum / n) converte depois de dividir e não adianta.
A03 Iniciante

Exercício 3. Posição do maior e do menor valor

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 100) e na 2ª linha N inteiros, e mostre o maior e o menor valor junto com a posição de cada um (o primeiro elemento é a posição 1). Se o mesmo valor aparecer mais de uma vez, mostre a posição do primeiro.
Exemplo de execução (a entrada está sublinhada)
5 3 9 2 9 1 Maior: 9 (posição 2) Menor: 1 (posição 5)
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 4 entradas preparadas.
Guardando o índice em vez do próprio valor, você sabe tanto o valor quanto a posição. Comece com imax = 0 e, se a[i] > a[imax], atualize com imax = i. Na hora de mostrar, a posição é imax + 1.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int imax = 0, imin = 0;
    for (int i = 1; i < n; i++) {
        if (a[i] > a[imax]) imax = i;
        if (a[i] < a[imin]) imin = i;
    }
    printf("Maior: %d (posição %d)\n", a[imax], imax + 1);
    printf("Menor: %d (posição %d)\n", a[imin], imin + 1);
    return 0;
}
Explicação: Se o valor inicial do máximo for 0, o resultado sai errado quando todos os números são negativos. O mais seguro é usar o primeiro elemento como valor inicial. E se a comparação for >=, a atualização acontece também com valores iguais, e a posição passa a ser a do último.
A04 Iniciante

Exercício 4. Diferença entre elementos vizinhos

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 100) e na 2ª linha N inteiros a1, a2, …, aN, e mostre em uma linha, separadas por espaço, as diferenças entre elementos vizinhos a2−a1, a3−a2, …, aN−aN−1. Quando N for 1, mostre uma linha vazia.
Exemplo de execução (a entrada está sublinhada)
5 3 7 4 4 10 4 -3 0 6
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 4 entradas preparadas.
São N−1 diferenças. Faça i ir de 0 até n - 2 e mostre a[i + 1] - a[i]. A condição do laço é i < n - 1.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    for (int i = 0; i < n - 1; i++) {
        printf("%d ", a[i + 1] - a[i]);
    }
    printf("\n");
    return 0;
}
Explicação: Ao usar a[i + 1], pense se i + 1 está dentro dos limites do array. Com a condição i < n, no final você lê a[n] (fora dos limites). Quando N=1, o laço não roda nenhuma vez e só a linha vazia é mostrada.
A05 Intermediário

Exercício 5. Buscar um valor

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 100), na 2ª linha N inteiros e na 3ª linha o valor X a ser buscado. Se X estiver no array, mostre a posição em que ele aparece pela primeira vez (o primeiro elemento é a posição 1) e quantas vezes X aparece. Se não aparecer nenhuma vez, mostre "Não encontrado".
Exemplo de execução (a entrada está sublinhada)
6 4 2 7 2 9 2 2 Primeira posição: 2 Quantidade: 3
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Inicialize a variável da posição com −1, que representa "ainda não encontrado". Quando a[i] == x, se a posição ainda for −1, registre i; a quantidade aumenta 1 toda vez.
#include <stdio.h>

int main(void) {
    int n, x;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    scanf("%d", &x);

    int pos = -1, count = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] == x) {
            if (pos == -1) pos = i;
            count++;
        }
    }

    if (count == 0) {
        printf("Não encontrado\n");
    } else {
        printf("Primeira posição: %d\n", pos + 1);
        printf("Quantidade: %d\n", count);
    }
    return 0;
}
Explicação: Se você quisesse só a primeira ocorrência, poderia usar break assim que encontrasse, mas neste exercício também é preciso contar, então o array é percorrido até o fim. Em compensação, a posição é registrada só na primeira vez (com pos = i toda vez, fica a última posição). Representar "não encontrado" com −1, um valor impossível como índice, é uma técnica clássica.
A06 Intermediário

Exercício 6. Valores maiores ou iguais à média

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 100) e na 2ª linha N inteiros (cada um entre −1000 e 1000). Na 1ª linha da saída mostre a média com duas casas decimais e, na 2ª linha, os valores maiores ou iguais à média, na ordem em que foram lidos, separados por espaço.
Exemplo de execução (a entrada está sublinhada)
6 50 60 70 80 90 100 Média: 75.00 80 90 100
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
A média só é conhecida depois de ler tudo. Por isso, guarde primeiro os valores no array, calcule a média e depois percorra o array de novo desde o início, mostrando os que satisfazem a[i] >= avg.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += a[i];
    }
    double avg = (double)sum / n;
    printf("Média: %.2f\n", avg);

    for (int i = 0; i < n; i++) {
        if (a[i] >= avg) {
            printf("%d ", a[i]);
        }
    }
    printf("\n");
    return 0;
}
Explicação: Processamentos em que "só dá para decidir depois de ver tudo" são exatamente as situações em que um array é necessário. Se você calcular a média com int avg = sum / n;, para a entrada 1 2 2 a média vira 1 e o 1 também é mostrado. Na comparação a[i] >= avg, o int é convertido para double antes de comparar.
A07 Intermediário

Exercício 7. Distribuição de frequência das notas

Leia na 1ª linha o número de pessoas N (1 ≤ N ≤ 100) e na 2ª linha as notas das N pessoas (inteiros de 0 a 100), e mostre a distribuição de frequência em faixas de 10 pontos, usando a quantidade de *. As faixas são 10: 0-9, 10-19, …, 80-89, 90-100 (a nota 100 entra em 90-100), e faixas sem ninguém também são mostradas, como "20-29:".
Exemplo de execução (a entrada está sublinhada)
10 0 9 10 55 59 60 89 90 99 100 0-9: ** 10-19: * 20-29: 30-39: 40-49: 50-59: ** 60-69: * 70-79: 80-89: * 90-100: ***
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 4 entradas preparadas.
Prepare um array int cnt[10] = {0}; para contar as pessoas de cada faixa. O número da faixa de uma nota s é s / 10, mas para 100 isso dá 10, então só nesse caso use 9.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int cnt[10] = {0};
    for (int i = 0; i < n; i++) {
        int k = a[i] / 10;
        if (k == 10) k = 9;
        cnt[k]++;
    }

    for (int k = 0; k < 10; k++) {
        if (k == 9) {
            printf("90-100: ");
        } else {
            printf("%d-%d: ", k * 10, k * 10 + 9);
        }
        for (int j = 0; j < cnt[k]; j++) {
            printf("*");
        }
        printf("\n");
    }
    return 0;
}
Explicação: "Calcular o índice a partir do valor e somar 1 nesse elemento" é a forma básica de uma distribuição de frequência (histograma). Se você esquecer o caso da nota 100, vai escrever em cnt[10], fora dos limites. Inicialize o array de contagem com = {0} para zerar todos os elementos (arrays dentro de funções, se não forem inicializados, têm conteúdo indeterminado).
A08 Intermediário

Exercício 8. O segundo maior valor

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 100) e na 2ª linha N inteiros, e mostre o segundo maior valor entre os valores distintos. Por exemplo, para 3 9 7 9 1, o maior é 9 e o segundo é 7. Se esse valor não existir (todos iguais, ou N igual a 1), mostre "Não há segundo maior valor".
Exemplo de execução (a entrada está sublinhada)
5 3 9 7 9 1 Segundo maior valor: 7
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
Fica mais fácil em duas passadas. Na 1ª, encontre o maior valor max; na 2ª, encontre "o maior entre os valores menores que max". Na 2ª passada, use uma variável (flag) que indique "ainda não encontrei nenhum".
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int max = a[0];
    for (int i = 1; i < n; i++) {
        if (a[i] > max) max = a[i];
    }

    int found = 0, second = 0;
    for (int i = 0; i < n; i++) {
        if (a[i] < max && (!found || a[i] > second)) {
            second = a[i];
            found = 1;
        }
    }

    if (found) {
        printf("Segundo maior valor: %d\n", second);
    } else {
        printf("Não há segundo maior valor\n");
    }
    return 0;
}
Explicação: Ordenando e pegando o penúltimo, para 3 9 7 9 1 a resposta seria 9 (o caso em que o maior valor se repete). Se o valor inicial de second for fixo, como 0, o resultado falha quando todos os números são negativos. Por isso usamos found para "aceitar diretamente o primeiro valor encontrado".
A09 Intermediário

Exercício 9. Soma das linhas e das colunas (array 2D)

Leia na 1ª linha o número de linhas R e de colunas C (1 ≤ R, C ≤ 10) e, nas R linhas seguintes, C inteiros por linha. Mostre a soma de cada linha em uma linha e a soma de cada coluna na linha seguinte, separadas por espaço.
Exemplo de execução (a entrada está sublinhada)
2 3 1 2 3 4 5 6 Soma das linhas: 6 15 Soma das colunas: 5 7 9
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 4 entradas preparadas.
a[i][j] é "linha i, coluna j". Para a soma das linhas, coloque i no laço externo e percorra j; para a soma das colunas, coloque j no laço externo e percorra i. A variável da soma volta a 0 toda vez que se entra no laço externo.
#include <stdio.h>

int main(void) {
    int r, c;
    int a[10][10];
    scanf("%d %d", &r, &c);
    for (int i = 0; i < r; i++) {
        for (int j = 0; j < c; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    printf("Soma das linhas:");
    for (int i = 0; i < r; i++) {
        int sum = 0;
        for (int j = 0; j < c; j++) {
            sum += a[i][j];
        }
        printf(" %d", sum);
    }
    printf("\n");

    printf("Soma das colunas:");
    for (int j = 0; j < c; j++) {
        int sum = 0;
        for (int i = 0; i < r; i++) {
            sum += a[i][j];
        }
        printf(" %d", sum);
    }
    printf("\n");
    return 0;
}
Explicação: Se sum = 0 ficar fora do laço aninhado, a soma da linha anterior é carregada adiante e vira um total acumulado. Inverter os índices na soma das colunas, como a[j][i], também é um erro comum: quando R e C são diferentes, o programa lê fora dos limites.
A10 Avançado

Exercício 10. Bubble sort e número de trocas

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 100) e na 2ª linha N inteiros, ordene-os em ordem crescente com o bubble sort e mostre-os separados por espaço. Na linha seguinte, mostre quantas vezes dois vizinhos foram trocados. A troca só é feita "quando o da esquerda é maior" (quando são iguais, não há troca).
Exemplo de execução (a entrada está sublinhada)
5 5 3 1 4 2 1 2 3 4 5 Trocas: 7
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
O laço externo roda N−1 vezes; no interno, j vai de 0 até n - 2 - i e, se a[j] > a[j + 1], os dois são trocados. Para trocar, use uma variável auxiliar tmp.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    int swaps = 0;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - 1 - i; j++) {
            if (a[j] > a[j + 1]) {
                int tmp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = tmp;
                swaps++;
            }
        }
    }

    for (int i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\nTrocas: %d\n", swaps);
    return 0;
}
Explicação: Se você escrever a troca como a[j] = a[j + 1]; a[j + 1] = a[j];, a 1ª linha apaga o a[j] original e os dois ficam com o mesmo valor. Sempre guarde o valor em tmp. A cada volta do laço externo, o maior valor fica fixo na ponta direita, então o alcance do laço interno pode diminuir até n - 1 - i. Aliás, o número de trocas é igual ao número de pares "à esquerda e maior que ele" (o número de inversões).
A11 Avançado

Exercício 11. Passo a passo do selection sort

Leia na 1ª linha um inteiro N (2 ≤ N ≤ 20) e na 2ª linha N inteiros, e ordene-os em ordem crescente com o selection sort. Na k-ésima passada (k = 1, 2, …, N−1), procure o menor valor a partir do k-ésimo elemento (se houver vários menores, o mais à esquerda) e troque-o com o k-ésimo elemento. Depois de cada passada, mostre o array naquele momento após "Passo k:", separado por espaço.
Exemplo de execução (a entrada está sublinhada)
5 5 3 1 4 2 Passo 1: 1 3 5 4 2 Passo 2: 1 2 5 4 3 Passo 3: 1 2 3 4 5 Passo 4: 1 2 3 4 5
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 4 entradas preparadas.
Pensando em índices, a passada k decide o valor da posição i = k - 1. Comece com imin = i, examine j = i + 1 até n - 1 e, se a[j] < a[imin], faça imin = j. No final, troque a[i] com a[imin] e mostre o array.
#include <stdio.h>

int main(void) {
    int n;
    int a[100];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }

    for (int i = 0; i < n - 1; i++) {
        int imin = i;
        for (int j = i + 1; j < n; j++) {
            if (a[j] < a[imin]) imin = j;
        }
        int tmp = a[i];
        a[i] = a[imin];
        a[imin] = tmp;

        printf("Passo %d:", i + 1);
        for (int j = 0; j < n; j++) {
            printf(" %d", a[j]);
        }
        printf("\n");
    }
    return 0;
}
Explicação: O selection sort repete "procurar o menor entre os restantes e trazê-lo para a frente". O ponto-chave é guardar o menor pelo índice (imin), não pelo valor: guardando só o valor, você não sabe a posição com que deve trocar. Se a comparação for <=, quando houver vários menores é escolhido o mais à direita, e para a entrada 3 1 3 1 o passo a passo muda.
A12 Avançado

Exercício 12. Produto de matrizes

Leia na 1ª linha os inteiros n, m e p (1 ≤ n, m, p ≤ 10). Em seguida, leia a matriz A de n linhas e m colunas em n linhas e a matriz B de m linhas e p colunas em m linhas (os elementos são inteiros entre −100 e 100). Mostre o produto C = AB (n linhas e p colunas), uma linha da matriz por linha, com os elementos separados por espaço. O elemento (i, j) de C é a soma dos produtos dos elementos correspondentes da linha i de A e da coluna j de B.
Exemplo de execução (a entrada está sublinhada)
2 3 2 1 2 3 4 5 6 7 8 9 10 11 12 58 64 139 154
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 5 entradas preparadas.
São três laços aninhados. Percorra i (linha de C) e j (coluna de C) e, dentro deles, faça k ir de 0 a m−1 acumulando c[i][j] += a[i][k] * b[k][j];.
#include <stdio.h>

int main(void) {
    int n, m, p;
    int a[10][10], b[10][10], c[10][10];
    scanf("%d %d %d", &n, &m, &p);
    for (int i = 0; i < n; i++) {
        for (int k = 0; k < m; k++) {
            scanf("%d", &a[i][k]);
        }
    }
    for (int k = 0; k < m; k++) {
        for (int j = 0; j < p; j++) {
            scanf("%d", &b[k][j]);
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < p; j++) {
            c[i][j] = 0;
            for (int k = 0; k < m; k++) {
                c[i][j] += a[i][k] * b[k][j];
            }
        }
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < p; j++) {
            printf("%d ", c[i][j]);
        }
        printf("\n");
    }
    return 0;
}
Explicação: Usar += em c[i][j] sem inicializá-lo com 0 faz a soma começar de um valor indeterminado. Os limites dos laços são n para i, p para j e m para k. Se você trocar algum deles, o teste com matrizes quadradas pode passar, mas quando n, m e p forem diferentes o programa lê fora dos limites.
A13 Avançado

Exercício 13. Busca binária

Leia na 1ª linha um inteiro N (1 ≤ N ≤ 1000) e na 2ª linha N inteiros em ordem crescente e sem repetição. Na 3ª linha leia o número de consultas Q (1 ≤ Q ≤ 100) e, nas Q linhas seguintes, um valor a buscar por linha. Para cada valor, mostre em uma linha a sua posição no array (o primeiro elemento é a posição 1), ou "Não encontrado" se ele não estiver no array. Use busca binária.
Exemplo de execução (a entrada está sublinhada)
7 2 3 5 7 11 13 17 4 7 2 17 4 4 1 7 Não encontrado
Seu código
"Executar" roda seu código com a entrada acima. "Corrigir" testa com 4 entradas preparadas.
Represente o intervalo de busca pelos índices lo a hi (no início, 0 a N−1) e, enquanto lo <= hi, compare com o elemento do meio, mid, e corte o intervalo pela metade. Se a[mid] for menor, lo = mid + 1; se for maior, hi = mid - 1.
#include <stdio.h>

int main(void) {
    int n, q;
    int a[1000];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    scanf("%d", &q);

    for (int t = 0; t < q; t++) {
        int x;
        scanf("%d", &x);

        int lo = 0, hi = n - 1, pos = -1;
        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;
            if (a[mid] == x) {
                pos = mid;
                break;
            } else if (a[mid] < x) {
                lo = mid + 1;
            } else {
                hi = mid - 1;
            }
        }

        if (pos >= 0) {
            printf("%d\n", pos + 1);
        } else {
            printf("Não encontrado\n");
        }
    }
    return 0;
}
Explicação: Na busca binária, o intervalo cai pela metade a cada comparação, então mesmo com N=1000 bastam cerca de 10 comparações no máximo (procurando do início em sequência, seriam até 1000). Se você esquecer o ±1, como em lo = mid, o intervalo pode não diminuir e o laço vira infinito. Com a condição lo < hi, o laço termina sem examinar o último elemento restante. A busca pressupõe que o array esteja ordenado; se não estiver, é preciso ordenar antes.

Revise estas aulas

← Voltar para todos os exercícios