UC00669

Programação em C/C++ — básico

Sintaxe, pointers, structs, ficheiros

Curso profissional · 50h · Linguagens de sistema

Plano

  1. C vs C++ — quando usar
  2. Setup e Hello World
  3. Sintaxe C básica
  4. Pointers e memória
  5. Arrays e strings
  6. Structs
  7. Funções e modularização
  8. Ficheiros
  9. Introdução a C++

Bloco 1 · Contexto

Por que aprender C/C++

  • Linguagens de sistema — kernels, drivers, embedded.
  • Performance máxima — controlo total da memória.
  • Base para Linux, Windows, jogos AAA, motores 3D.
  • Embedded — Arduino, microcontroladores, IoT.
  • Salários altos em embedded, jogos, finanças.

Curva difícil, mas conceitos compensam para sempre.

C vs C++

C C++
Procedural OOP + procedural + functional
Sintaxe simples Mais features (e complexidade)
printf cout (ou printf)
malloc / free new / delete ou smart pointers
Kernels, embedded Jogos, sistemas grandes

C é subset (quase) de C++. Vamos começar por C e depois ver C++.

Setup

# Linux/Mac: já tens gcc/g++
gcc --version
g++ --version

# Windows: instalar MSYS2 ou WSL
# Ou MinGW

# IDE: VSCode + extensão C/C++
# Ou CLion (JetBrains, pago)
# Ou Code::Blocks (gratuito)

Hello World em C

// hello.c
#include <stdio.h>

int main() {
    printf("Olá mundo!\n");
    return 0;
}
gcc hello.c -o hello
./hello

#include <stdio.h> = importa funções de I/O.
return 0 = sucesso.

Bloco 2 · Sintaxe C

Tipos primitivos

int idade = 25;              // 4 bytes
long populacao = 8000000000L;
short pequeno = 100;
char letra = 'A';            // 1 byte, ASCII
float taxa = 0.21f;
double preco = 9.99;

// sem tipo string nativo — usa-se char[]
char nome[] = "Ana";
sizeof(int);      // 4
sizeof(double);   // 8
sizeof(char);     // 1

printf e scanf

#include <stdio.h>

int main() {
    int idade;
    char nome[50];
    
    printf("Nome: ");
    scanf("%s", nome);     // sem & em arrays
    
    printf("Idade: ");
    scanf("%d", &idade);   // & = endereço de
    
    printf("Olá, %s! Tens %d anos.\n", nome, idade);
    return 0;
}

Format specifiers: %d (int), %f (float), %s (string), %c (char), %lf (double).

Operadores

// Aritméticos: + - * / %
int divisao = 10 / 3;       // 3 (int)
double real = 10.0 / 3;     // 3.333

// Atribuição composta
int x = 10;
x += 5;     // 15
x++;        // 16
++x;        // 17

// Comparação
a == b      // igual
a != b      // diferente
a < b, >, <=, >=

// Lógicos
&& ||  !

// Bitwise
&  |  ^  ~  <<  >>

Estruturas controlo

// If
if (idade >= 18) {
    printf("Adulto\n");
} else if (idade >= 13) {
    printf("Adolescente\n");
} else {
    printf("Criança\n");
}

// Switch
switch (dia) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        printf("Útil\n");
        break;
    case 6:
    case 7:
        printf("Weekend\n");
        break;
    default:
        printf("Inválido\n");
}

Loops

// For
for (int i = 0; i < 10; i++) {
    printf("%d\n", i);
}

// While
int i = 0;
while (i < 5) {
    printf("%d\n", i);
    i++;
}

// Do-while
do {
    // pelo menos uma vez
} while (cond);

// Break e continue
for (int i = 0; i < 100; i++) {
    if (i == 50) break;
    if (i % 2 == 0) continue;
    printf("%d\n", i);
}

Bloco 3 · Arrays e Strings

Arrays

int numeros[5] = {1, 2, 3, 4, 5};
int vazio[10];   // sem inicializar — lixo!
int auto[] = {1, 2, 3};   // tamanho inferido

// Acesso
numeros[0] = 10;
int primeiro = numeros[0];

// Tamanho (em compile-time)
int tamanho = sizeof(numeros) / sizeof(int);

// Iterar
for (int i = 0; i < 5; i++) {
    printf("%d\n", numeros[i]);
}

// CUIDADO: sem bounds check!
// numeros[100] = 0;  // crash ou corrupção

Strings (char arrays)

