quinta-feira, 21 de abril de 2016

Macros: uso avançado


Como prometi apresento este segundo exemplo mais avançado sobre Macro.
E falando ainda sobre a diretiva #define um recurso poderoso do C.
Blocos de códigos, rotinas completas e até mesmo funções  podem ser encapsuladas
dentro de uma macro, como é o caso deste exemplo.
Criei algumas Macros, a macro GOT recebe uma função inteira, justamente a que cria
uma moldura na tela do dos, e na macro NPRIM criei uma rotina completa para
mostrar números primos e não primos dentro do vetor que recebe de um contador os
100 primeiros números narurais.
Observe que na macro NPRIM chamamos outras macros, inclusive a função
got_color(2, 25, 3, 79, 2, 15); com seus seis parâmetros.
Aproveite este exemplo prático, copie e guarde o código para estudo, saiba que
dificilmente você encontrará outro exemplo como este e como os outros que já
postei no blog, disponibilizado em público sem querer nada em troca.

Veja abaixo uma imagem do progtrama em execução:



Veja abaixo o código do programa:



#include <stdio.h>
#include <conio.h>
#define VERMELHO textcolor(LIGHTRED);
#define AZUL textcolor(LIGHTBLUE);
#define PRETO textcolor(BLACK);
#define ROXO textcolor(LIGHTMAGENTA);
#define CINZA textcolor(DARKGRAY);
#define got\

void got_color(int tam_lin_ini, int tam_lin_fim, int tam_ini_col,\
         int tam_fim_col, int a, int b) {\
     int i, e;\
     if (a >= 1 && a <= 16) {\
         textcolor(a);\
     }\
     if (b >= 1 && b <= 16) {\
         textbackground(b);\
     }\
     for (i = tam_lin_ini; i < tam_lin_fim; i++) {\
         for (e = tam_ini_col; e < tam_fim_col; e++) {\
              gotoxy(e, i);\
              printf(" ");\
         }\
     }\
}
#define NPRIM\
         int i;\
         got_color(2, 25, 3, 79, 2, 15);\
         system("title MACROS: MAIS AVANÇADO");\
         VERMELHO\
         gotoxy(32, 3);\
         printf("MACROS: MAIS AVANÇADO");\
         CINZA\
         gotoxy(29, 5);\
         printf("Vetor de primos e não primos");\
         for( i = 1; i <= 100; i++ ){\
              Vet [ j  ] = i;\
              j++;\
         }\
         gotoxy(22,7);\
         for (i = 1; i < 100; i++){\
              if ( i == 10){ gotoxy(17,8);}\
              if ( i == 20) {gotoxy(17,9);}\
              if ( i == 30){gotoxy(17,10);}\
              if ( i == 40){gotoxy(17,11);}\
              if ( i == 50){gotoxy(17,12);}\
              if ( i == 60){gotoxy(17,13);}\
              if ( i == 70){gotoxy(17,14);}\
              if ( i == 80){gotoxy(17,15);}\
              if ( i == 90){gotoxy(17,16);}\
              for ( j = 2, primo = 0; j < Vet [ i ]; j++ )\
              if ( ( Vet [ i ] % j ) == 0 )\
              primo = 1;\
              if ( primo ){\
                   AZUL\
                   printf(" %3d ", Vet [ i ] );\
              }\
              else{\
                   VERMELHO\
                   printf(" %3d ", Vet [ i ] );\
              }\
         }\
         AZUL\
         gotoxy(19,18);\
         printf("Em vermelho os números primos entre ");\
         VERMELHO\
         printf("1 ");\
         AZUL\
         printf("e ");\
         VERMELHO\
         printf("100");\
         AZUL\
         gotoxy(19,19);\
         printf("Em azul os números não primos entre ");\
         VERMELHO\
         printf("1 ");\
         AZUL\
         printf("e ");\
         VERMELHO\
         printf("100");\
         Sleep(1800);\
         VERMELHO\
         gotoxy(26, 21);\
         printf("Por: ");\
         AZUL\
         printf("Samuel Lima");\
         PRETO\
         gotoxy(26, 22);\
         printf("sa_sp10@hotmail.com");\
         Sleep(1800);\
         VERMELHO\
         gotoxy(37, 24);\
         printf("MUITO OBRIGADO");
int main(){
     int Vet [ 100 ];
     int j = 0, primo;
     NPRIM
     got
     getche();
}

Macros: criando e utilizando

