Problemas Práticos de Programação em C

39 problemas práticos em nível universitário com filtros de dificuldade, dicas e soluções completas. Ótimo para autoestudo e preparação para prova.

Problemas de Condicionais

EX-01 Iniciante
Atribuição de Turma
Escreva um programa que leia um número de matrícula de estudante (inteiro positivo) e atribua o aluno a uma turma:
- Número 1–20 → Turma A
- Número 21 ou maior e par → Turma A
- Número 21 ou maior e ímpar → Turma B
Digite a matrícula: 25 Aluno 25 está na Turma B
Use um comando if para verificar o intervalo primeiro. Para números 21 ou maiores, use o operador % para testar par/ímpar.
Par: n % 2 == 0. Ímpar: n % 2 != 0.
#include <stdio.h>

int main(void) {
    int num;
    printf("Enter student ID: ");
    scanf("%d", &num);

    if (num >= 1 && num <= 20) {
        printf("Student %d is in Class A\n", num);
    } else if (num % 2 == 0) {
        printf("Student %d is in Class A\n", num);
    } else {
        printf("Student %d is in Class B\n", num);
    }
    return 0;
}
EX-02 Iniciante
Máximo de Três Inteiros
Leia três inteiros distintos do teclado, exiba-os na ordem em que foram digitados e depois imprima o maior deles.
Use uma cadeia if / else if / else junto com operadores lógicos.
a = 12 b = 45 c = 7 Entradas: a=12, b=45, c=7 Máximo é 45
Combine comparações com o operador E — por exemplo, a >= b && a >= c — para decidir qual valor é o maior.
#include <stdio.h>

int main(void) {
    int a, b, c;
    printf("a = "); scanf("%d", &a);
    printf("b = "); scanf("%d", &b);
    printf("c = "); scanf("%d", &c);
    printf("Inputs: a=%d, b=%d, c=%d\n", a, b, c);

    if (a >= b && a >= c) {
        printf("Maximum is %d\n", a);
    } else if (b >= a && b >= c) {
        printf("Maximum is %d\n", b);
    } else {
        printf("Maximum is %d\n", c);
    }
    return 0;
}
EX-03 Iniciante
Verificação Par/Ímpar e Quociente/Resto
Leia dois inteiros nas variáveis a e b, imprima se cada um é par ou ímpar, depois exiba o quociente e o resto de a dividido por b.
a = 17 b = 5 a é ímpar b é ímpar 17 / 5 = quociente 3, resto 2
Quociente: a / b (divisão inteira). Resto: a % b. Verifique par/ímpar com n % 2.
#include <stdio.h>

int main(void) {
    int a, b;
    printf("a = "); scanf("%d", &a);
    printf("b = "); scanf("%d", &b);
    printf("a is %s\n", a % 2 == 0 ? "even" : "odd");
    printf("b is %s\n", b % 2 == 0 ? "even" : "odd");
    printf("%d / %d = quotient %d, remainder %d\n", a, b, a / b, a % b);
    return 0;
}

Problemas de Laços e Vetores

EX-04 Iniciante
Tabuada
Imprima a tabuada de 1–9, linha 1 a linha 9, usando um laço for aninhado. Use um único for para o laço externo.
1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 ... 9 18 27 36 45 54 63 72 81
Laço externo: for(i=1; i<=9; i++). Laço interno: for(j=1; j<=9; j++). Use %2d ou %3d para manter as colunas alinhadas.
#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= 9; j++) {
            printf("%3d", i * j);
        }
        printf("\n");
    }
    return 0;
}
EX-05 Iniciante
Ache o Mínimo em um Vetor
Encontre o valor mínimo e seu índice no vetor int de 5 elementos {88, 72, 95, 55, 63} e imprima ambos.
mínimo é d[3]: 55
Mantenha uma variável como min_idx para acompanhar o índice do menor valor até agora e atualize-a nas comparações dentro do laço. Inicialize em 0.
#include <stdio.h>

int main(void) {
    int d[] = {88, 72, 95, 55, 63};
    int n = 5, min_idx = 0;

    for (int i = 1; i < n; i++) {
        if (d[i] < d[min_idx]) min_idx = i;
    }
    printf("minimum is d[%d]: %d\n", min_idx, d[min_idx]);
    return 0;
}
EX-06 Intermediário
Inverter uma String
Leia uma string (sem espaços) do teclado e imprima-a ao contrário.
Dica: toda string termina com '\0'.
Digite uma string: abcdef String invertida é fedcba
Chame strlen(str) para obter o tamanho, depois imprima um caractere por vez do último índice (len-1) até 0.
#include <stdio.h>
#include <string.h>

int main(void) {
    char str[128];
    printf("Enter a string: ");
    scanf("%s", str);

    int len = strlen(str);
    printf("Reversed string is ");
    for (int i = len - 1; i >= 0; i--) {
        printf("%c", str[i]);
    }
    printf("\n");
    return 0;
}
EX-07 Intermediário
Desenho de Retângulo
Leia uma largura e uma altura e desenhe uma borda retangular feita de *, colocando + nas posições das diagonais. O interior deve ser espaço em branco.
Largura: 7 Altura: 5 ******* *+ +* * + + * * + * *******
Use um laço aninhado para decidir o que imprimir em cada célula. Borda: i==0 || i==h-1 || j==0 || j==w-1. Diagonal: i==j || i+j==w-1.
#include <stdio.h>