#include <string.h>

char nome[50] = "Ana";

// strlen — comprimento
int len = strlen(nome);   // 3

// strcpy — copiar
char outro[50];
strcpy(outro, nome);

// strcat — concatenar
char saudacao[100] = "Olá, ";
strcat(saudacao, nome);   // "Olá, Ana"

// strcmp — comparar
if (strcmp(nome, "Ana") == 0) {
    printf("É a Ana!\n");
}

// fgets (mais seguro que scanf)
char linha[100];
fgets(linha, 100, stdin);

Strings terminam com '\0' (null terminator).

Bloco 4 · Pointers

O que é um pointer

Pointer = variável que guarda um endereço de memória.

int x = 42;
int *p = &x;     // p aponta para x

printf("%d\n", x);   // 42
printf("%d\n", *p);  // 42 (deref)
printf("%p\n", p);   // 0x7ffe... (endereço)

*p = 100;        // x agora vale 100
printf("%d\n", x);   // 100

& = endereço de.
* = valor apontado por (deref).

Pointers e arrays

int arr[5] = {10, 20, 30, 40, 50};

int *p = arr;    // p aponta para arr[0]
printf("%d\n", *p);      // 10
printf("%d\n", *(p+1));  // 20
printf("%d\n", p[2]);    // 30 (mesma coisa)

// Aritmética de pointers
p++;             // próximo int
printf("%d\n", *p);  // 20

Array é (quase) pointer ao primeiro elemento.

Memória dinâmica

#include <stdlib.h>

// malloc — aloca memória
int *arr = (int *) malloc(10 * sizeof(int));
if (arr == NULL) {
    // sem memória!
    return 1;
}

arr[0] = 42;
arr[9] = 99;

// free — liberta!
free(arr);
arr = NULL;  // boa prática

Cada malloc precisa de um free. Memory leaks são um problema clássico em C.

Bloco 5 · Funções

Definição e chamada

// Declaração (prototype) — opcional se definido antes
int somar(int a, int b);

// Definição
int somar(int a, int b) {
    return a + b;
}

int main() {
    int resultado = somar(2, 3);
    printf("%d\n", resultado);   // 5
    return 0;
}

Passar por valor vs por referência

// Por valor — cópia
void incrementa(int n) {
    n++;  // só altera cópia local
}

// Por referência (pointer) — altera original
void incrementa_real(int *n) {
    (*n)++;
}

int main() {
    int x = 5;
    incrementa(x);
    printf("%d\n", x);   // 5 (não mudou)
    
    incrementa_real(&x);
    printf("%d\n", x);   // 6
}

Modularização

Header (utils.h):

#ifndef UTILS_H
#define UTILS_H

int somar(int a, int b);
int maximo(int a, int b);

#endif

Implementação (utils.c):

#include "utils.h"

int somar(int a, int b) { return a + b; }
int maximo(int a, int b) { return a > b ? a : b; }

Main (main.c):

#include <stdio.h>
#include "utils.h"

int main() {
    printf("%d\n", somar(2, 3));
}

Compilar:

gcc main.c utils.c -o programa

Bloco 6 · Structs

Definição

struct Pessoa {
    char nome[50];
    int idade;
    double altura;
};

int main() {
    struct Pessoa p1;
    strcpy(p1.nome, "Ana");
    p1.idade = 25;
    p1.altura = 1.65;
    
    printf("%s, %d anos, %.2fm\n", p1.nome, p1.idade, p1.altura);
    
    // Initializer
    struct Pessoa p2 = {"Bruno", 30, 1.80};
    return 0;
}

typedef

typedef struct {
    char nome[50];
    int idade;
} Pessoa;

// Agora sem "struct"
Pessoa p1 = {"Ana", 25};
Pessoa *ptr = &p1;
ptr->idade = 26;   // -> para acesso via pointer

-> = deref + access (igual a (*ptr).idade).

Bloco 7 · Ficheiros

Ler ficheiro

#include <stdio.h>

int main() {
    FILE *f = fopen("dados.txt", "r");
    if (f == NULL) {
        perror("Erro");
        return 1;
    }
    
    char linha[256];
    while (fgets(linha, sizeof(linha), f) != NULL) {
        printf("%s", linha);
    }
    
    fclose(f);
    return 0;
}

Sempre fechar com fclose. Modos: "r", "w", "a", "r+", "rb" (binário).

Escrever ficheiro

