Disciplina · ISPS

Introdução à Programação em C

Da lógica de algoritmos à programação estruturada em C — variáveis, estruturas de controlo, funções, apontadores, memória dinâmica e ficheiros.

EET126 1.º Ano · 2.º Semestre 5 Créditos 80 h contacto

Ficha da disciplina

Informação Geral

Curso

  • Engenharia Electrónica e Telecomunicações

Docente

  • Isac Daniel

Objectivos

Compreender os conceitos gerais da programação, desenvolver programas a partir de pseudocódigo e fluxogramas, e aplicar a linguagem C para resolver problemas ligados a circuitos electrónicos.

Avaliação

3 testes práticos · 2 trabalhos individuais.
Mf = ⅔ Mt + ⅓ Tr
NF = ⅔ Mf + ⅓ NE

Índice

Módulos da Disciplina

  1. Conceitos Básicos de Programação
  2. A Linguagem de Programação C
  3. Estruturas de Controlo
  4. Funções e Arrays
  5. Apontadores e Memória Dinâmica
  6. Estruturas de Dados (struct)
  7. Manipulação de Ficheiros

Módulos 01–02

Conceitos Básicos de Programação

Tópicos

  • Arquitetura computacional básica
  • Implementação de algoritmos
  • Estrutura procedimental de um programa
  • Metodologias de desenvolvimento de programas
  • Ambientes de desenvolvimento integrados (IDEs)
  • Biblioteca de funções standard do C

Etapas do Desenvolvimento

1. Problema → 2. Algoritmo → 3. Código → 4. Compilação → 5. Execução

Estrutura Mínima de um Programa C

#include <stdio.h>

int main(void) {
    printf("Olá, Mundo!\n");
    return 0;
}

Compilar e Executar (Linux / macOS)

$ gcc programa.c -o programa
$ ./programa
Olá, Mundo!
💡 IDEs recomendadas: Code::Blocks, Dev-C++, Visual Studio Code (com extensão C/C++), CLion, ou o clássico gcc na linha de comandos.

Módulos 01–02

A Linguagem de Programação C

Tópicos

  • Estrutura dos programas em C
  • Elementos da linguagem (identificadores, palavras-chave, operadores)
  • Tipos primitivos, constantes e variáveis
  • Expressões e atribuições
  • Entrada e saída na consola

Tipos Primitivos em C

TipoTamanho típicoExemploFormato printf
int4 bytes42%d
float4 bytes3.14f%f
double8 bytes3.14159%lf
char1 byte'A'%c
void———

Entrada e Saída na Consola

#include <stdio.h>

int main(void) {
    int idade;
    float altura;
    char inicial;

    printf("Introduz a idade: ");
    scanf("%d", &idade);

    printf("Introduz a altura (m): ");
    scanf("%f", &altura);

    printf("Introduz a inicial do nome: ");
    scanf(" %c", &inicial);   // o espaço antes de %c ignora whitespace

    printf("Idade: %d anos | Altura: %.2f m | Inicial: %c\n",
           idade, altura, inicial);

    return 0;
}
⚠️ Atenção: no scanf() o nome da variável tem de ser precedido de & (endereço de memória) para tipos primitivos.

Módulos 03–05

Estruturas de Controlo

Instruções de Selecção

// if / else if / else
if (nota >= 14) {
    printf("Aprovado com distinção\n");
} else if (nota >= 10) {
    printf("Aprovado\n");
} else {
    printf("Reprovado\n");
}

// switch
switch (opcao) {
    case 1: ligar();            break;
    case 2: desligar();         break;
    case 3: modo_emergencia();  break;
    default: printf("Opção inválida\n");
}

Instruções de Repetição

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

// while — condição à cabeça
int n = 0;
while (n < 5) {
    printf("%d\n", n);
    n++;
}

// do-while — executa pelo menos uma vez
int x;
do {
    printf("Introduz valor positivo: ");
    scanf("%d", &x);
} while (x <= 0);

Instrução Composta

Combinação de selecção e repetição para resolver problemas complexos — por exemplo, ler N valores e calcular a média apenas dos positivos.

int n, soma = 0, contador = 0, valor;

printf("Quantos valores? ");
scanf("%d", &n);

for (int i = 0; i < n; i++) {
    scanf("%d", &valor);
    if (valor > 0) {
        soma += valor;
        contador++;
    }
}

if (contador > 0)
    printf("Média dos positivos: %.2f\n", (float)soma / contador);
else
    printf("Nenhum valor positivo.\n");

Módulos 06–07

Funções e Arrays

Funções em C

#include <stdio.h>

// Protótipo (declaração)
int soma(int a, int b);
float media(float a, float b);

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

float media(float a, float b) {
    return (a + b) / 2.0f;
}

int main(void) {
    printf("Soma: %d\n", soma(3, 5));
    printf("Média: %.2f\n", media(7.0, 9.0));
    return 0;
}