int main(void) {
    int w, h;
    printf("Width: "); scanf("%d", &w);
    printf("Height: "); scanf("%d", &h);

    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (i == 0 || i == h-1 || j == 0 || j == w-1)
                printf("*");
            else if (i == j || i + j == w - 1)
                printf("+");
            else
                printf(" ");
        }
        printf("\n");
    }
    return 0;
}

Problemas de Funções

EX-08 Iniciante
Função de Carinha Sorridente
Crie uma função disp_face que imprime (^_^) cada vez que é chamada. Chame-a três vezes a partir de main para a saída ser (^_^)(^_^)(^_^).
(^_^)(^_^)(^_^)
Defina uma função que não recebe argumentos e não retorna nada: void disp_face(void). Dentro, só chame printf("(^_^)").
#include <stdio.h>

void disp_face(void) {
    printf("(^_^)");
}

int main(void) {
    disp_face();
    disp_face();
    disp_face();
    printf("\n");
    return 0;
}
EX-09 Intermediário
Função Área do Retângulo (com Protótipo)
Defina uma função area_rectangle que calcula a área de um retângulo, declarada com um protótipo de função.
- main lê a altura e a largura do teclado.
- A função apenas faz o cálculo e retorna o resultado.
- main imprime a área.
Altura: 5 Largura: 8 Área é 40
Protótipo: coloque int area_rectangle(int h, int w); antes de main. Coloque o corpo da função depois de main.
#include <stdio.h>

int area_rectangle(int h, int w); // Protótipo

int main(void) {
    int h, w;
    printf("Height: "); scanf("%d", &h);
    printf("Width: "); scanf("%d", &w);
    printf("Area is %d\n", area_rectangle(h, w));
    return 0;
}

int area_rectangle(int h, int w) {
    return h * w;
}
EX-10 Intermediário
Função Mínimo Múltiplo Comum
Leia dois inteiros e escreva uma função lcm que retorna o mínimo múltiplo comum (MMC).
Calcule o MDC com o algoritmo de Euclides, depois use MMC = a * b / MDC.
a = 12 b = 18 MMC é 36
Algoritmo de Euclides: while(b != 0) { tmp = b; b = a % b; a = tmp; }. O valor final de a é o MDC.
MMC = (a original) * (b original) / MDC.
#include <stdio.h>

int gcd(int a, int b) {
    while (b != 0) {
        int tmp = b;
        b = a % b;
        a = tmp;
    }
    return a;
}

int lcm(int a, int b) {
    return a / gcd(a, b) * b;
}

int main(void) {
    int a, b;
    printf("a = "); scanf("%d", &a);
    printf("b = "); scanf("%d", &b);
    printf("LCM is %d\n", lcm(a, b));
    return 0;
}
EX-11 Intermediário
Usando Macros
Escreva um programa que atenda a estes requisitos:
- Defina uma macro VALUE definida como 50.
- Defina uma macro com parâmetros SUM(a,b) que soma dois valores.
- main contém apenas printf e return, e produz a saída 50+50=100.
50+50=100
Use #define VALUE 50 e #define SUM(a,b) ((a)+(b)). Envolver os argumentos da macro com parênteses é o estilo mais seguro.
#include <stdio.h>
#define VALUE 50
#define SUM(a, b) ((a) + (b))

int main(void) {
    printf("%d+%d=%d\n", VALUE, VALUE, SUM(VALUE, VALUE));
    return 0;
}

Problemas Abrangentes

EX-12 Avançado
Função de Ordenação Crescente
Leia 5 inteiros do teclado e imprima-os ordenados em ordem crescente.
Coloque a ordenação em uma função void ascend(int arr[], int n), usando bubble sort.
Entrada 1: 10 Entrada 2: 32 Entrada 3: 8 Entrada 4: 42 Entrada 5: 13 Crescente: 8, 10, 13, 32, 42
Bubble sort: compare cada par adjacente de trás para frente e troque se estiverem fora de ordem. Repita n-1 vezes.
Troca: tmp = a[j-1]; a[j-1] = a[j]; a[j] = tmp;
#include <stdio.h>

void ascend(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = n - 1; j > i; j--) {
            if (arr[j - 1] > arr[j]) {
                int tmp = arr[j - 1];
                arr[j - 1] = arr[j];
                arr[j] = tmp;
            }
        }
    }
    printf("Ascending: ");
    for (int i = 0; i < n; i++) {
        printf("%d", arr[i]);
        if (i < n - 1) printf(", ");
    }
    printf("\n");
}