FILE *f = fopen("output.txt", "w");
if (f == NULL) {
    perror("Erro");
    return 1;
}

fprintf(f, "Olá mundo!\n");
fprintf(f, "Número: %d\n", 42);

fclose(f);

"w" = sobrescreve; "a" = append.

Bloco 8 · C++

C++ vs C — diferenças básicas

// hello.cpp
#include <iostream>
using namespace std;

int main() {
    cout << "Olá mundo!" << endl;
    
    string nome;
    cout << "Nome: ";
    cin >> nome;
    cout << "Olá, " << nome << "!" << endl;
    
    return 0;
}
g++ hello.cpp -o hello
./hello
  • iostream em vez de stdio.h.
  • cout / cin em vez de printf / scanf.
  • string em vez de char[].

Classes em C++

class Pessoa {
private:
    string nome;
    int idade;
    
public:
    Pessoa(string n, int i) : nome(n), idade(i) {}
    
    void apresentar() {
        cout << "Olá, sou " << nome << endl;
    }
    
    string getNome() const { return nome; }
};

int main() {
    Pessoa p("Ana", 25);
    p.apresentar();
}

std::vector — alternativa a arrays

#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> nums = {1, 2, 3, 4, 5};
    nums.push_back(6);
    nums.pop_back();
    
    for (int n : nums) {
        cout << n << " ";
    }
    cout << endl;
    
    cout << "Size: " << nums.size() << endl;
}

vector = array dinâmico, sem malloc/free.

UC00669 · resumo

  • C é a base — sintaxe minimalista, controlo total.
  • Pointers são poderosos mas perigosos — entender bem.
  • malloc/free sempre em pares.
  • Strings em C são char[] terminados em \0.
  • Structs + typedef para tipos compostos.
  • Ficheiros com fopen/fclose.
  • C++ adiciona OOP, strings, vectors, exceptions.
  • Base para embedded, sistemas, jogos, kernels.

NOTAS DO PROFESSOR 📖 Porquê aprender C e C++ C e C++ são linguagens de sistema que estão na base de kernels, drivers, jogos AAA e sistemas embebidos, oferecendo desempenho máximo e controlo total da memória. A curva de aprendizagem é exigente, mas os conceitos que se ganham, como gestão de memória e ponteiros, valem para toda a carreira. Convém motivar os formandos mostrando onde estas linguagens estão presentes no dia a dia. 🗣️ Pontos a desenvolver oralmente • Dar exemplos concretos de software escrito em C ou C++ • Explicar a relação entre controlo de memória e desempenho • Enquadrar a dificuldade como investimento que compensa a longo prazo

NOTAS DO PROFESSOR 📖 Duas linguagens, uma raiz comum C é procedural e minimalista; C++ acrescenta orientação a objetos e muitas funcionalidades, ao custo de maior complexidade. Como C é quase um subconjunto de C++, faz sentido começar pelo C, dominar os fundamentos, e só depois subir para C++. Esta tabela ajuda os formandos a perceber quando cada linguagem é a escolha natural. 🗣️ Pontos a desenvolver oralmente • Justificar a opção pedagógica de começar por C • Contrastar malloc/free de C com new/delete de C++ • Dar exemplos de domínios típicos de cada linguagem

NOTAS DO PROFESSOR 📖 Preparar o ambiente de compilação Ao contrário de linguagens interpretadas, C e C++ precisam de um compilador, tipicamente o gcc e o g++, já presentes em Linux e Mac. Em Windows, há que instalar MSYS2, WSL ou MinGW, passo onde os iniciantes costumam encalhar. Convém também recomendar um editor com bom suporte, como o VS Code com a extensão C/C++. 🗣️ Pontos a desenvolver oralmente • Distinguir linguagem compilada de interpretada • Antecipar as dificuldades de instalação em Windows • Mostrar como confirmar que o compilador está instalado

NOTAS DO PROFESSOR 📖 O primeiro programa em C O clássico Olá mundo introduz vários elementos essenciais de uma só vez: o include para trazer funções de entrada e saída, a função main como ponto de entrada, o printf e o return 0 a sinalizar sucesso. É também o momento de mostrar o ciclo compilar e executar com o gcc, que será repetido em todos os exercícios. Convém fazer este percurso ao vivo para os formandos verem o programa a correr. 🗣️ Pontos a desenvolver oralmente • Explicar o papel da função main como ponto de entrada • Mostrar o comando de compilação e a execução do binário • Esclarecer o significado do valor de retorno do programa

