Revista Do Linux
EDIÇÃO DO MÊS
 CD do Mês
 Jogos
 Kernel

 Entrevista
 Capa
 Tutorial
 Debian
 Programação
 Portáteis
 Segurança

 

Curso de Linguagem C parte III

Olá novamente! Nesta terceira parte de nosso curso de linguagem C iremos apresentar um novo tipo de variável, duas novas operações, formas de impressão de variáveis e comandos novos para controle de fluxo. Com esses conceitos, mais aqueles vistos nas duas primeiras partes, iremos desenvolver um novo programa exemplo. Mãos à obra!

Errata

Antes de começar, quero pedir desculpas por um erro lamentável no último artigo, que detectei somente após a revista ter ido para a gráfica. Eu havia dito que, nas expressões lógicas, os resultados eram representados por 0, para verdadeiro e 1, para falso. Na verdade, o correto é o contrário: expressões verdadeiras têm o valor 1, e falsas têm o valor 0. Peço desculpas e farei o possível para que erros assim não se repitam.

Vetores

Vetores (em inglês, arrays) são um conjunto de dados de um determinado tipo, armazenados de forma ordenada, que podem ser acessados diretamente através de um identificador, conhecido em linguagem matemática por indexador ou índice.

Uma analogia pode ser feita com um conjunto de cinco gavetas, cada uma numerada de 1 a 5. Se colocarmos sempre um determinado tipo de roupa em uma determinada gaveta, por exemplo, camisas na gaveta 1, calças na gaveta 2, e assim por diante, para retirarmos uma calça, acessaremos diretamente a gaveta 2, não sendo necessário verificar todas as outras.

Em C, indicamos que uma determinada variável é um vetor colocando em sua declaração os caracteres de abrir colchete ([) e fechar colchete (]) logo após o nome, com o número de elementos do vetor entre eles. Assim, um vetor com cinco números inteiros é declarado da seguinte forma:


int numeros[5];

Cada um dos elementos do vetor é acessado pelo seu índice, também colocado logo após o nome:



numeros[0] = 13;
numeros[4] = 45;

Uma particularidade da linguagem C é que os índices dos elementos são contados a partir do zero. Por esse motivo, em um vetor de cinco elementos, o quinto (e último) elemento tem o índice 4. Acompanhe:



Primeiro elemento: números[0]
Segundo elemento: números[1]
Terceiro elemento: números[2]
Quarto elemento: números[3]
Quinto elemento: números[4]

Não há diferença na forma de se realizar operações:



numeros[0] = 389;
numeros[3] = 489;
numeros[4] = numeros[0] + numeros[3];
/* o valor de numeros[4] é 878 */

Lembre-se: o primeiro elemento do vetor tem valor 389, o quarto elemento do vetor tem valor 489 e o quinto (e último) elemento é a soma dos elementos anteriores.

Os vetores são largamente utilizados na linguagem C, razão pela qual os veremos novamente em nossos próximos artigos.

Imprimindo valores de variáveis

Na primeira parte do curso, foi mostrado o comando printf, e imprimimos um texto com ele. Mas, e a impressão de valores de variáveis?

Não basta apenas colocar o nome da variável entre aspas, pois dessa forma o nome se torna um texto. Para isso, é necessário utilizar mais um caractere de escape, o sinal de porcentagem (%).

Quando o sinal de porcentagem é colocado dentro de uma cadeia de impressão do comando printf, estamos orientando o compilador a interpretar a letra seguinte ao sinal como o tipo de uma variável. Por enquanto, vamos utilizar o tipo d, para números inteiros decimais. E o nome da variável? Ele deve ficar logo após a cadeia de impressão, separado por uma vírgula, e antes de fechar parênteses. Por exemplo:



int num1;
num1 = 45;
printf("O valor de num1 eh %d\n", num1);

O comando printf permite que sejam impressos os valores de múltiplas variáveis em uma cadeia, desde que haja nomes de variáveis correspondentes, separados por vírgulas:

int num1;
int num2;
num1 = 45;
num2 = 90;
printf("O valor de num1 eh %d e o de num2 eh %d\n", num1, num2);

Você deve estar perguntando como fazer para imprimir o caractere de porcentagem, sem que ele seja interpretado como caractere de escape. Basta colocar dois caracteres seguidos: printf("Imprimindo o sinal de porcentagem: %%\n");

Repare que não serão impressos dois sinais, somente um, pois o primeiro continua sendo um caractere de escape, e o segundo realmente indica que queremos imprimir o caractere.

Controles de fluxo

Como toda linguagem de programação, o C dispõe de comandos que permitem alterar o fluxo do programa, através de condições ou repetições.

O primeiro comando apresentado é o condicional:



if (expressao)
      comando1;
else
      comando2;

Estamos indicando que, se o resultado da expressão entre parênteses for verdadeira (valor = 1), o comando1 será executado; caso contrário (valor = 0), o comando2 será executado. Como, por exemplo, no quadro 1.

A condição de senão (else) é opcional. Caso ela não seja colocada, o comando após o if será executado somente se a expressão for verdadeira.

Se desejarmos que seja executado mais de um comando, podemos agrupá-los entre os caracteres de abrir chave ({) e fechar chave (}), para indicar ao compilador que os comandos fazem parte de um mesmo bloco. Como, por exemplo, no quadro 2.

A posição das chaves é livre, podendo-se inclusive juntar comandos e caracteres de chave na mesma linha.

Veja quadro 3.

O outro comando a ser apresentado é o de repetição:



while (expressao1)
         comando1;

O trecho acima indica que, enquanto a expressão1 for verdadeira (valor = 1) o comando1 será executado. Da mesma forma que no comando condicional, vários comandos podem ser agrupados entre chaves. Veja quadro 4.

Em rotinas de programação na qual a iniciação e a atualização da variável de controle utilizada na expressão são simples, como no exemplo acima, podemos utilizar o comando for:



for (comando0; expressao1; comando1)
        comando2;

Indicamos que, antes do início das repetições, o comando0 será executado, sendo então avaliada a expressão1. Caso ela seja verdadeira, o comando2 será executado. Após isso, o comando1 será executado, e a expressão1 será verificada novamente, repetindo-se o ciclo. O exemplo do comando while pode ser escrito com o comando for dessa forma. Veja quadro 5.

Repare que as chaves não foram necessárias, pois agora só existe um comando a ser repetido.

Operadores de incremento e decremento

Nos últimos dois exemplos, a variável contador era sempre adicionada com o valor 1 a cada repetição. Chamamos essa operação de incremento. Como ela é freqüentemente realizada em programação, o C disponibiliza um operador especial, denominado operador de incremento, e representado pelos caracteres ++ (dois sinais de adição seguidos).

O operador indica que deve ser somada à variável uma unidade:


i = 45;
i++; /* o valor de i eh 46 */

Para situações em que é necessária uma contagem regressiva, foi criado também o operador de decremento, representado pelos caracteres -- (dois sinais de subtração seguidos);



i = 89;
i--; /* o valor de i eh 88 */

Operador resto da divisão