int main(void) {
    int data[5];
    for (int i = 0; i < 5; i++) {
        printf("Input %d: ", i + 1);
        scanf("%d", &data[i]);
    }
    ascend(data, 5);
    return 0;
}
EX-13 Avançado
Calculadora com Variáveis Globais
Escreva um programa que atenda a estes requisitos:
- Declare variáveis globais val (inicializada em 0) e n.
- input(): lê um inteiro do teclado em n.
- addition(): soma n a val.
- product(): multiplica val por n.
- display(): imprime o valor atual de val.
- Em main, execute um menu em laço while: 1 = Somar, 2 = Multiplicar, -1 = Sair.
1: Somar 2: Multiplicar -1: Sair> 1 Digite um valor> 10 val agora é 10 1: Somar 2: Multiplicar -1: Sair> 2 Digite um valor> 3 val agora é 30 1: Somar 2: Multiplicar -1: Sair> -1
Laço com while(sw != -1) e desvio com switch(sw). Em cada case, leia a entrada → calcule a soma/produto → imprima o resultado.
#include <stdio.h>

int val = 0;
int n;

void input(void)    { printf("Enter a value> "); scanf("%d", &n); }
void display(void)  { printf("val is now %d\n", val); }
void addition(void) { val += n; }
void product(void)  { val *= n; }

int main(void) {
    int sw = 0;
    while (sw != -1) {
        printf("1: Add 2: Multiply -1: Exit> ");
        scanf("%d", &sw);
        switch (sw) {
        case 1: input(); addition(); display(); break;
        case 2: input(); product();  display(); break;
        }
    }
    return 0;
}
EX-14 Avançado
Função de Desenho de Gráfico
Armazene a quantidade de vendas de cada produto em um vetor e desenhe um gráfico de barras a partir de uma função draw_graph.
- Defina o intervalo dos marcadores em uma variável global (ex.: 5).
- Imprima * para cada unidade de venda e = nas posições dos marcadores.
- Declare a função com um protótipo.
Item 1 (12): ****=****=** Item 2 ( 8): ****=*** Item 3 (20): ****=****=****=****=
Imprima um caractere por iteração. Se j % interval == 0 && j != 0, imprima =; caso contrário, imprima *.
#include <stdio.h>

void draw_graph(int id, int sales);
int interval = 5; // Global: intervalo do marcador

int main(void) {
    int data[] = {12, 8, 20};
    int n = 3;
    for (int i = 0; i < n; i++)
        draw_graph(i + 1, data[i]);
    return 0;
}

void draw_graph(int id, int sales) {
    printf("Item %d (%2d): ", id, sales);
    for (int j = 1; j <= sales; j++) {
        if (j % interval == 0)
            printf("=");
        else
            printf("*");
    }
    printf("\n");
}

Problemas de printf / scanf / Formatação

EX-15 Iniciante
Exibição Formatada de Pesos
Leia dois pesos (como números reais) e imprima-os alinhados com uma casa decimal, junto com a soma e a diferença absoluta.
Peso 1: 3.5 Peso 2: 7.25 Peso 1 = 3.5 kg Peso 2 = 7.3 kg Soma = 10.8 kg Dif = 3.8 kg
printf("%5.1f", val) imprime o valor alinhado à direita em um campo de 5 caracteres com uma casa decimal.
#include <stdio.h>

int main(void) {
    double w1, w2;
    printf("Weight 1: "); scanf("%lf", &w1);
    printf("Weight 2: "); scanf("%lf", &w2);
    printf("Weight 1 = %5.1f kg\n", w1);
    printf("Weight 2 = %5.1f kg\n", w2);
    printf("Sum      = %5.1f kg\n", w1 + w2);
    printf("Diff     = %5.1f kg\n", w1 > w2 ? w1 - w2 : w2 - w1);
    return 0;
}
EX-16 Intermediário
Expressão com Três Variáveis
Leia os números reais x, y e z do teclado, calcule f(x,y,z) = x*x + 2*x*y + y*y*z e imprima o resultado.
x: 1.2 y: 2.2 z: 1.5 f(x,y,z) = 13.920000
Declare as variáveis como double e leia-as com scanf("%lf", &x). Você pode escrever a fórmula direto no código.
#include <stdio.h>

int main(void) {
    double x, y, z;
    printf("x: "); scanf("%lf", &x);
    printf("y: "); scanf("%lf", &y);
    printf("z: "); scanf("%lf", &z);
    double result = x*x + 2*x*y + y*y*z;
    printf("f(x,y,z) = %f\n", result);
    return 0;
}

Problemas de Ponteiros

EX-17 Intermediário
Trocar Valores com Ponteiros
Leia dois inteiros e troque-os usando uma função swap que recebe ponteiros, depois imprima o resultado.
a = 10 b = 20 Antes do swap: a=10, b=20 Depois do swap: a=20, b=10
Use int *pa, int *pb nos parâmetros e uma variável temporária tmp para trocar *pa e *pb. Chame como swap(&a, &b).
#include <stdio.h>

void swap(int *pa, int *pb) {
    int tmp = *pa;
    *pa = *pb;
    *pb = tmp;
}