NOTAS DO PROFESSOR 📖 Tipos primitivos e tamanho de memória Em C, cada tipo tem um tamanho fixo em bytes, e o programador deve estar consciente disso, ao contrário do que acontece em linguagens de mais alto nível. Um ponto crucial é que não existe tipo string nativo: usam-se arrays de char. O operador sizeof revela o espaço ocupado e é uma ferramenta útil para perceber como os dados vivem na memória. 🗣️ Pontos a desenvolver oralmente • Explicar porque os tamanhos dos tipos importam em C • Sublinhar a ausência de tipo string e o uso de char[] • Demonstrar o sizeof em diferentes tipos

NOTAS DO PROFESSOR 📖 Entrada e saída com printf e scanf O printf e o scanf são a forma básica de comunicar com o utilizador em C, e dependem de especificadores de formato que indicam o tipo de cada valor. Um detalhe que confunde os iniciantes é o uso do & no scanf para passar o endereço da variável, exceto com arrays. Errar o especificador de formato é uma fonte comum de bugs subtis que vale a pena prevenir. 🗣️ Pontos a desenvolver oralmente • Explicar porque o scanf precisa do & para variáveis simples • Relacionar cada especificador de formato com o seu tipo • Alertar para os erros causados por especificadores trocados

NOTAS DO PROFESSOR 📖 Operadores em C C oferece o leque completo de operadores: aritméticos, de atribuição composta, de comparação, lógicos e bit a bit. Um ponto a destacar é a divisão inteira: 10 dividido por 3 dá 3, perdendo a parte decimal, um erro clássico de quem vem de outras linguagens. Os operadores bit a bit, menos comuns noutras linguagens, são essenciais em programação de sistemas e embebida. 🗣️ Pontos a desenvolver oralmente • Demonstrar a diferença entre divisão inteira e divisão real • Explicar a diferença entre ++x e x++ • Dar um exemplo prático de operação bit a bit em embebido

NOTAS DO PROFESSOR 📖 Decidir com if e switch As estruturas de controlo permitem ao programa tomar decisões. O if/else if/else cobre condições gerais, enquanto o switch é ideal quando se compara uma variável com vários valores discretos. Um detalhe importante do switch é o break, cuja ausência faz a execução continuar pelos casos seguintes, comportamento que aqui é usado de propósito para agrupar dias úteis. 🗣️ Pontos a desenvolver oralmente • Explicar o efeito da ausência de break no switch • Mostrar como agrupar vários casos com um mesmo bloco • Discutir quando preferir switch a uma cadeia de if/else

NOTAS DO PROFESSOR 📖 Repetir com ciclos C oferece três ciclos: for, when o número de iterações é conhecido; while, quando depende de uma condição; e do-while, que executa pelo menos uma vez. Os comandos break e continue dão controlo fino, permitindo interromper ou saltar iterações. Convém praticar a tradução de um mesmo problema entre as várias formas de ciclo para consolidar a compreensão. 🗣️ Pontos a desenvolver oralmente • Distinguir quando usar for, while ou do-while • Explicar a diferença entre break e continue • Propor reescrever um for como while para fixar o conceito

NOTAS DO PROFESSOR 📖 Arrays e a ausência de verificação de limites Os arrays em C guardam elementos do mesmo tipo em memória contígua, acedidos por índice a começar em zero. O ponto mais crítico, e que distingue C de linguagens mais seguras, é a ausência de verificação de limites: aceder fora do array não dá erro imediato, mas corrompe memória ou faz crashar. Esta responsabilidade recai inteiramente sobre o programador. 🗣️ Pontos a desenvolver oralmente • Sublinhar que os índices começam em zero • Explicar o perigo de aceder fora dos limites do array • Mostrar o cálculo do tamanho com sizeof dividido pelo tipo

NOTAS DO PROFESSOR 📖 Strings como arrays de caracteres Em C, uma string é apenas um array de char terminado por um carácter nulo, o \0, que marca o seu fim. As funções da string.h, como strlen, strcpy, strcat e strcmp, operam sobre este formato e dependem desse terminador. Convém também apresentar fgets como alternativa mais segura ao scanf para ler linhas, prevenindo estouros de buffer. 🗣️ Pontos a desenvolver oralmente • Explicar o papel do terminador nulo no fim da string • Mostrar o que acontece se o terminador faltar • Justificar fgets como mais seguro que scanf para texto

