| Os candidatos devem ser capazes de: | Notas e orientações |
|---|---|
| Compreender o que se entende por um paradigma de programação | |
| Demonstrar compreensão das características de vários paradigmas de programação: | |
| • Baixo nível | Programação de Baixo Nível: • compreensão e capacidade de escrever código de baixo nível usando vários modos de endereçamento: imediato, direto, indireto, indexado e relativo |
| • Imperativo (Procedural) | Programação Imperativa (Procedural): • conhecimento pressuposto e compreensão de Programação Estruturada (ver detalhes na seção de conteúdo AS 11.3) • compreensão e capacidade de escrever código de programação imperativa (procedural) que usa variáveis, construções, procedimentos e funções. Ver detalhes no conteúdo AS |
| • Orientado a Objetos | Programação Orientada a Objetos (POO): • compreensão da terminologia associada à POO (incluindo objetos, propriedades/atributos, métodos, classes, herança, polimorfismo, contenção (agregação), encapsulamento, getters, setters, instâncias) • compreensão de como resolver um problema projetando classes apropriadas • compreensão e capacidade de escrever código que demonstre o uso de POO |
| • Declarativo | Programação Declarativa: • compreensão e capacidade de resolver um problema escrevendo fatores e regras adequados baseados nas informações fornecidas • compreensão e capacidade de escrever código que possa satisfazer um objetivo usando fatos e regras |
Programação Avançada
Ciência da Computação do A-Level · Tópico 20
13:52
Paradigmas de Programação
Aqui está um trabalho: liste todos os alunos com nota A. Um programador escreve um loop — comece no primeiro registro, verifique a nota, adicione o nome a uma lista, mova…
Narração em inglês · Legendas em inglês + 中文 gravadas
20.1
Paradigmas de programação
Programa
Fonte: Programa Cambridge International
Um paradigma de programação 编程范式 é um estilo de programação — uma maneira de estruturar programas, com suas próprias ideias e recursos de linguagem. Quatro paradigmas de programação estão neste programa.
"Descreva o que significa uma linguagem imperativa (procedural) (duas marcas)." Uma linguagem na qual o programa é uma sequência de instruções executadas em ordem e que alteram o estado do programa; o programador diz como a tarefa é feita, usando procedimentos, sequência, seleção e iteração. "Descreva o que significa uma linguagem declarativa": o programa declara fatos e regras (o que é conhecido e o que se quer) e o motor de inferência da linguagem descobre como encontrar a resposta; o programador não dá a sequência de passos.
Identifique o paradigma a partir de um exemplo de código (uma questão típica do Paper 3): LDD 200, ADD #5, STO 201 são de baixo nível (mnemônicos, registradores, endereços de memória); FOR Count ← 1 TO 10 … NEXT Count com procedimentos e atribuições é imperativo; CLASS Dog … PRIVATE Name : STRING … PUBLIC PROCEDURE NEW(…) é orientado a objetos; type(lion, wild). e dangerous(X) IF type(X, wild) são declarativos (lógica). Na questão de correspondência: baixo nível combina com "mnemônicos que correspondem diretamente às instruções da máquina", imperativo com "uma sequência de instruções que alteram o estado", OOP com "objetos que combinam atributos e métodos" e declarativo com "fatos e regras, sem ordem de execução dada".

Programação de baixo nível
Programação próxima ao hardware em código de máquina 机器码 ou linguagem de montagem 汇编语言, onde cada instrução mapeia para o que a CPU executa. Fornece acesso direto a registradores 寄存器和 endereços de memória 内存地址, usando diferentes modos de endereçamento 寻址方式 (imediato, direto, indireto, indexado e relativo). É muito rápido e compacto, mas específico da arquitetura, tedioso e difícil de manter. Esta é a programação de baixo nível 低级, usada para drivers de dispositivos, firmware e bootloaders.
Os cinco modos de endereçamento. A ementa pede código de baixo nível que use cada modo de endereçamento (o conjunto de instruções está no Topic 4). O operando de uma instrução de carga pode ser lido de cinco formas, e o exame fornece os conteúdos da memória e pergunta qual o acumulador contém:

- imediato (
LDM #105): o operando é o valor; ACC torna-se 105. - direto (
LDD 105): o operando é o endereço do valor; ACC torna-se o conteúdo de 105, aqui 27. - indireto (
LDI 105): o operando é o endereço de um endereço; ACC torna-se o conteúdo de 27, aqui 91. Usado para ponteiros e para dados cuja posição é decidida em tempo de execução. - indexado (
LDX 105): o endereço é o operando mais o registrador índice IX; com IX = 2, ACC torna-se o conteúdo de 107. Usado para percorrer uma matriz incrementando IX. - relativo (
JMR +65): o destino é um offset a partir do endereço da instrução atual, o que torna o código relocalizável.
Exemplo resolvido. Memória: 105 contém 27, 106 contém 64, 200 contém 0. Escreva código para somar os conteúdos de 105 e 106, armazenar o resultado em 200 e exibi-lo. LDD 105 (ACC = 27), ADD 106 (ACC = 91), STO 200, OUT. Para dobrar o valor em 105 em vez disso: LDD 105, ADD 105, STO 105. Indique o conteúdo dos registradores após cada linha quando solicitado a rastrear.
Programação imperativa (procedural)
Na programação imperativa 命令式编程, o programador escreve uma sequência de comandos que alteram o estado do programa — atribuições, condicionais, laços, chamadas de função. Variáveis 变量 mantêm o estado; as instruções o alteram; o código é organizado em procedimentos e funções (também chamado de programação estruturada). Este é o estilo dos Topics 9 e 11 (Python, C). Forte quando o algoritmo tem passos sequenciais claros.
Programação orientada a objetos (OOP)
Na programação orientada a objetos 面向对象编程, programas são construídos a partir de objetos 对象 — unidades que combinam dados (atributos 属性) e operações (métodos 方法). Objetos são instâncias 实例 de classes 类. Os quatro pilares:
- encapsulamento 封装 — os dados de um objeto estão ocultos atrás de seus métodos; o código externo usa apenas os métodos públicos, não os dados diretamente. Isso protege o objeto e permite que seu interior mude sem quebrar quem o chama. Por exemplo, um
BankAccountesconde seusbalance; você os altera apenas através dedeposit()ewithdraw(), que podem impor uma regra como "nunca descer abaixo de zero". - herança 继承 — uma subclasse 子类 especializa uma superclasse 父类, herdando seus atributos e métodos e adicionando ou sobrescrevendo 重写 eles. Modela "é-um" ("Um Gerente é um Funcionário").
- polimorfismo 多态 — objetos diferentes respondem à mesma chamada de método de forma diferente; quem chama não precisa saber o tipo exato. Todo
ShapetemArea(), e umCirclee umRectangleo implementam de suas próprias maneiras. - abstração 抽象 — mostrar uma interface simples e ocultar a implementação.
Outros termos:
- um construtor 构造函数 é um método especial executado quando um objeto é criado, para configurar seus atributos.
- getters e setters leem e gravam os atributos de um objeto (suas propriedades) através de métodos.
- agregação 聚合 e contenção 包含 constroem um objeto a partir de outros objetos (uma relação "tem-um").
OOP é usado para sistemas grandes, interfaces gráficas, simulações e jogos.
*Polimorfismo: a mesma chamada de método executa o código próprio de cada objeto
*Um diagrama de classe para Shape: atributos privados e métodos públicos
*Herança: partTime e fullTime são subclases de employee
*Encapsulamento: os dados de um objeto são privados, acessados apenas através de seus métodos públicos
OOP conforme o avaliador pontua
Definições. Classe: uma planta (projeto) que define os atributos e métodos dos objetos desse tipo. Objeto: uma instância de uma classe, criada a partir dela, com seus próprios valores para os atributos ("uma ocorrência de um objeto" é a expressão do exame para instância). Atributo (propriedade): um item de dado pertencente a uma classe. Método: um procedimento ou função pertencente a uma classe que atua sobre seus atributos. Encapsulamento: combinar atributos e métodos em uma classe e restringir o acesso externo aos dados: os atributos são privados e só podem ser lidos ou alterados através de métodos públicos. Herança: uma subclasse adquire os atributos e métodos de sua classe pai (super) e pode adicionar os seus próprios ou sobrescrevê-los. Polimorfismo: métodos com o mesmo nome que se comportam diferentemente em classes diferentes; tipicamente uma subclasse ** redefine** um método de seu pai, e a versão certa roda para cada objeto. Contenção: uma classe tem um objeto de outra classe como atributo (um carro tem um motor). "Identificar o recurso que restringe o acesso externo aos dados" é encapsulamento; "o termo para uma ocorrência de um objeto" é instância.
"Esboce a estrutura de uma classe" (três marcas): atributos (propriedades) que mantêm os dados do objeto, geralmente declarados como privados; métodos (procedimentos e funções) que atuam sobre esses atributos, geralmente públicos; e um construtor, um método que roda quando um objeto é criado para inicializar os atributos. "Dê três benefícios da OOP": o código é reutilizado através da herança; os dados são protegidos pelo encapsulamento, então só podem ser alterados pelos métodos próprios da classe; um programa grande é dividido em classes que são escritas e testadas independentemente, facilitando a manutenção e expansão; as classes modelam entidades do mundo real, tornando o design mais fácil de entender; o polimorfismo permite que a mesma chamada funcione para objetos diferentes.
A classe em pseudocódigo, conforme o Paper 3 a define:
CLASS Car
PRIVATE Registration : STRING
PRIVATE Year : INTEGER
PRIVATE Mileage : INTEGER
PUBLIC PROCEDURE NEW(NewReg : STRING, NewYear : INTEGER)
Registration ← NewReg
Year ← NewYear
Mileage ← 0
ENDPROCEDURE
PUBLIC FUNCTION GetMileage() RETURNS INTEGER
RETURN Mileage
ENDFUNCTION
PUBLIC PROCEDURE AddMileage(Extra : INTEGER)
Mileage ← Mileage + Extra
ENDPROCEDURE
ENDCLASS
Um objeto é criado com MyCar ← NEW Car("AB12 CDE", 2020) e usado com MyCar.AddMileage(150) e OUTPUT MyCar.GetMileage(). Uma subclasse reutiliza o construtor do pai através de SUPER:
CLASS ElectricCar INHERITS Car
PRIVATE BatteryCapacity : REAL
PUBLIC PROCEDURE NEW(NewReg : STRING, NewYear : INTEGER, NewCapacity : REAL)
SUPER.NEW(NewReg, NewYear)
BatteryCapacity ← NewCapacity
ENDPROCEDURE
ENDCLASS
A mesma classe em Python, conforme o Paper 4 espera: os atributos tornam-se privados com dois underscores, o construtor é __init__, e uma subclasse nomeia seu pai entre parênteses e chama super().__init__(…):
class Car:
def __init__(self, reg, year):
self.__registration = reg
self.__year = year
self.__mileage = 0
def get_mileage(self):
return self.__mileage
def add_mileage(self, extra):
self.__mileage = self.__mileage + extra
class ElectricCar(Car):
def __init__(self, reg, year, capacity):
super().__init__(reg, year)
self.__capacity = capacity
cars = []
cars.append(Car("AB12 CDE", 2020))
cars.append(ElectricCar("EV21 XYZ", 2023, 75.0))
cars[1].add_mileage(150)
print(cars[1].get_mileage())
Em Java, as mesmas ideias são private/public campos, um construtor com o nome da classe, extends e super(…); em VB.NET Private/Public, Sub New, Inherits e MyBase.New. Um método polimórfico é escrito no pai e sobrescrito no filho com o mesmo nome; uma chamada através de uma variável do tipo pai executa a versão do filho.
Estruturas de dados como objetos. O Paper 4 constrói uma pilha, lista encadeada ou árvore binária a partir de uma Node classe cujos atributos são os dados e uma ou duas referências para outros nós; uma Tree (ou LinkedList) classe mantém a raiz (ou início) e os métodos.

