Curso de aprofundamento na linguagem C Módulos em C Curso de aprofundamento na linguagem C
Módulos Divisões lógicas de um programa Podem incluir estruturas de dados, funções, constantes e globais Facilitam a manutenção Compilação mais rápida Reuso de código
Módulos: convenções A main fica num módulo separado e apenas inclui os outros módulos Compostos por um arquivo .c e por um arquivo .h Porque 2 arquivos? O que poderia acontecer se fosse apenas um arquivo?
Header X Sources O que fica no cabeçalho? Structs e unions Tipos auxiliares (typedef) Constantes Macros Protótipos de funções Declarações de globais Declaração não é definição!
Header X Source O que fica no fonte? Definições de globais Implementações de funções descritas no header Funções euxiliares que não são exportadas
Propriedade dos Módulos Podem esconder certos símbolos para aplicar um nível de “information hiding” Podemos aplicar alguns conceitos de Orientação a Objetos na construção de módulos
Módulos X Classes Pode ser encarado como uma Classe Várias estruturas de C podem ter equivalências com os conceitos de OO
Equivalências O módulo todo seria uma classe, mas o objeto seria definido por uma struct Atributos agregados na struct Não existem atributos privados em estruturas Diminui o overhead Cuidado no acesso!
Equivalências Métodos: funções que alteram membros da struct Convenções: Devem receber como 1° parâmetro a struct Devem ter nome associado à struct Métodos estáticos: funções que não alteram membros da struct Podem ser definidos como funções normais
Equivalências Métodos privados: podem ser definidos apenas adicionando a palavra chave static Não pode ser visto por outros módulos Visibilidade restrita ao arquivo fonte
Equivalências Atributos Estáticos: variáveis globais Perigo no acesso concorrente Podem ter caráter privado se definidas como static
Equivalências Herança e Polimorfismo Atributos na mesma ordem dos pais Utilização de macros Casts Polimorfismo forçado
Padrões de codificação Importante para adoção da divisão baseada em objetos Ausência implica em: Duplicação de variáveis globais/funções Tempo de produção do programador diminuído
Padrões de codificação Exemplo de notação Adição de prefixos ao nome de globais e funções que são referentes a um determinado módulo ou struct Exemplo: double conta_creditar(Conta *c, double v); Pode ser combinada com algum outro padrão da escolha do usuário Notação húngara Padrão Java de codificação Padrão Linux
Padrões de codificação Construtores e destrutores Incentivam o uso de funções Concentram o processo de alocar e liberar memória, evitando memory leak Exemplo padrões de construtores: Alocação externa void init_conta(Conta *c, int numero, double v); Alocação interna Conta *create_conta(int numero, double v);
Padrões de codificação Destrutores void destroy_conta(Conta *c);
Preprocessador C Executado antes de qualquer processo de compilação ou verificação de tipo Comando identificados pelo prefixo “#” Ferramenta cpp utilizada em conjunto com o gcc Pode ser utilizada em conjunto com outros tipos de arquivo, mas é otimizada para arquivos C (comentários e estilo de programação)
#include Inclui declarações de outros arquivos no arquivo atual Substituição da diretiva #include pelo conteúdo literal do arquivo (copia e cola) Parâmetros entre <> ou “” Deve receber APENAS arquivos de cabeçalho
#define Macros Substituídas pelo preprocessador antes da compilação Constantes Substituídas pelo preprocessador antes da compilação Erros de semântica em Macros Exemplo SQR
#if, #ifdef, #ifndef Decisões de precompilação Código interno da diretiva é adicionado ao programa caso a condição seja satisfeita Código multiplataforma Uso de bibliotecas Construção de headers
#if, #ifdef, #ifndef Utilizados em conjunto com as diretivas #else #elif #endif #if e #elif Expressão como parâmetro Não existem tipos Operadores resultam em inteiros (expressões C)
#if, #ifdef, #ifndef #ifdef e #ifndef Macros como parâmetro Equivalentes aos #if defined #if !defined Exemplo de utilização Arquivos de cabeçalho
#pragma Configuração de opções do compilador Específico para cada compilador Exemplos GCC: #pragma GCC poison [name1 name2...] #pragma GCC dependency “arquivo” [comentário]
#pragma Exemplos VC++ #pragma deprecated(nome1, nome2, …) #pragma hdrstop #pragma once
Comandos # e ## Utilizados normalmente dentro de macros # Prefixo que converte um parâmetro em string. O valor do parâmetro não é utilizado, e sim apenas o nome #define STR(x) #x
Comandos # e ## ## Funde dois tokens A ## B resulta em AB struct command { char *name; void (*function) (void); }; struct command commands[] = { "quit", quit_command }, { "help", help_command }, ... #define COMMAND(NAME) { #NAME, NAME ## _command } struct command commands[] = { COMMAND (quit), COMMAND (help), ... };
Macros pré-definidas __LINE__ __FILE__ __cplusplus __DATE__ ...
#error e #warning Emitem mensagens de erro antes da compilação #error Emite mensagem e aborta compilação #warning Apenas emite mensagem