Quando realizamos operações de divisão com números inteiros, temos duas possibilidades:

  • o dividendo é múltiplo do divisor, e o resto da operação é zero, ou;
  • o dividendo não é múltiplo do divisor, caso em que o resto é diferente de zero.

    Na linguagem C, a divisão entre dois números inteiros resulta em um número inteiro:

    
    
    int a;
    a = 5 / 2;/* o valor de a eh 2 */
    
    

    Para calcular o valor do resto de uma divisão, a linguagem C disponibiliza o operador resto de divisão, ou módulo, representado pelo sinal de porcentagem (%):

    
    
    int b;
    b = 5 % 2; /* o valor de b eh 1 */
    
    

    Lembre que o sinal de porcentagem aqui indica uma operação, enquanto no caso de cadeias de impressão ele é um caractere de escape. São situações diferentes e facilmente identificáveis.

    Temos agora todos os conhecimentos necessários para desenvolver nosso programa.

    Números primos

    Vamos agora ao programa exemplo. Iremos apresentar um programa para cálculo dos números primos entre 2 e 50. Para lembrar, números primos são aqueles diferentes da unidade, que são divisíveis (resto da divisão igual a zero) apenas por dois números: ele mesmo e a unidade. Assim, 3 é um número primo, pois é divisível por ele mesmo e 1 apenas; 5 também é um número primo, mas 6 não, pois al&eacu e;m de ser divisível por ele mesmo e 1, ele também é divisível por 2 e por 3.

    Uma das formas para determinar se um número é primo ou não é dividi-lo pelos números primos menores que ele. Utilizando esse procedimento, podemos fazer um programa que calcule os números primos de 2 a 50, de forma crescente, armazenando os números primos encontrados em um vetor, e dividindo os números seguintes pelos números primos já calculados.

    Uma listagem do programa é apresentada a seguir. Você pode gravá-lo com o nome primos.c. Para compilar e gerar um executável, siga os procedimentos já mostrados na primeira parte. Veja quadro 6.

    Todas as variáveis a serem utilizadas são do tipo inteiro. Repare que reservamos cinqüenta posições em um vetor (primos) em que iremos armazenar os números primos já calculados, embora já saibamos que nem todos os números de 2 a 50 são primos. Porém, como não sabemos a quantidade exata, será necessário reservar o máximo de espaço possível.

    O comando de impressão apenas indica que já sabemos qual o primeiro número primo. Este é armazenado na primeira posição do vetor (primos[0]), e um contador (qtdprimos) é iniciado com a quantidade de números primos que já calculamos.

    O primeiro comando de repetição determina a faixa em que iremos calcular os números. Conforme definimos, o número final é 50.

    O segundo comando de repetição fará as divisões do número sendo analisado (i) pelos números primos já calculados. Veja que iniciamos duas variáveis: j, que servirá como índice do vetor, e naoprimo, que será alterado para 1 somente quando houver uma divisão com resto igual a zero, o que indicará que o número sendo analisado não é primo.

    O comando break faz exatamente o que significa, ele "quebra" a seqüência de repetições. Isso foi feito porque a partir do momento em que encontramos um número cuja divisão resultou em resto zero, não são mais necessários novos cálculos, pois já sabemos que o número analisado não é primo. O comando break é bastante útil quando estamos realizando repetições e uma determina a situação permite interromper o processo. Ele pode também ser utilizado em repetições com o comando while, tendo o mesmo efeito.

    O teste para verificar o conteúdo da variável naoprimo é necessário porque não sabemos se as repetições terminaram porque foram feitas todas as divisões pelos números primos ou porque um divisor foi encontrado.

    Caso tenhamos encontrado mais um número primo, o armazenamos no vetor. Repare que, antes de atualizarmos o contador qtdprimos, nós o utilizamos como índice da posição disponível. Você consegue entender a razão disso? Lembre-se do que foi dito sobre os índices dos vetores e qual é o primeiro elemento.

    Por fim, imprimimos na tela o novo número encontrado. Após todas essas explicações, o programa já parece bem simples. Mas ele utilizou recursos interessantes da linguagem, e nos permitiu um bom estudo dos comandos. Como exercício, proponho a substituição dos comandos for por while. Lembre que será necessário iniciar as variáveis!

    O resultado final do programa deverá ser este:

    
    
    # /root> primos
    1 eh primo
    2 eh primo
    3 eh primo
    4 eh primo
    5 eh primo
    7 eh primo
    11 eh primo
    13 eh primo
    17 eh primo
    19 eh primo
    23 eh primo
    29 eh primo
    31 eh primo
    37 eh primo
    41 eh primo
    43 eh primo
    47 eh primo
    

    Se houver diferenças, verifique se não houve possíveis problemas de digitação. Caso ainda haja problemas, entre em contato, para podermos analisar seu problema.

    Conclusão

    Estamos gradativamente conhecendo mais detalhes da linguagem C, com novos operadores, comandos e tipos de variáveis. O próximo artigo continuará esses detalhamentos, com um novo programa exemplo. Até lá!

    Quadro 1

    
    if ( 5 > 4 )
               printf(Cinco eh maior que Quatro\n);
    else
               printf(Cinco nao eh maior que Quatro\n);
    
    Quadro 2
    if ( 5 > 4 )
               {
               printf("Cinco eh maior que Quatro\n");
               printf("E isso todos sabemos\n");
               }
    else
               {
               printf("Cinco nao eh maior que Quatro\n");
               printf("Mas isso eh um absurdo!\n")
               }
    
    Quadro 3
    if ( 5 > 4 ) {
               printf("Cinco eh maior que Quatro\n");
               printf("E isso todos sabemos\n");
    } else    {
               printf("Cinco nao eh maior que Quatro\n");
               printf("Mas isso eh um absurdo!\n");
    }
    
    Quadro 4
    contador = 1;
    while (contador < 3) {
            contador = contador + 1;
            printf("Valor do contador = %d\n", contador);
    
    Quadro 5
    for(contador=1; contador<3; contador = contador +1)
            printf("Valor do contador = %d\n", contador);
    
    Quadro 6
    
    # gcc -o primos primos.c
    # ./primos
    
     Segue a listagem:
    
    #include <stdio.h>
    main()
    {
       int i;
       int j;
       int qtdprimos;
       int naoprimo;
       int primos[50];
       printf("2 eh primo\n");
       primos[0] = 2;
       qtdprimos = 1;
       for(i=3; i<=50; i++) {
        for (j=0, naoprimo=0; j < qtdprimos; j++) {
         if ((i % primos[j]) == 0) {
          naoprimo = 1;
          break;
         }
        }
        if ( naoprimo == 0 ) {
         primos[qtdprimos] = i;
         qtdprimos++;
         printf("%d eh primo\n", i);
        }
       }
    }
    }
    
    
    
  •  

    A Revista do Linux é editada pela Conectiva S/A
    Todos os Direitos Reservados.

    Política de Privacidade
    Anuncie na Revista do Linux