int main(void) {
    int a, b;
    printf("a = "); scanf("%d", &a);
    printf("b = "); scanf("%d", &b);
    printf("Before swap: a=%d, b=%d\n", a, b);
    swap(&a, &b);
    printf("After swap:  a=%d, b=%d\n", a, b);
    return 0;
}
EX-18 Intermediário
Soma e Média via Ponteiros
Armazene 5 inteiros em um vetor e escreva uma função que calcule a soma e a média através de ponteiros.
Use a assinatura void calc(int *arr, int n, int *sum, double *avg).
data = {10, 20, 30, 40, 50} Soma: 150 Média: 30.0
Retorne a soma e a média através dos parâmetros ponteiro. Inicialize com *sum = 0;, acumule com *sum += arr[i];, depois calcule *avg = (double)*sum / n;.
#include <stdio.h>

void calc(int *arr, int n, int *sum, double *avg) {
    *sum = 0;
    for (int i = 0; i < n; i++) *sum += arr[i];
    *avg = (double)*sum / n;
}

int main(void) {
    int data[] = {10, 20, 30, 40, 50};
    int sum; double avg;
    calc(data, 5, &sum, &avg);
    printf("Sum: %d\n", sum);
    printf("Average: %.1f\n", avg);
    return 0;
}
EX-19 Avançado
Converter String para Maiúsculas via Ponteiro
Escreva uma função to_upper(char *s) que percorra a string por um ponteiro e converta cada letra minúscula em maiúscula.
Entrada: Hello World Convertido: HELLO WORLD
Se 'a' <= *s && *s <= 'z', subtraia 32: *s -= 32; (a diferença ASCII entre minúsculas e maiúsculas é 32). Faça um laço com while(*s) até o terminador nulo.
Use fgets para entrada que contenha espaços.
#include <stdio.h>
#include <string.h>

void to_upper(char *s) {
    while (*s) {
        if (*s >= 'a' && *s <= 'z') *s -= 32;
        s++;
    }
}

int main(void) {
    char str[128];
    printf("Input: ");
    fgets(str, 128, stdin);
    str[strcspn(str, "\n")] = '\0';
    to_upper(str);
    printf("Converted: %s\n", str);
    return 0;
}

Problemas de Estruturas

EX-20 Intermediário
Gerenciamento de Notas de Alunos
Defina uma struct Student com um nome (até 20 caracteres) e uma nota. Leia os dados de 3 alunos e imprima o aluno com a maior nota.
Aluno 1 Nome: Taro Nota: 80 Aluno 2 Nome: Hanako Nota: 95 Aluno 3 Nome: Jiro Nota: 70 Maior: Hanako (95 pontos)
Defina struct Student { char name[20]; int score; }; e declare um vetor de 3 alunos. Encontre o índice com a maior nota em um laço.
#include <stdio.h>

struct Student { char name[20]; int score; };

int main(void) {
    struct Student s[3];
    for (int i = 0; i < 3; i++) {
        printf("Student %d Name: ", i+1); scanf("%s", s[i].name);
        printf("           Score: "); scanf("%d", &s[i].score);
    }
    int max = 0;
    for (int i = 1; i < 3; i++)
        if (s[i].score > s[max].score) max = i;
    printf("Highest: %s (%d points)\n", s[max].name, s[max].score);
    return 0;
}
EX-21 Avançado
Distância Entre Pontos
Defina uma struct Point com coordenadas 2D (x, y). Leia dois pontos e escreva uma função double distance(Point p1, Point p2) que retorne a distância entre eles.
Ponto 1 x: 0.0 y: 0.0 Ponto 2 x: 3.0 y: 4.0 Distância: 5.000
Distância = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)). Use sqrt de math.h. Em alguns sistemas, vai precisar linkar com -lm.
#include <stdio.h>
#include <math.h>

struct Point { double x, y; };

double distance(struct Point p1, struct Point p2) {
    double dx = p2.x - p1.x, dy = p2.y - p1.y;
    return sqrt(dx*dx + dy*dy);
}

int main(void) {
    struct Point p1, p2;
    printf("Point 1 x: "); scanf("%lf", &p1.x);
    printf("        y: "); scanf("%lf", &p1.y);
    printf("Point 2 x: "); scanf("%lf", &p2.x);
    printf("        y: "); scanf("%lf", &p2.y);
    printf("Distance: %.3f\n", distance(p1, p2));
    return 0;
}

Problemas de Memória Dinâmica e I/O de Arquivos