NOTAS DO PROFESSOR 📖 O conceito de ponteiro O ponteiro é o conceito mais poderoso e mais temido de C: uma variável que guarda um endereço de memória, em vez de um valor direto. É essencial separar bem dois operadores: o & obtém o endereço de uma variável, e o * acede ao valor guardado nesse endereço. Alterar o valor através do ponteiro modifica a variável original, ideia que sustenta tudo o que vem a seguir. 🗣️ Pontos a desenvolver oralmente • Usar uma analogia, como morada e casa, para endereço e valor • Distinguir claramente os operadores & e * • Mostrar ao vivo que mexer via ponteiro altera o original

NOTAS DO PROFESSOR 📖 A relação íntima entre ponteiros e arrays Em C, o nome de um array comporta-se quase como um ponteiro para o seu primeiro elemento, e por isso aceder por índice ou por aritmética de ponteiros é equivalente. A aritmética de ponteiros avança em unidades do tipo apontado, não em bytes, o que é uma subtileza importante. Compreender esta ligação desmistifica muito código C que parece obscuro à primeira vista. 🗣️ Pontos a desenvolver oralmente • Mostrar que p[2] e *(p+2) dão o mesmo resultado • Explicar que a aritmética avança pelo tamanho do tipo • Esclarecer a diferença subtil entre array e ponteiro

NOTAS DO PROFESSOR 📖 Gerir memória manualmente Ao contrário de linguagens com recolha automática de lixo, em C o programador aloca memória com malloc e tem de a libertar com free. A regra de ouro é que cada malloc precisa de um free correspondente; esquecê-lo causa fugas de memória, um problema clássico que degrada programas a longo prazo. É também boa prática verificar se a alocação falhou e anular o ponteiro depois de libertar. 🗣️ Pontos a desenvolver oralmente • Explicar a diferença entre memória na stack e no heap • Sublinhar a regra um malloc, um free • Mostrar como uma fuga de memória se acumula ao longo do tempo

NOTAS DO PROFESSOR 📖 Definir e chamar funções As funções permitem organizar o código em blocos reutilizáveis, recebendo parâmetros e devolvendo um resultado. Um conceito importante é o protótipo, ou declaração, que informa o compilador da assinatura da função antes da sua definição. Note-se a separação entre declaração, definição e chamada, que estrutura qualquer programa C bem organizado. 🗣️ Pontos a desenvolver oralmente • Explicar para que serve o protótipo de uma função • Distinguir parâmetros de argumentos • Mostrar o fluxo entre a chamada na main e o retorno da função

NOTAS DO PROFESSOR 📖 Passar por valor ou por referência Por omissão, C passa argumentos por valor, ou seja, a função recebe uma cópia e não altera o original. Para modificar a variável original, passa-se o seu endereço com um ponteiro, simulando passagem por referência. Este contraste é uma aplicação direta dos ponteiros e explica muito código C onde se vê o & na chamada e o * dentro da função. 🗣️ Pontos a desenvolver oralmente • Demonstrar que a função por valor não altera o original • Mostrar como o ponteiro permite alterar a variável de fora • Ligar este conceito ao que foi visto sobre ponteiros

NOTAS DO PROFESSOR 📖 Organizar o código em módulos À medida que os programas crescem, convém dividi-los em ficheiros: o header com as declarações e o ficheiro de implementação com o código. O guarda de inclusão, com ifndef e define, evita que o mesmo header seja incluído duas vezes. Compilar vários ficheiros num só comando mostra como o código modular se junta no binário final. 🗣️ Pontos a desenvolver oralmente • Explicar a separação entre header e implementação • Mostrar o papel do guarda de inclusão no header • Demonstrar a compilação de múltiplos ficheiros em conjunto

NOTAS DO PROFESSOR 📖 Agrupar dados com structs As structs permitem juntar dados de tipos diferentes numa única entidade lógica, como uma pessoa com nome, idade e altura. Acede-se aos campos com o operador ponto, e podem inicializar-se de uma só vez com um inicializador. São o primeiro passo para representar entidades do mundo real no código, antes de chegar às classes em C++. 🗣️ Pontos a desenvolver oralmente • Comparar uma struct com uma ficha de dados do mundo real • Mostrar o acesso aos campos com o operador ponto • Antecipar a relação entre structs em C e classes em C++