CLASS Node
PUBLIC Data : INTEGER
PUBLIC Left : Node // NULL when there is no child
PUBLIC Right : Node
PUBLIC PROCEDURE NEW(NewData : INTEGER)
Data ← NewData
Left ← NULL
Right ← NULL
ENDPROCEDURE
ENDCLASS
CLASS Tree
PRIVATE Root : Node
PUBLIC PROCEDURE Insert(NewData : INTEGER)
DECLARE NewNode, Current : Node
DECLARE Placed : BOOLEAN
NewNode ← NEW Node(NewData)
IF Root = NULL THEN
Root ← NewNode
ELSE
Current ← Root
Placed ← FALSE
WHILE NOT Placed
IF NewData < Current.Data THEN
IF Current.Left = NULL THEN
Current.Left ← NewNode
Placed ← TRUE
ELSE
Current ← Current.Left
ENDIF
ELSE
IF Current.Right = NULL THEN
Current.Right ← NewNode
Placed ← TRUE
ELSE
Current ← Current.Right
ENDIF
ENDIF
ENDWHILE
ENDIF
ENDPROCEDURE
ENDCLASS
Um método find percorre o mesmo caminho e retorna TRUE quando Current.Data = Target, FALSE quando atinge NULL; um método produção in-order é recursivo: output da subárvore esquerda, do nó, então da subárvore direita. Para uma lista encadeada o nó tem uma referência, Next, e a classe da lista mantém Start; para uma pilha construída a partir de uma lista, push e pop ambos funcionam em Start.
Exemplo resolvido. Um jogo tem personagens. Cada um tem um nome, saúde (começando em 100) e uma posição dada por X e Y. Escreva uma classe Character com um construtor e um método Move(DX, DY); então uma subclass Wizard que adiciona Mana (começando em 50) e um método CastSpell() que consome 10 mana e retorna TRUE se houvesse suficiente.
CLASS Character
PRIVATE Name : STRING
PRIVATE Health : INTEGER
PRIVATE X : INTEGER
PRIVATE Y : INTEGER
PUBLIC PROCEDURE NEW(NewName : STRING, StartX : INTEGER, StartY : INTEGER)
Name ← NewName
Health ← 100
X ← StartX
Y ← StartY
ENDPROCEDURE
PUBLIC PROCEDURE Move(DX : INTEGER, DY : INTEGER)
X ← X + DX
Y ← Y + DY
ENDPROCEDURE
ENDCLASS
CLASS Wizard INHERITS Character
PRIVATE Mana : INTEGER
PUBLIC PROCEDURE NEW(NewName : STRING, StartX : INTEGER, StartY : INTEGER)
SUPER.NEW(NewName, StartX, StartY)
Mana ← 50
ENDPROCEDURE
PUBLIC FUNCTION CastSpell() RETURNS BOOLEAN
IF Mana >= 10 THEN
Mana ← Mana - 10
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTION
ENDCLASS
As marcas são para atributos privados, um construtor que define todos os atributos, a linha de herança, a chamada ao construtor do pai e um método que usa e altera os dados próprios do objeto. Quando a questão pede um diagrama de classe, desenhe uma caixa em três partes (nome; atributos com - para privado; métodos com + para público) e junte uma subclasse a seu pai com uma seta apontando para o pai.
Programação declarativa
Em programação declarativa 声明式编程, você diz o que calcular, não como — a execução decide os passos. Dois tipos:
- programação funcional 函数式编程 — construída a partir de funções puras 纯函数 (sem efeitos colaterais 副作用; mesma entrada sempre gera mesma saída) compostas entre si. Exemplos: Haskell, Lisp.
- programação lógica 逻辑编程 — declara fatos e regras; o motor responde a um objetivo (interrogação) por inferência. Exemplo: Prolog.
Um exemplo familiar de programação declarativa é SQL 结构化查询语言: SELECT * FROM Customer WHERE Country = 'UK' diz o que você quer, não como percorrer os registros.
Fatos, regras e objetivos são o que as provas testam no paradigma declarativo. Dados esses fatos 事实 (afirmações verdadeiras) e uma regra 规则 (uma conclusão válida quando suas condições forem válidas):
01 type(leopard, wild).
02 type(lion, wild).
03 type(tabby, domestic).
04 size(leopard, large).
05 size(lion, large).
06 size(tabby, small).
07 dangerous(X) IF type(X, wild) AND size(X, large).
"Escreva o resultado do objetivo type(X, wild)":* X = leopard, X = lion. O motor compara o objetivo com cada fato sequencialmente; toda correspondência é uma solução, e uma letra maiúscula é uma variável preenchida pela correspondência. "Escreva um fato para mostrar que um guepardo é selvagem": type(cheetah, wild). "Explique o que a linha 07 faz": ela define uma regra com a conclusão dangerous(X), que é verdadeira para qualquer X que seja tanto selvagem quanto grande, então dangerous(A) retorna A = leopard, A = lion. "Escreva uma regra: um recurso F pode estar disponível para um estilo de carroceria B se F for um recurso e B for um estilo de carroceria e F não estiver indisponível para B": may_be_available(F, B) IF feature(F) AND body_style(B) AND NOT unavailable(F, B). Copie exatamente os nomes dos predicados e a ordem dos argumentos usados nos fatos da questão; um novo fato termina com ponto final, e as condições de uma regra são unidas por AND.
Comparando paradigmas
| Paradigma | Força | Linguagens típicas |
|---|---|---|
| Baixo nível | controle máximo, velocidade | assembly |
| Imperativa | direta, intuitiva | C, Python |
| Orientada a objetos | modular, modela entidades | Java, C#, Python |
| Funcional | clara, sem efeitos colaterais | Haskell, F# |
| Lógica | inferência, regras | Prolog |
| Banco de dados | consultas de dados | SQL |
Linguagens modernas frequentemente misturam paradigmas — Python suporta todos os de procedural, POO e funcional. A escolha depende do problema.
Laboratório de conceito de programação
Conecte exemplos à ideia de programação que eles mostram.
| Inglês | Chinês | Pinyin |
|---|---|---|
| programming paradigm/ˈprəʊɡræmɪŋ ˈpærədaɪm/ | 编程范式 | biān chéng fàn shì |
| facts/fækts/ | 事实 | shì shí |
| rule/ruːl/ | 规则 | guī zé |
| low-level/ləʊ ˈlevl/ | 低级 | dī jí |
| registers/ˈredʒɪstəz/ | 寄存器 | jì cún qì |
| memory addresses/ˈmeməri əˈdresɪz/ | 内存地址 | nèi cún dì zhǐ |
| objects/ˈɒbdʒekts/ | 对象 | duì xiàng |
| attributes/ˈætrɪbjuːts/ | 属性 | shǔ xìng |
| methods/ˈmeθədz/ | 方法 | fāng fǎ |
| machine code/məˈʃiːn kəʊd/ | 机器码 | jī qì mǎ |
| assembly language/əˈsemblɪ ˈlæŋɡwɪdʒ/ | 汇编语言 | huì biān yǔ yán |
| addressing modes/əˈdresɪŋ məʊdz/ | 寻址方式 | xún zhǐ fāng shì |
| classes/ˈklæsɪz/ | 类 | lèi |
| encapsulation/ɪnˌkæpsjʊˈleɪʃn/ | 封装 | fēng zhuāng |
| inheritance/ɪnˈherɪtəns/ | 继承 | jì chéng |
| subclass/ˈsʌbklæs/ | 子类 | zi lèi |
| superclass/ˈsuːpəklæs/ | 父类 | fù lèi |
| overriding/ˌəʊvəˈraɪdɪŋ/ | 重写 | chóng xiě |
| polymorphism/ˈpɒlɪmɔːfɪzəm/ | 多态 | duō tài |
| abstraction/əbˈstrækʃn/ | 抽象 | chōu xiàng |
| constructor/kənˈstrʌktə/ | 构造函数 | gòu zào hán shù |
| aggregation/ˌæɡrɪˈɡeɪʃn/ | 聚合 | jù hé |
| containment/kənˈteɪnmənt/ | 包含 | bāo hán |
| declarative programming/dɪˈklærətɪv ˈprəʊɡræmɪŋ/ | 声明式编程 | shēng míng shì biān chéng |
| functional programming/ˈfʌŋkʃənl ˈprəʊɡræmɪŋ/ | 函数式编程 | hán shù shì biān chéng |
| pure functions/pjʊə ˈfʌŋkʃnz/ | 纯函数 | chún hán shù |
| side effects/saɪd ɪˈfekts/ | 副作用 | fù zuò yòng |
| logic programming/ˈlɒdʒɪk ˈprəʊɡræmɪŋ/ | 逻辑编程 | luó jí biān chéng |
| SQL/ˌes kjuː ˈel/ | 结构化查询语言 | jié gòu huà chá xún yǔ yán |
20.2
Processamento de arquivos
Programa
| Os candidatos devem ser capazes de: | Notas e orientações |
|---|---|
| Escrever código para realizar operações de processamento de arquivos | Abrir (no modo leitura, escrita, anexar) e fechar um arquivo Ler um registro de um arquivo e escrever um registro em um arquivo Realizar operações de processamento de arquivos em arquivos série, sequenciais, aleatórios |
| Demonstre compreensão de uma exception e da importância do exception handling | Saiba quando é apropriado usar exception handling Escreva código de programa para usar exception handling |
Fonte: Programa Cambridge International
Isso estende o manuseio de arquivo 文件 do Tema 10, processando arquivos seriais, sequenciais e aleatórios (acesso direto). Operações em pseudocódigo: OPENFILE name FOR READ | WRITE | APPEND (READ abre um arquivo existente, WRITE cria/sobrescreve, APPEND adiciona ao final); READFILE name, line; WRITEFILE name, value; CLOSEFILE name; e EOF(name) que é VERDADEIRO no final.
Leia um arquivo inteiro:
OPENFILE "names.txt" FOR READ
WHILE NOT EOF("names.txt") DO
READFILE "names.txt", thisName
OUTPUT thisName
ENDWHILE
CLOSEFILE "names.txt"
Pesquise um arquivo (pare ao encontrar):
found ← FALSE
OPENFILE "people.txt" FOR READ
WHILE NOT EOF("people.txt") AND NOT found DO
READFILE "people.txt", line
IF line = target THEN
found ← TRUE
ENDIF
ENDWHILE
CLOSEFILE "people.txt"
Atualizando um arquivo in-place
A maioria das linguagens não pode editar um arquivo de texto in-place. Em vez disso: abra o original para READ e um arquivo temporário para WRITE; para cada linha, escreva a nova versão se deve mudar, senão a original; feche ambos; depois substitua o original pelo arquivo temporário. O mesmo padrão lida com exclusão de linhas (pule-as) e inserção de linhas.

