No tópico anterior nós vimos os seguintes conceitos:
Seqüências de Escape: representação de caracteres invisíveis através de letras precedidas de contra-barra.
Declaração de variáveis: a declaração é feita, em C, escrevendo primeiro o tipo de dado e depois o identificador da variável, ou seja, seu nome.
Tipos primitivos de dados: estruturas pré-definidas pela linguagem que permitem ao programador seu uso sem qualquer pré-requisito. Em C, temos char, int, float, double e ponteiros.
Qualificadores de tipo: os tipos primitivos podem ser extendidos, melhorados, através do uso de qualificadores. Em C, temos signed, unsigned, short, long, const e volatile.
Atribuição/Assignment: comando ou expressão que (re)define o valor armazenado numa variável, seja em tipo primitivo ou em tipo definido pelo usuário. Permite que uma mesma variável possua valores diferentes no decorrer do programa.
Expressões Matemáticas: combinação de variáveis, constantes, parênteses, funções e operadores suportados em C, de acordo com suas respectivas precedências e associações, para solução de cálculos.
Caracteres de Conversão/Conversion Characters: assim são chamados por K&R os caracteres substituídos nas exibição de uma string formatada ou na leitura através de scanf. Em alguns trechos também usam o termo "Conversion Specification".
Porém são mais comumente referenciados em português como "caracteres de formatação", "códigos de formatação", "comandos de formatação", "especificadores de conversão", "especificadores de formato"(format specifiers, by Microsoft*), "especificadores de tipos", "formatadores de tipos" e outros. Em momento oportuno será apresentada sua tabela e o modo de formatar caracteres de conversão.
*Format Specifiers (C/C++ Language Expressions)
http://msdn.microsoft.com/en-us/library/75w45ekt%28v=vs.71%29.aspx
Constantes Simbólicas/Symbolic Constants
Sempre é preciso conhecer boas práticas de programação. Evite esconder "valores mágicos" como 20 e 300 no fundo de seu código. Eles transmitem pouca informação para quem lê o código e ainda dificulta seu acesso quando for necessário fazer sua alteração.
Um bom modo de tratá-los é através da utilização de nomes significativos. Uma linha iniciada por "#define" determina um nome simbólico(symbolic name/symbolic constant) para uma particular sequência de caracteres, um literal*.
/* Programa para calcular o
custo de um funcionário */
#include <stdio.h>
#include <stdlib.h>
#define SALARIO 650.00
#define DURACAO_DO_CONTRATO 6
#define CARGO "Programador"
int main(){
printf("Tabela de Salario\n");
printf("Cargo: %s\n",CARGO);
printf("Salario: R$%4.2f\n",SALARIO);
printf("Duracao do contrato: %d meses\n", DURACAO_DO_CONTRATO);
printf("Custo para empresa: R$%4.2f\n\n",(SALARIO*DURACAO_DO_CONTRATO));
/***
* Perceba os tipos
* CARGO é string
* SALARIO é float
* DURACAO_DO_CONTRATO é int
***/
return(0);
}
Os valores CARGO, SALARIO e DURACAO_DO_CONTRATO são constantes simbólicas, não são variáveis, e, portanto, não são declaradas, são apenas definidas. Constantes simbólicas são convencionamente escritas em letras maiúsculas para serem facilmente diferenciadas das variáveis, que devem ser escritas em minúsculo.
Por fim, atenção, não se coloca ";" no final da definição de uma constante simbólica.
* Nota do tradutor: o termo literal, principalmente, em obras estrangeiras se refere a algo que é como ele realmente é, e não ao conceito de string. Neste sentido "140" é um literal e é do tipo numérico. Seria portanto um literal numérico.
Um outro modo simples de entender o que é um literal é pensá-lo como sendo um valor fixo, constante, com tipo determinado, podendo ou não ser do tipo string, atribuído à uma variável, constante ou função.
Entrada e Saída de Caracteres
O modelo de entrada/input e saída/output suportado pela biblioteca padrão é bastante simples. Entrada ou saída de texto, independentemente de onde seja originada ou para onde vá, é apenas o tratamento do fluxo/stream de caracteres.
Um fluxo de texto (text stream) é uma seqüência de caracteres divida em linhas, na qual, cada linha consiste em zero ou mais caracteres seguidos por um caractere de nova linha. Essa é a responsabilidade da biblioteca, criar fluxos de E/S (Entrada/Saída, I/O) de acordo com esse modelo. Enquanto isso, o programador C que se valha da biblioteca não precisará se preocupar com a saída de seu programa.
A biblioteca padrão provê inúmeras formas de leitura e escrita de um caractere por vez. Os mais simples são "getchar" e "putchar". O comando getchar lê o próximo caractere de entrada do fluxo de texto e retorna seu valor.
c = getchar();
/* c irá receber o
próximo caractere
do fluxo de texto */
O presente leitor poderá estranhar a expressão "fluxo de texto", porém, saiba que a entrada de texto nem sempre é feita através do teclado ou pelo usuário, poderá, por exemplo, ser de um arquivo de texto ou de uma requisição WEB ou de uma conversa entre programas e etc.
A função putchar imprime, normalmente na tela, o caracter do valor inteiro da variável passada como parâmetro.
putchar(c);
Uma curiosidade da linguagem C em relação ao fluxo de texto é que os caracteres são todos diretamente intercambiáveis com números. A documentação inclusive recomenda a utilização do tipo int para leitura de caracteres, por ter uma faixa de valores possíveis maior que uma variável char comum.
#include <stdio.h>
#include <stdlib.h>
/* Apresentaremos os valores
decimais dos caracteres
invisíveis de C */
int main() {
int i;
/* Salvaremos CHARs em INTs
sem casting explícito. */
i = EOF;
printf("\n EOF = %3d\n\n",i);
i = '\0';
printf("\n \\0 = %3d\n\n",i);
i = '\a';
printf("\n \\a = %3d (bell)\n\n",i);
i = '\b';
printf("\n \\b = %3d (backspace)\n\n",i);
i = '\f';
printf("\n \\f = %3d (formfeed)\n\n",i);
i = '\n';
printf("\n \\n = %3d (newline)\n\n",i);
i = '\r';
printf("\n \\r = %3d (carriage return)\n\n",i);
i = '\t';
printf("\n \\t = %3d (h tab)\n\n",i);
i = '\v';
printf("\n \\v = %3d (v tab)\n\n",i);
i = 'A';
printf("\n A = %3d\n\n",i);
int c;
printf("Digite uma letra: ");
c = getchar();
/* putchar(c); */
printf("\nchar = %d\n\n",c);
return(0);
}
Nas palavras dos autores: um caractere escrito entre aspas simples representa um valor inteiro igual ao valor numérico do caractere no mapa da caracteres da máquina. Isto é chamado de um caractere constante e é apenas uma outra forma de escrever um inteiro pequeno.
Exercício*: faça um programa que leia um texto e que escreva-o substituindo cada seqüência de caracteres em branco por um único espaço.
* Nota do tradutor: o exercício apresentado faz uso de desvios condicionais e uma iteração. Como esta introdução se preocupa em ser uma primeira visão da linguagem para alguém que se inicia em algoritmos, não é esperado que você consiga fazê-lo. Entretando, preferi apresentar a pergunta e uma possível solução para simplesmente não me afastar muito do conteúdo original do livro K&R C.
/***
* Uma possível solução para o
* exercício 1-9 do livro de Brian Kernighan
* e Dennis Ritchie - The C Programming
* Language 2ed, em inglês, mais conhecido
* como K&R C.
*
* A solução não faz uso de vetores. Usa
* apenas três variáveis inteiras e uma
* iteração.
*
***/
#include <stdio.h>
#include <stdlib.h>
#define FIM '\n'
#define ESPACO ' '
int main() {
int
entrada, /* Fluxo de entrada */
posicao, /* Posição do caractere
no fluxo de entrada */
ultimo_espaco; /* Posição do último espaço */
posicao = 0;
/* Posição começa com zero */
ultimo_espaco = -1;
/* O último espaço precisa ser um valor
inválido, ou seja, um valor menor que
zero. Caso contrário, minha lógica
não funcionará. */
while( (entrada = getchar()) != FIM ){
posicao++;
if(entrada == ESPACO ){
if( (posicao - 1) != ultimo_espaco){
putchar(entrada);
} /* Fim do IF aninhado */
ultimo_espaco = posicao;
} else{
putchar(entrada);
} /* Fim do IF-THEN-ELSE */
} /* Fim do WHILE */
return(0);
} /* Fim do MAIN */
Não se preocupe caso não tenha entendido o programa acima. Em breve seremos capazes de solucionar desafios muito maiores. Tenha persistência!
abraços
Nenhum comentário:
Postar um comentário