12 AiB Algoritmia+LingC
12 AiB Algoritmia+LingC
Aplicações Informáticas B
Introdução à programação
(Algoritmia + Linguagem C)
Atualizado em 21/09/2022
2 25/09/2022
Conteúdos e objetivos
Conceitos de Linguagem, Sintaxe, Semântica, Gramática e
Expressão.
Conceito de algoritmo: compreender a noção de algoritmo.
Elaborar algoritmos simples através de pseudocódigo,
fluxogramas e linguagem natural.
Distinção e identificação de linguagens naturais e linguagens
formais.
Utilizar de uma linguagem de programação imperativa
codificada para elaborar programas simples, em ambiente de
consola.
Identificar e utilizar diferentes tipos de dados em programas.
Reconhecer diferentes operadores aritméticos, lógicos,
3 relacionais e respetivas regras de prioridade. 25/09/2022
Conteúdos e objetivos
Desenvolver programas que incluam estruturas de controlo
de seleção e estruturas repetitivas com vista à resolução de
problemas de baixa complexidade.
Utilizar funções em programas.
Distinguir diferentes formas de passagem de parâmetros a
funções.
Executar operações básicas com arrays.
Estudo e utilização de um ambiente integrado de
desenvolvimento de programas para edição, compilação e
teste de programas.
Implementar Algoritmos de complexidade crescente.
4 25/09/2022
Ferramentas/recursos a utilizar
Algoritmia (Análise de problemas e pseudocódigo)
Notepad (Bloco de Notas do Windows ou equivalente)
Dia (desenho de Fluxogramas)
https://projects.gnome.org/dia/
Codeblocks (Ambiente de desenvolvimento C/C++)
http://www.codeblocks.org/
Outras ferramentas alternativas e/ou complementares
Notepad++ (Editor de Linguagens de programação)
http://notepad-plus-plus.org/
CygWin – Ferramentas GNU e Open Source similar a uma distribuição
Linux (Linha de comandos, Compilador C/C++, etc.) integrável no
Codeblocks
https://cygwin.com/
5 25/09/2022
Definição de Linguagem
Linguagem é o sistema através do qual o homem comunica as
suas ideias e sentimentos, seja pela fala, escrita ou outros
meios convencionais.
As linguagens artificiais (criadas para um fim específico, tal
como, a lógica matemática ou a informática) também são
designadas por linguagens formais.
A linguagem de programação de computadores é uma
linguagem formal que consiste em códigos e regras
específicas que correspondem a instruções para
computadores.
6 25/09/2022
Sintaxe
Sintaxe é a forma como as instruções de uma linguagem são
escritas, mas sem atender ao seu significado.
Na sintaxe de uma linguagem de programação existem
descrições formais, que são chamadas de lexemas. Os
lexemas de uma LP incluem os seus identificadores, palavras
reservadas, literais e operadores.
Um símbolo de uma linguagem é uma categoria de lexemas e
é denominado token.
As gramáticas descrevem naturalmente a estrutura sintática
hierárquica das linguagens que definem. Estas estruturas são
designadas por árvores de análise.
7 25/09/2022
Semântica
A Semântica é complementar a sintaxe. Corresponde à
descrição do significado das instruções válidas de uma
linguagem.
Por exemplo, a sintaxe da instrução if da linguagem C é:
if () {}
e sua semântica é:
“se o valor da expressão for verdadeiro, as instruções
incorporadas serão executadas pelo programa”.
É através da semântica que se consegue utilizar melhor e
validar uma linguagem.
8 25/09/2022
Algoritmia e Fluxogramas
Um algoritmo é uma sequência finita de instruções bem definidas
e não ambíguas, cada uma das quais pode ser executada
mecanicamente num período de tempo finito e com uma
quantidade de esforço finita.
O conceito de algoritmo é frequentemente ilustrado pelo
exemplo de uma receita culinária, embora muitos algoritmos
sejam mais complexos.
Eles podem repetir passos (fazer iterações) ou necessitar de
decisões (tais como comparações ou lógica) até que a tarefa seja
completada.
Um algoritmo corretamente executado não irá resolver um
problema se estiver implementado incorretamente ou se não for
apropriado ao problema.
9 25/09/2022
Algoritmo
Um algoritmo não representa, necessariamente, um programa de
computador, mas sim os passos necessários para realizar uma tarefa.
A sua implementação pode ser feita por um computador, por outro tipo
de autómato ou mesmo por um ser humano.
Diferentes algoritmos podem realizar a mesma tarefa usando um
conjunto diferenciado de instruções em mais ou menos tempo, espaço
ou esforço do que outros.
Tal diferença pode ser reflexo da complexidade computacional aplicada,
que depende de estruturas de dados adequadas ao algoritmo.
Por exemplo, um algoritmo para vestir pode especificar que se vista
primeiro as meias e os sapatos antes de vestir as calças enquanto outro
algoritmo especifica que se deve primeiro vestir as calças e depois as
meias e os sapatos.
É claro que o primeiro algoritmo é mais difícil de executar que o
segundo apesar de ambos conduzirem ao mesmo resultado.
10 25/09/2022
Outros exemplos algorítmicos
1. Preparar um bolo
2. Trocar um pneu de um automóvel
3. Apertar os atacadores dos sapatos
4. Andar de bicicleta
5. Levantar dinheiro numa caixa Multibanco
6. Etc..
11 25/09/2022
Programa de computador
Um programa de computador é essencialmente um algoritmo que
diz ao computador os passos específicos e em que ordem eles
devem ser executados, como por exemplo, os passos a serem
tomados para calcular as notas que serão impressas nos boletins
dos alunos de uma escola.
Logo, o algoritmo pode ser considerado uma sequência de
operações que podem ser simuladas por uma máquina de Turing
completa.
Quando os procedimentos de um algoritmo envolvem o
processamento de dados, a informação é lida de uma fonte de
entrada, processada e retornada sob novo valor após
processamento, o que geralmente é realizado com o auxílio de
uma ou mais estrutura de dados.
12 25/09/2022
Implementação
A maioria dos algoritmos é desenvolvida para ser implementada
em um programa de computador.
Apesar disso eles também podem ser implementados por outros
modos tais como
uma rede neural biológica (tal como no cérebro quando
efetuamos operações aritméticas)
em circuitos elétricos ou
até mesmo em dispositivos mecânicos.
Para programas de computador existe uma grande variedade de
linguagens de programação, cada uma com características
específicas que podem facilitar a implementação de determinados
algoritmos ou atender a propósitos mais gerais.
13 25/09/2022
Conceito de Fluxograma
A maneira mais simples de se pensar um algoritmo é como
uma lista de procedimentos bem definida, na qual as
instruções são executadas passo a passo a partir do começo da
lista.
Esta ideia que pode ser facilmente visualizada através de um
fluxograma.
Fluxograma é um tipo de diagrama que pode ser entendido
como uma representação esquemática de um processo,
muitas vezes feito através de gráficos que ilustram de forma
simplificada a transição de informações entre os elementos
que o compõem.
14 25/09/2022
Fluxograma algorítmico simples
15 25/09/2022
Fluxograma para troca de meias
16 25/09/2022
Símbolos de um fluxograma
Iniciador Ponto de conexão
Terminador
Linha
Entrada e/ou
saída de dados
Seta
Decisão Conexão em
ângulos retos
17 25/09/2022
Como abordar um problema
Um meio de exibir um algoritmo é através da implementação
por pseudocódigo em português estruturado.
Os passos a dar para obter a sequência de ações para executar
uma tarefa:
1. Determinar qual deve ser a saída.
2. Identificar os dados, ou entrada, necessária para obter a saída.
3. Determinar como processar a entrada para obter a saída
desejada.
Representação esquemática:
Entrada de Saída de
Processamento
dados dados
18 25/09/2022
Exemplo: fazer um bolo de maçã
Saída
bolo de maçã
Entrada
ingredientes e respetivas quantidades que são
determinados por aquilo que se quer fazer
Processamento
a receita indica os passos a dar, ou seja, como se deve
proceder para preparar o bolo (misturar os ingredientes
na quantidade certa e na ordem correta, levar ao forno
a uma dada temperatura durante um determinado
período de tempo)
19 25/09/2022
Exemplo prático: Problema
Considere-se o seguinte problema:
Dados 2 números inteiros, calcular a sua soma.
Resultados pretendidos no problema
1 número inteiro que seja a soma dos 2 números dados
Dados de entrada do problema
2 números inteiros (por exemplo, o numA e o numB)
Ação pretendida
Somar os dois números: “soma numA + numB”
A expressão “soma numA + numB” significa:
a variável soma toma o valor da adição do valor da variável
numA com o valor da variável numB
20 25/09/2022
Exemplo prático: Análise do problema
Entrada de Saída de
Processamento
dados dados
numA
numB
soma
21 25/09/2022
Exemplo prático: Fluxograma
Na passagem da análise do
problema para o fluxograma
terão que ser
lidos valores para as
variáveis de entrada e
no final
escrever os valores das
variáveis de saída.
22 25/09/2022
Exemplo prático: Pseudocódigo
Algoritmo Soma2Inteiros
Variáveis
soma,numA,numB: Inteiro
Inicio
Ler(numA)
Ler(numB)
soma numA + numB Na passagem do fluxograma
para o pseudocódigo as
Escrever(soma)
variáveis terão de
Fim ser declaradas.
23 25/09/2022
Exemplo prático: Linguagem C
#include <stdio.h>
int numA, numB, soma;
int main()
{
Na passagem do printf("Digite um numero: ");
pseudocódigo para o scanf("%i", &numA);
código C deverão ser
adicionadas printf("Digite outro numero: ");
mensagens de scanf("%i", &numB);
comunicação soma = numA + numB;
com o utilizador
do programa. printf("A soma e’ %i", soma);
return 0;
}
24 25/09/2022
Exercício 1
Cada aluno deverá recorrer às ferramentas indicadas no início para
editar a solução do problema atrás apresentado de modo a treinar
a utilização destas ferramentas. O aluno deverá:
1. Abrir um documento no Bloco de Notas (ou Notepad++),
denominado “Algoritmo.txt” onde deverá registar o enunciado do
problema e efetuar a respetiva análise.
2. Criar um documento com a aplicação Dia, denominado
“Fluxograma.dia”, onde deverá desenhar o fluxograma do
problema referido.
3. Acrescentar ao documento “Algoritmo.txt” o pseudocódigo da
resolução do problema.
4. Criar um projeto em Codeblocks, denominado “Soma2Numeros”,
onde deverá implementar a solução do problema em linguagem C.
25 25/09/2022
Exercício 2
Criar um programa que dado um número inteiro
calcule o seu dobro.
a) Análise do problema:
Entrada → Processamento → Saída
b) Fluxograma
c) Pseudocódigo
d) Código em Linguagem C
Nota: A multiplicação representa-se
em pseudocódigo por x (letra xis)
e em linguagem C por * (asterisco)
26 25/09/2022
Pseudocódigo: atribuição
Quando escrevemos código em português também
utilizamos símbolos na forma de pontuação e caracteres
especiais.
Sem estes seria difícil representar tudo o que é necessário
numa linguagem de programação.
Por exemplo, para representar a atribuição de valores a
variáveis, tal como foi visto anteriormente, usam-se símbolos
tais como ←, << ou <-, designados como operadores de
atribuição.
soma <- numA + numB
27 25/09/2022
Pseudocódigo: palavras reservadas
Há um conjunto de palavras chave que podem ser utilizadas em
pseudocódigo tal como são usadas em linguagens de programação.
Estas podem indicar operações de entrada ou saída de dados, ou
ainda operações de processamento.
Também são utilizadas para nomear variáveis e respetivos tipos de
dados.
Por exemplo, a palavra “Ler” pode ser utilizada para representar o
ato de ler alguma informação a partir do teclado do computador
ou a partir de um ficheiro alojado nalgum tipo de dispositivo de
armazenamento de informação (disco, rede, etc.):
Ler(numA)
28 25/09/2022
Pseudocódigo: tipos de dados
O tipo de dados pretende dizer ao programa de computador como
se pretende que determinado dado seja tratado.
Por exemplo, o dado “21032020” pode ser
um número de Cartão de Cidadão (identifica um cidadão e pode ser
usado para pesquisa ou ordenação),
uma data (21 de março de 2020)
ou um valor numérico sobre o qual se podem realizar cálculos.
É de máxima importância dizer ao programa como se pretende que
os dados sejam tratados por isso se deve especificar os tipos de dados
a utilizar.
Dados numéricos do tipo inteiro, declaram-se:
Inteiro numA, numB, soma
ou
numA, numB, soma: Inteiro
29 25/09/2022
Exercício 3 (total com IVA)
Dado o preço unitário de um produto e a respetiva
quantidade, calcular o total a pagar considerando que o IVA é
23%.
Algumas notas ao problema:
23% 23 / 100 = 0,23
Valores monetários são do tipo real, pelo que as variáveis devem
ser declaradas:
Pseudocódigo Linguagem C
preço: Real float preco;
33 25/09/2022
Conjunto de caracteres
Letras: a-z, A-Z, _
Dígitos: 0-9
Pontuação:
~ ! # % ^ & ( ) - + = : < > , . ? | / | { } [ ]
Caracteres de espaço: espaço, tabulação horizontal, tabulação vertical, form
feed, newline.
Newline indica o fim de uma linha de texto; não precisa de corresponder a
um simples carácter, todavia, por conveniência o C trata-o como tal.
Caracteres de espaço são ignorados a não ser como separadores de
palavras.
Podem ser usados caracteres multibyte (por exemplo, Unicode
introduzido com o último padrão C11) apesar de esta característica ainda
não estar largamente implementada.
34 25/09/2022
Designação de caracteres
Caracter Designação em português Designação em inglês
" Aspa Quotation mark/quotes
' Plica/Aspa simples Apostrophe/Single quote
& E (i) comercial Ampersand
# Cardinal Number sign
$ Cifrão Dollar sign
@ Arroba At sign
; Ponto-e-vírgula Semicolon
_ Hífen Underscore
| Barra vertical Vertical bar
\ Barra de escape Backslash
/ Barra de diretório Slash
35 25/09/2022
Palavras reservadas
O padrão C89 possui 32 palavras reservadas com significado
especial:
auto continue enum if short switch volatile
break default extern int signed typedef while
case do float long sizeof union char double for
register static unsigned const else goto return
struct void
O padrão C99 adicionou mais 5 palavras reservadas:
_Bool _Complex _Imaginary inline restrict
padrão C11 adicionou mais 7 palavras reservadas:
_Alignas _Alignof _Atomic _Generic _Noreturn
_Static_assert _Thread_local
36 25/09/2022
Elementos da linguagem
Identificadores
é uma sequência de letras, dígitos e underscores (_).
O primeiro carácter não pode ser um dígito.
Não podem ser usadas palavras reservadas.
Constantes
Inteiras (decimal, octal, hexadecimal)
Reais (parte inteira, ponto decimal, parte fracional)
Caracteres
um carácter é apresentado entre plicas, tal como 'x'.
um carácter corresponde a um inteiro (tabela de caracteres).
Strings
Em C, uma string é uma sequência de caracteres (array) e representa-se entre
“aspas”.
37 25/09/2022
Caracteres especiais em strings
Sequência com \ Descrição
\n Nova linha, mudança de linha (newline)
\t Tabulação horizontal
\\ Barra inclinada à esquerda (backslash)
\' Plica
\" Aspas
\? Interrogação
\a Campainha ou aviso sonoro (bell)
\0 Carácter nulo
40 25/09/2022
A função printf (saída de dados)
A função printf (que significa print formatado) escreve na saída
padrão (ecrã) uma sequência de dados formatados.
O formato geral da função printf é:
41 25/09/2022
Especificadores de formato %
Código Significado
%c Exibe um dado carácter no ecrã
%i Exibe um inteiro no ecrã
%f Exibe um ponto flutuante em formato decimal
%s Exibe uma string (array de caracteres com terminador nulo)
%% Exibe um sinal de %
%d Exibe um inteiro em formato decimal (equivalente a %i)
%i → 5
%f → 2.45
%c → 'A'
%s → "Ola mundo!"
42 25/09/2022
Dicas de formatação em printf
43 25/09/2022
A função scanf (entrada de dados)
A função scanf (que significa scan formatado) lê da entrada
padrão (teclado) uma sequência de dados formatados.
O formato geral da função scanf é:
46 25/09/2022
Tipos de dados básicos
char
é geralmente usado para conter valores definidos pelo conjunto de caracteres
ASCII. Valores fora desta gama podem ser manuseados de modo diferente por
diferentes compiladores.
int
usado para conter números inteiros, negativos ou positivos. A gama de valores
permitida por este tipo pode variar entre compiladores, sendo em geral, 32 bits.
float
usado para conter números reais no formato de vírgula flutuante, na notação
normal.
double
usado para conter números reais no formato de vírgula flutuante, na notação
científica, ou seja, com expoente base 10.
void
usado essencialmente em dois tipos de casos: declaração de funções que não
retornam qualquer valor (procedimento) ou para representar apontadores
genéricos, ou seja, que apontam para qualquer tipo de dados.
47 25/09/2022
Tipos de dados numéricos
Tipo de Tamanho Especi-
Descrição (precisão)
dados (bytes) -ficador
char 1 %c|%d|%i Inteiro ou caracter
short 2 %d|%i Inteiro curto
int 4 %d|%i Inteiro
long 4 ou 8 %ld Inteiro longo
long long 8 %lld Inteiro extra longo
float 4 %f Número real em vírgula-flutuante (6)
double 8 %f Número real em vírgula-flutuante longo (10)
long double 8 ou 16 %Lf Número real em vírgula-flutuante extra longo (10)
No caso dos tipos reais: float, double e long double, pode-se usar o
especificador %g ou %G para que o número seja exibido em notação
científica: 1234.56 será exibido como 1.234560E+003 25/09/2022
48
Inteiros com sinal
Por defeito todos os tipos inteiros em linguagem C são com
sinal (valores negativos e positivos)
Tal pode ser explicitamente especificado recorrendo à palavra
chave signed:
signed char sc; // -128 … +128
signed short ss; // -32768 … +32767
signed int si; // -2^31 … 2^31-1
signed long sl; // -2^31 … 2^31-1
signed long long sll; // -2^63 … 2^63-1
Pelo que o uso da palavra reservada signed é opcional, não
sendo habitualmente usada.
49 25/09/2022
Inteiros sem sinal
Se só é necessário guardar valores inteiros positivos, os tipos
inteiros podem ser declarados como unsigned (sem sinal),
permitindo assim duplicar a gama de valores permitidos:
unsigned char uc; // 0 … +255
unsigned short us; // 0 … +65535
unsigned int ui; // 0 … 2^32-1
unsigned long ul; // 0 … 2^32-1
unsigned long long ull; // 0 … 2^64-1
Os especificadores a utilizar nas funções printf e scanf são,
respetivamente:
Tipo de dados Especificador
unsigned char, short ou int %u
unsigned long %lu
50 unsigned long long %llu 25/09/2022
Variáveis em C
Uma variável uma localização em memória a que se atribui
um nome e que é usada para armazenar um valor que pode
ser modificado pelo programa.
Todas as variáveis devem ser declaradas antes de poderem ser
usadas.
A forma geral de uma declaração é:
tipo lista_de_variáveis;
onde tipo deve ser um tipo válido eventualmente combinado
com modificadores, e a lista_de_variáveis pode consistir num
ou mais nomes identificadores, separados por vírgula.
51 25/09/2022
Declaração de variáveis
Alguns exemplos de declarações:
int i, j, k;
short int si;
unsigned int ui;
double custo, lucro, perda;
Na declaração de variáveis pode-se fazer simultaneamente a
respetiva inicialização:
tipo nomeDaVariável = valor;
Alguns exemplos:
char c = 'a';
int primeiro = 0;
float custo = 132.25;
52 25/09/2022
Nomes das variáveis
Os nomes das variáveis não têm nada a ver com o seu tipo.
Devem ser descritivos do seu conteúdo.
Deve-se ter em conta que os nomes de variáveis:
só se podem usar letras, números e o underscore;
só podem começar por uma letra ou underscore;
maiúsculas e minúsculas são diferentes.
Por exemplo,
nome1, menorCusto e _letra são nomes válidos
maior-custo, 2nome e digito? não são nomes válidos
53 25/09/2022
Constantes em linguagem C
A primeira consiste no recurso ao pré-compilador, o qual, procede a
substituições de código antes de este ser compilado.
Para declarar a variável PI com o valor 3.14, fica:
#define PI 3.14
Sempre que em qualquer parte do programa for referido o nome da
constante (PI), o pré-compilador faz em cada um desses locais uma
substituição da palavra PI pelo valor respetivo.
Alternativamente, pode-se definir uma constante recorrendo à
palavra reservada const (introduzida com o padrão C89), que é um
modificador de acesso, a qual é processada pelo compilador e não
pelo pré-compilador.
Para fazer uma declaração equivalente à anterior, ficaria:
const float PI = 3.14;
que é a declaração de uma variável cujo valor inicial não pode ser
54 alterado. 25/09/2022
Constantes: nota importante
A declaração de uma constante no pré-compilador, sendo a
forma inicial de declarar constantes, tem a vantagem de não
consumir recursos de memória, pelo que é vantajosa em
sistemas com recursos limitados (por exemplo,
microcontroladores).
A declaração recorrendo a alocação de memória para a
constante não permite a utilização da constante em declaração
de variáveis globais, só podendo ser utilizada dentro de funções,
incluindo a função main.
const int MAX = 100;
int lista[MAX]; //error: variably modified 'lista' at file scope
55 25/09/2022
Resumo
Pseudocódigo Linguagem C
Algoritmo Título #include <stdio.h>
Constantes #define NOMEC valor
NOMEC = valor
Variáveis tipo nomeV;
nomeV: Tipo
Início int main()
Instruções {
Fim Instruções;
}
56 25/09/2022
Expressões em C
As expressões em C, são substancialmente mais gerais e mais
poderosas do que na maioria das outras linguagens de
programação.
As expressões são formadas a partir dos elementos atómicos:
dados e operadores.
Os dados podem ser representados por variáveis ou por
constantes.
Quanto aos operadores, o C possui também uma rica coleção
que será apresentada em seguida, onde se apresentarão
exemplos diversos, ilustrativos de como se constroem as
expressões em C.
57 25/09/2022
Operadores em C
Aritméticos
+, -, *, /, %
Atribuição
=, +=, -=, *=, /=, %=
Incremento/decremento
++, --
Comparação
==,!=, <, >, <=, >=
Lógicos
!, &&, ||
de Bits
&, |, ~, ^, <<, >>
58 25/09/2022
Operadores aritméticos
Operador Descrição Exemplo
- Negação (simétrico de um número) res = -a
+ Adição (soma de dois números) res = a + b
- Subtração (diferença entre dois números) res = a - b
* Multiplicação (produto de dois números) res = a * b
/ Divisão (quociente da divisão inteira) res = a / b
% Resto da divisão inteira (módulo) res = a % b
59 25/09/2022
Operadores aritméticos: notas
A divisão em linguagem C pode ser inteira:
5 / 2 = 2 (5 % 2 = 1)
Ou pode ser real:
5.0 / 2 = 2.5
A diferença entre uma e outra está no tipo de dados dos seus
operandos:
se os dois são inteiros (5 e 2) realiza-se uma divisão inteira
(podendo obter-se também o resto da divisão recorrendo ao
operador %.
Se pelo menos um dos operandos é real (5.0 e/ou 2.0), realiza-se
uma divisão real (neste caso o resto da divisão deixa de fazer
sentido).
60 25/09/2022
Outros operadores de atribuição
61 25/09/2022
Operadores de atribuição: notas
A variável do lado esquerdo do operador de atribuição,
quando este for composto (+=, -=, *=, /= ou %=, etc.),
recebe como valor o seu atual valor operacionado com todo o
lado direito da expressão. Por exemplo:
x += a + b / 2;
é equivalente a
x = x + (a + b / 2);
não esquecendo de reparar na utilização do parênteses.
Aconteceria exatamente o mesmo com qualquer outro
operador que fosse emparelhado com a atribuição.
62 25/09/2022
Resumo
Pseudocódigo Linguagem C
Atribuição ← ou <- =, +=, -=, *=, /=, %=
Operador adição + +
Operador subtração - -
Operador multiplicação x *
Operador divisão inteira DIV /
Operador resto da divisão MOD %
Operador divisão real / /
Notas:
5 DIV 2 = 2
5 MOD 2 = 1
5 / 2 = 2.5
Em C, a divisão só é real se pelo menos um dos operandos é um número real.
63 25/09/2022
Resumo (continuação)
Declaração de variáveis
Pseudocódigo Linguagem C
Variáveis // Variáveis
num, alturaMax: Inteiro int num, alturaMax;
custoUnitario, iva: Real float custoUnitario, iva;
Declaração de constantes
Pseudocódigo Linguagem C
Constantes // Constantes
PI = 3.14 #define PI 3.14
TAMANHO = 100 #define TAMANHO 100
// Alternativamente
const float PI = 3.14;
const int TAMANHO = 100;
64 25/09/2022
Estruturas de controlo
Um programa de computador é um conjunto de instruções
sequenciais, que define as ações a serem executadas e a
ordem pela qual essas ações devem ser executadas.
Essas ações incluem o que se chama transferência de
controlo, que permite que a instrução a ser executada não
seja a imediatamente a seguir, passando o controlo para outra
instrução ou bloco de instruções escrito noutra parte do
programa.
A transferência de controlo permite a ramificação dos
programas, representando sequências possíveis de instruções
que o computador haverá de executar, dependendo da
satisfação ou não das condições requeridas.
65 25/09/2022
Tipos de estruturas de controlo
Estruturas de sequência
as ações são executadas, uma de cada vez, de forma encadeada,
na ordem definida no algoritmo/programa (ver exemplo da
soma de 2 números inteiros)
Estruturas de seleção
a partir da verificação de uma condição, o programa realiza ou
não uma ação e volta à sequência normal do
algoritmo/programa.
Estruturas de repetição
um bloco de ações é repetido um número de vezes conforme se
deseje, e em seguida o controlo volta à sequência normal do
algoritmo/programa.
66 25/09/2022
Estrutura de controlo de sequência
As instruções/ações sucedem-se numa determinada sequência
instrução1;
instrução2;
...
...
...
instruçãoN;
67 25/09/2022
Exemplo (estrutura sequencial)
Enunciado:
Dados 2 números apresentar a sua soma.
Análise do problema:
numA
soma numA + numB soma
numB
68 25/09/2022
Fluxograma
69 25/09/2022
Pseudocódigo
Algoritmo Soma2Inteiros
Variáveis
numA, numB, soma: Inteiro
Inicio
Ler (numA)
Ler (numB)
soma numA + numB
Escrever (soma)
Fim
70 25/09/2022
Código em linguagem C
#include <stdio.h>
// Declaração de variáveis
int numA, numB, soma;
void main()
{
// Entrada de dados
printf ("Indique um número inteiro: ");
scanf ("%i", &numA);
printf ("Indique outro número inteiro: ");
scanf ("%i", &numB);
// Processamento
soma = numA + numB;
// Saída de resultados
printf ("%i + %i = %i", numA, numB, soma);
}
71 25/09/2022
Estruturas de controlo de seleção (if)
Esta estrutura permite realizar diferentes ações dependendo
de uma condição ser verdadeira ou falsa.
Uma condição é uma expressão cuja valor pode ser um valor
boleano (verdadeiro/falso).
Exemplos da linguagem comum:
“Se ainda houver bilhetes, vou ao cinema.”
“Se hoje chover, levo guarda-chuva; se não chover levo chapéu
de sol.”
“Se chegar em primeiro lugar, ganho a medalha de ouro; senão
se chegar em segundo lugar, ganho a medalha de prata; senão se
chegar em terceiro lugar, ganho a medalha de bronze; senão não
ganho nada”.
72 25/09/2022
Seleção simples (if)
A instrução/ação só se realiza se se verificar uma determinada
condição.
73 25/09/2022
Seleção (if - else)
A instrução1/ação1 só se realiza se se verificar uma determinada
condição, caso contrário, realiza-se a outra (instrução2/ação2).
if (condição)
Se condição Então {
instruções1 instruções1;
Senão }
instruções2 else
FimSe {
instruções2;
}
74 25/09/2022
Seleção múltipla (if - else if - else)
A instrução1/ação1 só se realiza se se verificar a condição1, caso
contrário, se a condição2 se verifica, realiza-se a instrução2/ação2,
senão realiza-se a instrução3/ação3.
if (condição1)
Se condição1 Então {
instruções1 instruções1;
Senão Se condição2 Então }
instruções2 else if (condição2)
Senão {
instruções3 instruções2;
FimSe }
else
{
instruções3;
}
75 25/09/2022
Seleção múltipla (if - else if - else)
77 25/09/2022
Fluxograma
78 25/09/2022
Pseudocódigo
Algoritmo MaiorDe2Inteiros
Variáveis
num1, num2, maior: Inteiro
Inicio
Ler (num1)
Ler (num2)
Se num1 > num2 Então
maior num1
Senão
maior num2
FimSe
Escrever (maior)
Fim
79 25/09/2022
Código em linguagem C
#include <stdio.h>
int num1, num2, maior;
void main()
{
printf ("Indique um número inteiro: ");
scanf ("%i", &num1);
printf ("Indique outro número inteiro: ");
scanf ("%i", &num2);
if (num1 > num2)
maior = num1;
else
maior = num2;
printf("O maior de %i e %i e' %i.\n", num1, num2,
maior);
}
80 25/09/2022
Notar que…
Quando temos uma única instrução, a estrutura if não precisa
de chavetas
if (num1 > num2)
maior = num1;
else
maior = num2;
Quando há mais que 1 instrução é obrigatório usar chavetas:
if (num1 > num2)
{
maior = num1;
menor = num2;
}
else
...
81 25/09/2022
Operadores relacionais (de comparação)
Operador Descrição Exemplo
== Igual a a == b
!= Diferente de a != b
< Menor que a < b
> Maior que a > b
<= Menor ou igual a a <= b
>= Maior ou igual a a >= b
82 25/09/2022
Operadores relacionais: notas
Alguns exemplos de avaliação de expressões com operadores
relacionais:
Expressão Leitura Valor lógico
5 == 6 5 igual a 6 Falso
5 != 6 5 diferente de 6 Verdadeiro
5 < 6 5 menor que 6 Verdadeiro
5 > 6 5 maior que 6 Falso
5 <= 6 5 menor ou igual a 6 Verdadeiro
5 >= 6 5 maior ou igual a 6 Falso
83 25/09/2022
Operadores lógicos
Considerar as variáveis
int a = 1; // verdadeiro
int b = 0; // falso
int res; // resultado
85 25/09/2022
Tipo Booleano em linguagem C
A linguagem C não possuía inicialmente um tipo de dados
lógico/booleano, ou seja, não possui um tipo de dados que assuma
só 2 valores: Verdadeiro ou Falso.
Em C, o valor inteiro 0 e todos os equivalentes são considerados
logicamente falsos (0, 0.0, '\0').
Todos os valores diferentes de zero são considerados logicamente
verdadeiros.
Ex:
A variável x é verdadeira se x != 0 (x diferente de 0)
-3 é verdadeiro
0.0 é falso
′\0′ (carácter nulo) é falso
86 25/09/2022
Como criar o tipo booleano em C
A linguagem C é tão flexível que permite simular a existência
de um tipo booleano.
Para isso basta:
// Usar diretiva define do pré-processador de C
#define bool int
#define TRUE 1 // equivalente a: const int TRUE=1;
#define FALSE 0 // equivalente a: const int FALSE=0;
87 25/09/2022
O tipo bool
O padrão C99 introduziu o tipo booleano para aumentar a
compatibilidade com o C++.
As variáveis deste tipo podem armazenar um valor booleano
cujo valor pode ser só 1 (true) ou 0 (false).
O tipo booleano é obtido usando a palavra reservada bool
definida na biblioteca stdbool.h:
#include <stdbool.h>
bool b = true;
Esta biblioteca também define true e false como sendo 1 e
0, respetivamente.
88 25/09/2022
Condições/expressões lógicas
Em C podemos construir expressões lógicas ou booleanas
recorrendo a praticamente tudo;
Todavia, os operadores relacionais e os operadores lógicos são
os principais elementos para a construção de expressões
lógicas.
Operadores relacionais:
==, !=, <, >, <=, >= =, ≠, <, >, ≤, ≥
Operadores lógicos
!, &&, || NOT, AND, OR
Operador (A XOR B) é equivalente a
(A || B) && !(A && B)
89 25/09/2022
Condições: exemplos
if (x>0 && x<100) printf("%i", x);
//só imprime valores que estejam entre 1 e 99
if (x<0 || x>100) printf("%i", x);
//só imprime valores abaixo de 0 ou acima de 100
if (!(x<0 || x>100)) printf("%i", x);
//só imprime valores entre 0 e 100
if (!(x<0)) printf("%i", x);
//só imprime valores positivos não nulos
if (!(x<0) && !(x>0)) printf("%i", x);
//só imprime valores nulos
90 25/09/2022
Resumo
Operadores Relacionais Pseudocódigo Linguagem C
Igualdade = ==
Diferença <> !=
Menor < <
Maior > >
Menor ou igual <= <=
Maior ou igual >= >=
91 25/09/2022
Exercício (se-então-senão)
Dado um número inteiro, se este for par, apresentar a sua
metade como resultado, senão, se este for ímpar, apresentar
o seu dobro.
92 25/09/2022
Exercícios extra
1. Dado um número inteiro, dizer se este é ou não par.
Número: 5
Não é par
2. Dados 3 números inteiros, calcular qual é o menor, o
médio e o maior dos 3.
3. Dado um número inteiro positivo com um máximo de 3
dígitos, dizer se este está na ordem das unidades, das
dezenas ou das centenas.
4. Dados 3 números inteiros, calcular o maior produto dois a
dois. Por exemplo,
Números: 4 2 5
Maior produto = 4 x 5 = 20
93 25/09/2022
Estruturas de controlo de seleção (switch)
Existe ainda uma estrutura de controlo de seleção
múltipla (switch) onde:
a estrutura verifica se o valor da variável
critério é igual a cada uma das N possibilidades
dadas por possibilidade1, possibilidade2, ... ,
possibilidadeN, e executa o bloco de instruções
correspondente;
caso o critério seja diferente de todas as
possibilidades, o bloco de instruções alternativo
94
é executado. 25/09/2022
Estruturas de controlo de seleção (switch)
switch(critério)
{
Caso critério Seja case posibilidade1:
possibilidade1: instruções1;
instruções1 break;
possibilidade2: case possibilidade2:
instruções2 instruções2;
... break;
possibilidadeN: ...
instruçõesN case possibilidadeN:
Senão: instruçõesN;
instruçõesAlternativas break;
FimCaso default:
instruçõesAlternativas;
}
95 25/09/2022
Estruturas de controlo de seleção (switch)
96 25/09/2022
Exemplo (Estrutura Caso Seja)
Em linguagem C só são permitidos valores de seleção inteiros ou
carateres.
Exemplo com inteiros
Variáveis
posição: Inteiro
Início
Caso posição Seja
1: Escrever ("Ouro")
2: Escrever ("Prata")
3: Escrever ("Bronze")
Senão: Escrever ("Tente outra vez")
FimCaso
Fim
97 25/09/2022
Exemplo (Estrutura switch-case)
#include <stdio.h>
int posicao;
int main()
{
printf("Indique a posicao: ");
scanf("%i", &posicao);
switch(posicao)
{
case 1: printf("Ouro\n"); break;
case 2: printf("Prata\n"); break;
case 3: printf("Bronze\n"); break;
default: printf("Tente outra vez\n");
}
return 0;
}
98 25/09/2022
Nota
Cada case, na estrutura switch-case, deverá seguir a seguinte
regra:
...
switch(posicao)
{
case 1:
printf("Ouro\n");
break;
case 2:
printf("Prata\n");
break;
case 3:
printf("Bronze\n");
break;
default:
printf("Tente outra vez\n");
}
...
99 25/09/2022
Exemplo (Estrutura Caso Seja)
Exemplo com carateres:
Variáveis
letra: Caráter
Início
Caso letra Seja
′O′: Escrever ("Ouro")
′P′: Escrever ("Prata")
′B′: Escrever ("Bronze")
Senão: Escrever (“Letra inválida")
FimCaso
Fim
100 25/09/2022
Exemplo (Estrutura switch-case)
#include <stdio.h>
char letra;
int main()
{
printf("Indique uma letra: ");
scanf("%c", &letra);
switch( letra)
{
case 'o': case 'O': printf("Ouro\n"); break;
case 'p': case 'P': printf("Prata\n"); break;
case 'b': case 'B': printf(“Bronze\n"); break;
default: printf("Letra inválida\n");
}
return 0;
}
101 25/09/2022
Exercício: calculadora
Enunciado:
Dados 2 números inteiros e 1 operador (+, -, × ou ÷) apresente o
resultado da operação que envolve os 2 números e o operador.
Análise do problema:
102 25/09/2022
Exercício (fluxograma)
103 25/09/2022
Exercício (pseudocódigo)
Variáveis
num1, num2, res: Inteiro
operador: Caráter
Início
Ler (num1)
Ler (num2)
Ler (operador)
Caso operador Seja
′+′ :
res num1 + num2
′-′ :
res num1 - num2
′x′ :
res num1 x num2
′/′ :
res num1 / num2
FimCaso
Escrever (res)
104 Fim 25/09/2022
Exercício (código C)
#include <stdio.h>
int num1, num2, res;
char operador;
int main()
{
printf("Introduza uma expressao (a+b,a-b,axb,a/b): ");
scanf("%i%c%i", &num1, &operador, &num2);
switch (operador)
{
case '+': res = num1 + num2; break;
case '-': res = num1 - num2; break;
case 'x': res = num1 * num2; break;
case '/': res = num1 / num2; break;
}
printf("%i %c %i = %i", num1, operador, num2, res);
return 0;
}
105 25/09/2022
Exercício (instrução system)
Criar um programa em C que apresente um Menu com
diferentes opções para execução de aplicações do sistema.
Por defeito deve executar a Linha de comandos: “cmd.exe”.
Para executar uma aplicação externa ao programa, a
linguagem C utiliza a função “system” que tem a seguinte
definição:
system(“nome_do_ficheiro_da_função_do_sistema");
106 25/09/2022
Exercício (continuação)
#include <stdio.h>
#include <stdlib.h> // Contem definicao da funcao "system"
char opcao;
int main()
{
printf("---------- MENU APLICACOES ----------\n");
printf("| B - Bloco de Notas (notepad.exe) |\n");
printf("| P - Microsoft Paint (mspaint.exe)|\n");
printf("| C - Calculadora (calc.exe) |\n");
printf("| ----------------------------------|\n");
printf("Opcao: "); scanf("%c", &opcao);
switch(opcao)
{
case 'b’: case 'B’: system("notepad.exe"); break;
case 'p': case 'P’: system("mspaint.exe"); break;
case 'c': case 'C': system("calc.exe"); break;
default: system("cmd.exe");
}
return 0;
}
107 25/09/2022
Resumo
Representação literal de um carácter faz-se colocando-o
entre plicas ('). Por exemplo, o carácter 'A'.
Tipo carácter
Declaração em Pseudocódigo
nomeVar: Carácter
Declaração em linguagem C
char nomeVar;
A função system em linguagem C permite executar dentro
de um programa outros programas externos. Por exemplo,
system("cmd.exe");
executa o programa linha de comandos do Windows.
108 25/09/2022
Estruturas de controlo de repetição
Enquanto (while) - o algoritmo/programa verifica a condição e,
se for verdadeira, executa a ação do bloco de instruções, após o
que torna a verificar a condição.
A execução do bloco de instruções é repetida até que a condição se
torne falsa.
Nesse caso, o controlo do programa segue para a primeira instrução
após a estrutura.
Fazer-Enquanto (do-while) - o algoritmo/programa primeiro
executa a ação definida pelo bloco de instruções e testa a condição
depois.
Se for verdadeira, o bloco de instruções é repetido e a condição é
novamente testada.
Se for falsa, o programa segue para a primeira instrução após a
estrutura.
109 25/09/2022
Estruturas de controlo de repetição
(while)
Enquanto-Fazer (while)
As instruções/ações repetem-se enquanto uma determinada
condição se verificar.
110 25/09/2022
Exemplo
Mostrar todos os números entre 1 e 99.
n 1 n = 1;
Enquanto n < 100 Fazer while (n < 100)
Escrever(n) {
n <- n + 1 printf("%i\n", n);
FimEnquanto n = n + 1
}
n 100 n = 100;
Enquanto n >= 1 Fazer while (n >= 1)
Escrever(n) {
n n - 1 printf("%i\n", n);
FimEnquanto n = n – 1;
}
111 25/09/2022
Exercício Enquanto-Fazer (while)
Enunciado:
Dado um número inteiro positivo, apresentar o seu fatorial.
Notar que, por exemplo,
fatorial(0) = 1
fatorial(1) = 1
fatorial(5) = 5 x 4 x 3 x 2 x 1 = 120.
Análise do problema:
fatorial 1
Enquanto num > 0 Fazer
num fatorial fatorial x num fatorial
num num – 1
FimEnquanto
112 25/09/2022
Exercício (fluxograma)
113 25/09/2022
Exercício (pseudocódigo)
Algoritmo Fatorial
Variáveis
num, fatorial: Inteiro
Início
Ler (num)
fatorial 1
Enquanto num > 0 Fazer
fatorial fatorial x num
num num – 1
FimEnquanto
Escrever (fatorial)
114 Fim 25/09/2022
Exercício (código C)
#include <stdio.h>
int num;
unsigned long fatorial; // Inteiro longo sem sinal
int main()
{
printf("Numero inteiro: ");
scanf("%i", &num);
//Processamento
fatorial = 1;
while(num > 0)
{
fatorial = fatorial * num;
num = num - 1;
}
// %lu significa long unsigned
printf("Fatorial = %lu\n", fatorial);
return 0;
115 } 25/09/2022
Estruturas de controlo de repetição
(do-while)
Fazer-Enquanto (do-while)
As instruções/ações realizam-se uma vez e depois repetem-se
enquanto uma determinada condição se verificar.
Fazer do
instruções {
Enquanto condição instruções;
}while (condição);
116 25/09/2022
Exercício do-while (problema)
Enunciado:
Dado um número natural, calcular o número dos seus divisores, sabendo
que um número natural é um inteiro positivo não nulo.
Nota: Os divisores de um número são todos os números pelos quais o
número dado é divisível, ou seja, todos os números que ao dividir o
número dado por eles obtém-se resto zero. Por exemplo:
- Os divisores de 12 são 12, 6, 4, 3, 2 e 1;
- Os divisores de 13 são 13 e 1;
- Os divisores de 21 são 21, 7, 3 e 1.
Análise do problema:
contador 0
divisor num
Fazer
Se num MOD divisor = 0 Então
num contador
contador contador + 1
FimSe
divisor divisor - 1
117 Enquanto divisor > 0 25/09/2022
Exercício do-while (Fluxograma)
118 25/09/2022
Exercício do-while (Pseudocódigo)
Algoritmo ContaDivisores
Variáveis
num, contador, divisor: Inteiro
Início
Ler (num)
contador 0
divisor num
Fazer
Se num MOD divisor = 0 Então
contador contador + 1
FimSe
divisor divisor - 1
Enquanto divisor > 0
Escrever(contador)
119 Fim 25/09/2022
Exercício do-while (Código C)
#include <stdio.h>
unsigned int num, contador;
int main()
{
unsigned int divisor; // Variável auxiliar para a contagem
printf("Indique um numero natural: ");
scanf("%u", &num); // %u <=> inteiro sem sinal (unsigned)
contador = 0;
divisor = num;
do
{
if(num % divisor == 0)
contador++; //o mesmo que “contador = contador + 1”
divisor--; //o mesmo que “divisor = divisor – 1”
} while(divisor > 0);
printf("O numero %u tem %u divisores.\n", num, contador);
return 0;
}
120 25/09/2022
Operadores Incremento/Decremento
Incremento/Decremento (só funciona com inteiros)
x++; ++x; aumentar o valor da variável x em 1
x--; --x; diminuir o valor da variável x em 1
x=3; y=++x*2; pré-incremento (x=4, y=8)
x=3; y=x++*2; pós-incremento (x=4, y=6)
x=3; y=--x*2; pré-decremento (x=2, y=4)
x=3; y=x--*2; pós-decremento (x=2, y=6)
Expressão com Inc/Dec Equivalência
x = x + 1;
y = ++x * 2;
y = x * 2;
y = x * 2;
y = x++ * 2;
x = x + 1; 25/09/2022
121
Utilização particular do-while
#include <stdio.h>
int opcao, num;
int main() {
printf("Indique um numero inteiro positivo: "); scanf("%i", &num);
do {
printf(" --------- MENU --------- \n");
printf("| 1 - Metade |\n");
printf("| 2 - Dobro |\n");
printf("| 0 - Sair |\n");
printf(" ------------------------ \n");
printf("Opcao: "); scanf("%i", &opcao);
switch(opcao) {
case 1: printf(“Metade = %i\n", num / 2); break;
case 2: printf(“Dobro = %i\n", num * 2); break;
case 0: printf("Adeus!\n"); break;
default: printf("Opcao invalida.\n");
}
} while (opcao != 0);
return 0;
122 } 25/09/2022
Estruturas de controlo de repetição (for)
Para (for)
o algoritmo/programa usa um iterador para contar o número
de iterações.
O iterador é iniciado com um valor inicial;
É testada a condição de permanência e se esta é verdadeira,
executa-se o conjunto de instruções;
O iterador avança para o valor seguinte e volta-se a testar a
condição de permanência.
O ciclo termina quando a condição não se verificar.
O ciclo for tem a seguinte estrutura:
for (inicialização; condição; alteração) instruções;
123 25/09/2022
Estruturas de controlo de repetição (for)
O algoritmo/programa repete-se um determinado número de vezes
recorrendo a um iterador (i) que varia entre Início e Fim em
saltos dados pelo valor do Passo que pode ser negativo ou
positivo.
124 25/09/2022
Estruturas de controlo de repetição (for)
125 25/09/2022
Exemplo ciclo for
Imprimir todos os números entre 1 e 100
1. Em pseudocódigo
Para n 1 Até 100 Fazer
Escrever(n)
FimPara
2. Em código C
for( int n=1; n<=100; n++)
{
printf("%i\n", n);
}
126 25/09/2022
Exemplo ciclo for
Imprimir todos os números pares entre 100 e 0
1. Em pseudocódigo
Para n 100 Até 0 Passo -2 Fazer
Escrever(n)
FimPara
2. Em código C
for( int n=100; n>=0; n-=2)
{
printf("%i\n", n);
}
127 25/09/2022
Exercício for (Problema)
Enunciado:
Dado um número natural, dizer se este é ou não primo.
Nota: Um número primo só é divisível por ele próprio e por
1. Por exemplo: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37…
Análise do problema:
nDivisores 0
Para divisor 1 Até num Fazer
Se num MOD divisor = 0 Então
nDivisores nDivisores + 1
FimSe
num FimPara éPrimo
Se nDivisores > 2 Então
éPrimo FALSO
Senão
éPrimo VERDADEIRO
128 FimSe 25/09/2022
Exercício for (Fluxograma)
129 25/09/2022
Exercício for (Pseudocódigo)
Algoritmo PrimoOuNao
Variáveis
num, nDivisores, divisor: Inteiro
éPrimo: Booleano
Início
Ler (num)
nDivisores 0
Para divisor 1 Até num Fazer
Se num MOD divisor = 0 Então
nDivisores nDivisores + 1
FimSe
FimPara
Se nDivisores > 2 Então
éPrimo FALSO
Senão
éPrimo VERDADEIRO
FimSe
Escrever(éPrimo)
130 25/09/2022
Fim
Exercício for (Código C)
#include <stdio.h>
#include <stdbool.h>
int num;
bool ePrimo; // ePrimo sera tratado como variável booleana 0=false; 1=true
int main()
{
int nDivisores, divisor; // Variáveis auxiliares
printf("Indique um numero natural: ");
scanf("%i", &num);
nDivisores = 0;
for(divisor = 1; divisor <= num; divisor++)
if(num % divisor == 0)
nDivisores++;
if(nDivisores > 2) ePrimo = false;
else ePrimo = true;
if(ePrimo) printf("O numero %i e primo.", num);
else printf("O numero %i nao e primo.", num);
return 0;
}
131 25/09/2022
Instruções de salto
return
termina a execução de uma função e retorna o controlo à função que
a chamou.
break
termina a execução do ciclo do, for, while ou a instrução switch mais
próximo e que o contém no seu corpo.
continue
passa o controlo para a próxima iteração do ciclo do, for, ou while
mais próximo que o contém, não executando quaisquer instruções
que restem até ao fim do corpo do ciclo.
goto
transfere o controlo para um dada etiqueta (label). A etiqueta deve
estar na mesma função, antes ou depois da instrução goto.
132 25/09/2022
Instrução break
Para além da sua utilização na estrutura switch-case também pode ser
usada em estruturas de repetição para quebrar o ciclo repetitivo.
No exemplo são apresentados valores inteiros até que n fique com o
valor 0.
int n;
for( n = 1; n < 100; n++)
{
if(n % 2 == 0) continue; // Se n é par
printf("%i", n); // Se n é ímpar
}
134 25/09/2022
Instrução goto
A instrução goto é “proibida” em programação estruturada
apesar de existir na maioria das linguagens por motivos
históricos, visto que esta instrução é essencial na
programação de baixo nível (Assembly).
Em C, por exemplo, pode listar todos os números entre 10 e
1 do seguinte modo:
int n = 10;
Inicio: // Etiqueta para salto
printf("%i ", n);
n = n - 1;
if(n>0) goto Inicio; // Salta para a etiqueta
135 25/09/2022
Notas sobre números aleatórios
Para a geração de números aleatórios fazer:
Incluir bibliotecas <stdlib.h> e <time.h>
Usar funções srand(time(NULL)); como semente
geradora de números aleatórios
Usar num = rand(); para obter um número entre 0 e
MAXINT
Exemplo para gerar números entre 1 e 5:
srand(time(NULL));
num = rand() % 5 + 1;
136 25/09/2022
Operadores bit-a-bit (bitwise)
Considerar as variáveis
int a = 5; // em binário: 101
int b = 3; // em binário: 010
Operador Designação Utilização
~ NOT bit-a-bit res = ~a; // -6
& AND bit-a-bit res = a & b; // 1
| OR bit-a-bit res = a | b; // 7
^ XOR bit-a-bit res = a ^ b; // 6
<< Deslocamento para a esquerda res = a << b; // 40
>> Deslocamento para a direita res = a >> 2; // 1
138 25/09/2022
Operações com carateres
A biblioteca stdio.h disponibiliza um conjunto de funções para
leitura/escrita de valores do tipo caráter.
char c; // declaração de una variável
A inicialização de uma variável do tipo char usa-
se o símbolo ′ (plica)
c = ′X′;
Não esquecer que em linguagem C o tipo char também pode
ser tratado como inteiro (código ASCII do caráter).
Algumas dessas funções são:
int getchar(void); // Lê caráter do teclado
void putchar(int); // Envia caráter para o ecrã
139 25/09/2022
Operações com carateres
A biblioteca ctype.h disponibiliza um conjunto de funções
para manuseamento de valores do tipo caráter.
char c;
Algumas dessas funções são:
int isalnum(int c); // verifica se é alfanumérico
int isalpha(int c); // verifica se é alfabético
int iscntrl(int c); // verifica se é de controlo
int isdigit(int c); // verifica se é um dígito
int islower(int c); // verifica se é letra minúscula
int ispunct(int c); // verifica se é pontuação
int isspace(int c); // verifica se é espaço
int isupper(int c); // verifica se é maiúscula
int tolower(int c); // converte para minúscula
int toupper(int c); // converte para maiúscula
140 25/09/2022
Notas sobre leitura de caráteres
A leitura recorrendo a certas funções, tais como, a função
scanf, não fazem a leitura do '\n' final quando é feita uma
entrada de dados.
Assim sendo, na leitura seguinte é lido o '\n' que ficou no
buffer em vez de esperar pela entrada do utilizador do
programa.
Para resolver este problema, aconselha-se:
1. Limpar sempre o buffer depois de uma leitura que deixe o '\n'
para trás, recorrendo a getchar:
scanf("%f", &x); getchar();
2. Colocar um espaço antes de %c sempre que for feita a leitura de
caráteres com scanf de modo a limpar os '\n':
scanf(" %f", &x);
141 25/09/2022
Conjuntos de carateres
Dígitos
0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Dígitos Hexadecimais
0 1 2 3 4 5 6 7 8 9A B C D E F a b c d e f
Letras minúsculas
abcdefghijklmnopqrstuvwxyz
Letras maiúsculas
A B C D E F G H I J K L M N O P Q R S T U V W XY Z
Carateres de pontuação
!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
Carateres espaço
tab, newline, vertical tab, form feed, carriage return, e espaço
142 25/09/2022
Notas sobre leitura de caracteres
As funções scanf ou getchar não fazem a leitura dos carateres
de controlo a menos que estes sejam introduzidos na forma:
Ctrl+Letra
Para isso, em compiladores Windows, pode-se usar a função
getch (sem mostrar) ou getche (mostra caráter - echo) que
estão disponíveis na biblioteca <conio.h>:
int getch(void)
int getche(void)
Estas funções fazem a leitura imediata de qualquer tecla que
seja pressionada.
Todavia não são funções padrão da linguagem C pelo que
devem ser evitadas.
143 25/09/2022
Exercício de aplicação
Fazer a leitura validada (só aceita caracteres válidos) de
números inteiros entre 1 e 9.
Se o número inserido for válido, apresentá-lo por extenso.
Por exemplo,
1 → Um
2 → Dois
…
9 → Nove
Se não for válido, apresentar a frase
“Número Inválido”
144 25/09/2022
Conversão de tipos de dados
Conversão de tipo numa atribuição
o valor do lado direito da instrução (expressão) é convertido
para o tipo do lado esquerdo (variável destino)
int x :
char c ;
float f ;
c = x; //c recebe 8 bits mais baixos de x
x = f; //x recebe a parte inteira de f
f = c; //f recebe valor de c em vírgula flutuante
f = x; //f recebe valor de x em vírgula flutuante
145 25/09/2022
Conversão implícita de tipos
146 25/09/2022
Conversão forçada de tipos
Este método, que permite converter uma expressão para um
tipo específico, é denominado cast e a sua forma geral é
(tipo) expressão;
os parênteses são obrigatórios.
Por exemplo, para assegurar que uma divisão dá resultado do
tipo float escreve-se
int x = 3;
printf("%d/2=%f\n" , x,(float) x/2);
onde sem o cast só uma divisão inteira seria realizada.
O cast assegura que a parte decimal da resposta é exibida.
147 25/09/2022
Conversão explícita de tipos
148 25/09/2022
Funções de conversão <stdlib.h>
A biblioteca stdlib.h disponibiliza funções de conversão
entre tipos de dados.
Função Descrição
Converte a string str para um
double atof(const char *str)
número real (tipo double)
Converte a string str para um
int atoi(const char *str)
número inteiro (tipo int)
Converte a string str para um
long int atol(const char *str)
número inteiro longo (long int)
int abs(int x) Retorna o valor absoluto de x
149 25/09/2022
Exemplos
Conversão para inteiro:
int i = atoi("12"); // i 12
int i = atoi("12a"); // i 12
int i = atoi("a12"); // i 0 (erro)
Conversão para real
double f = atof("12"); // f 12.000000
double f = atof("12.25"); // f 12.250000
double f = atof("2E-3"); // f 0.002000
double f = atof("2.1e3"); // f 2100.000000
150 25/09/2022
Exemplo de aplicação
Leitura e validação de um número inteiro positivo entre 1 e 100:
#include <stdio.h>
#include <stdlib.h
int main()
{
char leitura[8]; // Declaração de string
int num;
do
{
printf(″Numero inteiro positivo: ″);
scanf(″%s″, leitura);
num = atoi(leitura);
} while( num < 1 || num > 100);
printf(″Foi lido o numero %i.\n″, num);
return 0;
151
} 25/09/2022
Funções em linguagem C
As funções são os blocos de construção da linguagem C e o
lugar onde toda a atividade do programa ocorre.
Em termos gerais, é um módulo independente de código,
que tem um nome e executa uma determinada tarefa
específica.
O nome da função deve ser único em todo o programa.
Praticamente todas as linguagens de programação possuem
algo equivalente às funções.
Estas podem aparecer com nomes alternativos tais como
subrotinas ou procedimentos.
152 25/09/2022
Funcionamento das funções
Algumas linguagens distinguem entre funções que retornam variáveis
e as que não retornam.
O C assume que qualquer função retorna um valor.
Se o programador deseja um valor de retorno deve usar a instrução
return.
Se não deseja qualquer valor, nada deve ser usado quando a função é
chamada.
Na programação estruturada, cada problema é dividido em
subproblemas, de modo a que cada um corresponda a tarefa simples
e pequena.
A cada tarefa deve corresponder um módulo independente de
código.
O código de uma função é privado, logo não pode ser acedido por
qualquer instrução em qualquer outra função a não ser através de
uma chamada à própria função.
153 25/09/2022
Estrutura de uma função
tipoDeRetorno nomeDaFunção (listaDeParâmetros)
{
corpoDaFunção
}
154 25/09/2022
Parâmetros de uma função
Uma função pode não ter parâmetros, ou seja, a respetiva lista é
vazia.
Todavia, mesmo que não haja parâmetros, os parênteses são
obrigatórios e é boa prática colocar entre parênteses a palavra
void de modo a significar objetivamente que a função não tem
parâmetros.
Todos os parâmetros de uma função devem ser declarados
individualmente mesmo que sejam do mesmo tipo, ou seja,
155 25/09/2022
O corpo da função
O corpoDaFunção inclui, normalmente, duas partes, que
são a zona de declarações locais e as instruções da função,
entre as quais aparece normalmente a instrução return.
Uma função termina automaticamente quando atinge o fim
do corpo da função, a não ser que antes disso encontre a
instrução return.
As variáveis declaradas como parâmetros da função e aquelas
que forem declaradas no interior da função são denominadas
variáveis locais da função, sendo só reconhecidas dentro
desta (corpo da função).
156 25/09/2022
Chamada/invocação de funções
158 25/09/2022
Exemplo: função maior
159 25/09/2022
Função divisores de um número
A função recebe como parâmetro um número
inteiro e calcula o número de divisores desse
número.
160 25/09/2022
Função é par
161 25/09/2022
Alternativa melhorada
162 25/09/2022
Função potência de um número
163 25/09/2022
Alternativa melhorada
164 25/09/2022
Funções num programa
Declaração de constante
Declaração de função
Declaração de variável
Chamada de função
Definição de função
165 25/09/2022
Estrutura de um programa
166 25/09/2022
Recursividade em funções
Uma função recursiva é aquela que dentro do seu corpo faz
uma ou mais chamadas/invocações a si própria.
Exemplo: função fatorial
1, 𝑛=0
𝑓𝑎𝑡 𝑛 = ቊ
𝑛 × 𝑓𝑎𝑡(𝑛 − 1), 𝑛>0
Chamada
recursiva à
função fat
167 25/09/2022
Arrays: sequências de dados
Em programação de computadores, array, variável indexada ou
arranjo (as duas últimas denominações são mais preferíveis),
também conhecido como vetor (para arrays unidimensionais) ou
matriz (para arrays bidimensionais), é uma das mais simples
estruturas de dados.
Os arrays mantêm uma série de elementos de dados, geralmente do
mesmo tamanho e tipo de dados.
Elementos individuais são acedidos pela sua posição no array.
A posição é dada por um índice, também chamado de subscrição. O
índice geralmente utiliza uma sequência de números inteiros.
Apesar de haver arrays multidimensionais, os arrays uni e
bidimensionais são os mais comuns.
168 25/09/2022
O que é um array em linguagem C
É uma coleção de elementos do mesmo tipo que são
guardados sob um mesmo nome.
Um array pode ser visualizado com uma linha de uma tabela
em que cada célula pode ser visto como bytes de memória
que contêm um elemento.
Por exemplo, um array de 5 elementos:
169 25/09/2022
Acesso aos elementos do array
O acesso aos elementos de um array faz-se através do
respetivo índice:
lista 5 3 7 2 1
0 1 2 3 4
índice
170 25/09/2022
Declaração e inicialização de arrays
Em C, os arrays são declarados, definindo primeiro o seu
tipo, em seguida o seu nome e por fim a sua dimensão:
tipo nome[numDeElementos];
Exemplos:
int entrada[10];
char letra[26];
float despesa[7];
Declaração com iniciação:
int entrada[] = {4,5,2,7,9,0,1,3,8,6};
char letra[] = {'a','b','c','d',…,'z'};
float despesa[] = {20.5, 12.0,…,17.4};
171 25/09/2022
Exemplo: ordenação de array
172 25/09/2022
Exemplo completo
173 25/09/2022
Arrays: resumo
Declaração de um array
tipoDoArray nomeDoArray [ dimensãoDoArray ] ;
Acesso ao elemento do array índice cinco:
tipoDoArray nomeVar = nomeDoArray[5];
Alteração do valor do elemento índice três do´array:
nomeDoArray[3] = valor;
Acesso a todos os elementos do array, um a um:
for( int ind=0; ind <dimensãoDoArray; ind++)
fazerAlgo ( nomeDoArray[ind] );
174 25/09/2022
Arrays como parâmetros de funções
Ao contrário de uma variável simples, no caso de um array, o
nome da variável não representa os valores dos elementos do
array (são mais que 1) mas sim um endereço da zona de
memória onde o array está armazenado. Por exemplo,
int nomeArray[NUMELEMENTOS]
nomeArray é um endereço e não um valor.
Assim sendo, quando passamos um array a uma função,
estamos na verdade a passar o endereço do array e não
qualquer valor, como acontece nas variáveis simples.
void nomeFuncao( int nomeArray[]);
Diz-se que estamos a passar à função um parâmetro por
referência e não por valor como acontece com variáveis
simples.
175 25/09/2022
Exemplo: função de leitura
void lerSequencia(int seq[], int nElems)
{
int i;
Nota: Reparar que o iterador i do ciclo for corresponde ao índice do array seq
176 25/09/2022
Exemplo: função de escrita
void escreverSequencia(int seq[], int nElems)
{
int i;
177 25/09/2022
Exemplo: função de ordenação
void ordenarSequencia(int seq[], int nElems)
{
int i, j, aux;
for( i=0; i< nElems-1; i++)
{
for( j=i+1; j<nElems; j++)
{
if( seq[i] > seq[j])
{
aux = seq[i];
seq[i] = seq[j];
seq[j] = aux;
}
}
}
}
178 25/09/2022
Exercício de aplicação
Alterar exemplo anterior de modo a que o array
contenha números reais em vez de números inteiros:
1. Criar um array de números reais
2. Fazer a leitura de 10 números reais.
3. Mostrar lista de números desordenada.
4. Ordenar a lista de números existente no array.
5. Mostrar lista ordenada.
179 25/09/2022
Arrays bidimensionais
Declaração de um array bidimensional (2 dimensões)
tipo nomeArray[NLINHAS][NCOLUNAS];
Um array bidimensional é, em linguagem matemática,
designado por matriz. A respetiva inicialização inclui o
valor de todos os seus elementos.
int matriz[3][2] = {{1,2},{3,4},{5,6}};
O primeiro índice refere-se ao número de linhas da matriz
e o segundo índice ao número de colunas.
1 2
3 4
5 6
180 25/09/2022
Exemplo: função de leitura
void lerMatriz(int mat[][], int nLins, int nCols)
{
int l, c;
for( l=0; l< nLins; l++)
{
for( c=0; c< nCols; c++)
{
printf(“Célula %i,%i: ", l+1, c+1);
scanf("%i", &mat[l][c]);
}
}
}
Nota: Reparar que a formatação %4i seguido de \t faz com que os números
ocupem sempre 4 espaços, ou seja, metade dos espaços da tabulação, ficando assim
centrado na célula da matriz.
182 25/09/2022
Exercício prático (Arrays)
Escrever um programa em C que, dada uma sequência de
10 inteiros, faça o seguinte:
1. Apresente a sequência ordenada por ordem crescente;
2. Obtenha o menor valor da sequência;
3. Obtenha o maior valor da sequência;
4. Obtenha a mediana da sequência;
5. Obtenha a média da sequência.
Deve ser criado um MENU para escolher a operação a
realizar, devendo este ser apresentado depois de cada
operação até que seja escolhida a opção nº 0 (zero).
183 25/09/2022
Strings em C
Em C, uma string é um array de caracteres terminado com o
carácter nulo (‘\0’). A sua declaração é como a de um array:
char nome[MaxChars+1]; // +1 para o '\0’
A inicialização de uma string é ligeiramente diferente:
char nome[] = {'X', 'i', 'c', 'o', '\0'};
O carácter nulo é necessário como terminador para que se
possa manusear a string como um todo, o que não se pode fazer
com um array.
É por isso que se pode inicializar uma string assim:
char nome[] = "Xico"; // tamanho do array será 4+1
Aqui não é necessário separar explicitamente os caracteres que
constituem a string nem apresentar o carácter nulo.
184 25/09/2022
Strings: leitura e escrita
Funções para leitura de strings a partir da entrada padrão
Lê string para o endereço apontado por str. A leitura termina
quando lê espaço, newline ou eof (end-of-file)
int scanf("%s", str);
Lê string para o endereço apontado por str. A leitura termina
quando lê newline ou eof (end-of-file)
char[] gets(char str[]) // char *gets(char *str)
Envia string dada para a saída padrão
int printf("%s", str);
Envia string para a saída padrão colocando newline no fim
int puts(const char str[]) // const char *str
185 25/09/2022
Problema com a função gets
A função gets não tem qualquer informação sobre a
dimensão do buffer para onde lê, pelo que irá continuar a ler
para além do espaço de memória do buffer dado:
char buffer[10];
gets(buffer);
Se introduzir mais de 10 carateres, os restantes irão ocupar
memória que não pertence ao buffer.
Solução: usar fgets com stdin:
char buffer[10];
fgets(buffer, sizeof(buffer), stdin);
Só lerá até que o buffer termine porque tem informação sobre
o tamanho do mesmo.
186 25/09/2022
Problema com a função fgets
Ao contrário da função gets, a função fgets também lê o
ENTER final, ficando este no índice imediatamente anterior
ao índice do caracter nulo (fim da string).
Para resolver isto, deve-se sempre puxar o caracter nulo uma
posição atrás, de modo a sobrepor-se ao caracter ENTER.
Exemplo:
char buffer[10];
fgets(buffer, sizeof(buffer), stdin);
buffer[strlen(buffer)-1] = ˈ\0ˈ;
Depois de ler a palavra “ola”,
buffer = {ˈoˈ, ˈlˈ, ˈaˈ, ˈ\nˈ, ˈ\0ˈ}
Depois de puxar o caracter nulo atrás, fica
buffer = {ˈoˈ, ˈlˈ, ˈaˈ, ˈ\0ˈ, ˈ\0ˈ}
187 25/09/2022
Outro problema com a função fgets
A função fgets também apresenta ainda um problema que é o
facto de que quando são inseridos caracteres em excesso para
além do tamanho especificado, esses caracteres ficam no buffer
e serão lidos nas leituras seguintes do programa, o que poderá
originar erros de funcionamento.
A solução será implementar uma função que resolva todos
estes problemas de modo a poder ser utilizada em qualquer
aplicação em linguagem C padrão.
Proposta de função:
void readstr(char str[], int n);
em que str é a string a ler e n o seu tamanho máximo.
188 25/09/2022
Solução para leitura de strings
void readstr(char str[], int n)
{
int i; // Índice do caracter lido na string/array
char c; // Caracter lido com getchar
i = 0;
while((c = getchar()) != '\n' && i < n)
{
str[i++] = c;
}
str[i] = '\0'; // Termina string com caracter nulo
/* Limpa caracteres extra no buffer de entrada,
incluindo '\n', quando existirem. */
if( i == n)
while( getchar() != '\n');
}
189 25/09/2022
Funções para operar strings
Biblioteca
#include <string.h>
Funções
190 25/09/2022
Exemplo: funções gets e strlen
191 25/09/2022
Exemplo: função strcmp
192 25/09/2022
Exemplo: função strstr
194 25/09/2022
Apontadores
Como já se viu anteriormente, pode-se, dentro de um programa,
aceder aos valores guardados em memória.
A ferramenta que permite aceder a estes valores são os denominados
apontadores (pointers).
Os apontadores são uma das características mais poderosas da
linguagem C, mas também uma das mais perigosas.
O tipo base do apontador define que tipo de variáveis podem sem
apontadas pelo apontador.
Tecnicamente, qualquer tipo de apontador pode apontar para
qualquer zona
de memória. Todavia, toda a aritmética de apontadores é realizada
relativamente ao seu
tipo base, por isso é importante declarar corretamente os
195 apontadores. 25/09/2022
Apontadores e apontados
Um apontador é um tipo de dados que armazena uma
referência para qualquer coisa, ou seja, guarda o endereço em
memória de uma determinada informação, seja uma variável,
uma função, ou outro tipo de dados.
Uma variável que contém o endereço de outra, diz-se que a
primeira “aponta” para a segunda
196 25/09/2022
Atribuição de apontadores
A atribuição de um apontador a outro faz com que ambos
fiquem a apontar para o mesmo apontado. Ou seja,
ap1 = ap2;
faz com que ap2 fique a pontar para o mesmo apontado de ap1.
A atribuição entre apontadores não mexe nos apontados.
Esta só altera um dos apontadores de modo a que este fique
com a mesma referência do outro apontador.
Depois de uma atribuição entre apontadores, diz-se que os dois
partilham o mesmo apontado.
O operador & pode ser utilizado para obter o endereço de
uma variável:
int *ap, x=5;
ap = &x; 25/09/2022
197
Utilização de apontadores
Saída na consola
199 25/09/2022
Apontadores e strings
Uma string, sendo um array, também o seu nome é um
apontador:
200
Saída na consola 25/09/2022
Apontadores em ciclos
202 25/09/2022
Declaração de estruturas e variáveis
Estrutura para armazenar as classificações de um jogador num
jogo em que há vitórias, empates e derrotas:
struct jogador
{
char nome[16];
int vitorias;
int empates;
int derrotas;
};
Notar que a declaração anterior não definiu quaisquer variável;
limitou-se a definir um novo tipo de dados, não lhe sendo,
portanto, reservado qualquer espaço em memória.
A partir deste novo tipo podem-se definir variáveis de acordo com
as regras utilizadas anteriormente. Por exemplo,
struct jogador jogX, jogO;
203 25/09/2022
Utilização de estruturas
Após declarar uma variável do tipo estrutura, para aceder aos
campos desta estrutura recorre-se ao operador ponto (.) da
seguinte forma:
nomeVarEstrutura.nomeMembro
Por exemplo, considere-se a ficha referente ao jogador jogX:
struct jogador jogX;
Para inicializar os dados do jogX, supondo que este se chama
Zacarias e tem 3 vitórias, 1 empate e 2 derrotas, ficaria:
strcpy( jogX.nome, "Zacarias");
jogX.vitorias = 3;
jogX.empates = 1;
jogX.derrotas = 2;
204 25/09/2022
printf e scanf com estruturas
Se em vez de os dados serem obtidos de alguma posição em
memória, estes tivessem de ser lidos do teclado, ficaria:
gets(jogX.nome);
scanf("%i", &jogX.vitorias);
scanf("%i", &jogX.empates);
scanf("%i", &jogX.derrotas);
Reparar que na função gets, sendo “nome” um array de
caracteres, o próprio nome do array já é um apontador para a
string.
Para mostrar os dados no ecrã pode-se usar a função printf:
printf(“%s\t%i\t%i\t%i\n”, jogX.nome, \
jogX.vitorias, jogX.empates, jogX.derrotas);
205 25/09/2022
Estruturas e apontadores
A linguagem C permite apontadores para estruturas tal como para
qualquer outro tipo de dados. Todavia, há alguns aspetos especiais
relativos a apontadores para estruturas que é importante saber.
A declaração de apontadores para estruturas é semelhante a outros
tipos de dados.
Usa-se o operador * antes do nome da variável de estrutura:
struct jogador *apj;
Há duas utilizações primárias dos apontadores quando se trabalha
com estruturas, que são:
passar uma estrutura por referência a uma função (permitindo assim
que a função possa alterar o valor dos seus elementos);
criar listas ligadas e outras estruturas de dados dinâmicas.
206 25/09/2022
Estruturas em funções
Supondo que se quer escrever uma função que faça a leitura
dos dados de qualquer jogador, a declaração da função seria:
void LerDados( struct jogador *);
A definição da mesma função ficaria:
208 25/09/2022
Exemplo de função
211 25/09/2022
Ficheiros padrão
Três ficheiros são automaticamente abertos quando um programa é
iniciado:
Standard input (entrada padrão),
standard output (saída padrão) e
standard error (erro padrão).
A abertura de um ficheiro devolve um apontador para uma estrutura
FILE.
Para os ficheiros padrão, acima indicados, os apontadores são,
respetivamente:
stdin - entrada padrão (teclado)
stdout - saída padrão (monitor)
stderr - erro padrão (monitor)
Estes apontadores estão definidos como macros na biblioteca stdio.h.
A menos que sejam redirecionados, estão normalmente associados ao
terminal.
212 25/09/2022
Utilização de ficheiros padrão
Para ler uma linha de texto a partir do ficheiro de entrada padrão:
char linha[MAX]; // buffer de entrada
fgets( linha, MAX, stdin);
Para escrever linha de texto no saída padrão:
char linha[] = "texto a escrever";
fputs( linha, stdout);
Para leitura formatada do tipo “1 – viagens -> 12.5” , fazer:
int a; char t[MAX]; float x;
fscanf( stdin, "%i - %s -> %f", &a, t, &x);
Para escrita formatada do mesmo tipo, fazer:
int a; char t[MAX]; float x;
fprintf( stdout, "%i - %s -> %f", a, t, x);
213 25/09/2022
Outros aspetos sobre ficheiros
Nomes de ficheiro
Em qualquer sistema operativo, os ficheiros possuem nomes que
os identificam seguindo regras, para a sua constituição, específicas
de cada sistema.
O nome do ficheiro é limitado a FILENAME_MAX caracteres (no
mínimo 1), sendo esta constante uma macro definida na biblioteca
stdio.h.
Esta biblioteca disponibiliza um vasto conjunto de funções para
trabalhar com ficheiros.
Tipos de ficheiros
Ficheiros de texto (sequência de caracteres)
Ficheiros binários (sequência de bits/bytes)
214 25/09/2022
Acesso a ficheiros
Em C, consideram-se 3 tipos de acesso a ficheiro:
Leitura
Escrita
Leitura/Escrita
Para aceder a um ficheiro, começa-se por proceder à abertura
do mesmo recorrendo à função fopen.
Esta função tem a seguinte definição:
FILE *fopen( const char *nomeFicheiro, const char *modoAbertura);
215 25/09/2022
A estrutura FILE
A estrutura FILE tem a seguinte definição:
typedef struct _iobuf
{
char* _ptr; // próximo caracter
int _cnt; // nº de cars disponíveis
char* _base; // endereço do ficheiro
int _flag; // modo do ficheiro (r,w)
int _file; // descritor do ficheiro
int _charbuf; // para permitir ungetc
int _bufsiz; // tamanho atual do ficheiro
char* _tmpfname; // nome do ficheiro
} FILE;
216 25/09/2022
Modos de abertura de ficheiros
Modo Descrição
"r" Abertura de um ficheiro de texto para leitura.
"w" Criar um ficheiro de texto para escrita. Se este já existir, o seu conteúdo é Apagado
"a" Abre ou cria um ficheiro de texto para adição no fim deste.
"r+" Abertura de ficheiro de texto para atualização, isto é, leitura e escrita.
"w+" Criar um ficheiro de texto para atualização. Se este existir, o seu conteúdo é eliminado.
"a+" Abre ou cria um ficheiro de texto para atualização, escrevendo no fim deste.
221 25/09/2022
Função de leitura de linhas
int LerFicheiro( const char fic[TAMNOME], char linhas[MAXLINHAS][TAMLINHA])
{
FILE *apf;
char linha[TAMLINHA];
int i, numLinhas;
numLinhas = 0;
// Carrega linhas do ficheiro
for( i=0; i<MAXLINHAS; i++) {
if( fgets( linha, TAMLINHA, apf) != NULL) {
strcpy(linhas[i], linha);
numLinhas++;
} else {// nao existe uma nova linha -> pergunta vazia
strcpy(linhas[i], "");
}
}
return numLinhas;
}
222 25/09/2022
Função de separação de linhas
int SepararLinha( char linha[TAMLINHA], char partes[NUMLINHAS][TAMLINHA])
{
char *parte; // apontador para a parte atual
int p = 0; // índice de cada parte no array partes
223 25/09/2022
Leitura/escrita em bloco
De cada vez será lido/escrito um bloco de dados, no exemplo dado
corresponde a uma estrutura do tipo struct jogador.
A declaração da função fread é:
int fread(void *apt, int tamanho, int num, FILE *apf);
Para ler uma estrutura ficaria:
res = fread (&jogadorX, sizeof( struct jogador), 1, apf);
E para escrever, a declaração da função fwrite é:
int fwrite(void *apt, int tamanho, int num, FILE *apf);
Para escrever uma estrutura ficaria:
fwrite(&jogadorX, sizeof( struct jogador), 1, apf);
224 25/09/2022
Função de leitura em bloco
int LerFicheiro( const char fic[TAMNOME], struct ficha fichas[MAXFICHAS])
{
FILE *apf;
int i, res, numFichas;
// Se ha erro ao aceder ao ficheiro retorn -1
if(( apf = fopen (fic , "r" ) ) == NULL) { fclose( apf); return -1; }
numFichas = 0;
// Carrega classificacoes de ficheiro
for( i=0; i<MAXFICHAS; i++) {
res = fread (&fichas[i] , sizeof( struct ficha), 1, apf);
if( res > 0) {
numFichas++;
} else {
// Inicializa todos os campos de ficha[i] a vazio/0
}
}
return numFichas; // retorna numero de fichas lidas do ficheiro
}
225 25/09/2022
Função de escrita de bloco
int EscreverFicheiro( const char fic[TAMNOME], struct ficha fichas[MAXFICHAS])
{
FILE *apf;
int i, numFichas;
// Se ha erro ao aceder ao ficheiro retorn -1
if(( apf = fopen (fic , "w" ) ) == NULL) { fclose( apf); return -1; }
numFichas = 0;
// Escreve fichas no ficheiro
for( i=0; i<MAXFICHAS; i++)
{
if( strcmp(fichas[i].nome, "") != 0) // fichas[i].numero != 0
{
fwrite(&fichas[i] , sizeof( struct ficha), 1, apf);
numFichas++;
}
}
return numFichas; // retorna numero de fichas gravadas no ficheiro
}
226 25/09/2022