Registros e arquivos de acesso aleatório
Modos de abertura. READ: o arquivo deve existir e a leitura começa no início. WRITE: um arquivo novo é criado, e um arquivo existente desse nome é sobrescrito. APPEND: a escrita adiciona ao final de um arquivo existente. Todo arquivo aberto é fechado com CLOSEFILE, e EOF(name) é TRUE quando o último item foi lido.
Três organizações de arquivos. Em um arquivo serial, os registros estão na ordem em que foram adicionados; em um arquivo sequencial, estão em ordem de chave; ambos são lidos do início. Um arquivo aleatório 随机文件 (arquivo de acesso direto) armazena cada registro em um endereço calculado a partir de sua chave por uma função de hashing 哈希, permitindo encontrar um registro sem ler os outros. Registros são declarados como tipo definido pelo usuário:
TYPE AccountRecord
DECLARE AccNo : INTEGER
DECLARE Name : STRING
DECLARE Balance : REAL
DECLARE Active : BOOLEAN
ENDTYPE

As operações de arquivo aleatório em pseudocódigo são OPENFILE "Acc.dat" FOR RANDOM, SEEK "Acc.dat", Address (move o ponteiro do arquivo para esse registro), GETRECORD "Acc.dat", Rec (lê o registro ali) e PUTRECORD "Acc.dat", Rec (escreve o registro ali). Encontrar um cliente por número de conta, conforme definido no Paper 3:
DECLARE Rec : AccountRecord
DECLARE Target, Address : INTEGER
INPUT Target
Address ← Target MOD 1000 // the hashing function
OPENFILE "Acc.dat" FOR RANDOM
SEEK "Acc.dat", Address
GETRECORD "Acc.dat", Rec
WHILE Rec.AccNo <> Target AND Rec.AccNo <> 0 // 0 marks an empty slot
Address ← Address + 1 // a collision: try the next slot
SEEK "Acc.dat", Address
GETRECORD "Acc.dat", Rec
ENDWHILE
IF Rec.AccNo = Target THEN
OUTPUT Rec.Name, Rec.Balance
ELSE
OUTPUT "No such account"
ENDIF
CLOSEFILE "Acc.dat"
Para armazenar um registro, hashie sua chave, SEEK para o endereço e PUTRECORD, avançando sobre qualquer slot já ocupado. Marcas vão para o hash, o SEEK antes do GET ou PUT, a comparação com o alvo, o tratamento de colisão e o fechamento do arquivo.
Exemplo resolvido. ActiveFile.dat contém AccountRecord registros. Escreva pseudocódigo que copie todos os registros cujo campo Active seja FALSE para o final de ArchiveFile.dat.
DECLARE Rec : AccountRecord
OPENFILE "ActiveFile.dat" FOR READ
OPENFILE "ArchiveFile.dat" FOR APPEND
WHILE NOT EOF("ActiveFile.dat")
READFILE "ActiveFile.dat", Rec
IF Rec.Active = FALSE THEN
WRITEFILE "ArchiveFile.dat", Rec
ENDIF
ENDWHILE
CLOSEFILE "ActiveFile.dat"
CLOSEFILE "ArchiveFile.dat"
Arquivos de texto em Python (Paper 4): file = open("HighScore.txt", "r"), depois for line in file: com line.strip() e line.split(",") para separar os campos, int(…) para converter uma pontuação, e file.close(); para escrever, open(name, "w") (ou "a" para anexar) e file.write(str(score) + "\n"). Uma tabela de maiores pontuações é lida em uma lista de registros, a nova pontuação inserida em seu lugar, e toda a lista reescrita. O examinador atribui marcas pela abertura com modo correto, um laço que lê cada linha, a conversão de texto para números e o fechamento.
Armadilhas
Esquecer de fechar um arquivo (dados podem ser perdidos); abrir para WRITE quando queria APPEND (sobrescreve tudo); ler além de EOF; caminhos fixos — um caminho como /Users/Admin/data.txt falha em outra máquina, então use uma constante relativa como DataFile = "./data/scores.txt".
Rota de acesso a arquivo
Siga um arquivo do armazenamento ao programa e de volta com segurança.
| Inglês | Chinês | Pinyin |
|---|---|---|
| file/faɪl/ | 文件 | wén jiàn |
| random file/ˈrændəm faɪl/ | 随机文件 | suí jī wén jiàn |
| hashing/ˈhæʃɪŋ/ | 哈希 | hā xī |
20.2
Tratamento de exceções
Uma exceção 异常 é um erro ou condição inesperada durante a execução — divisão por zero, arquivo não encontrado, falha de rede, índice de array 数组 fora do intervalo. Tratamento de exceções 异常处理 permite que um programa detecte isso e responda graciosamente em vez de travar.
Importa porque programas reais enfrentam erros que não podem ser prevenidos antecipadamente (arquivos movidos, redes caídas, entrada inválida); sem isso, cada operação precisaria de sua própria verificação IF; e separa o fluxo normal do tratamento de erros, mantendo o caminho principal limpo. Por exemplo, um arquivo pode ser deletado por outro usuário entre seu programa verificar que existe e realmente abri-lo — você não pode prevenir isso, apenas lidar com a falha quando ocorrer.
"Descreva, com um exemplo, o que significa uma exceção (duas marcas). Um evento inesperado ou erro que ocorre durante a execução de um programa (em tempo de execução) e interrompe seu fluxo normal; por exemplo, dividir por zero, abrir um arquivo que não existe, converter entrada não numérica em inteiro, índice de array fora do intervalo ou esgotar memória. "Identifique duas possíveis causas de exceções" é respondido a partir dessa lista, mais "um dispositivo ou rede não está disponível" e "tipo de dado inválido inserido".
"Enumere as razões para incluir tratamento de exceções (três marcas). Para evitar que o programa trave (termine inesperadamente); para exibir uma mensagem significativa ao usuário em vez de um erro do sistema; para permitir que o programa recupere e continue, por exemplo pedindo a entrada novamente, ou fechar arquivos com segurança antes de terminar; e porque alguns erros não podem ser previstos quando o programa é escrito. "Descreva como evitar o término do programa devido a uma exceção: coloque as instruções que poderiam levantar uma exceção dentro de um bloco TENTAR; escreva um bloco EXCEPT (catch) para essa exceção que a trate, por exemplo exibindo uma mensagem, para que a execução continue após o bloco em vez de parar. "Explique o que significa tratamento de exceções: detectar uma exceção quando ocorre e executar código (o manipulador) que a lidem para que o programa continue.
Padrão
TRY
OPENFILE "data.txt" FOR READ
READFILE "data.txt", line
OUTPUT line
CLOSEFILE "data.txt"
EXCEPT FileNotFound
OUTPUT "Sorry, the file does not exist."
EXCEPT ReadError
OUTPUT "Sorry, error reading the file."
ENDTRY
O bloco TRY contém o código que pode falhar; o primeiro bloco EXCEPT correspondente é executado. Linguagens reais também têm um catch-all EXCEPT e um bloco FINALLY que roda independentemente de exceção ter ocorrido — útil para limpeza (fechar arquivos).