Passagem de Parâmetros

  • Por valor: a função recebe uma cópia — alterações não afectam o original
  • Por referência (apontadores): a função recebe o endereço — alterações afectam o original
// Por valor — NÃO altera o original
void dobrar_valor(int x) {
    x = x * 2;
}

// Por referência — ALTERA o original
void dobrar_ref(int *x) {
    *x = (*x) * 2;
}

int main(void) {
    int a = 10;
    dobrar_valor(a);
    printf("a = %d\n", a);   // a = 10

    dobrar_ref(&a);
    printf("a = %d\n", a);   // a = 20
    return 0;
}

Vectores (Arrays Unidimensionais)

int notas[5] = {10, 12, 8, 15, 14};

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

// Cálculo da média
int soma = 0;
for (int i = 0; i < 5; i++) soma += notas[i];
printf("Média: %.2f\n", (float)soma / 5);

Matrizes (Arrays Bidimensionais)

int matriz[3][3] = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        printf("%d ", matriz[i][j]);
    }
    printf("\n");
}

Módulos 08–10

Apontadores e Alocação Dinâmica

Conceito de Apontador

Um apontador é uma variável que armazena o endereço de memória de outra variável. É uma das características mais poderosas (e delicadas) do C.

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

printf("Valor de x: %d\n", x);       // 42
printf("Endereço de x: %p\n", &x);    // 0x7ffee...
printf("Valor via p: %d\n", *p);      // 42

*p = 100;                              // altera x através do apontador
printf("x agora: %d\n", x);           // 100

Apontadores e Arrays

int v[5] = {10, 20, 30, 40, 50};
int *p = v;   // p aponta para v[0]

printf("%d\n", *p);       // 10
printf("%d\n", *(p + 2)); // 30   (equivale a v[2])

Alocação Dinâmica — malloc / free

#include <stdlib.h>

// Alocar array de 10 inteiros
int *arr = (int *) malloc(10 * sizeof(int));

if (arr == NULL) {
    printf("Erro de alocação\n");
    return 1;
}

// Usar
for (int i = 0; i < 10; i++) {
    arr[i] = i * i;
}

// Libertar sempre
free(arr);
arr = NULL;   // boa prática: evitar dangling pointer
⚠️ Regra de ouro: cada malloc() deve ter um free() correspondente para evitar memory leaks.

Módulos 11–13

Estruturas de Dados (struct)

Uma struct agrupa várias variáveis (de tipos possivelmente diferentes) num único tipo personalizado.

#include <stdio.h>
#include <string.h>

struct Aluno {
    int   numero;
    char  nome[50];
    float nota;
};

int main(void) {
    // Inicialização directa
    struct Aluno a1 = {123, "Isac Daniel", 17.5};

    printf("Aluno: %s | Nota: %.1f\n", a1.nome, a1.nota);

    // Acesso via apontador
    struct Aluno *ptr = &a1;
    ptr->nota = 18.0;                        // equivale a (*ptr).nota = 18.0
    strcpy(ptr->nome, "Isac O. V. Daniel");

    printf("Aluno: %s | Nota: %.1f\n", ptr->nome, ptr->nota);

    return 0;
}

Array de Structs

struct Aluno turma[3] = {
    {1, "Ana Silva",     15.5},
    {2, "Bruno Costa",   12.0},
    {3, "Carla Mendes",  18.0}
};

for (int i = 0; i < 3; i++) {
    printf("%d — %s : %.1f\n",
           turma[i].numero, turma[i].nome, turma[i].nota);
}
💡 Nota: . acede a campos de uma struct directa; -> acede via apontador.

Módulos 14–16

Manipulação de Ficheiros

Escrita num Ficheiro

#include <stdio.h>

int main(void) {
    FILE *f = fopen("dados.txt", "w");

    if (f == NULL) {
        printf("Erro ao abrir ficheiro\n");
        return 1;
    }

    fprintf(f, "Linha 1\n");
    fprintf(f, "Linha 2\n");
    fprintf(f, "Valor: %d\n", 42);

    fclose(f);
    return 0;
}

Leitura de um Ficheiro

#include <stdio.h>

int main(void) {
    FILE *f = fopen("dados.txt", "r");
    if (f == NULL) return 1;

    char linha[100];
    while (fgets(linha, sizeof(linha), f) != NULL) {
        printf("%s", linha);
    }

    fclose(f);
    return 0;
}

Modos de Abertura

ModoSignificado
"r"Leitura (erro se não existir)
"w"Escrita (cria / trunca)
"a"Append (adiciona ao fim)
"r+"Leitura + escrita
"w+"Escrita + leitura (trunca)
"a+"Leitura + append
"rb" / "wb"Modo binário
⚠️ Lembrete: verificar sempre se fopen() devolveu NULL antes de usar o ficheiro, e fechar sempre com fclose().

Tens dúvidas sobre Programação em C?

Envia-me uma mensagem — respondo a estudantes e colegas.

Contactar