Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
Ambos lados da revisão anterior Revisão anterior Próxima revisão | Revisão anterior | ||
c:organizacao_de_codigo [2023/08/01 20:15] – edição externa 127.0.0.1 | c:organizacao_de_codigo [2024/09/17 16:52] (atual) – maziero | ||
---|---|---|---|
Linha 1: | Linha 1: | ||
+ | ====== Organização de código ====== | ||
+ | |||
+ | {{ progc_organizacao.mkv |Video desta aula}} | ||
+ | |||
+ | À medida em que um software cresce em tamanho e funcionalidades, | ||
+ | |||
+ | O método usual de organização de código em C consiste em dividir o programa em módulos que são vistos como " | ||
+ | |||
+ | Um programa em C é estruturado em arquivos de código (extensão '' | ||
+ | |||
+ | <note tip> | ||
+ | Dado um arquivo '' | ||
+ | |||
+ | Com isso, funções e tipos que são usados **somente** dentro de '' | ||
+ | </ | ||
+ | |||
+ | Ao dividir o código-fonte em arquivos separados, alguns cuidados devem ser tomados: | ||
+ | |||
+ | * Agrupe as funções e definições de dados associados ao mesmo tópico ou assunto em um mesmo arquivo '' | ||
+ | * Coloque os protótipos das funções públicas e as definições de dados necessárias a esses protótipos em um arquivo de cabeçalho '' | ||
+ | * Somente faça inclusões (''# | ||
+ | |||
+ | <note warning> | ||
+ | **Maldições imperdoáveis** :-X: | ||
+ | * fazer inclusão de arquivos "'' | ||
+ | * colocar código real (for, if, while, ...) em arquivos de cabeçalho ((Exceto quando se tratar de [[https:// | ||
+ | </ | ||
+ | |||
+ | ===== Exemplo ===== | ||
+ | |||
+ | Este exemplo implementa uma mini-biblioteca de números complexos, ou seja, um conjunto de funções para definir e manipular números complexos((Esta biblioteca é inútil, pois o padrão C99 já inclui o suporte a números complexos ...)). | ||
+ | |||
+ | O arquivo principal (neste exemplo, '' | ||
+ | |||
+ | <code c exemplo.c> | ||
+ | // Demonstraçao da biblioteca simples de números complexos :-) | ||
+ | // Carlos Maziero, DINF/UFPR 2020 | ||
+ | |||
+ | #include < | ||
+ | #include " | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | cpx_t a, b, c, d ; | ||
+ | |||
+ | // (10 + 7i) + (-2 + 4i) = (8 + 11i) | ||
+ | a = cpx (10, 7) ; | ||
+ | b = cpx (-2, 4) ; | ||
+ | c = cpx_sum (a, b); | ||
+ | printf ("c vale %s\n", cpx_str (c)) ; | ||
+ | |||
+ | // (3 + 2i) * (1 + 4i) = –5 + 14i | ||
+ | d = cpx_mul (cpx (3, 2), cpx (1, 4)); | ||
+ | printf ("d vale %s\n", cpx_str (d)) ; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <note tip> | ||
+ | Como o arquivo '' | ||
+ | </ | ||
+ | |||
+ | Nossa " | ||
+ | |||
+ | O arquivo de cabeçalho '' | ||
+ | |||
+ | <code c cpx.h> | ||
+ | // Biblioteca simples de números complexos :-) | ||
+ | // Carlos Maziero, DINF/UFPR 2020 | ||
+ | |||
+ | #ifndef __CPX__ | ||
+ | #define __CPX__ | ||
+ | |||
+ | // estrutura de um número complexo | ||
+ | typedef struct { | ||
+ | float r, i; // componentes real e imaginária | ||
+ | } cpx_t ; | ||
+ | |||
+ | // define o valor de um complexo | ||
+ | cpx_t cpx (float r, float i) ; | ||
+ | |||
+ | // operações aritméticas entre dois complexos | ||
+ | cpx_t cpx_sum (cpx_t a, cpx_t b) ; | ||
+ | cpx_t cpx_sub (cpx_t a, cpx_t b) ; | ||
+ | cpx_t cpx_mul (cpx_t a, cpx_t b) ; | ||
+ | cpx_t cpx_div (cpx_t a, cpx_t b) ; | ||
+ | |||
+ | // devolve os componentes de um número complexo | ||
+ | float cpx_real (cpx_t c) ; | ||
+ | float cpx_imag (cpx_t c) ; | ||
+ | |||
+ | // gera uma string a partir de um número complexo | ||
+ | char* cpx_str (cpx_t c) ; | ||
+ | |||
+ | // outras operações | ||
+ | // ... | ||
+ | |||
+ | #endif | ||
+ | </ | ||
+ | |||
+ | Deve-se observar o uso das macros de pré-compilação ''# | ||
+ | |||
+ | Por sua vez, o arquivo '' | ||
+ | |||
+ | <code c cpx.c> | ||
+ | // Biblioteca simples de números complexos :-) | ||
+ | // Carlos Maziero, DINF/UFPR 2020 | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include " | ||
+ | |||
+ | // conversão de coordenadas polares em retangulares. | ||
+ | // Obs: esta é uma função interna; com o modificador " | ||
+ | // ela só pode ser acessada por código dentro deste arquivo. | ||
+ | static void polar_to_rect (float r, float a, float *x, float *y) | ||
+ | { | ||
+ | // implementação da função | ||
+ | // ... | ||
+ | } | ||
+ | |||
+ | // define os valores de um número complexo | ||
+ | cpx_t cpx (float r, float i) | ||
+ | { | ||
+ | cpx_t new = {r, i} ; | ||
+ | return (new) ; | ||
+ | } | ||
+ | |||
+ | // soma de dois complexos | ||
+ | cpx_t cpx_sum (cpx_t a, cpx_t b) | ||
+ | { | ||
+ | cpx_t sum ; | ||
+ | sum.r = a.r + b.r ; | ||
+ | sum.i = a.i + b.i ; | ||
+ | return (sum) ; | ||
+ | } | ||
+ | |||
+ | // diferença de dois complexos | ||
+ | cpx_t cpx_sub (cpx_t a, cpx_t b) | ||
+ | { | ||
+ | cpx_t sum ; | ||
+ | sum.r = a.r - b.r ; | ||
+ | sum.i = a.i - b.i ; | ||
+ | return (sum) ; | ||
+ | } | ||
+ | |||
+ | // produto de dois complexos | ||
+ | cpx_t cpx_mul (cpx_t a, cpx_t b) | ||
+ | { | ||
+ | cpx_t prod ; | ||
+ | prod.r = a.r * b.r - a.i * b.i ; | ||
+ | prod.i = a.r * b.i + a.i * b.r ; | ||
+ | return (prod) ; | ||
+ | } | ||
+ | |||
+ | // implementação das demais funções | ||
+ | // ... | ||
+ | </ | ||
+ | |||
+ | Em resumo: | ||
+ | |||
+ | * '' | ||
+ | * '' | ||
+ | * '' | ||
+ | |||
+ | Para compilar: | ||
+ | |||
+ | < | ||
+ | cc -Wall exemplo.c cpx.c -o exemplo | ||
+ | </ | ||
+ | |||
+ | O arquivo '' | ||
+ | |||
+ | < | ||
+ | cc -Wall -c cpx.c | ||
+ | |||
+ | cc -Wall exemplo.c cpx.o -o exemplo | ||
+ | </ | ||
+ | |||
+ | Essa organização torna mais simples a construção de bibliotecas e a distribuição de código binário para incorporação em outros projetos (reuso de código). Além disso, essa estruturação agiliza a compilação de grandes projetos, através do [[o sistema Make|sistema Make]]. | ||