EX-22 Avançado
Vetor Dinâmico para Quantidade Arbitrária de Inteiros
Leia a quantidade de elementos n primeiro, aloque um vetor de n elementos com malloc, leia n inteiros e depois imprima a soma e a média. Sempre chame free no final.
Número de elementos: 4 data[0] = 10 data[1] = 20 data[2] = 30 data[3] = 40 Soma: 100, Média: 25.0
Aloque com int *data = (int *)malloc(sizeof(int) * n);. Não esqueça da verificação de NULL. Chame free(data); quando terminar.
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n;
    printf("Number of elements: "); scanf("%d", &n);
    int *data = (int *)malloc(sizeof(int) * n);
    if (data == NULL) { printf("Memory allocation failed\n"); return 1; }

    int sum = 0;
    for (int i = 0; i < n; i++) {
        printf("data[%d] = ", i); scanf("%d", &data[i]);
        sum += data[i];
    }
    printf("Sum: %d, Average: %.1f\n", sum, (double)sum / n);
    free(data);
    return 0;
}
EX-23 Avançado
Gravar Notas em Arquivo
Leia nomes e notas de 3 pessoas e grave-os em um arquivo texto, scores.txt. Depois de gravar, leia o arquivo de volta e imprima o conteúdo.
Nome 1: Taro Nota: 80 Nome 2: Hanako Nota: 95 Nome 3: Jiro Nota: 70 --- conteúdo de scores.txt --- Taro 80 Hanako 95 Jiro 70
Gravação: fopen("scores.txt", "w")fprintffclose.
Leitura: fopen("scores.txt", "r") → laço fscanf até EOF → fclose.
#include <stdio.h>

int main(void) {
    char names[3][20]; int scores[3];
    for (int i = 0; i < 3; i++) {
        printf("Name %d: ", i+1); scanf("%s", names[i]);
        printf("  Score: "); scanf("%d", &scores[i]);
    }
    // Write
    FILE *fp = fopen("scores.txt", "w");
    for (int i = 0; i < 3; i++)
        fprintf(fp, "%s %d\n", names[i], scores[i]);
    fclose(fp);
    // Read
    printf("--- contents of scores.txt ---\n");
    fp = fopen("scores.txt", "r");
    char n[20]; int s;
    while (fscanf(fp, "%s %d", n, &s) != EOF)
        printf("%s %d\n", n, s);
    fclose(fp);
    return 0;
}

Problemas de Desenho de Padrões e Algoritmos

EX-24 Intermediário
Padrão em Triângulo
Leia uma altura n e desenhe um triângulo retângulo feito de *.
Altura: 5 * ** *** **** *****
Laço externo para a linha (i=1..n), laço interno imprime i asteriscos e depois quebra linha.
#include <stdio.h>

int main(void) {
    int n;
    printf("Height: "); scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < i; j++) printf("*");
        printf("\n");
    }
    return 0;
}
EX-25 Intermediário
Desenho de Grade (Globais e Funções)
Leia largura, altura, intervalo horizontal e intervalo vertical, e escreva uma função de grade que imprime a borda com #, as posições dos marcadores com + e o resto com -.
Armazene os intervalos em variáveis globais e declare a função com um protótipo.
Largura: 10 Altura: 7 H-Intervalo: 3 V-Intervalo: 2 ########## #--+--+--# #--------# #--+--+--# #--------# #--+--+--# ##########
Borda: i==0 || i==h-1 || j==0 || j==w-1#.
Marcadores: i%v_interval==0 && j%h_interval==0+.
Resto: -.
#include <stdio.h>

void grid(int w, int h);
int v_interval, h_interval;

int main(void) {
    int w, h;
    printf("Width: "); scanf("%d", &w);
    printf("Height: "); scanf("%d", &h);
    printf("H-Interval: "); scanf("%d", &h_interval);
    printf("V-Interval: "); scanf("%d", &v_interval);
    grid(w, h);
    return 0;
}

void grid(int w, int h) {
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            if (i==0||i==h-1||j==0||j==w-1) printf("#");
            else if (i%v_interval==0 && j%h_interval==0) printf("+");
            else printf("-");
        }
        printf("\n");
    }
}
EX-26 Avançado
Teste de Primos
Leia um inteiro n e imprima todos os números primos de 2 até n. Coloque o teste de primalidade em uma função int is_prime(int n).
n = 30 2 3 5 7 11 13 17 19 23 29 Quantidade de primos: 10
Teste de primo: verifique a divisibilidade de 2 até sqrt(n). Se algum divide exato, não é primo. Usar sqrt de math.h é eficiente.
#include <stdio.h>
#include <math.h>

int is_prime(int n) {
    if (n < 2) return 0;
    for (int i = 2; i <= (int)sqrt(n); i++)
        if (n % i == 0) return 0;
    return 1;
}

int main(void) {
    int n, count = 0;
    printf("n = "); scanf("%d", &n);
    for (int i = 2; i <= n; i++) {
        if (is_prime(i)) { printf("%d ", i); count++; }
    }
    printf("\nNumber of primes: %d\n", count);
    return 0;
}
EX-27 Avançado
Funções add e max
Escreva um programa com as duas funções a seguir:
- add(int a, int b): exibe a soma de dois inteiros
- max(double a, double b, double c): exibe o máximo de três números reais
Em main, inicialize variáveis int (12, 25) e variáveis double (23.5, 69.2, 10.3) e chame cada função.
12 + 25 = 37 max(23.5, 69.2, 10.3) = 69.2
A função add pode ser void e chamar printf internamente, ou retornar int e deixar main chamar printf. A função max compara três valores.
#include <stdio.h>

