tds-lp
Apostila de Linguagem C
Disciplina: Lógica de Programação – Prof. Mauro Borges França
Curso: Técnico em Desenvolvimento de Sistemas Integrado ao Ensino Médio - TDS
Material: apostila de Linguagem C organizada na mesma sequência das aulas de lógica em Portugol (VisuAlg).
Sumário
Como encontrar um assunto: use este sumário para navegar pelos capítulos ou consulte o Índice por assunto no final da apostila. Nos arquivos digitais, os itens são clicáveis. No material impresso, procure pelo número da seção (ex.: 5.15), que aparece no título de cada seção.
- Capítulo 0 – Preparando o ambiente
- Capítulo 1 – Introdução: do algoritmo ao programa em C
- 1.1 – Conceitos iniciais
- 1.2 – Método para a construção de algoritmos (vale também para C)
- 1.3 – Do Portugol para C: o primeiro exemplo
- 1.4 – Estrutura do programa em C
- 1.5 – Tipos básicos de dados (primitivos)
- 1.6 – Constantes
- 1.7 – Variáveis e formação de identificadores
- 1.8 – Declaração e atribuição
- 1.9 – Operadores aritméticos
- 1.10 – Operadores relacionais
- 1.11 – Operadores lógicos
- 1.12 – Comandos de entrada e saída
- 1.13 – Blocos de comandos e indentação
- 1.14 – Prática
- Capítulo 2 – Estrutura Condicional (Parte 1)
- Capítulo 3 – Estrutura Condicional (Parte 2):
switch - Capítulo 4 – Estruturas de Repetição
- Capítulo 5 – Estrutura de Dados: Vetores
- 5.1 – O que é um vetor?
- 5.2 – A grande diferença: em C, o índice começa em 0
- 5.3 – Diferença entre variável simples e vetor
- 5.4 – Declaração de um vetor
- 5.5 – Índices e posições
- 5.6 – Limites do vetor
- 5.7 – Atribuição direta de valores
- 5.8 – Leitura de valores em um vetor
- 5.9 – Exibição dos valores
- 5.10 – Percurso em ordem normal e inversa
- 5.11 – Soma dos valores de um vetor
- 5.12 – Cálculo da média
- 5.13 – Contagem de valores
- 5.14 – Exibição de valores que atendem a uma condição
- 5.15 – Maior valor do vetor
- 5.16 – Menor valor do vetor
- 5.17 – Maior e menor valor no mesmo programa
- 5.18 – Localização da posição do maior valor
- 5.19 – Busca de um valor no vetor
- 5.20 – Alteração de uma posição
- 5.21 – Capacidade e quantidade preenchida
- 5.22 – Vetores paralelos
- 5.23 – Exemplo completo: análise de notas
- 5.24 – Erros comuns no uso de vetores em C
- 5.25 – Resumo
- 5.26 – Atividades de fixação
- Capítulo 6 – Estrutura de Dados: Matriz
- Capítulo 7 – Procedimentos (funções
void)- 7.1 – O que são funções e procedimentos?
- 7.2 – Procedimentos em C
- 7.3 – Organizando as listas de exercícios com menu
- 7.4 – Como escrever um procedimento em C
- 7.5 – Onde colocar e como chamar o procedimento
- 7.6 – Exemplo completo: uma lista com menu
- 7.7 – Como adaptar um exercício que você já resolveu
- 7.8 – Cuidados importantes
- Capítulo 8 – Funções
- 8.1 – O que são funções?
- 8.2 – Estrutura básica de uma função em C
- 8.3 – Tipos de funções quanto aos parâmetros
- 8.4 – Como chamar uma função
- 8.5 – Parâmetros e argumentos
- 8.6 – Tipos de retorno das funções
- 8.7 – Compare os exemplos
- 8.8 – Retornar não é o mesmo que exibir
- 8.9 – Programa completo com todas as funções da aula
- 8.10 – Como planejar uma função simples
- 8.11 – Dicas importantes
- Apêndice – Tabela de equivalência Portugol × C
- Índice por assunto
Apresentação
Durante as aulas de Lógica de Programação, construímos algoritmos em Portugol usando o VisuAlg. Agora vamos escrever os mesmos algoritmos em Linguagem C.
A ideia central desta apostila é simples: a lógica vem antes da linguagem. Todos os exemplos seguem a mesma sequência das aulas, com os mesmos nomes de variáveis e o mesmo raciocínio. O que muda é a forma de escrever.
ENTRADA → receber os dados
↓
PROCESSAMENTO → realizar cálculos e decisões
↓
SAÍDA → apresentar os resultados
Sequência da apostila
| Capítulo | Aula de origem (Portugol) | Conteúdo em C |
|---|---|---|
| 0 | Linguagens de programação | Preparação do ambiente (VS Code + GCC) |
| 1 | Introdução à Lógica de Programação | Estrutura do programa, tipos, variáveis, operadores, printf e scanf |
| 2 | Estrutura Condicional – Parte 1 | Operadores relacionais e lógicos, if, if/else, encadeamento |
| 3 | Estrutura Condicional – Parte 2 | switch/case |
| 4 | Estruturas de Repetição | for, while e do/while |
| 5 | Estrutura de Dados – Vetores | Vetores (arrays) |
| 6 | Estrutura de Dados – Matriz | Matrizes |
| 7 | Procedimentos | Funções void e menu de exercícios |
| 8 | Funções | Funções com parâmetros e retorno |
| — | Apêndice | Tabela de equivalência Portugol × C |
Observação: em cada capítulo há uma tabela Portugol → C com a tradução dos comandos estudados. Consulte-a sempre que estiver convertendo um algoritmo seu para C.
Capítulo 0 – Preparando o ambiente
Ano: 1972
Criador/origem: Dennis Ritchie, nos Bell Labs
Tipagem: Estática
Forma de execução: Compilada
IDE/editor indicado: VS Code + GCC
No VisuAlg, escrevíamos e executávamos o algoritmo no mesmo programa. Em C, o processo tem duas etapas: primeiro o compilador (GCC) transforma o código-fonte em um programa executável; depois executamos esse programa.
main.c → GCC → programa.exe → execução
Links
Passo a passo
- Baixe e instale o Visual Studio Code. Durante a instalação, mantenha habilitada a opção de adicionar o VS Code ao PATH, quando disponível.
- Abra o VS Code, pressione
Ctrl + Shift + X, pesquise por C/C++ e instale a extensão publicada pela Microsoft. - Baixe e instale o MSYS2 pelo site oficial. Use o diretório padrão, normalmente
C:\msys64. - Abra o terminal MSYS2 UCRT64 e atualize os pacotes com
pacman -Syu. Se o terminal solicitar reinício, feche-o e abra novamente o MSYS2 UCRT64. - No MSYS2 UCRT64, instale as ferramentas com
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain. Quando aparecer a lista de pacotes, pressione Enter para aceitar o conjunto padrão. - No Windows, abra Editar as variáveis de ambiente do sistema → Variáveis de Ambiente → Path → Editar → Novo e acrescente
C:\msys64\ucrt64\bin. - Feche e abra novamente o VS Code. No terminal integrado, execute
gcc --version. Se a versão for exibida, a configuração está pronta. - Crie uma pasta para a aula, abra-a no VS Code e crie
main.c. - Compile com
gcc main.c -o programa.exee execute no PowerShell com.\programa.exe.
Compilando com avisos
Use a opção -Wall para que o GCC mostre avisos sobre possíveis erros. Ela ajuda muito quem está começando:
gcc -Wall main.c -o programa.exe
.\programa.exe
Ponto de atenção – acentos: dependendo da configuração do terminal do Windows, letras acentuadas podem aparecer com símbolos estranhos. Por isso, nos exemplos desta apostila as mensagens exibidas na tela foram escritas sem acentos (ex.:
"Numero","Media"). Os comentários podem ter acentos normalmente.
Capítulo 1 – Introdução: do algoritmo ao programa em C
1.1 – Conceitos iniciais
- Programação: ato de escrever instruções para que máquinas executem uma determinada função ou várias funções encadeadas.
- Lógica de programação: metodologia para resolver problemas, criando uma sequência organizada de passos.
- Algoritmo: sequência finita e ordenada de passos para atingir um objetivo.
- Linguagem de programação: conjunto de regras usado para escrever o algoritmo de forma que o computador consiga executá-lo. Em nosso caso, a Linguagem C.
1.2 – Método para a construção de algoritmos (vale também para C)
- Compreender completamente o problema a ser resolvido;
- Definir os dados de entrada;
- Definir o processamento (cálculos e restrições);
- Definir os dados de saída;
- Construir o algoritmo (agora, o programa em C);
- Testar realizando simulações (teste de mesa e execução).
1.3 – Do Portugol para C: o primeiro exemplo
Na aula de introdução, fizemos um algoritmo que multiplica dois números:
Algoritmo "semnome"
Var
n1, n2, m: inteiro
Inicio
escreva("Digite dois números")
leia(n1)
leia(n2)
m:= n1 * n2
escreva("O resultado é =",m)
Fimalgoritmo
O mesmo algoritmo em C:
// Disciplina : Lógica de Programação
// Professor : Mauro Borges França
// Descrição : Multiplicar dois números inteiros
// Autor(a) : Nome do(a) aluno(a)
// Data atual : 05/10/2026
#include <stdio.h>
int main() {
// Seção de declarações das variáveis
int n1, n2, m;
// Seção de comandos
printf("Digite dois numeros\n");
scanf("%d", &n1);
scanf("%d", &n2);
m = n1 * n2;
printf("O resultado e = %d\n", m);
return 0;
}
1.4 – Estrutura do programa em C
No Portugol, a estrutura era: INÍCIO → DECLARAÇÃO DE VARIÁVEIS → SEÇÃO DE COMANDOS → FIM. Em C, a estrutura é equivalente:
// Seção 1 - Identificação: título, descrição, autor e data (comentários)
#include <stdio.h> // Bibliotecas utilizadas
int main() { // Início do programa principal (equivale ao Inicio)
// Seção 2 - Declaração das variáveis
// Seção 3 - Comandos de entrada, processamento e saída
return 0; // Término normal do programa
} // Equivale ao Fimalgoritmo
| Portugol (VisuAlg) | C | Significado |
|---|---|---|
Algoritmo "nome" | comentário // ... no topo | Identificação do programa |
| — | #include <stdio.h> | Disponibiliza funções de entrada e saída |
Var | declarações no início de main | Declaração das variáveis |
Inicio | int main() { | Início dos comandos |
Fimalgoritmo | return 0; e } | Fim do programa |
// comentário | // comentário ou /* ... */ | Comentários |
Atenção: em C, toda instrução termina com ponto e vírgula (
;). C também diferencia letras maiúsculas de minúsculas:soma,SomaeSOMAsão três nomes diferentes.
1.5 – Tipos básicos de dados (primitivos)
| Portugol | C | Exemplo em C |
|---|---|---|
inteiro | int | int irmaos = 3; |
real | float ou double | float altura = 1.73; |
caractere (um símbolo) | char | char resposta = 'S'; |
caractere (texto) | char nome[50] (vetor de caracteres) | char nome[50] = "Felisberto"; |
logico | bool (com #include <stdbool.h>) | bool ligada = true; |
Observações importantes:
- Em C, o número real usa ponto:
1.73, e não1,73.- Um único caractere é escrito entre aspas simples (
'S'); um texto é escrito entre aspas duplas ("Felisberto").- C não possui um tipo “texto” como o
caracteredo VisuAlg. Um texto é um vetor dechar(veremos vetores no Capítulo 5). Por enquanto, basta declararchar nome[50];para guardar um nome de até 49 letras.- O tipo lógico
boolexige#include <stdbool.h>e usa os valorestrue(verdadeiro) efalse(falso). Internamente, C trata0como falso e qualquer outro valor como verdadeiro.
1.6 – Constantes
Uma constante não muda durante a execução do programa. Em C, podemos usar const:
const float PI = 3.14159;
const int ANO_ATUAL = 2026;
Por convenção, nomes de constantes são escritos em letras maiúsculas.
1.7 – Variáveis e formação de identificadores
As regras são as mesmas do Portugol, com alguns cuidados extras:
- Devem começar por uma letra (ou
_); - Podem ser seguidos por letras, números ou
_; - Não podem ter acentos, espaços ou caracteres especiais;
- Não podem ser palavras reservadas da linguagem (
int,if,for,while,return…).
| Válidos | Inválidos |
|---|---|
alpha, x, bj153, k7, notas, media, ano_nascimento | 5x, e(13), a:b, x-y, nota/2, média, int |
1.8 – Declaração e atribuição
No Portugol, declarávamos nome: tipo e atribuíamos com <-. Em C, o tipo vem antes do nome e a atribuição usa =:
char nome[50];
int idade;
float nota;
float peso;
idade = 18;
nota = 93.5;
peso = 71.63;
Atenção: para atribuir um texto a um vetor de
chardepois da declaração, usamosstrcpy(nome, "Vagner");(biblioteca<string.h>). Também é possível inicializar na declaração:char nome[50] = "Vagner";.
| Portugol | C |
|---|---|
idade: inteiro | int idade; |
idade <- 18 | idade = 18; |
nota <- 93,5 | nota = 93.5; |
1.9 – Operadores aritméticos
| Operação | Portugol | C | Observação |
|---|---|---|---|
| Soma | + | + | |
| Subtração | - | - | |
| Multiplicação | * | * | |
| Divisão | / | / | Entre dois int, o resultado é inteiro |
| Divisão inteira | div | / (entre inteiros) | 7 / 2 resulta em 3 |
| Resto | % ou mod | % | Somente com inteiros |
| Exponenciação | ^ ou ** | pow(base, expoente) | Requer #include <math.h> |
Ponto de atenção – divisão: em C,
7 / 2vale3, pois os dois operandos são inteiros. Para obter3.5, pelo menos um deles deve ser real:7.0 / 2ou(float) a / b.
1.10 – Operadores relacionais
| Operação | Portugol | C |
|---|---|---|
| Igual a | = | == |
| Diferente de | <> | != |
| Maior que | > | > |
| Menor que | < | < |
| Maior ou igual a | >= | >= |
| Menor ou igual a | <= | <= |
Cuidado: em C,
=é atribuição e==é comparação. Escreverif (x = 10)é um erro comum!
1.11 – Operadores lógicos
| Operador Portugol | C | Função |
|---|---|---|
nao | ! | Negação |
e | && | Conjunção |
ou | || | Disjunção |
As tabelas-verdade são exatamente as mesmas estudadas nas aulas:
| A | B | A && B | A || B | !A |
|---|---|---|---|---|
| F | F | F | F | V |
| F | V | F | V | V |
| V | F | F | V | F |
| V | V | V | V | F |
1.12 – Comandos de entrada e saída
| Portugol | C | Função |
|---|---|---|
escreva(...) | printf("..."); | Saída sem pular linha |
escreval(...) | printf("...\n"); | Saída pulando linha (\n) |
leia(a) | scanf("%d", &a); | Entrada de dados |
O printf e o scanf utilizam especificadores de formato para indicar o tipo do dado:
| Especificador | Tipo | Exemplo |
|---|---|---|
%d | int | printf("%d", idade); |
%f | float | printf("%f", nota); |
%.2f | float com 2 casas decimais | printf("%.2f", media); (equivale a media:4:2) |
%lf | double (no scanf) | scanf("%lf", &valor); |
%c | char | scanf(" %c", &resposta); |
%s | texto (vetor de char) | printf("%s", nome); |
int a;
char nome[50];
scanf("%d", &a); // leia(a)
scanf(" %49[^\n]", nome); // leia(nome) - lê o nome completo, com espaços
printf("Mauro Borges Franca"); // escreva("Mauro Borges França")
printf("%s\n", nome); // escreval(nome)
Pontos de atenção no
scanf:
- Use
&antes do nome da variável:scanf("%d", &idade);. A exceção são os textos (char nome[50]), que não usam&.- O espaço antes de
%ce de%49[^\n](em" %c") faz oscanfignorar o Enter digitado na leitura anterior.%49[^\n]lê até 49 caracteres, inclusive espaços, até o Enter. Assim, nomes compostos como “Ana Paula” são lidos completos.
1.13 – Blocos de comandos e indentação
Em C, os blocos são delimitados por chaves { }. A indentação não é obrigatória para o compilador, mas é obrigatória para a organização do código e para a correção dos exercícios.
Código indentado (algoritmo calcula_idade em C):
// Disciplina : Lógica de Programação
// Professor : Mauro Borges França
// Descrição : Calcular a idade dos clientes do cinema
// Data atual : 05/10/2026
#include <stdio.h>
int main() {
// Seção de declarações das variáveis
char nome[50];
int ano_nascimento;
int ano_atual;
int idade;
// Seção de comandos
printf("Favor forneca o nome do cliente:\n");
scanf(" %49[^\n]", nome);
printf("Entre com seu ano de nascimento:\n");
scanf("%d", &ano_nascimento);
ano_atual = 2026;
idade = ano_atual - ano_nascimento;
printf("A idade do cliente e: %d\n", idade);
return 0;
}
Código não indentado (funciona, mas é difícil de ler):
#include <stdio.h>
int main() {
char nome[50];
int ano_nascimento;
int ano_atual;
int idade;
printf("Favor forneca o nome do cliente:\n");
scanf(" %49[^\n]", nome);
printf("Entre com seu ano de nascimento:\n");
scanf("%d", &ano_nascimento);
ano_atual = 2026;
idade = ano_atual - ano_nascimento;
printf("A idade do cliente e: %d\n", idade);
return 0;
}
1.14 – Prática
Dicas básicas:
- Coloque o cabeçalho com nome do programa, autor, descrição e data (em comentários);
- Inclua as bibliotecas necessárias (
#include);- Declare as variáveis com o tipo correto;
- Pense logicamente no desenvolvimento do problema e faça as operações;
- Calcule e mostre o que se pede;
- Compile com
gcc -Walle corrija todos os erros e avisos;- Salve o arquivo
.cno pendrive ou na nuvem.
Exercício 1 – Acesso ao cinema
O dono de uma rede de cinemas deseja fazer a indicação de filmes de acordo com a faixa etária de seus clientes. Para automatizar o processo, crie um programa em C que receba o nome e o ano de nascimento do cliente e mostre quantos anos ele fez (ou fará) neste ano.
Exercício 2 – As quatro operações
Uma professora de matemática deseja fazer um experimento com seus alunos. Ela precisa de um programa em C em que seja possível informar dois números inteiros e visualizar o resultado das quatro operações (adição, subtração, multiplicação e divisão) realizadas entre eles.
Dica: para a divisão apresentar casas decimais, utilize
(float) numero1 / numero2e o formato%.2f.
Capítulo 2 – Estrutura Condicional (Parte 1)
2.1 – Operadores relacionais
Permitem comparar dois valores do mesmo tipo básico. O resultado sempre será um valor lógico: verdadeiro ou falso. Em C, verdadeiro é representado por 1 (ou true) e falso por 0 (ou false).
Exemplo: a expressão (5 > 10) resulta em falso (0).
| Operação | Portugol | C |
|---|---|---|
| Igual a | = | == |
| Diferente de | <> | != |
| Maior que | > | > |
| Menor que | < | < |
| Maior ou igual a | >= | >= |
| Menor ou igual a | <= | <= |
Exemplos de expressões comparativas
Suponha x igual a 10:
| Expressão em C | Resultado |
|---|---|
x > 0 | Verdadeiro |
x == 9 | Falso |
20 <= x | Falso |
x != 10 | Falso |
x >= 9 | Verdadeiro |
10 >= x | Verdadeiro |
2.2 – Operadores lógicos
| Portugol | C | Função | Descrição |
|---|---|---|---|
e | && | Conjunção | Verdadeiro se todas as condições forem verdadeiras |
ou | || | Disjunção | Verdadeiro se pelo menos uma condição for verdadeira |
nao | ! | Negação | Verdadeiro se a condição for falsa |
2.2.1 – Assimilando o operador && (“e”)
Suponha x igual a 10:
| Expressão em C | Valores | Resultado |
|---|---|---|
(x > 0) && (x == 10) | V V | Verdadeiro |
(20 <= x) && (x != 10) | F F | Falso |
(x == 10) && (x < 2) | V F | Falso |
(x >= 9) && (x == 10) && (x != 20) | V V V | Verdadeiro |
Observação: todas as condições devem ser verdadeiras para o resultado da expressão ser verdadeiro.
Exemplo – João quer jogar futebol. Ele precisa terminar a lição de casa e o tempo precisa estar ensolarado.
#include <stdio.h>
int main() {
char licao_de_casa, tempo_ensolarado;
printf("Joao terminou a licao de casa? (S/N): ");
scanf(" %c", &licao_de_casa);
printf("O tempo esta ensolarado?.......(S/N): ");
scanf(" %c", &tempo_ensolarado);
if ((licao_de_casa == 'S') && (tempo_ensolarado == 'S')) {
printf("Joao pode sair de casa\n");
} else {
printf("Joao nao pode sair de casa\n");
}
return 0;
}
Atenção: como a resposta é um único caractere, usamos
char, aspas simples ('S') e" %c"noscanf.
2.2.2 – Assimilando o operador || (“ou”)
Suponha x igual a 10:
| Expressão em C | Valores | Resultado |
|---|---|---|
(x < 0) || (x == 10) | F V | Verdadeiro |
(20 <= x) || (x != 10) | F F | Falso |
(x == 10) || (x < 2) | V F | Verdadeiro |
(x >= 9) || (x != 10) || (x > 20) | V F F | Verdadeiro |
Observação: pelo menos uma das condições deve ser verdadeira para o resultado ser verdadeiro.
Exemplo – Mariana quer assistir TV. Basta terminar a lição de casa ou ser final de semana.
#include <stdio.h>
int main() {
char licao_de_casa, final_de_semana;
printf("Mariana terminou a licao de casa? (S/N): ");
scanf(" %c", &licao_de_casa);
printf("E final de semana?.................(S/N): ");
scanf(" %c", &final_de_semana);
if ((licao_de_casa == 'S') || (final_de_semana == 'S')) {
printf("Mariana pode assistir TV\n");
} else {
printf("Mariana nao pode assistir TV\n");
}
return 0;
}
2.2.3 – Assimilando o operador ! (“não”)
Suponha x igual a 10:
| Expressão em C | Valor interno | Resultado |
|---|---|---|
!(x == 10) | V | Falso |
!(20 <= x) | F | Verdadeiro |
!((x == 10) && (x < 2)) | V && F = F | Verdadeiro |
Observação: o operador
!sempre inverte o resultado da expressão lógica, de F para V ou de V para F.
Exemplo – Carlos quer jogar videogame. Ele só pode jogar se não houver tarefas pendentes.
#include <stdio.h>
int main() {
char tarefas_pendentes;
printf("Carlos tem tarefas pendentes? (S/N): ");
scanf(" %c", &tarefas_pendentes);
if (!(tarefas_pendentes == 'S')) {
printf("Carlos pode jogar videogame\n");
} else {
printf("Carlos nao pode jogar videogame\n");
}
return 0;
}
2.3 – Estruturas condicionais (estruturas de controle)
Conceito: uma estrutura condicional permite que um bloco de comandos seja executado somente quando uma condição específica for satisfeita, alterando o fluxo de execução do programa.
| Portugol | C |
|---|---|
se <condicao> entao | if (condicao) { |
senao | } else { |
fimse | } |
Atenção: em C, a condição do
iffica sempre entre parênteses, e não existe a palavraentao.
2.3.1 – Estrutura condicional simples
if (condicao) {
comando1;
comando2;
comandoN;
}
- Verdadeiro: executa o bloco de comandos;
- Falso: pula o bloco de comandos.
// Descrição : Exemplo de estrutura condicional simples
// Autor(a) : Mauro Borges França
#include <stdio.h>
int main() {
// Declaração de variável
int idade;
// Entrada de dados
printf("Digite a sua idade: ");
scanf("%d", &idade);
// Estrutura condicional simples
if (idade >= 18) {
printf("Voce e maior de idade!\n");
}
return 0;
}
2.3.2 – Estrutura condicional composta
if (condicao) {
comando1;
comandoN;
} else {
comando3;
comandoN;
}
- Verdadeiro: executa somente o bloco do
if; - Falso: executa somente o bloco do
else.
// Descrição : Exemplo de estrutura condicional composta
// Autor(a) : Mauro Borges França
#include <stdio.h>
int main() {
// Declaração de variável
int idade;
// Entrada de dados
printf("Digite a sua idade: ");
scanf("%d", &idade);
// Estrutura condicional composta
if (idade >= 18) {
printf("Voce e maior de idade!\n");
} else {
printf("Voce e menor de idade!\n");
}
return 0;
}
2.3.3 – E se eu tiver mais de duas possibilidades?
Tradicionalmente, uma população é dividida em três faixas etárias:
- Jovens: até 19 anos;
- Adultos: de 20 até 59 anos;
- Idosos: 60 anos em diante.
No Portugol, colocávamos um se dentro do senao. Em C, fazemos o mesmo:
if (condicao1) {
comando1;
} else {
if (condicao2) {
comando2;
} else {
comando3;
}
}
Em C, é muito comum escrever esse encadeamento de forma mais compacta com else if. As duas formas têm a mesma lógica:
if (condicao1) {
comando1;
} else if (condicao2) {
comando2;
} else {
comando3;
}
// Descrição : Estrutura condicional composta com mais de duas possibilidades
// Autor(a) : Mauro Borges França
#include <stdio.h>
int main() {
// Declaração de variável
int idade;
// Entrada de dados
printf("Digite a sua idade: ");
scanf("%d", &idade);
// Estrutura condicional com mais de duas possibilidades
if (idade <= 19) {
printf("Voce e uma pessoa jovem!\n");
} else if ((idade >= 20) && (idade <= 59)) {
printf("Voce e uma pessoa adulta!\n");
} else {
printf("Voce e uma pessoa idosa!\n");
}
return 0;
}
2.4 – Vamos para a prática
Dicas básicas para um melhor desempenho:
- Coloque o cabeçalho do programa (nome, autor, descrição e data);
- Declare as variáveis com o tipo correto;
- Pense logicamente no desenvolvimento do problema;
- Utilize as estruturas condicionais, calcule e mostre o que se pede;
- Faça a indentação corretamente e confira se cada
{tem o seu};- Faça o teste de mesa para garantir o funcionamento correto;
- Compile com
gcc -Walle teste com valores que caiam em todas as condições.
Atividades de fixação
- Leia um número inteiro e informe se ele é positivo, negativo ou zero.
- Leia duas notas, calcule a média e informe “Aprovado” (média maior ou igual a 6), “Recuperação” (média entre 4 e 5.9) ou “Reprovado” (média menor que 4).
- Leia um número inteiro e informe se ele é par ou ímpar (use o operador
%). - Leia a idade e informe se a pessoa pode votar de forma obrigatória (18 a 70 anos), facultativa (16, 17 ou acima de 70) ou se não pode votar (menos de 16).
Capítulo 3 – Estrutura Condicional (Parte 2): switch
3.1 – Estrutura de seleção switch/case
Conceito: a estrutura escolha-caso do Portugol corresponde ao switch/case em C. Ela é utilizada quando temos vários if/else aninhados que testam o valor de uma mesma variável. O switch permite ir direto ao bloco de código desejado.
| Portugol | C |
|---|---|
escolha <variavel> | switch (variavel) { |
caso <valor> | case valor: |
| (fim de cada caso) | break; |
outrocaso | default: |
fimescolha | } |
switch (variavel) {
case valor1:
comando1;
comandoN;
break;
case valor2:
comando1;
comandoN;
break;
case valor3:
comando1;
comandoN;
break;
default:
comando1;
comandoN;
}
Atenção – o
break: em C, cadacasedeve terminar combreak;. Sem ele, o programa continua executando os casos seguintes. No VisuAlg isso não acontecia, por isso esse é um erro muito comum ao converter algoritmos.Limitação: o
switchem C só funciona com valores inteiros ou caracteres (intouchar). Não é possível usarswitchcom números reais ou textos.
3.2 – Comparação com o if/else
Versão com if/else aninhados:
// Descrição : Exercício - Dia da semana - com if/else
// Autor(a) : Professor Mauro Borges França
#include <stdio.h>
int main() {
int dia;
printf("Digite um numero de 1 a 7: ");
scanf("%d", &dia);
if (dia == 1) {
printf("Domingo\n");
} else {
if (dia == 2) {
printf("Segunda-feira\n");
} else {
if (dia == 3) {
printf("Terca-feira\n");
} else {
if (dia == 4) {
printf("Quarta-feira\n");
} else {
if (dia == 5) {
printf("Quinta-feira\n");
} else {
if (dia == 6) {
printf("Sexta-feira\n");
} else {
if (dia == 7) {
printf("Sabado\n");
} else {
printf("Numero invalido\n");
}
}
}
}
}
}
}
return 0;
}
Observação: veja como os
if/elseaninhados deixam o código mais complexo. A lógica funciona, porém fica difícil de ler. Veja o mesmo programa comswitch:
// Descrição : Exercício - Dia da semana - estrutura switch
// Autor(a) : Professor Mauro Borges França
#include <stdio.h>
int main() {
int dia;
printf("Digite um numero de 1 a 7: ");
scanf("%d", &dia);
printf("Dia da semana: ");
switch (dia) {
case 1:
printf("Domingo\n");
break;
case 2:
printf("Segunda-feira\n");
break;
case 3:
printf("Terca-feira\n");
break;
case 4:
printf("Quarta-feira\n");
break;
case 5:
printf("Quinta-feira\n");
break;
case 6:
printf("Sexta-feira\n");
break;
case 7:
printf("Sabado\n");
break;
default:
printf("Numero invalido\n");
}
return 0;
}
Observação: bem mais organizado. A lógica dos dois programas é a mesma; para algumas soluções, o
switché mais adequado.Outra observação: o
defaulté opcional, assim como ooutrocaso, mas é muito útil e será utilizado na maioria das aplicações.
3.2.1 – Vários valores para o mesmo bloco
Como o case sem break “cai” no seguinte, podemos agrupar valores que executam o mesmo bloco:
switch (dia) {
case 1:
case 7:
printf("Fim de semana\n");
break;
case 2:
case 3:
case 4:
case 5:
case 6:
printf("Dia util\n");
break;
default:
printf("Numero invalido\n");
}
Atividades de fixação
- Leia um número de 1 a 12 e mostre o nome do mês correspondente.
- Leia dois números reais e um caractere de operação (
+,-,*ou/) e mostre o resultado da operação escolhida (useswitchcomchar). - Reescreva com
switchum dos seus exercícios deif/elseda Lista de Estrutura Condicional.
Capítulo 4 – Estruturas de Repetição
Conceito: uma estrutura de repetição (também conhecida como laço ou loop) repete um bloco de comandos várias vezes, enquanto uma condição for verdadeira ou durante um número determinado de vezes.
Contexto: lembra do algoritmo que calcula a média de um aluno? Se forem 50 alunos, não faz sentido escrever o mesmo código 50 vezes. Escrevemos uma vez e usamos uma estrutura de repetição.
| Tipo | Portugol | C |
|---|---|---|
| Baseada em contagem | para ... fimpara | for |
| Condição testada no início | enquanto ... fimenquanto | while |
| Condição testada no final | repita ... ate | do ... while |
4.1 – Repetição baseada em contagem: for (estrutura PARA)
Utilizada quando se sabe o número de vezes que um trecho deve ser repetido.
Para <variavel> de <valor-inicial> ate <valor-final> [passo <incremento>] faca
<comandos>
fimpara
Em C, o for reúne em uma única linha as três partes do controle:
for (inicializacao; condicao; incremento) {
comandos;
}
| Parte | Exemplo | Equivale no Portugol |
|---|---|---|
| Inicialização | i = 1 | de 1 |
| Condição | i <= 10 | ate 10 |
| Incremento | i++ (soma 1 em i) | passo 1 (padrão) |
| Portugol | C |
|---|---|
para i de 1 ate 10 faca | for (i = 1; i <= 10; i++) |
para i de 0 ate 20 passo 2 faca | for (i = 0; i <= 20; i += 2) |
para i de 10 ate 1 passo -1 faca | for (i = 10; i >= 1; i--) |
Lembrete:
i++é o mesmo quei = i + 1;i--é o mesmo quei = i - 1;i += 2é o mesmo quei = i + 2.
Exemplo 1 – Estrutura for:
// Descrição : Exemplo para demonstrar a estrutura for (PARA)
#include <stdio.h>
int main() {
int i;
for (i = 1; i <= 10; i++) {
printf("Numero -> %d\n", i);
}
return 0;
}
Explicação:
ié a variável que funciona como contador;for (i = 1; i <= 10; i++)define que o laço começa em 1 e termina em 10;- a cada repetição, o
printfmostra o valor atual dei.
Numero -> 1
Numero -> 2
Numero -> 3
...
Numero -> 10
Exemplo 2 – Soma de 1 a 100:
// Descrição : Somar os 100 primeiros números com for
#include <stdio.h>
int main() {
int i, soma;
soma = 0;
for (i = 1; i <= 100; i++) {
soma = soma + i;
}
printf("A soma dos numeros de 1 ate 100 e: %d\n", soma);
return 0;
}
Explicação:
- A variável
somacomeça com 0 (acumulador inicializado); - O laço percorre todos os números de 1 até 100;
- A cada repetição, o valor de
ié adicionado àsoma; - No final, o programa exibe o total acumulado: 5050.
4.2 – Repetição com teste no início: while (estrutura ENQUANTO)
Utilizada quando não se sabe o número de vezes que um trecho deverá ser repetido. O bloco é executado enquanto a condição for verdadeira. Se a condição já começar falsa, o bloco não é executado nenhuma vez.
| Portugol | C |
|---|---|
enquanto (condicao) faca | while (condicao) { |
fimenquanto | } |
Exemplo 1 – Contar com while:
// Descrição : Exemplo para demonstrar a estrutura while (ENQUANTO)
#include <stdio.h>
int main() {
int contador;
contador = 1;
while (contador <= 5) {
printf("Numero: %d\n", contador);
contador = contador + 1;
}
printf("Saiu do laco\n");
return 0;
}
Explicação:
- O laço começa com
contador = 1e vai até 5; - A cada volta, mostra o número e soma 1;
- Quando
contadorpassa a valer 6, a condição fica falsa, o programa sai do laço e executa o primeiro comando após a estrutura.
Cuidado – laço infinito: se esquecer a linha
contador = contador + 1;, a condição nunca ficará falsa e o programa não terminará. Para interromper no terminal, pressioneCtrl + C.
Exemplo 2 – Ler números até digitar zero:
// Descrição : Ler números até o usuário digitar zero (while)
#include <stdio.h>
int main() {
int numero;
printf("Digite um numero (0 para sair): ");
scanf("%d", &numero);
while (numero != 0) {
printf("Voce digitou: %d\n", numero);
printf("Digite outro numero (0 para sair): ");
scanf("%d", &numero);
}
printf("Programa encerrado.\n");
return 0;
}
Explicação:
- O laço continua pedindo números enquanto o valor digitado for diferente de 0 (
!=); - Quando o usuário digita 0, o laço termina;
- Se o usuário digitar 0 logo no início, o laço nem começa.
4.3 – Repetição com teste no final: do/while (estrutura REPITA)
Diferente do while, que verifica a condição antes, o do/while verifica a condição no final. Por isso, os comandos são executados pelo menos uma vez.
Atenção – a condição é invertida! No Portugol, o
repitacontinua ATÉ a condição ser verdadeira. Em C, odo/whilecontinua ENQUANTO a condição for verdadeira. Por isso, ao converter, invertemos a condição:
| Portugol | C |
|---|---|
repita | do { |
ate (contador > 5) | } while (contador <= 5); |
ate (numero = 0) | } while (numero != 0); |
ate opcao = 0 | } while (opcao != 0); |
Repare também no ponto e vírgula depois do
while (...)no final dodo/while.
Exemplo 1 – Contar com do/while:
// Descrição : Exemplo para demonstrar a estrutura do/while (REPITA)
#include <stdio.h>
int main() {
int contador;
contador = 1;
do {
printf("Numero: %d\n", contador);
contador = contador + 1;
} while (contador <= 5); // Portugol: ate (contador > 5)
printf("Saiu do laco\n");
return 0;
}
Exemplo 2 – Ler números com do/while:
// Descrição : Ler números até o usuário digitar zero (do/while)
#include <stdio.h>
int main() {
int numero;
do {
printf("Digite um numero (0 para sair): ");
scanf("%d", &numero);
} while (numero != 0); // Portugol: ate (numero = 0)
printf("Programa encerrado.\n");
return 0;
}
Explicação:
- O
do/whilegarante que o número será lido pelo menos uma vez; - O processo se repete até o usuário digitar 0.
4.4 – Qual estrutura escolher?
| Situação | Estrutura em C |
|---|---|
| Sei quantas vezes vou repetir | for |
| Não sei quantas vezes; pode ser que não execute nenhuma vez | while |
| Não sei quantas vezes; precisa executar pelo menos uma vez (ex.: menus) | do/while |
Atividades de fixação
- Mostre a tabuada de um número informado pelo usuário (de 1 a 10) usando
for. - Mostre os números pares de 0 a 50 usando
forcom incremento 2. - Leia as notas de uma turma até que seja digitada uma nota negativa. Ao final, mostre a quantidade de notas e a média (use
while). - Leia uma senha numérica até que o usuário digite
1234(usedo/while). - Calcule o fatorial de um número inteiro informado pelo usuário.
Capítulo 5 – Estrutura de Dados: Vetores
Objetivos
Ao final deste capítulo, o estudante deverá ser capaz de:
- compreender o conceito de vetor em C;
- diferenciar uma variável simples de uma variável composta;
- declarar vetores em C;
- acessar, preencher e alterar posições de um vetor;
- percorrer vetores em ordem normal e inversa;
- realizar cálculos utilizando os valores armazenados;
- localizar elementos em um vetor;
- identificar erros comuns no uso de índices.
5.1 – O que é um vetor?
Um vetor, também chamado de array, é uma variável composta homogênea de uma dimensão. Ele:
- armazena vários valores;
- armazena valores do mesmo tipo;
- utiliza um único nome;
- organiza os valores em posições;
- identifica cada posição por meio de um índice.
Considere cinco idades: 18, 20, 17, 22, 19. Em vez de declarar cinco variáveis:
int idade1, idade2, idade3, idade4, idade5;
podemos declarar apenas um vetor:
int idades[5];
5.2 – A grande diferença: em C, o índice começa em 0
No VisuAlg, declarávamos vetor[1..5] e as posições iam de 1 a 5. Em C, o primeiro índice é sempre 0. Um vetor de 5 posições tem os índices 0, 1, 2, 3 e 4.
| Índice em C | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| Valor | 18 | 20 | 17 | 22 | 19 |
| “Posição” para o usuário | 1ª | 2ª | 3ª | 4ª | 5ª |
Assim, idades[0] representa o valor 18 e idades[3] representa o valor 22.
| Portugol (VisuAlg) | C |
|---|---|
idades: vetor[1..5] de inteiro | int idades[5]; |
primeira posição: idades[1] | primeira posição: idades[0] |
última posição: idades[5] | última posição: idades[4] |
para i de 1 ate 5 faca | for (i = 0; i < 5; i++) |
Dica: para mostrar ao usuário “1º número”, “2º número”…, usamos
i + 1na mensagem, mas guardamos o valor emnumeros[i].
Características de um vetor
- É uma estrutura de dados simples;
- Possui uma quantidade definida de posições (em C, o tamanho não muda depois de declarado);
- Armazena dados do mesmo tipo;
- Permite acesso direto a qualquer posição;
- É armazenado de forma sequencial na memória;
- Serve de base para estruturas mais complexas, como matrizes, listas, filas e pilhas.
5.3 – Diferença entre variável simples e vetor
| Variável simples | Vetor |
|---|---|
| Armazena apenas um valor | Armazena vários valores |
| Não utiliza índice | Utiliza índice |
| Possui apenas uma posição | Possui várias posições |
int idade; | int idades[5]; |
5.4 – Declaração de um vetor
Para declarar um vetor em C, definimos o tipo, o nome e, entre colchetes, a quantidade de posições:
tipo nomeVetor[quantidade];
float notas[10];
int idades[20];
bool respostas[10]; // requer #include <stdbool.h>
char nomes[5][50]; // 5 nomes de até 49 letras (vetor de textos)
No exemplo float notas[10]; temos: nome notas; 10 posições; índices de 0 a 9; tipo float.
Vetor de textos: como em C um texto já é um vetor de
char, um vetor de nomes precisa de dois colchetes:char nomes[5][50];significa 5 nomes, cada um com até 49 letras.
Também é possível inicializar o vetor na declaração:
int idades[5] = {18, 20, 17, 22, 19};
5.5 – Índices e posições
notas[0] = 8.5;
notas[1] = 7.0;
notas[2] = 9.5;
| Índice | 0 | 1 | 2 |
|---|---|---|---|
| Valor | 8.5 | 7.0 | 9.5 |
Atenção: o índice não é o valor armazenado. Em
notas[1] = 7.0;,1é o índice e7.0é o valor.
5.6 – Limites do vetor
Ao declarar int numeros[5];, as posições válidas são 0, 1, 2, 3 e 4. numeros[0] e numeros[4] são válidos; numeros[5] e numeros[-1] são inválidos.
Muito importante: no VisuAlg, acessar uma posição inexistente gerava uma mensagem de erro. Em C, o compilador não avisa e o programa pode exibir valores sem sentido, alterar outras variáveis ou fechar inesperadamente. Por isso, a condição do laço deve ser
i < 5, e nãoi <= 5.
5.7 – Atribuição direta de valores
numeros[0] = 10;
numeros[1] = 25;
numeros[2] = 8;
numeros[1] = 30; // substitui o valor anterior (25)
| Índice 0 | Índice 1 | Índice 2 | |
|---|---|---|---|
| Antes | 10 | 25 | 8 |
| Depois | 10 | 30 | 8 |
5.8 – Leitura de valores em um vetor
#include <stdio.h>
int main() {
int numeros[5];
int i;
// Percorre todas as posições do vetor
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
return 0;
}
O comando scanf("%d", &numeros[i]); utiliza o valor de i para indicar a posição que será preenchida:
i = 0 → numeros[0] (1º número)
i = 1 → numeros[1] (2º número)
i = 2 → numeros[2] (3º número)
i = 3 → numeros[3] (4º número)
i = 4 → numeros[4] (5º número)
5.9 – Exibição dos valores
#include <stdio.h>
int main() {
int numeros[5];
int i;
// Leitura dos valores
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
printf("\nValores armazenados:\n");
// Exibição dos valores
for (i = 0; i < 5; i++) {
printf("Posicao %d: %d\n", i + 1, numeros[i]);
}
return 0;
}
5.10 – Percurso em ordem normal e inversa
| Portugol | C | |
|---|---|---|
| Ordem normal | para i de 1 ate 5 faca | for (i = 0; i < 5; i++) |
| Ordem inversa | para i de 5 ate 1 passo -1 faca | for (i = 4; i >= 0; i--) |
#include <stdio.h>
int main() {
int numeros[5];
int i;
// Preenchimento do vetor
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
// Exibição em ordem normal
printf("\n===== ORDEM NORMAL =====\n");
for (i = 0; i < 5; i++) {
printf("Posicao %d: %d\n", i + 1, numeros[i]);
}
// Exibição em ordem inversa
printf("\n===== ORDEM INVERSA =====\n");
for (i = 4; i >= 0; i--) {
printf("Posicao %d: %d\n", i + 1, numeros[i]);
}
return 0;
}
5.11 – Soma dos valores de um vetor
#include <stdio.h>
int main() {
int numeros[5];
int i, soma;
soma = 0;
// Leitura dos valores
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
// Soma dos valores
for (i = 0; i < 5; i++) {
soma = soma + numeros[i];
}
printf("Soma dos valores: %d\n", soma);
return 0;
}
5.12 – Cálculo da média
#include <stdio.h>
int main() {
float notas[5];
int i;
float soma, media;
soma = 0;
// Leitura das notas
for (i = 0; i < 5; i++) {
printf("Digite a %d nota: ", i + 1);
scanf("%f", ¬as[i]);
soma = soma + notas[i];
}
// Cálculo da média
media = soma / 5;
printf("Media das notas: %.2f\n", media);
return 0;
}
5.13 – Contagem de valores
Exemplo – Contar números pares:
#include <stdio.h>
int main() {
int numeros[5];
int i, qtdPares;
qtdPares = 0;
// Leitura dos valores
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
// Contagem dos números pares
for (i = 0; i < 5; i++) {
if (numeros[i] % 2 == 0) {
qtdPares = qtdPares + 1;
}
}
printf("Quantidade de numeros pares: %d\n", qtdPares);
return 0;
}
5.14 – Exibição de valores que atendem a uma condição
printf("Numeros maiores que 10:\n");
for (i = 0; i < 5; i++) {
if (numeros[i] > 10) {
printf("%d\n", numeros[i]);
}
}
5.15 – Maior valor do vetor
Para encontrar o maior valor, utilizamos inicialmente o primeiro elemento do vetor (numeros[0]) e comparamos com os demais.
#include <stdio.h>
int main() {
int numeros[5];
int i, maior;
// Leitura dos valores
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
// O primeiro elemento é inicialmente considerado o maior
maior = numeros[0];
// Comparação com os demais elementos
for (i = 1; i < 5; i++) {
if (numeros[i] > maior) {
maior = numeros[i];
}
}
printf("Maior valor: %d\n", maior);
return 0;
}
Por que não iniciar o maior com zero? Considere o vetor
-5, -2, -10, -4, -8. Commaior = 0;, o programa informaria que o maior valor é zero, mesmo que zero não esteja armazenado. Por isso, usemaior = numeros[0];.
5.16 – Menor valor do vetor
#include <stdio.h>
int main() {
int numeros[5];
int i, menor;
// Leitura dos valores
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
menor = numeros[0];
// Procura pelo menor valor
for (i = 1; i < 5; i++) {
if (numeros[i] < menor) {
menor = numeros[i];
}
}
printf("Menor valor: %d\n", menor);
return 0;
}
5.17 – Maior e menor valor no mesmo programa
#include <stdio.h>
int main() {
int numeros[5];
int i, maior, menor;
// Preenchimento do vetor
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
// Inicialização com o primeiro valor
maior = numeros[0];
menor = numeros[0];
// Comparação com os demais valores
for (i = 1; i < 5; i++) {
if (numeros[i] > maior) {
maior = numeros[i];
}
if (numeros[i] < menor) {
menor = numeros[i];
}
}
printf("Maior valor: %d\n", maior);
printf("Menor valor: %d\n", menor);
return 0;
}
5.18 – Localização da posição do maior valor
#include <stdio.h>
int main() {
int numeros[5];
int i, maior, posMaior;
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
maior = numeros[0];
posMaior = 0;
for (i = 1; i < 5; i++) {
if (numeros[i] > maior) {
maior = numeros[i];
posMaior = i;
}
}
printf("Maior valor: %d\n", maior);
printf("Posicao do maior valor: %d\n", posMaior + 1);
return 0;
}
Observação: guardamos o índice real (
posMaior = i) e somamos 1 apenas na hora de mostrar ao usuário.
5.19 – Busca de um valor no vetor
#include <stdio.h>
#include <stdbool.h>
int main() {
int numeros[5];
int i, procurado;
bool encontrou;
// Preenchimento do vetor
for (i = 0; i < 5; i++) {
printf("Digite o %d numero: ", i + 1);
scanf("%d", &numeros[i]);
}
// Número que será procurado
printf("Digite o numero que deseja procurar: ");
scanf("%d", &procurado);
encontrou = false;
// Busca pelo número
for (i = 0; i < 5; i++) {
if (numeros[i] == procurado) {
printf("Numero encontrado na posicao %d\n", i + 1);
encontrou = true;
}
}
// Mensagem apresentada quando não houver ocorrência
if (encontrou == false) {
printf("Numero nao encontrado.\n");
}
return 0;
}
Observação: se o mesmo número aparecer mais de uma vez, o programa mostrará todas as posições em que ele foi encontrado. A condição
encontrou == falsetambém pode ser escrita como!encontrou.
5.20 – Alteração de uma posição
#include <stdio.h>
int main() {
int numeros[5];
int i, posicao, novoValor;
// Preenchimento do vetor
for (i = 0; i < 5; i++) {
printf("Digite o valor da posicao %d: ", i + 1);
scanf("%d", &numeros[i]);
}
printf("Informe a posicao que deseja alterar (1 a 5): ");
scanf("%d", &posicao);
// Validação da posição
if (posicao >= 1 && posicao <= 5) {
printf("Informe o novo valor: ");
scanf("%d", &novoValor);
numeros[posicao - 1] = novoValor; // posição 1 do usuário = índice 0
printf("Valor alterado com sucesso.\n");
} else {
printf("Posicao invalida.\n");
}
// Exibição do vetor atualizado
printf("\nVetor atualizado:\n");
for (i = 0; i < 5; i++) {
printf("Posicao %d: %d\n", i + 1, numeros[i]);
}
return 0;
}
5.21 – Capacidade e quantidade preenchida
Um vetor pode possuir mais posições do que a quantidade de dados realmente utilizada.
char nomes[10][50];
int qtd, i;
printf("Quantos nomes deseja cadastrar? ");
scanf("%d", &qtd);
for (i = 0; i < qtd; i++) {
printf("Digite o %d nome: ", i + 1);
scanf(" %49[^\n]", nomes[i]);
}
Nesse caso: capacidade do vetor: 10; quantidade utilizada: valor de qtd.
Cuidado: valide
qtdpara que ele não seja maior que a capacidade (10).
5.22 – Vetores paralelos
Vetores paralelos são vetores diferentes cujas posições representam informações relacionadas.
| Índice | nomes | notas |
|---|---|---|
| 0 | Ana | 8.5 |
| 1 | Carlos | 6.0 |
| 2 | Maria | 9.0 |
| 3 | João | 5.5 |
| 4 | Pedro | 7.5 |
nomes[2] e notas[2] representam os dados do mesmo aluno.
#include <stdio.h>
int main() {
char nomes[5][50];
float notas[5];
int i;
// Cadastro dos alunos
for (i = 0; i < 5; i++) {
printf("Digite o nome do %d aluno: ", i + 1);
scanf(" %49[^\n]", nomes[i]);
printf("Digite a nota de %s: ", nomes[i]);
scanf("%f", ¬as[i]);
}
// Apresentação dos dados
printf("\n===== ALUNOS E NOTAS =====\n");
for (i = 0; i < 5; i++) {
printf("Aluno: %s\n", nomes[i]);
printf("Nota: %.2f\n", notas[i]);
printf("--------------------------\n");
}
return 0;
}
Atenção: em
scanf(" %49[^\n]", nomes[i]);não usamos&, poisnomes[i]já é um texto (vetor dechar).
5.23 – Exemplo completo: análise de notas
O programa deverá: ler cinco notas; mostrar todas as notas; calcular a média; informar a maior e a menor nota; contar quantas notas estão acima da média; mostrar as notas em ordem inversa.
#include <stdio.h>
int main() {
float notas[5];
int i, qtdAcima;
float soma, media, maior, menor;
soma = 0;
qtdAcima = 0;
// Leitura das notas
for (i = 0; i < 5; i++) {
printf("Digite a %d nota: ", i + 1);
scanf("%f", ¬as[i]);
soma = soma + notas[i];
}
// Cálculo da média
media = soma / 5;
// Inicialização do maior e do menor valor
maior = notas[0];
menor = notas[0];
// Procura pelo maior e pelo menor valor
for (i = 1; i < 5; i++) {
if (notas[i] > maior) {
maior = notas[i];
}
if (notas[i] < menor) {
menor = notas[i];
}
}
// Contagem das notas acima da média
for (i = 0; i < 5; i++) {
if (notas[i] > media) {
qtdAcima = qtdAcima + 1;
}
}
// Apresentação das notas
printf("\n===== NOTAS INFORMADAS =====\n");
for (i = 0; i < 5; i++) {
printf("Nota %d: %.2f\n", i + 1, notas[i]);
}
// Apresentação dos resultados
printf("\n===== RESULTADOS =====\n");
printf("Media: %.2f\n", media);
printf("Maior nota: %.2f\n", maior);
printf("Menor nota: %.2f\n", menor);
printf("Notas acima da media: %d\n", qtdAcima);
// Apresentação em ordem inversa
printf("\n===== ORDEM INVERSA =====\n");
for (i = 4; i >= 0; i--) {
printf("%.2f\n", notas[i]);
}
return 0;
}
5.24 – Erros comuns no uso de vetores em C
1. Não utilizar o índice
scanf("%d", &numeros); // Incorreto
scanf("%d", &numeros[i]); // Correto
2. Acessar uma posição inexistente
int numeros[5];
numeros[5] = 10; // Incorreto: os índices vão de 0 a 4
3. Usar <= no lugar de < no laço
for (i = 0; i <= 5; i++) // Incorreto: acessa numeros[5]
for (i = 0; i < 5; i++) // Correto
4. Começar o laço em 1 (hábito do VisuAlg)
for (i = 1; i <= 5; i++) // Incorreto: ignora numeros[0] e acessa numeros[5]
for (i = 0; i < 5; i++) // Correto
5. Confundir posição com valor – em numeros[3] = 20;, 3 é o índice e 20 é o valor.
6. Não inicializar um acumulador – em C, uma variável não inicializada contém “lixo de memória”. Sempre faça soma = 0; antes do laço.
7. Inicializar o maior valor com zero – prefira maior = numeros[0];.
8. Usar nomes diferentes – se o vetor foi declarado como numeros, use numeros[i], e não numero[i].
9. Esquecer o & no scanf de números – scanf("%d", numeros[i]); está incorreto; o correto é scanf("%d", &numeros[i]);.
5.25 – Resumo
| Operação | C |
|---|---|
| Declaração | int numeros[5]; |
| Acesso | numeros[0] |
| Leitura | scanf("%d", &numeros[i]); |
| Exibição | printf("%d\n", numeros[i]); |
| Percurso | for (i = 0; i < 5; i++) |
| Ordem inversa | for (i = 4; i >= 0; i--) |
| Soma | soma = soma + numeros[i]; |
| Comparação | if (numeros[i] > maior) |
| Busca | if (numeros[i] == procurado) |
5.26 – Atividades de fixação
Exercício 1 – Leitura e apresentação. Faça um programa que leia oito números inteiros, armazene-os em um vetor e apresente todos os valores na ordem em que foram informados.
Exercício 2 – Ordem inversa. Faça um programa que leia dez números inteiros e apresente-os na ordem inversa à ordem de entrada.
Exercício 3 – Números pares. Faça um programa que leia dez números inteiros e apresente: todos os números informados; somente os números pares; a quantidade de números pares.
Exercício 4 – Soma e média. Faça um programa que leia seis números reais e apresente: a soma dos valores; a média; os valores maiores que a média.
Exercício 5 – Maior e menor. Faça um programa que leia oito números inteiros e apresente: o maior número e sua posição; o menor número e sua posição.
Exercício 6 – Busca de valor. Faça um programa que leia dez números inteiros. Em seguida, solicite um número ao usuário e informe se ele está armazenado no vetor. Caso esteja, mostre também sua posição.
Exercício 7 – Alteração de valor. Faça um programa que leia cinco números inteiros. Depois, solicite uma posição e um novo valor. O programa deverá verificar se a posição é válida, substituir o valor e apresentar o vetor atualizado.
Exercício 8 – Notas dos alunos. Faça um programa que leia o nome e a nota de dez alunos utilizando dois vetores. Apresente: o nome e a nota de todos os alunos; a média da turma; os alunos com nota maior ou igual a 60; a quantidade de alunos abaixo da média.
Exercício 9 – Temperaturas. Faça um programa que armazene a temperatura registrada durante sete dias. Apresente: a média; a maior temperatura; a menor temperatura; quantos dias tiveram temperatura acima da média.
Exercício 10 – Cadastro de produtos. Faça um programa que leia o nome e o preço de cinco produtos utilizando vetores paralelos. Apresente: todos os produtos cadastrados; o produto mais caro; o produto mais barato; a média dos preços; os produtos com preço abaixo da média.
Capítulo 6 – Estrutura de Dados: Matriz
6.1 – O que é uma matriz
Uma matriz é uma variável composta homogênea e multidimensional. Todos os elementos são do mesmo tipo, possuem o mesmo nome e são alocados sequencialmente na memória. O que distingue cada elemento são os índices. O mais comum são duas dimensões — linhas e colunas —, como em uma planilha eletrônica.
Características:
- é uma estrutura de dados composta multidimensional;
- cada valor ocupa uma posição identificada por um índice para cada dimensão;
- permite acesso direto a qualquer elemento usando
[linha][coluna]; - representa naturalmente dados tabulares (tabelas, planilhas) e serve de base para aplicações como imagens, gráficos e cálculos matemáticos.
Diferença entre variável simples, vetor e matriz
| Estrutura | Dimensão | Armazena | Exemplo prático | Declaração em C | Acesso em C |
|---|---|---|---|---|---|
| Variável simples | 0D | 1 valor | A nota de um aluno | float nota; | nota |
| Vetor | 1D | Vários valores do mesmo tipo | Notas de um aluno | float notas[4]; | notas[2] (3ª nota) |
| Matriz | 2D (ou mais) | Vários valores do mesmo tipo | Tabela de notas de vários alunos | float notas[3][4]; | notas[1][3] (2º aluno, 4ª nota) |
6.2 – Declaração de uma matriz
Para declarar uma matriz em C, informamos o tipo, o nome e a quantidade de posições de cada dimensão, cada uma em seu próprio colchete:
tipo nomeMatriz[linhas][colunas];
float notas[3][4]; // 3 linhas (alunos) e 4 colunas (notas)
| Portugol (VisuAlg) | C |
|---|---|
notas: vetor[1..3, 1..4] de real | float notas[3][4]; |
notas[2,4] | notas[1][3] |
leia(notas[i,j]) | scanf("%f", ¬as[i][j]); |
Observação: no VisuAlg não existe posição zero. Em C, linhas e colunas começam em 0: em
float notas[3][4];, as linhas vão de 0 a 2 e as colunas de 0 a 3.
6.3 – Acesso aos elementos
notas[0][0] = 7.5; notas[0][1] = 8.0; notas[0][2] = 9.0; notas[0][3] = 6.0;
notas[1][0] = 6.0; notas[1][1] = 9.5; notas[1][2] = 7.0; notas[1][3] = 4.0;
notas[2][0] = 5.0; notas[2][1] = 3.0; notas[2][2] = 3.0; notas[2][3] = 9.0;
| Coluna 0 (1ª nota) | Coluna 1 (2ª nota) | Coluna 2 (3ª nota) | Coluna 3 (4ª nota) | |
|---|---|---|---|---|
| Linha 0 (1º aluno) | 7.5 | 8.0 | 9.0 | 6.0 |
| Linha 1 (2º aluno) | 6.0 | 9.5 | 7.0 | 4.0 |
| Linha 2 (3º aluno) | 5.0 | 3.0 | 3.0 | 9.0 |
notas[1][0] acessa o segundo aluno em sua primeira nota: o valor 6.0.
Também é possível inicializar a matriz na declaração:
float notas[3][4] = {
{7.5, 8.0, 9.0, 6.0},
{6.0, 9.5, 7.0, 4.0},
{5.0, 3.0, 3.0, 9.0}
};
6.4 – Leitura e escrita em matrizes
Para preencher ou exibir uma matriz, usamos dois laços: o laço externo (i) controla as linhas e o laço interno (j) controla as colunas.
Exemplo – Ler 4 notas de 3 alunos e apresentar na tela:
// Descrição : Programa para apresentar os conceitos de matriz
#include <stdio.h>
int main() {
float notas[3][4];
int i, j;
// Seção de entrada de dados
for (i = 0; i < 3; i++) {
printf("Forneca as notas do %d aluno\n", i + 1);
for (j = 0; j < 4; j++) {
printf("Digite a %d nota: ", j + 1);
scanf("%f", ¬as[i][j]);
}
}
// Seção para apresentar os dados
for (i = 0; i < 3; i++) {
printf("O %d aluno tirou as notas\n", i + 1);
for (j = 0; j < 4; j++) {
printf("%d nota: %.1f\n", j + 1, notas[i][j]);
}
}
return 0;
}
Observação: a necessidade de dois laços se dá porque a matriz possui duas dimensões. O laço externo (
i) percorre as linhas; o interno (j) percorre as colunas. Essa combinação permite visitar cada célula[i][j].
Área de visualização (tela):
Forneca as notas do 1 aluno
Digite a 1 nota: 10
Digite a 2 nota: 9
Digite a 3 nota: 8
Digite a 4 nota: 7
Forneca as notas do 2 aluno
...
O 1 aluno tirou as notas
1 nota: 10.0
2 nota: 9.0
3 nota: 8.0
4 nota: 7.0
...
Memória após a leitura:
notas[0][0] = 10 notas[0][1] = 9 notas[0][2] = 8 notas[0][3] = 7
notas[1][0] = 7 notas[1][1] = 9 notas[1][2] = 8 notas[1][3] = 7
notas[2][0] = 10 notas[2][1] = 8 notas[2][2] = 9 notas[2][3] = 7
6.5 – Exibindo a matriz em formato de tabela
for (i = 0; i < 3; i++) {
for (j = 0; j < 4; j++) {
printf("%6.1f", notas[i][j]); // 6 posições, 1 casa decimal
}
printf("\n"); // pula linha ao final de cada linha da matriz
}
6.6 – Média de cada aluno (cálculo por linha)
#include <stdio.h>
int main() {
float notas[3][4];
float soma, media;
int i, j;
for (i = 0; i < 3; i++) {
printf("Forneca as notas do %d aluno\n", i + 1);
for (j = 0; j < 4; j++) {
printf("Digite a %d nota: ", j + 1);
scanf("%f", ¬as[i][j]);
}
}
for (i = 0; i < 3; i++) {
soma = 0; // reinicia o acumulador para cada aluno
for (j = 0; j < 4; j++) {
soma = soma + notas[i][j];
}
media = soma / 4;
printf("Media do %d aluno: %.2f\n", i + 1, media);
}
return 0;
}
Atenção: o acumulador
somaé zerado dentro do laço das linhas, para que a soma de um aluno não se misture com a do próximo.
Atividades de fixação
- Leia uma matriz 3×3 de inteiros e mostre-a em formato de tabela.
- Leia uma matriz 4×4 de inteiros e mostre a soma de todos os elementos.
- Leia uma matriz 3×3 e mostre os elementos da diagonal principal (onde
i == j). - Leia as 4 notas de 5 alunos e mostre a média de cada aluno e a média de cada avaliação (coluna).
- Leia uma matriz 3×4 e mostre o maior valor e a sua posição (linha e coluna).
Capítulo 7 – Procedimentos (funções void)
7.1 – O que são funções e procedimentos?
Imagine que você está escrevendo um livro. Se precisar repetir a mesma frase várias vezes, seria mais fácil dar um nome a ela e “chamar” esse nome sempre que precisar.
Funções e procedimentos são blocos de código com uma tarefa específica e um nome. Você escreve o código uma vez e pode usá-lo quantas vezes quiser.
Por que usar?
- Organização: o código fica mais limpo e fácil de entender;
- Reaproveitamento: não é preciso repetir o mesmo código;
- Manutenção: se a lógica mudar, altera-se em um único lugar.
Curiosidade: o próprio
main()é uma função! É a função por onde o programa começa.
7.2 – Procedimentos em C
Um procedimento executa uma ação e não retorna valor. Em C, não existe a palavra procedimento: usamos uma função do tipo void (“vazio”), indicando que ela não devolve nada.
| Portugol (VisuAlg) | C |
|---|---|
procedimento Saudacao | void saudacao() { |
var (variáveis locais) | declarações dentro das chaves |
inicio … fimprocedimento | { … } |
chamada: Saudacao() | chamada: saudacao(); |
void nome_do_procedimento() {
// Declaração de variáveis locais, se houver
// Código do procedimento
}
// Para chamar o procedimento: nome_do_procedimento();
Exemplo prático – mensagem de boas-vindas:
// Descrição : Exemplo de procedimento simples
#include <stdio.h>
// Seção de procedimentos e funções
void saudacao() {
printf("Ola! Seja bem-vindo(a) ao meu programa.\n");
printf("Este e um procedimento simples.\n");
}
// Corpo do programa principal
int main() {
printf("--- Inicio do Programa Principal ---\n\n");
saudacao(); // Chamando o procedimento
printf("\n--- Fim do Programa Principal ---\n");
return 0;
}
7.3 – Organizando as listas de exercícios com menu
Imagine uma lista com três exercícios:
| Procedimento | Responsabilidade |
|---|---|
exercicio01() | Executar o exercício 01 |
exercicio02() | Executar o exercício 02 |
exercicio03() | Executar o exercício 03 |
O menu permite escolher o exercício. O procedimento contém a resolução: leitura dos dados, processamento e apresentação do resultado.
Criar um procedimento não faz com que ele seja executado automaticamente. É preciso chamá-lo pelo nome.
7.4 – Como escrever um procedimento em C
void exercicio01() {
float numero1, numero2, soma;
printf("Digite o primeiro numero: ");
scanf("%f", &numero1);
printf("Digite o segundo numero: ");
scanf("%f", &numero2);
soma = numero1 + numero2;
printf("Soma: %.2f\n", soma);
}
| Parte do código | Significado |
|---|---|
void exercicio01() | Define o nome do procedimento; void indica que não há retorno. |
float numero1, numero2, soma; | Variáveis locais, usadas somente nesse exercício. |
{ e } | Marcam o começo e o final do procedimento. |
scanf, cálculo e printf | Realizam a tarefa do exercício. |
As variáveis declaradas dentro do procedimento são locais: pertencem àquele procedimento.
Nesta atividade usaremos procedimentos sem parâmetros: os parênteses ficam vazios e os dados são lidos com scanf dentro de cada procedimento. Quando dizemos que o procedimento não retorna valor, significa que ele não entrega um valor para uma atribuição: chamamos com exercicio01();, e não escrevemos resultado = exercicio01();.
7.5 – Onde colocar e como chamar o procedimento
Em C, assim como no VisuAlg, os procedimentos ficam antes do programa principal (main):
#include <stdio.h>
void exercicio01() {
float numero1, numero2, soma;
printf("Digite o primeiro numero: ");
scanf("%f", &numero1);
printf("Digite o segundo numero: ");
scanf("%f", &numero2);
soma = numero1 + numero2;
printf("Soma: %.2f\n", soma);
}
// Início do programa principal
int main() {
printf("Vamos executar o exercicio 01!\n");
exercicio01();
printf("O exercicio terminou.\n");
return 0;
}
A execução acontece nesta ordem:
- Começa no
maine exibe a primeira mensagem; - Encontra
exercicio01();e executa os comandos desse procedimento; - Ao chegar ao
}do procedimento, volta para o comando seguinte à chamada; - Exibe “O exercicio terminou.” e encerra.
Atenção: se o procedimento for escrito depois do
main, o compilador não o conhecerá no momento da chamada. Nesse caso, seria preciso declarar o protótipovoid exercicio01();antes domain. Para simplificar, escreva sempre os procedimentos antes domain.
7.6 – Exemplo completo: uma lista com menu
Agora vamos reunir dois exercícios no arquivo lista01.c:
- Exercício 01: somar dois números;
- Exercício 02: calcular a área de um retângulo.
// Arquivo : lista01.c
// Descrição : Lista de exercícios organizada com menu e procedimentos
#include <stdio.h>
// Exercicio 01 - Somar dois numeros
void exercicio01() {
float numero1, numero2, soma;
printf("--- EXERCICIO 01: SOMA ---\n");
printf("Digite o primeiro numero: ");
scanf("%f", &numero1);
printf("Digite o segundo numero: ");
scanf("%f", &numero2);
soma = numero1 + numero2;
printf("Soma: %.2f\n", soma);
}
// Exercicio 02 - Calcular a area de um retangulo
void exercicio02() {
float base, altura, area;
printf("--- EXERCICIO 02: AREA ---\n");
printf("Digite a base em metros: ");
scanf("%f", &base);
printf("Digite a altura em metros: ");
scanf("%f", &altura);
area = base * altura;
printf("Area: %.2f m2\n", area);
}
// Programa principal: menu e chamadas
int main() {
int opcao;
do {
printf("\n");
printf("==============================\n");
printf(" LISTA 01\n");
printf("==============================\n");
printf("1 - Somar dois numeros\n");
printf("2 - Calcular a area do retangulo\n");
printf("0 - Sair\n");
printf("Escolha uma opcao: ");
scanf("%d", &opcao);
printf("\n");
switch (opcao) {
case 1:
exercicio01();
break;
case 2:
exercicio02();
break;
case 0:
printf("Programa encerrado.\n");
break;
default:
printf("Opcao invalida! Tente novamente.\n");
}
} while (opcao != 0);
return 0;
}
Entendendo o menu
| Comando | O que faz |
|---|---|
scanf("%d", &opcao); | Recebe a escolha do usuário. |
switch (opcao) | Seleciona o case correspondente ao número digitado. |
exercicio01(); | Chama o procedimento do exercício 01. |
exercicio02(); | Chama o procedimento do exercício 02. |
default: | Mostra uma mensagem se a opção não existir. |
do { ... } while (opcao != 0); | Repete o menu até o usuário escolher sair (Portugol: repita ... ate opcao = 0). |
A variável opcao fica no main, pois é usada pelo menu. As variáveis de cálculo ficam dentro dos respectivos procedimentos.
Vamos acompanhar uma execução?
- O usuário digita 1 no menu;
- O
case 1chamaexercicio01(); - O usuário informa os números 5 e 3;
- O procedimento mostra a soma 8.00 e termina;
- A execução volta ao menu. Como a opção é diferente de 0, a repetição continua;
- O usuário pode executar outro exercício, repetir o mesmo ou digitar 0 para sair.
7.7 – Como adaptar um exercício que você já resolveu
- Crie um procedimento com o número do exercício, antes do
main; - Coloque as variáveis do exercício dentro do procedimento;
- Coloque a resolução entre as chaves do procedimento;
- Acrescente a opção correspondente nas mensagens do menu;
- Acrescente um
caseque chame o procedimento.
Para incluir o exercício 03, por exemplo:
// Junto das mensagens com as opcoes:
printf("3 - Descricao do exercicio 03\n");
// Dentro do switch, antes do default:
case 3:
exercicio03();
break;
Esse trecho mostra apenas o que acrescentar; ele não é um programa completo.
Não copie um programa inteiro para dentro do procedimento. Cada arquivo terá somente um
maine um único#include <stdio.h>no topo.
7.8 – Cuidados importantes
- Use o mesmo nome na declaração e na chamada (C diferencia maiúsculas de minúsculas);
- Coloque os procedimentos antes do
main; - Não esqueça os parênteses e o ponto e vírgula na chamada:
exercicio01();; - Não esqueça o
break;em cadacasedo menu; - Inicialize acumuladores e contadores dentro do procedimento, antes de usá-los.
Capítulo 8 – Funções
8.1 – O que são funções?
Funções são partes de um programa que recebem um nome, realizam uma tarefa e devolvem um resultado para o trecho que as chamou. Elas podem receber dados para realizar essa tarefa.
Imagine uma calculadora com uma tecla chamada dobro: ao receber 5, devolve 10; ao receber 8, devolve 16.
| Valor recebido | Processamento | Resultado devolvido |
|---|---|---|
| 5 | 5 × 2 | 10 |
| 8 | 8 × 2 | 16 |
| 3 | 3 × 2 | 6 |
8.2 – Estrutura básica de uma função em C
Em C, o tipo do retorno vem antes do nome da função:
tipo_do_retorno nome(parametros) {
// variáveis locais, quando necessárias
// comandos da função
return resultado;
}
| Portugol (VisuAlg) | C |
|---|---|
funcao dobro(valor: inteiro): inteiro | int dobro(int valor) { |
retorne valor * 2 | return valor * 2; |
fimfuncao | } |
resultado <- dobro(numero) | resultado = dobro(numero); |
8.3 – Tipos de funções quanto aos parâmetros
| Tipo de função | Recebe dados na chamada? | Devolve um resultado? |
|---|---|---|
| 1. Sem parâmetros e com retorno | Não. | Sim. |
| 2. Com parâmetros e com retorno | Sim, um ou mais valores. | Sim. |
8.3.1 – Função sem parâmetros e com retorno
float fornecerPi() {
return 3.14159;
}
Recebe: nenhum parâmetro. Retorna: um valor do tipo float.
float valor;
valor = fornecerPi();
printf("%f\n", valor);
Diferença para o VisuAlg: em C, os parênteses são obrigatórios na chamada, mesmo sem parâmetros:
fornecerPi().
8.3.2 – Função com parâmetros e com retorno
int dobro(int valor) {
return valor * 2;
}
| Parte | Significado |
|---|---|
int (antes do nome) | Indica que o resultado devolvido será inteiro. |
dobro | Nome da função. |
int valor | Parâmetro que recebe um número inteiro. |
{ e } | Delimitam os comandos da função. |
return valor * 2; | Devolve o resultado para quem chamou a função. |
Definir uma função não a executa. Para utilizá-la, precisamos fazer uma chamada.
8.4 – Como chamar uma função
Escreva a função antes do main:
#include <stdio.h>
int dobro(int valor) {
return valor * 2;
}
int main() {
int numero, resultado;
numero = 5;
resultado = dobro(numero);
printf("Dobro: %d\n", resultado);
return 0;
}
O programa exibe Dobro: 10.
Acompanhe a execução
- O programa começa no
main, enumerorecebe 5; - A chamada
dobro(numero)envia o valor 5 para a função; - O parâmetro
valorrecebe 5, e a função calcula5 * 2; - A função devolve 10, e esse valor é guardado em
resultado; - O
printfmostra o resultado na tela.
Na atribuição resultado = dobro(numero);, o lado direito é resolvido primeiro; depois, o valor devolvido é guardado na variável à esquerda.
Reutilize a mesma função
resultado = dobro(3);
printf("%d\n", resultado);
resultado = dobro(8);
printf("%d\n", resultado);
Esse trecho exibe 6 e depois 16. A função foi escrita uma vez e utilizada duas vezes.
Pense: se a chamada fosse
dobro(9), qual valor seria devolvido?
8.5 – Parâmetros e argumentos
Parâmetro é a variável indicada na definição da função. Argumento é o valor ou a expressão enviada na chamada.
- Na definição
int dobro(int valor),valoré o parâmetro; - Na chamada
dobro(5), o argumento é 5; - Na chamada
dobro(numero), enviamos o valor guardado emnumero.
Uma função com dois parâmetros
int somar(int a, int b) {
return a + b;
}
Diferença para o VisuAlg: em C, cada parâmetro tem o seu tipo, mesmo que sejam iguais:
int a, int b(e nãoint a, b).
| Chamada | a recebe | b recebe | Retorno |
|---|---|---|---|
somar(4, 6) | 4 | 6 | 10 |
somar(10, 3) | 10 | 3 | 13 |
somar(0, 8) | 0 | 8 | 8 |
int primeiro, segundo, total;
primeiro = 4;
segundo = 6;
total = somar(primeiro, segundo);
printf("Soma: %d\n", total);
Os nomes das variáveis enviadas não precisam ser iguais aos nomes dos parâmetros. O que importa é respeitar a quantidade, a ordem e os tipos. Os valores são copiados para os parâmetros, e o parâmetro valor de dobro pertence somente à função.
8.6 – Tipos de retorno das funções
| Portugol | C | O que a função devolve | Exemplo de resultado |
|---|---|---|---|
inteiro | int | Um número sem parte decimal | 10 |
real | float | Um número que pode ter parte decimal | 7.5 |
logico | bool | O resultado de uma verificação | true ou false |
caractere | const char * | Um texto | "Bem-vindo!" |
| (procedimento) | void | Nada | — |
8.6.1 – Função com retorno inteiro
As funções dobro e somar retornam valores do tipo int.
8.6.2 – Função com retorno real e variável local
float calcularMedia(float n1, float n2) {
float m;
m = (n1 + n2) / 2;
return m;
}
n1 e n2 são parâmetros, e m é uma variável local. A chamada calcularMedia(7, 8) devolve 7.5.
Exemplo completo com entrada de dados:
#include <stdio.h>
float calcularMedia(float n1, float n2) {
float m;
m = (n1 + n2) / 2;
return m;
}
int main() {
float nota1, nota2, media;
printf("Digite a primeira nota: ");
scanf("%f", ¬a1);
printf("Digite a segunda nota: ");
scanf("%f", ¬a2);
media = calcularMedia(nota1, nota2);
printf("Media: %.2f\n", media);
return 0;
}
Observe a divisão das tarefas: o main lê os dados e exibe o resultado; a função calcula e devolve a média.
8.6.3 – Função com retorno lógico
#include <stdbool.h>
bool ehPositivo(int numero) {
return numero > 0;
}
Recebe: um número inteiro. Retorna: um valor lógico.
bool resultadoLogico;
resultadoLogico = ehPositivo(4);
if (resultadoLogico) {
printf("verdadeiro\n");
} else {
printf("falso\n");
}
As chamadas ehPositivo(0) e ehPositivo(-3) devolvem false.
Observação: o
printfnão possui um formato próprio parabool. Se usarmosprintf("%d", resultadoLogico);, será exibido1(verdadeiro) ou0(falso). Por isso, no exemplo usamos umifpara mostrar o texto.
8.6.4 – Função com retorno de texto
const char *obterMensagem() {
return "Bem-vindo ao sistema!";
}
const char *mensagem;
mensagem = obterMensagem();
printf("%s\n", mensagem);
Observação: em C, um texto fixo é representado pelo tipo
const char *. Por enquanto, basta saber que esse é o tipo de retorno usado para devolver uma mensagem fixa e que ele é exibido com%s.
O tipo do parâmetro pode ser diferente do tipo do retorno
Em ehPositivo, o parâmetro é int, mas o retorno é bool. O primeiro tipo descreve o dado que entra; o segundo descreve o resultado que volta.
8.7 – Compare os exemplos
| Função em C | Quanto aos parâmetros | Tipo do retorno | Exemplo de chamada |
|---|---|---|---|
fornecerPi | Sem parâmetros | float | valor = fornecerPi(); |
dobro | Um parâmetro int | int | resultado = dobro(5); |
calcularMedia | Dois parâmetros float | float | media = calcularMedia(7, 8); |
ehPositivo | Um parâmetro int | bool | resultadoLogico = ehPositivo(4); |
obterMensagem | Sem parâmetros | const char * | mensagem = obterMensagem(); |
8.8 – Retornar não é o mesmo que exibir
O return entrega um resultado ao trecho que fez a chamada. O printf mostra uma informação na tela.
resultado = dobro(5); // guarda 10, mas não mostra nada
printf("%d\n", resultado); // agora sim, exibe 10
8.9 – Programa completo com todas as funções da aula
#include <stdio.h>
#include <stdbool.h>
float fornecerPi() {
return 3.14159;
}
int dobro(int valor) {
return valor * 2;
}
int somar(int a, int b) {
return a + b;
}
float calcularMedia(float n1, float n2) {
float m;
m = (n1 + n2) / 2;
return m;
}
bool ehPositivo(int numero) {
return numero > 0;
}
const char *obterMensagem() {
return "Bem-vindo ao sistema!";
}
int main() {
printf("%s\n", obterMensagem());
printf("Pi: %.5f\n", fornecerPi());
printf("Dobro de 9: %d\n", dobro(9));
printf("Soma de 4 e 6: %d\n", somar(4, 6));
printf("Media de 7 e 8: %.2f\n", calcularMedia(7, 8));
if (ehPositivo(-3)) {
printf("-3 e positivo\n");
} else {
printf("-3 nao e positivo\n");
}
return 0;
}
Observação: o valor retornado por uma função pode ser usado diretamente dentro de outro comando, como em
printf("%d\n", dobro(9));.
8.10 – Como planejar uma função simples
- Escolha uma tarefa pequena, como calcular o dobro ou somar dois números;
- Decida se a função precisa receber dados na chamada;
- Se precisar, defina os nomes e os tipos dos parâmetros;
- Defina o tipo do resultado que será devolvido;
- Escolha um nome que explique a tarefa;
- Escreva os comandos e utilize
returnpara devolver o resultado; - Faça a chamada e teste com valores cujo resultado você já conhece.
Antes de escrever, responda: quais dados entram, o que será feito com eles e qual resultado deve voltar?
8.11 – Dicas importantes
- Escreva as funções antes do
main; - Identifique se a função precisa receber parâmetros;
- Defina se o retorno será
int,float,bool,const char *ouvoid; - Lembre-se de chamar a função; apenas defini-la não executa seus comandos;
- Use nomes descritivos, como
calcularMediaeareaRetangulo; - Mantenha uma tarefa clara por função;
- Declare as variáveis auxiliares dentro da função quando forem usadas apenas nela;
- Use uma variável de tipo compatível para guardar o retorno;
- Confira o resultado com um cálculo feito à mão.
Atividades de fixação
- Crie a função
float precoComDesconto(float valor, float taxa)que devolve o preço com o desconto percentual aplicado. - Crie a função
bool ehPar(int numero)e use-a para informar se um número digitado é par ou ímpar. - Crie a função
const char *situacaoAluno(float media)que devolve"Aprovado"(média maior ou igual a 60) ou"Reprovado". - Crie a função
float areaRetangulo(float base, float altura). - Crie a função
int maiorDeTres(int a, int b, int c).
Apêndice – Tabela de equivalência Portugol × C
| Conceito | Portugol (VisuAlg) | C |
|---|---|---|
| Início do programa | Algoritmo "nome" … Inicio | #include <stdio.h> … int main() { |
| Fim do programa | Fimalgoritmo | return 0; } |
| Inteiro | inteiro | int |
| Real | real | float |
| Caractere (um) | caractere | char |
| Texto | caractere | char nome[50] |
| Lógico | logico | bool (<stdbool.h>) |
| Verdadeiro / Falso | verdadeiro / falso | true / false |
| Declaração | idade: inteiro | int idade; |
| Atribuição | idade <- 18 | idade = 18; |
| Saída | escreva(x) / escreval(x) | printf("%d", x); / printf("%d\n", x); |
| Entrada | leia(x) | scanf("%d", &x); |
| Casas decimais | media:4:2 | printf("%.2f", media); |
| Divisão inteira | div | / entre inteiros |
| Resto | % / mod | % |
| Potência | ^ / ** | pow(b, e) (<math.h>) |
| Igual / Diferente | = / <> | == / != |
| E / OU / NÃO | e / ou / nao | && / || / ! |
| Condicional | se ... entao ... senao ... fimse | if (...) { ... } else { ... } |
| Escolha | escolha ... caso ... outrocaso ... fimescolha | switch ... case ...: break; default: |
| Para | para i de 1 ate 10 faca ... fimpara | for (i = 1; i <= 10; i++) { ... } |
| Enquanto | enquanto (c) faca ... fimenquanto | while (c) { ... } |
| Repita | repita ... ate (c) | do { ... } while (!c); |
| Vetor | v: vetor[1..5] de inteiro | int v[5]; (índices 0 a 4) |
| Matriz | m: vetor[1..3,1..4] de real | float m[3][4]; |
| Acesso à matriz | m[i,j] | m[i][j] |
| Procedimento | procedimento p() ... fimprocedimento | void p() { ... } |
| Função | funcao f(x: inteiro): inteiro ... fimfuncao | int f(int x) { ... } |
| Retorno | retorne x | return x; |
| Comentário | // texto | // texto ou /* texto */ |
Conclusão
A Linguagem C exige mais detalhes do que o Portugol: tipos antes dos nomes, ponto e vírgula, chaves, & no scanf, índices começando em zero e break no switch. Porém, a lógica é exatamente a mesma. Se o algoritmo está correto em Portugol, a tradução para C é uma questão de conhecer a “gramática” da nova linguagem.
Links e telas de instalação podem mudar ao longo do tempo. Em caso de diferença visual, utilize sempre a página oficial indicada e procure a opção equivalente para o sistema operacional utilizado.
Índice por assunto
Os números indicam a seção da apostila (ex.: 5.15 = Capítulo 5, seção 15). Nos arquivos digitais, clique no número para ir direto ao conteúdo.
Assuntos de lógica de programação
A
- Acumulador (somar valores em uma variável) — 4.1, 5.11, 6.6
- Algoritmo – conceito — 1.1
- Alterar um valor do vetor — 5.20
- Ambiente de programação (instalação) — Cap. 0
- Argumento — 8.5
- Atividades de fixação / exercícios — 1.14, 2.4, 4.4, 5.26, 6.6, 8.11
- Atribuição — 1.8
B
C
- Capacidade do vetor — 5.21
- Chamada de função — 8.4
- Chamada de procedimento — 7.5
- Comentários — 1.4
- Condicional composta (se/senão) — 2.3.2
- Condicional encadeada (mais de duas possibilidades) — 2.3.3
- Condicional simples (se) — 2.3.1
- Constantes — 1.6
- Contador / contagem de valores — 4.2, 5.13
D
E
- Enquanto (estrutura) — 4.2
- Entrada de dados — 1.12
- Erros comuns com vetores — 5.24
- Escolha-caso (estrutura) — 3.1, 3.2
- Estrutura do programa — 1.4
- Execução de uma função passo a passo — 8.4
- Exibir os valores de um vetor — 5.9
- Exibir somente valores que atendem a uma condição — 5.14
- Exponenciação / potência — 1.9
F
- Função com parâmetros e com retorno — 8.3.2
- Função sem parâmetros e com retorno — 8.3.1
- Função – como planejar — 8.10
- Função – conceito — 8.1
- Função – estrutura básica — 8.2
I
- Identificadores (nomes de variáveis) — 1.7
- Indentação — 1.13
- Índice do vetor (começa em 0) — 5.2, 5.5
L
M
- Maior e menor valor no mesmo programa — 5.17
- Maior valor do vetor — 5.15
- Matriz – acesso aos elementos — 6.3
- Matriz – conceito — 6.1
- Matriz – declaração — 6.2
- Matriz – exibir em formato de tabela — 6.5
- Matriz – leitura e escrita (dois laços) — 6.4
- Média — 5.12, 5.23, 6.6, 8.6.2
- Menor valor do vetor — 5.16
- Menu de exercícios — 7.3, 7.6, 7.7
- Método para construção de algoritmos — 1.2
O
- Operador E — 2.2.1
- Operador NÃO — 2.2.3
- Operador OU — 2.2.2
- Operadores aritméticos — 1.9
- Operadores lógicos — 1.11, 2.2
- Operadores relacionais (comparação) — 1.10, 2.1
- Ordem inversa (percorrer o vetor de trás para frente) — 5.10
P
- Par ou ímpar — 5.13
- Para (estrutura) — 4.1
- Parâmetro — 8.5
- Passo / incremento do laço — 4.1
- Portugol × linguagem (tabela de equivalência) — Apêndice
- Posição do maior valor — 5.18
- Primeiro programa (Portugol → linguagem) — 1.3
- Procedimento – como escrever — 7.4
- Procedimento – conceito — 7.1, 7.2
- Procedimento – cuidados — 7.8
Q
- Qual estrutura de repetição escolher — 4.4
R
- Repetição – conceito e tipos — Cap. 4
- Repita (estrutura) — 4.3
- Resto da divisão — 1.9
- Retornar × exibir — 8.8
- Retorno de texto — 8.6.4
- Retorno inteiro — 8.6.1
- Retorno lógico — 8.6.3
- Retorno real — 8.6.2
S
T
V
- Variável local — 7.4, 8.6.2
- Variável simples × vetor × matriz — 5.3, 6.1
- Vetor – análise completa de notas — 5.23
- Vetor – conceito — 5.1
- Vetor – declaração — 5.4
- Vetor – resumo dos comandos — 5.25
- Vetores paralelos — 5.22
Comandos e recursos da linguagem C
Símbolos
!=(diferente) — 1.10, 2.1&&(e) — 2.2.1!(não) — 2.2.3\|\|(ou) — 2.2.2%(resto) — 1.9%49[^\n](ler nome com espaços) — 1.12, 5.22
A
- Acentos na saída (terminal) — Cap. 0
B
C
case— 3.1char(caractere) — 1.5, 2.2.1char nome[50](texto) — 1.5, 1.12char nomes[5][50](vetor de textos) — 5.4, 5.22- Compilação com avisos (
-Wall) — Cap. 0 const— 1.6const char *(retorno de texto) — 8.6.4
D
E
F
G
gcc(compilar) — Cap. 0
I
L
- Lixo de memória — 5.24
M
main()— 1.4
N
P
R
return— 8.2
S
V
void— 7.2
W
while— 4.2
Símbolos
=×==— 1.10
Copyleft 🄯 2026 - Professor Mauro Borges França.