Levantando uma exceção
Uma subrotina que detecta um erro pode levantar 抛出 uma exceção para que o chamador a trate:
PROCEDURE Divide(a : INTEGER, b : INTEGER) RETURNS INTEGER
IF b = 0 THEN
RAISE DivideByZero
ENDIF
RETURN a DIV b
ENDPROCEDURE
Onde tratar exceções
Trate-as perto do erro se a resposta for simples (uma mensagem, uma retrial), ou mais acima na pilha de chamada 调用栈 se apenas o código externo souber o que fazer (um loop GUI de nível superior registra o erro e mostra um diálogo amigável). Não engula exceções silenciosamente — pelo menos registre-as, caso contrário a depuração torna-se impossível.
Exceções comuns: FileNotFound, IOError, DivisionByZero, IndexOutOfRange, InvalidArgument, NullReference, OutOfMemory. Envolver cada operação falhante em um TRY com manipuladores EXCEPT adequados dá a um programa que degrada graciosamente em vez de travar.
Exemplo resolvido (Paper 4). Escreva uma função que leia números inteiros, um por linha, de um arquivo cujo nome é passado como parâmetro e os retorne em uma lista. Ela não deve travar se o arquivo não existir ou uma linha não for um número inteiro.
def read_scores(filename):
scores = []
try:
file = open(filename, "r")
for line in file:
scores.append(int(line))
file.close()
except FileNotFoundError:
print("The file", filename, "does not exist")
except ValueError:
print("A line in the file was not a whole number")
return scores
O bloco try contém o código que pode falhar (a abertura e a conversão); cada except nomeia uma exceção e faz algo útil; a função ainda retorna uma lista, então o chamador continua. Em Java a mesma estrutura é try { … } catch (FileNotFoundException e) { … } catch (NumberFormatException e) { … }; em VB.NET Try … Catch ex As FileNotFoundException … End Try. Marcas: as instruções arriscadas dentro do try, os nomes corretos de exceção, uma mensagem para cada, e o programa continuando depois; um catch-all except: ganha a marca de crash mas não a de "exceção apropriada".
Exemplo resolvido. Um arquivo de texto com membros precisa que o número de telefone de um membro seja alterado. Por que o programa não pode simplesmente sobrescrever essa linha, e qual é o padrão? As linhas de um arquivo de texto têm comprimentos diferentes, e o arquivo não possui espaços para absorver a diferença: uma substituição mais longa invadiria o próximo registro, e uma mais curta deixaria parte da linha antiga para trás. Portanto, o padrão consiste em abrir o original para LEITURA e um arquivo temporário para ESCRITA, ler cada linha sequencialmente, escrever a versão nova para a linha que muda e a linha original para todas as outras, fechar ambos e, em seguida, substituir o original pelo arquivo temporário. A mesma estrutura serve para excluir (omitar a linha) e inserir (escrever a linha extra). Observe que todas as linhas são escritas, não apenas a alterada — escrever apenas o novo registro e perder o resto do arquivo é um erro clássico.
Como o tratamento de exceções flui
Passe passo a passo sobre o que acontece quando o código falha. A exceção salta fora do fluxo normal para um manipulador, FINALLY limpa de qualquer forma, e o programa continua em vez de travar.
| Inglês | Chinês | Pinyin |
|---|---|---|
| array/əˈreɪ/ | 数组 | shù zǔ |
| imperative programming/ɪmˈperətɪv ˈprəʊɡræmɪŋ/ | 命令式编程 | mìng lìng shì biān chéng |
| Variables/ˈveərɪəblz/ | 变量 | biàn liàng |
| object-oriented programming/ˈɒbdʒekt ˈɔːrɪəntɪd ˈprəʊɡræmɪŋ/ | 面向对象编程 | miàn xiàng duì xiàng biān chéng |
| instances/ˈɪnstənsɪz/ | 实例 | shí lì |
| exception/ekˈsepʃn/ | 异常 | yì cháng |
| exception handling/ekˈsepʃn ˈhændlɪŋ/ | 异常处理 | yì cháng chǔ lǐ |
| raise/reɪz/ | 抛出 | pāo chū |
| call stack/kɔːl stæk/ | 调用栈 | diào yòng zhàn |
20.2
Definições aceitas pelo examinador
Uma questão de definição é avaliada contra wording fixo. Aprenda estas exatamente, e dê apenas uma resposta.
| Termo | Definição |
|---|---|
| paradigma de programação | um estilo ou modo de programar, com sua própria forma de estruturar um programa |
| linguagem imperativa | o programa é uma sequência de instruções que alteram o estado do programa; o programador diz como a tarefa é realizada |
| linguagem declarativa | o programa declara fatos e regras, e o motor de inferência descobre como encontrar a resposta |
| classe | um modelo que define os atributos e métodos dos objetos desse tipo |
| objeto (instância) | uma ocorrência de uma classe, com seus próprios valores para os atributos |
| atributo | um item de dados pertencente a uma classe |
| método | um procedimento ou função pertencente a uma classe e que atua sobre seus atributos |
| encapsulamento | manter os atributos e métodos juntos em uma classe e restringir o acesso externo aos dados, de modo que sejam alterados apenas por meio de métodos públicos |
| herança | uma subclasse adquire os atributos e métodos de sua superclasse e pode adicioná-los ou sobrescrevê-los |
| polimorfismo | métodos com o mesmo nome que se comportam de maneira diferente para classes distintas |
| construtor | um método que é executado quando um objeto é criado e inicializa seus atributos |
| contenção | uma classe possui um objeto de outra classe como um de seus atributos |
| fato | uma afirmação em um programa declarativo que é verdadeira |
| regra | uma conclusão que vale quando suas condições são verdadeiras |
| arquivo serial, sequencial, aleatório | registros na ordem em que foram adicionados; registros em ordem de chave; cada registro em um endereço calculado a partir de sua chave |
| exceção | um erro ou evento inesperado durante a execução que interrompe o fluxo normal |
| tratamento de exceções | detectar uma exceção quando ela ocorre e executar código que a trata, para que o programa continue |
20.2
Dicas de prova
- Paradigmas: saiba a descrição de uma linha de cada um e esteja pronto para nomear o paradigma a partir de um trecho de código; perguntas de nível baixo exigem os cinco modos de endereçamento e o que o acumulador recebe.
- Definições de POO aparecem em toda sessão: classe, objeto, atributo, método, encapsulamento, herança, polimorfismo, construtor. Escreva uma classe em pseudocódigo com atributos PRIVADOS, um CONSTRUTOR PÚBLICO e getters; uma subclasse com HERDA e SUPER.CONSTRUTOR.
- Declarativa: um objetivo com uma variável retorna todos os fatos correspondentes; uma regra é uma conclusão SE condições unidas com E; copie exatamente os nomes dos predicados da questão.
- Arquivos: os três modos e o que cada um faz com um arquivo existente; READFILE em um loop WHILE NOT EOF; arquivos aleatórios usam hash, SEEK, GETRECORD e PUTRECORD, com colisão de passo-over.
- Exceções: definição com exemplo, três razões para tratá-las, e TRY com EXCEPT nomeado que permite ao programa continuar.
Erros comuns
- Descrever um programa declarativo como "uma sequência de passos que dá a resposta"; ele declara o que é verdadeiro e o que se deseja, não como.
- Confundir um objeto com uma classe, ou uma instância com um atributo; a pergunta "uma ocorrência de um objeto" quer dizer instância.
- Declarar os atributos PÚBLICOS, ou acessá-los de fora da classe em vez de por meio de um getter, o que perde as marcas de encapsulamento.
- O construtor de uma subclasse que define diretamente os atributos do pai em vez de chamar SUPER.CONSTRUTOR.
- Explicar polimorfismo como "muitos objetos"; é o mesmo nome de método se comportando diferentemente para classes distintas.
- Abrir um arquivo FOR WRITE para adicionar um registro, o que destrói o conteúdo existente; use APPEND.
- Ler um arquivo aleatório do início; USE SEEK no endereço hash primeiro.
- Colocar o manipulador de exceções ao redor de código que não pode falhar, ou capturar tudo sem mensagem, ou descrever tratamento de exceções como "verificar a entrada com IF".
Aulas interativas sobre este tópico
Passe por ele passo a passo, com exercícios de verificação instantânea.