void add(int a, int b) {
    printf("%d + %d = %d\n", a, b, a + b);
}

void max3(double a, double b, double c) {
    double m = a;
    if (b > m) m = b;
    if (c > m) m = c;
    printf("max(%.1f, %.1f, %.1f) = %.1f\n", a, b, c, m);
}

int main(void) {
    int x = 12, y = 25;
    double a = 23.5, b = 69.2, c = 10.3;
    add(x, y);
    max3(a, b, c);
    return 0;
}
EX-28 Avançado
Ordenação Decrescente (Selection Sort)
Leia 5 inteiros do teclado e exiba-os ordenados em ordem decrescente.
O EX-12 usou bubble sort; desta vez implemente usando selection sort.
Entrada 1: 5 Entrada 2: 23 Entrada 3: 11 Entrada 4: 2 Entrada 5: 17 Decrescente: 23, 17, 11, 5, 2
Selection sort: encontre o máximo na região não ordenada e troque-o com o início. Como a ordenação é decrescente, procure o "máximo".
#include <stdio.h>

void descend(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int max_idx = i;
        for (int j = i + 1; j < n; j++)
            if (arr[j] > arr[max_idx]) max_idx = j;
        int tmp = arr[i]; arr[i] = arr[max_idx]; arr[max_idx] = tmp;
    }
}

int main(void) {
    int data[5];
    for (int i = 0; i < 5; i++) {
        printf("Input %d: ", i+1); scanf("%d", &data[i]);
    }
    descend(data, 5);
    printf("Descending: ");
    for (int i = 0; i < 5; i++) {
        printf("%d", data[i]);
        if (i < 4) printf(", ");
    }
    printf("\n");
    return 0;
}
EX-29 Avançado
Potência via Recursão
Leia uma base e um expoente, e calcule a potência usando uma função recursiva int power(int base, int exp). Não use laços.
Base: 2 Expoente: 10 2^10 = 1024
Caso base: exp == 0 -> retorna 1. Caso recursivo: base * power(base, exp - 1).
#include <stdio.h>

int power(int base, int exp) {
    if (exp == 0) return 1;
    return base * power(base, exp - 1);
}

int main(void) {
    int b, e;
    printf("Base: "); scanf("%d", &b);
    printf("Exponent: "); scanf("%d", &e);
    printf("%d^%d = %d\n", b, e, power(b, e));
    return 0;
}
EX-30 Avançado
Busca Binária
Dado um vetor ordenado em ordem crescente, use busca binária para encontrar um valor de entrada e exibir seu índice. Se não encontrado, exiba "Não encontrado".
data = {2, 5, 8, 12, 16, 23, 38, 56, 72, 91} Valor a buscar: 23 Encontrado em data[5]
Defina low=0, high=n-1. Calcule mid = (low + high) / 2. Se arr[mid] == target, encontrado. Se arr[mid] < target, defina low = mid + 1; senão high = mid - 1.
#include <stdio.h>

int binary_search(int arr[], int n, int target) {
    int low = 0, high = n - 1;
    while (low <= high) {
        int mid = (low + high) / 2;
        if (arr[mid] == target) return mid;
        else if (arr[mid] < target) low = mid + 1;
        else high = mid - 1;
    }
    return -1;
}

int main(void) {
    int data[] = {2,5,8,12,16,23,38,56,72,91};
    int n = 10, target;
    printf("Value to search: "); scanf("%d", &target);
    int idx = binary_search(data, n, target);
    if (idx >= 0) printf("Found at data[%d]\n", idx);
    else printf("Not found\n");
    return 0;
}

Problemas de Preencher (Preparação para Prova Final)

Nos problemas a seguir, preencha as partes 【???】 no código. Essas questões foram feitas para se parecer com questões reais de prova.
EX-31 Iniciante
Verificação de Vogal (Preencher)
Preencha as lacunas de um programa que lê um caractere e imprime "é uma vogal" se for vogal (a, e, i, o, u) ou "é uma consoante" caso contrário.
Digite um caractere> e 'e' é uma vogal Digite um caractere> k 'k' é uma consoante
#include <stdio.h>

int main(void) {
    char c;
    printf("Enter a character> ");
    scanf("%c", 【???】);

    if (c=='a' || c=='e' || c=='i' || 【???】 || c=='u') {
        printf("'%c' is a vowel\n", c);
    } else {
        printf("'%c' is a 【???】\n", c);
    }
    return 0;
}
Lacuna 1: como você passa um endereço para scanf? Lacuna 2: quais são as vogais restantes? Lacuna 3: qual é o oposto de uma vogal?
Resposta:
Lacuna 1: &c (passe o endereço do char)
Lacuna 2: c=='o' (vogal restante 'o')
Lacuna 3: consonant
EX-32 Intermediário
Calculadora das Quatro Operações (Preencher)
Preencha as lacunas de um programa que deixa o usuário selecionar uma operação (1:Somar 2:Subtrair 3:Multiplicar 4:Dividir) e realiza o cálculo em dois números. Escolhas inválidas pedem nova entrada.
Operação (1:+ 2:- 3:* 4:/)> 4 x = 21.0 y = 4.0 x / y = 5.250000
#include <stdio.h>