Um outro recurso que impressiona e que também faz parte do C, são as macros.
Para criar uma macro basta usar a diretiva #define e incluir na frente um nome
que será o identificador da macro.
O c possui diversas diretivas que foram definida pelo padrão C ANSI,
más neste e na maioria dos programas mais simples, usamos pelo menos duas que são: #include e #define.
Estas diretivas são definidas geralmente numa única linha e ponto-e-vírgula não são usados.
Espaços são aceitos entre o nome e a string desde que a macro não esteja recebendo parâmetros.
Vale lembrar que se a string for muito longa basta colocar uma barra invertida no final da
linha para que o compilador entenda que tem que continuar na linha seguinte.
Definir os nomes de uma macro em maiúscula pode ser uma boa prática
de programação, porém não são regras.
O programa que criei para exemplo gera 12 números num vetor, e em seguida embaralha
seus elementos, e são chamados um por vez, para que as operações sejam feitas
individualmente.
Criei algumas macros para este exemplo e mostro na prática seu
funcionamento, na verdade fui bem além, em chamar a função textcolor();
 da conio.h através de macro rodando perfeitamente.
Pretendo mostrar outro exemplo de uso de macros mais avançado,
e não quero incluir neste programa para não torna-lo mais complicado,
portanto será muito bom vê-lo no próximo post.

Veja abaixo uma imagem do programa em execução:


Veja abaixo o código do programa:


#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#define tam 12
#define QUADR(x) ( ( x ) * ( x ) )
#define CUBO(x) ( ( x ) * ( x ) * ( x ) )
#define par if( a % 2 == 0 )
#define impar if( a % 2 == 1 )
#define VERMELHO textcolor(LIGHTRED);
#define AZUL textcolor(LIGHTBLUE);
#define PRETO textcolor(BLACK);
#define ROXO textcolor(LIGHTMAGENTA);
#define CINZA textcolor(DARKGRAY);
void got_color(int tam_lin_ini, int tam_lin_fim, int tam_ini_col,
        int tam_fim_col, int a, int b) {
    int i, e;
    if (a >= 1 && a <= 16) {
        textcolor(a);
    }
    if (b >= 1 && b <= 16) {
        textbackground(b);
    }
    for (i = tam_lin_ini; i < tam_lin_fim; i++) {
        for (e = tam_ini_col; e < tam_fim_col; e++) {
            gotoxy(e, i);
            printf(" ");
        }
    }
}
int main(){
    system("title MACROS: CRIANDO E UTILIZANDO");
    int a = 0;
    int y = 0;
    int p = 0;
    int Vet [ tam ];
    int i;
    int x = 0;
    do{
        normvideo();
        system("cls");
        got_color(2, 25, 3, 79, 2, 15);
        for( i = 1; i <= 12; i++ ){
            Vet [ p  ] = i;
            p++;
        }
        if ( tam > 1 ){
            for ( i = 0; i < tam; i++ ){
                p = i + rand() % ( tam - i  );
                int t = Vet [ p ];
                Vet [ p ] = Vet [ i ];
                Vet [ i ] = t;
            }
        }
        VERMELHO
        gotoxy(28, 3);
        printf("MACROS: CRIANDO E UTILIZANDO");
        AZUL
        gotoxy(14, 5);
        printf("SORTEADO          QUADRADO         CUBO          SOBRE");
        for ( i = 0; i < tam; i++){
            for ( i = 0; i < tam; i++ ) {
                do{
                    if ( Vet [ i ] == 0 )
                        Vet [ i ] = tam;
                    a = Vet [ i ];
                    PRETO
                    gotoxy(17, i + 7);
                    printf("%d", a );
                    VERMELHO
                    printf(" %18d ", QUADR ( a ) );
                    ROXO
                    printf(" %14d ", CUBO ( a ) );
                    gotoxy(64, i + 7);
                    CINZA
                    par
                    printf("Par" );
                    impar
                    printf("Ímpar" );
                    i++;
                    x++;
                    Sleep(1800);
                    break;
                }while ( x < tam );
                i = i - 1;
            }
            i = i - 1;
        }
        y++;
        Sleep(1800);
        VERMELHO
        gotoxy(26, 20);
        printf("Por: ");
        AZUL
        printf("Samuel Lima");
        PRETO
        gotoxy(26, 21);
        printf("sa_sp10@hotmail.com");
        Sleep(1800);
        VERMELHO
        gotoxy(37, 23);
        printf("MUITO OBRIGADO");
        getche();
    }while ( y < 1 );
    return 0;
}