NOTAS DO PROFESSOR 📖 Simplificar tipos com typedef O typedef cria um nome alternativo para um tipo, evitando repetir a palavra struct em cada utilização e tornando o código mais limpo. Surge também aqui um operador novo, a seta, usado para aceder a campos de uma struct através de um ponteiro, equivalente a desreferenciar e aceder. Este operador aparece constantemente em código C que manipula structs por ponteiro. 🗣️ Pontos a desenvolver oralmente • Mostrar como o typedef elimina a repetição da palavra struct • Explicar a equivalência entre a seta e a forma com asterisco e ponto • Justificar porque a seta é tão comum em código real

NOTAS DO PROFESSOR 📖 Ler ficheiros em C A leitura de ficheiros segue um padrão claro: abrir com fopen, verificar se a abertura falhou, ler e por fim fechar com fclose. Verificar o ponteiro nulo é essencial, pois o ficheiro pode não existir ou estar inacessível. Usar fgets dentro de um ciclo é a forma idiomática de percorrer um ficheiro linha a linha até ao fim. 🗣️ Pontos a desenvolver oralmente • Sublinhar a importância de verificar o resultado de fopen • Explicar porque fechar o ficheiro com fclose é obrigatório • Apresentar os vários modos de abertura e quando usar cada um

NOTAS DO PROFESSOR 📖 Escrever em ficheiros Escrever segue uma estrutura simétrica à leitura: abrir no modo adequado, escrever com fprintf e fechar. O detalhe mais importante é a diferença entre os modos: w apaga o conteúdo existente e começa do zero, enquanto a acrescenta ao fim sem destruir o que lá estava. Confundir estes dois modos é uma fonte comum de perda acidental de dados. 🗣️ Pontos a desenvolver oralmente • Alertar para o risco do modo w apagar o ficheiro existente • Mostrar quando o modo append é a escolha certa, como em logs • Reforçar mais uma vez a importância de fechar o ficheiro

NOTAS DO PROFESSOR 📖 As diferenças básicas do C++ A passagem de C para C++ traz conveniências imediatas: o iostream com cout e cin substitui o printf e scanf, e o tipo string facilita muito o trabalho com texto face aos arrays de char. Note-se a compilação com g++ em vez de gcc. Estas melhorias tornam o C++ mais produtivo, mantendo todo o poder e desempenho do C por baixo. 🗣️ Pontos a desenvolver oralmente • Comparar cout/cin com printf/scanf no mesmo programa • Destacar a comodidade do tipo string face a char[] • Esclarecer que se compila com g++ e não gcc

NOTAS DO PROFESSOR 📖 Classes: o coração da orientação a objetos As classes em C++ juntam dados e funções que operam sobre eles, com controlo de acesso através de private e public. O construtor inicializa o objeto no momento da criação, e os métodos definem o seu comportamento. Note-se a evolução natural a partir das structs de C: a struct guardava só dados, a classe acrescenta comportamento e encapsulamento. 🗣️ Pontos a desenvolver oralmente • Explicar o papel de private e public no encapsulamento • Mostrar o construtor a inicializar o objeto na criação • Relacionar a classe com a struct vista em C

NOTAS DO PROFESSOR 📖 std::vector: arrays sem dores de cabeça O std::vector resolve um dos maiores incómodos do C: a gestão manual de arrays dinâmicos. É um array que cresce e encolhe sozinho, com métodos como push_back, e que liberta a memória automaticamente, eliminando o par malloc e free. Para a maioria dos casos em C++, o vector deve ser a escolha por omissão face aos arrays de C. 🗣️ Pontos a desenvolver oralmente • Contrastar a gestão automática do vector com malloc e free • Mostrar o ciclo for baseado em intervalo a percorrer o vector • Recomendar o vector como opção por defeito em C++

NOTAS DO PROFESSOR 📖 Síntese do percurso em C e C++ Este resumo consolida os pilares da UC: a sintaxe minimalista de C, o poder e o perigo dos ponteiros, a regra malloc e free, as strings terminadas em nulo, as structs e os ficheiros, culminando na introdução ao C++. A mensagem central é que dominar a gestão de memória e os ponteiros é o que distingue quem realmente sabe C. Estas bases abrem a porta ao embebido, aos sistemas e aos jogos. 🗣️ Pontos a desenvolver oralmente • Pedir aos formandos para identificarem o conceito que acharam mais difícil • Reforçar a importância dos ponteiros e da gestão de memória • Sugerir um pequeno projeto que combine structs, ficheiros e funções