int main(void) {
    int sw;
    double x, y;

    printf("Operation (1:+ 2:- 3:* 4:/)> ");
    scanf("%d", &sw);
    while (【???】) {
        printf("Enter 1-4> ");
        scanf("%d", &sw);
    }
    printf("x = "); scanf("【???】", &x);
    printf("y = "); scanf("%lf", &y);

    switch (【???】) {
    case 1: printf("x + y = %f\n", x + y); break;
    case 2: printf("x - y = %f\n", x - y); break;
    case 3: printf("x * y = %f\n", x * y); break;
    case 4: printf("x / y = %f\n", 【???】); break;
    }
    return 0;
}
Condição do while: rejeite valores fora de 1-4. Formato do scanf: leitura de double. switch: em qual variável desviar? Expressão de divisão: x/y.
Resposta:
Lacuna 1: sw < 1 || sw > 4 (loop enquanto fora do intervalo)
Lacuna 2: %lf (especificador de formato para ler double)
Lacuna 3: sw (variável para o switch)
Lacuna 4: x / y (expressão de divisão)
EX-33 Intermediário
Comparação de Comprimento de String (Preencher)
Preencha as lacunas de um programa que usa uma função de comprimento personalizada para comparar o comprimento de duas strings.
String 1> orange String 2> apple orange tem 6 caracteres apple tem 5 caracteres Total é 11 caracteres orange é maior
#include <stdio.h>
#define MAX 101

int length(char 【???】) {
    int len = 0;
    for (int i = 0; str[i] != 【???】; i++) {
        len++;
    }
    return 【???】;
}

int main(void) {
    char s1[MAX], s2[MAX];
    printf("String 1> "); scanf("%s", s1);
    printf("String 2> "); scanf("%s", s2);

    int len1 = length(s1), len2 = length(s2);
    printf("%s is %d characters\n", s1, len1);
    printf("%s is %d characters\n", s2, len2);
    printf("Total is %d characters\n", 【???】);

    if (len1 > len2) printf("%s is longer\n", s1);
    else if (len2 > len1) printf("%s is longer\n", s2);
    else printf("Same length\n");
    return 0;
}
Argumento da função: como receber um vetor? Terminador: qual é o fim de uma string em C? return: o que deve retornar? Total: some os dois comprimentos.
Resposta:
Lacuna 1: str[] (receber vetor como argumento)
Lacuna 2: '\0' (terminador nulo)
Lacuna 3: len (retornar o comprimento calculado)
Lacuna 4: len1 + len2 (comprimento total)
EX-34 Avançado
Simulação de Dados (Preencher)
Preencha as lacunas de um programa que rola um dado n vezes e exibe a contagem e a proporção de cada face.
Rolagens: 1000 Face 1: 168 vezes (16.8%) Face 2: 172 vezes (17.2%) Face 3: 155 vezes (15.5%) Face 4: 170 vezes (17.0%) Face 5: 167 vezes (16.7%) Face 6: 168 vezes (16.8%)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {
    int n, count[6] = {0};
    printf("Rolls: "); scanf("%d", &n);
    srand((unsigned)time(NULL));

    for (int i = 0; i < 【???】; i++) {
        int die = rand() % 【???】;  // 0-5
        【???】;
    }

    for (int i = 0; i < 6; i++) {
        printf("Face %d: %d times (%.1f%%)\n",
            i + 1, count[i], (double)【???】 / n * 100);
    }
    return 0;
}
Contagem do laço: n rolagens. rand()%6: gera 0-5. Contagem: incremente o índice correspondente. Proporção: faça cast de count[i] para double.
Resposta:
Lacuna 1: n (laço n vezes)
Lacuna 2: 6 (gera valor aleatório 0-5)
Lacuna 3: count[die]++ (incrementa a contagem da face rolada)
Lacuna 4: count[i] (cast da contagem para double)
EX-35 Avançado
Pseudoaleatório Linear Congruente (Preencher)
Gere uma sequência pseudoaleatória seguindo a recorrência xn+1 = (a x xn + b) mod m. Preencha as lacunas para calcular a média de 100 valores e a proporção de valores em [0.2, 0.4).
Parâmetros: a=717, b=23, m=65536, x inicial=1234. Converta para um número real em [0, 1) usando y = x / m.
0.501 0.211 0.636 0.298 0.626 0.530 0.119 0.238 0.782 0.955 0.923 0.543 0.112 0.315 0.813 0.165 0.005 0.687 0.807 0.307 ... (omitido) ... Média é 0.505 Proporção de valores em [0.2, 0.4) é 0.200
#include <stdio.h>

int main(void) {
    int m = 65536, a = 717, b = 23, x = 1234;
    int i, count = 0;
    double y, sum = 0.0;

    for (i = 0; 【???】; i++) {
        x = (【???】) % m;
        y = (double)x / m;
        sum += 【???】;

        if (【???】) {
            count++;
        }

        printf("%1.3f ", y);
        if (【???】) {
            printf("\n");
        }
    }
    printf("\nAverage is %1.3f\n", sum / i);
    printf("Proportion of values in [0.2, 0.4) is %1.3f\n",
           (double)【???】);
    return 0;
}
Condição do laço: 100 iterações. Recorrência: a*x+b. Acumule: some y. Teste de intervalo: y>=0.2 e y<0.4. Quebra de linha: a cada 10 valores. Proporção: count/i.
Resposta:
Lacuna 1: i < 100 (100 iterações)
Lacuna 2: a * x + b (recorrência linear congruente)
Lacuna 3: y (soma y ao total)
Lacuna 4: y >= 0.2 && y < 0.4 (verifica se o valor está em [0.2, 0.4))
Lacuna 5: i % 10 == 9 (nova linha a cada 10 valores)
Lacuna 6: count / i (proporção = count / total)
EX-36 Intermediário
Copiar Vetor em Ordem Reversa (Preencher)
Preencha as lacunas de uma função que copia os elementos de um vetor para outro em ordem reversa.
#include <stdio.h>

void reverse_copy(int src[], int dst[], int n) {
    for (int i = 0; i < n; i++) {
        dst[i] = src[【???】];
    }
}

int main(void) {
    int a[] = {1, 2, 3, 4, 5};
    int b[5];
    reverse_copy(a, b, 【???】);
    for (int i = 0; i < 5; i++)
        printf("%d ", b[i]);
    printf("\n");  // Saída: 5 4 3 2 1
    return 0;
}
Índice reverso: quando i=0, o último elemento (n-1); quando i=1, n-2, ... ou seja n - 1 - i.
Resposta:
Lacuna 1: n - 1 - i (índice em ordem reversa)
Lacuna 2: 5 (tamanho do vetor)
EX-37 Avançado
Multiplicação de Matrizes (Preencher)
Preencha as lacunas de um programa que calcula o produto de duas matrizes 2x2.
A = {{1,2},{3,4}}, B = {{5,6},{7,8}} C[0][0]=19 C[0][1]=22 C[1][0]=43 C[1][1]=50
#include <stdio.h>
#define N 2

int main(void) {
    int A[N][N] = {{1,2},{3,4}};
    int B[N][N] = {{5,6},{7,8}};
    int C[N][N] = {0};

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            for (int k = 0; k < N; k++) {
                C[i][j] += 【???】;
            }
        }
    }

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++)
            printf("C[%d][%d]=%d ", i, j, C[i][j]);
        printf("\n");
    }
    return 0;
}
Produto matricial: C[i][j] = Sigma A[i][k] * B[k][j]. Acumule no mais interno dos três laços aninhados.
Resposta:
A[i][k] * B[k][j]
Definição do produto matricial: Cij = Sigmak Aik x Bkj
EX-38 Intermediário
Ponteiro e Vetor (Preencher)
Preencha as lacunas de uma função que dobra cada elemento de um vetor usando um ponteiro.
#include <stdio.h>

void double_array(【???】 arr, int n) {
    for (int i = 0; i < n; i++) {
        【???】 *= 2;
    }
}

int main(void) {
    int data[] = {3, 7, 1, 9};
    double_array(data, 4);
    for (int i = 0; i < 4; i++)
        printf("%d ", data[i]);
    printf("\n");  // Saída: 6 14 2 18
    return 0;
}
Argumento da função: qual tipo recebe um vetor via ponteiro? Acesso a elemento: como acessar o i-ésimo elemento via ponteiro?
Resposta:
Lacuna 1: int * (ponteiro int recebe o vetor)
Lacuna 2: arr[i] ou *(arr + i) (acesso ao elemento via ponteiro)
EX-39 Avançado
Inserção em Lista Encadeada (Preencher)
Preencha as lacunas de uma função que insere um nó no início de uma lista simplesmente encadeada.
#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node *next;
};

struct Node* insert_head(struct Node *head, int val) {
    struct Node *new_node = (struct Node*)malloc(【???】);
    new_node->data = 【???】;
    new_node->next = 【???】;
    return 【???】;
}

int main(void) {
    struct Node *list = NULL;
    list = insert_head(list, 30);
    list = insert_head(list, 20);
    list = insert_head(list, 10);

    struct Node *p = list;
    while (p != NULL) {
        printf("%d -> ", p->data);
        p = p->next;
    }
    printf("NULL\n"); // Saída: 10 -> 20 -> 30 -> NULL
    return 0;
}
malloc: tamanho de um Node. data: o valor do argumento. next: o head original. return: o novo nó-cabeça.
Resposta:
Lacuna 1: sizeof(struct Node) (aloca memória para um nó)
Lacuna 2: val (guarda o argumento em data)
Lacuna 3: head (define o head antigo como next do novo nó)
Lacuna 4: new_node (retorna o novo head)
Compartilhe este artigo
Compartilhar no X (Twitter) Compartilhar no Facebook Compartilhar no LinkedIn Compartilhar no Reddit