Curso de C
Variáveis, Constantes, #Define e Argumentos


  O armazenamento de dados em C pode ser feito de duas maneiras. A primeira delas é através de um tipo de dado que pode ser alterado tanto no código do programa, como também durante a execução dele. Estamos falando das variáveis. O outro tipo de dado pode somente ser modificado no código do programa. Uma vez compilado este e posto a executar, esse valor não pode ser mais alterado. Estamos falando das constantes.
  A diretiva #define substitui um alias (apelido) por um valor ou expressão.
  Os argumentos são dados passados pelo usuário ao programa, através da linha de comando do DOS.
Variáveis   As variáveis são os tipos de dados que podem ter seu valor alterado em tempo de execução.

  O C possui suas variáveis divididas em: INT   Variáveis do tipo inteiro.

  As variáveis do tipo inteiro podem ser:

VARIÁVEL TAMANHO
char 1 byte
short int 2 bytes
int 2 bytes
long int 4 bytes

  Exemplo:
#include <stdio.h>

int idade;

main()
{
  idade = 21;
  printf("A idade e' %d anos.\n", idade);
}
  Saída:
  A idade e' 21 anos.

  Obs: no programa anterior, também poderíamos indicar o valor da idade na declaração, removendo essa declaração dentro da função main().
int idade = 21;

main()
{
  printf("A idade e' %d anos.\n", idade);
}

  Número sinalizado x não sinalizado

  Na linguagem C, as variáveis são distinguidas em números sinalizados e não sinalizados.
  Os números NÃO sinalizados são aqueles que não possuem sinal de positivo ou negativo. Dessa forma, o domínio de um número varia de 0 a N-1, onde N depende do tipo de variável utilizada. Toda variável não sinalizada é declarada precedida pelo termo unsigned. Por exemplo:
unsigned int dado;
  Uma vez que uma variável do tipo int tem DOIS byte, logo o domínio da variável dado vai de 0 a 65535.

  Por sua vez, os números sinalizados possuem um sinal para definir se o valor é positivo ou negativo. Nesse caso, o último bit do valor armazenado (o mais significativo) indica o seu sinal. O valor 0 indica um número positivo e o valor 1 indica um número negativo. Os valores de um número sinalizado variam de -N/2 a N/2 - 1.

  Por exemplo, os números +4 e -8, se representados como char (1 byte ou 8 bits), terão as seguintes configurações em binário:
 bits  76543210
 --------------
  +4 = 00000100
  -8 = 11111000

  Um número sinalizado de 1 byte varia de -128 a 127, enquanto que um número não sinalizado de 1 byte varia de 0 a 255. Veja o exemplo a seguir, onde o mesmo valor 200 é atribuído a uma variável sinalizada e outra não sinalizada.
#include <stdio.h>

unsigned char a;
char b;

int main(void)
{
  a = 200;
  b = 200;

  printf("Valor de a: %d.\n", a);
  printf("Valor de b: %d.\n", b);

  return 1;
}
  Saída:
  Valor de a: 200.
  Valor de b: -56.

  A declaração de unsigned/signed deve sempre vir antes do tipo de dado. Observe que para o signed, não é necessário a indicação (default).

  Literais

  As literais são as formas com que declaramos as variáveis utilizando valores.

  Para os valores inteiros, temos:
  Exemplo:
#include <stdio.h>

unsigned char byte = 0xFF;

main()
{
  printf("Valor do byte em decimal: %d\n", byte);
  printf("Valor do byte em hexadecimal: %X\n", byte);
}
  Saída:
  Valor do byte em decimal: 255
  Valor do byte em hexadecimal: FF

  Observação importante: se tivéssemos esquecido de declarar unsigned à variável byte, teríamos as respectivas saídas: -1 e FFFFFFFF. O valor -1 é BEM diferente do valor esperado 255, o que poderia acarretar em uma série de problemas, se estivéssemos utilizando essa variável em algum tipo de cálculo.
FLOAT   Variável que trabalha com números reais.

  Tipos de variáveis:

VARIÁVEL TAMANHO
float 4 bytes
double 4 bytes

  Exemplo:
#include <stdio.h>
#include <math.h>

double pi = 3.1415927;
double angulo;

int main(void)
{
  angulo = pi/4.0;
  printf("O cosseno de pi/4 é %f.\n", cos(angulo));

  return 1;
}
  Saída:
  O cosseno de pi/4 é 0.707107.

  Observação importante:

  No Hi-Tech C, quando são utilizados pontos flutuantes (double, float), é obrigatória a indicação da biblioteca "libf" na compilação. No caso do exemplo acima, deve-se compilar assim:
A>c -lf teste
  Onde teste é referente ao nome de arquivo "teste.c".

  Caso não seja usada a opção "-lf", um erro em tempo de link acontece:
undefined symbol:
flmul

  Caso esteja compilando no GCC do PC, utilize a opção -lm ao final.
CHAR   Variáveis do tipo letra.

  A variável do tipo char pode se comportar tanto com um número inteiro de um byte, como um caractere. No caso de um caractere, o valor do código ASCII da letra é armazenado.
  Veja o exemplo a seguir.
#include <stdio.h>

unsigned char letra;

main()
{
  /* Define o caractere 'a' */
  letra = 'a';

  /* Forma alternativa de declarar 'a', pelo código ASCII */
  letra = 0x61;

  printf("Letra armazenada: %c\n",letra);
  printf("Respectivo código ASCII: &H%x ou %d\n", letra, letra);
}
  Resultado impresso na tela:
  Letra armazenada: a
  Respectivo código ASCII: &H61 ou 97

  Uma vez que o char se comporta como inteiro, podemos realizar operações aritméticas sobre ele. Veja o exemplo a seguir.
#include <stdio.h>

unsigned char letra1, letra2;

main()
{
  letra1 = 'a';

  /* Operação aritmética sobre 'a' */
  letra2 = letra1 + 1;

  printf("A letra '%c' vem logo apos a letra '%c'.\n", letra2, letra1);
}
  Saída:
  A letra 'b' vem logo apos a letra 'a'
STRING   A variável string é uma cadeia de caracteres. Ela é declarada através de um vetor de caracteres ou um ponteiro de caractere. Vetores e ponteiros veremos mais adiante, porém, cabe a nós sabermos agora o que acarreta a escolha de cada um.
  Ao utilizarmos um vetor para declarar uma string, devemos indicar o número máximo de caracteres. Por exemplo:
char nome[10];
  Declara uma string com tamanho igual a 10 caracteres.

  Já a declaração utilizando ponteiros, não define o tamanho. Exemplo:
char *nome;

  Observe o exemplo a seguir.
#include <stdio.h>
#include <string.h>

char nome[10];
char *endereco;

int main(void)
{
  strcpy(nome,"Cristiane");
  endereco = "Salvador";

  printf("A %s mora em %s.\n", nome, endereco);

  return 1;
}
  Saída:
  A Cristiane mora em Salvador.

  A manipulação de strings requer uma biblioteca chamada string.h. A função strcopy insere na variável nome o valor "Cristiane".

  A função "scanf", que recebe dados do teclado, utiliza como delimitador de strings o espaço em branco. Assim, para palavras compostas, devemos utilizar a função "gets". Veja os exemplos a seguir.
#include <stdio.h>

char nome[20];

main()
{
  printf("Entre com o nome: ");
  scanf("%s",nome);

  printf("Seu nome e': %s\n", nome);
}
  Saída:
  Entre com o nome: Salvador Dali
  Seu nome e': Salvador

#include <stdio.h>

char nome[20];

main()
{
  printf("Entre com o nome: ");
  gets(nome);

  printf("Seu nome e': %s\n", nome);
}
  Saída:
  Entre com o nome: Salvador Dali
  Seu nome e': Salvador Dali

  O uso do "scanf" antes do "gets" fará com que esse "gets" seja ignorado. Para resolver ess problema, temos que utilizar uma outra função "gets" antes. Veja os exemplos a seguir.
#include <stdio.h>

char nome[20];
int idade;

main()
{
  printf("Entre com a idade: ");
  scanf("%d",&idade);

  printf("Entre com o nome: ");
  gets(nome);

  printf("%s tem %d anos.\n", nome, idade);
}
  Saída:
  Entre com a idade: 60
  Entre com o nome:
    tem 60 anos.

#include <stdio.h>

char nome[20];

main()
{
  printf("Entre com a idade: ");
  scanf("%d",&idade);

  printf("Entre com o nome: ");
  gets(nome);
  gets(nome); /* Esse vale! */

  printf("%s tem %d anos.\n", nome, idade);
}
  Saída:
  Entre com a idade: 60
  Entre com o nome: Maria Jose
  Maria Jose tem 60 anos.
Variáveis globais e locais   As variáveis globais são aquelas que são declaradas fora de qualquer estrutura, têm a duração total do programa e podem ser acessadas em qualquer parte do programa. Veja o exemplo a seguir.
#include <stdio.h>

int x=12;

void testa_x()
{
  printf("Valor de x: %d\n", x);
}

main()
{
  testa_x();
}
  Saída:
  Valor de x: 12

  As variáveis locais são criadas dentro de uma estrutura, duram enquanto a estrutura estiver ativa e somente podem ser acessadas naquele local. Veja o exemplo a seguir.
#include <stdio.h>

void testa_y()
{
  int y=5;
  printf("Valor de y: %d\n", y);
}

main()
{
  testa_y();
}
  Saída:
  Valor de y: 5

  Agora, veja o que acontece se tentarmos ler o valor da variável local "y" fora da estrutura em que ela foi declarada.
#include <stdio.h>

void testa_y()
{
  int y=5;
}

main()
{
  printf("Valor de y: %d\n", y);
}
  O programa dá um erro de compilação, dizendo que a variável "y" não foi declarada. Isto acontece porque o compilador não enxerga as variáveis locais fora do ambiente em que elas foram declaradas.

  O mesmo acontece quando a variável é declarada dentro do corpo principal do programa.
#include <stdio.h>

void testa_y()
{
  printf("Valor de y: %d\n", y);
}

main()
{
  int y=5;
  testa_y();
}

  No caso do programa anterior, devemos passar o valor da variável "y" como parâmetro para a função para que ela passe a enxergar esse valor.
#include <stdio.h>

void testa_y(int y)
{
  printf("Valor de y: %d\n", y);
}

main()
{
  int y=5;
  testa_y(y);
}
  Saída:
  Valor de y: 5

  E se eu declarar uma variável local com o mesmo nome de uma variável global?
  Isso é possível, e a variável local prevalece sobre a global. Isto significa que dentro do ambiente da variável local, o valor dela é que vale. Exemplo:
#include <stdio.h>

int x=12;

void testa_x()
{
  int x=4;
  printf("Valor local de x: %d\n", x);
}

main()
{
  printf("Valor global de x: %d\n", x);
  testa_x();
}
  Saída:
  Valor global de x: 12
  Valor local de x: 4
Qual o tamanho de variável que devo esolher?   O tamanho da variável depende do seu programa. Entretanto, procure escolher os tipos de variáveis compatíveis com o domínio do problema. Não há a necessidade, por exemplo, de se utilizar números reais, inteiros longos ou números não sinalizados para armazenar IDADES, que variam normalmente de 0 a 120 anos. Nem tampouco uma string de 255 caracteres para armazenar nome de disciplinas escolares.
  Imagine um banco de dados que armazene milhares de registros. A escolha de uma variável superdimensionada pode comprometer a memória do sistema sem necessidade.
  Já no caso de aplicações científicas, a escolha de uma variável com o máximo de precisão faz toda a diferença. Nesse caso, o espaço de armazenamento é irrrelevante.
Constantes   Uma constante define um tipo de dado que não poderá ter seu valor alterado em tempo de execução.
Através da declaração const   Sua sintaxe é:
const <tipo> <variavel>;

  Veja o exemplo a seguir.
#include <stdio.h>

const int dado = 12;
const double pi = 3.1415927;
const char c = 'k';

main()
{
  printf("Valor de dado: %d\n", dado);
  printf("Valor de pi: %f\n", pi);
  printf("Valor de c: %c\n", c);
}
  Saída:
  Valor de dado: 12
  Valor de pi: 3.141593
  Valor de c: k

  Ao tentarmos alterar o valor de uma constante, um erro em tempo de compilação surge.
const int dado = 12;

main()
{
  dado = 1;
}
Através da diretiva #define   Sua sintaxe é:
#define <alias> <valor>

  Exemplo:
#include <stdio.h>

#define M_PI 3.1415927

main()
{
  printf("Valor de pi: %f\n", M_PI);
}
  Saída:
  Valor de pi: 3.141593
#Define   A diretiva #define substitui um alias (apelido) por um valor ou expressão no programa.

  Exemplos:
#define M_PI 3.1415          /* Substitui o apelido M_PI pelo valor declarado */
#define uchar unsigned char  /* Substitui o apelido uchar pela expressão "unsigned char" */

  Exemplo prático:
#include <stdio.h>

#define uchar unsigned char
#define potencia(a) a*a

uchar a=4;

main()
{
  printf("A potencia de %d e': %d\n", a, potencia(a));
}
  Saída:
  A potencia de 4 e': 16
Passagem de argumentos pela linha de comando do DOS   O C permite a passagem de argumentos pela linha de comandos do DOS, quando o programa é chamado.
  Os argumentos passados pela linha de comando são capturados por dois parâmetros da função main, que devem ser declarados nela:
main (int argc, char *argv[])
  O parâmetro "argc" indica o número de argumentos passados pela linha de comando, enquanto que "argv[]" é um vetor contendo os argumentos.

  Veja o exemplo a seguir.
#include <stdio.h>

main (int argc, char *argv[])
{
  int i;

  for (i=0; i<argc; i++)
    printf("Argumento %d: %s\n", i, argv[i]);
}

  Compilando o arquivo com o nome de TESTE.C, temos a partir da linha de DOS:
A:>TESTE Ola
Argumento 0: TESTE
Argumento 1: Ola
  O primeiro argumento é o próprio nome do programa.

  Os argumentos são separados por espaços em brancos. Por exemplo, o nome Rio de Janeiro se for passado como argumento, teremos:
A:>TESTE Rio de Janeiro
Argumento 0: TESTE
Argumento 1: Rio
Argumento 2: de
Argumento 3: Janeiro
  Cada nome separado por espaço foi considerado como um argumento. Para resolver isso, basta colocar o nome entre aspas:
A:>TESTE "Rio de Janeiro"
Argumento 0: TESTE
Argumento 1: Rio de Janeiro

  O programa a seguir recebe um argumento e o escreve na tela.
#include <stdio.h>

main (int argc, char *argv[])
{
  printf("Bom dia, %s.\n", argv[1]);
}
  Saída:
A:>TESTE Pedro
Bom dia, Pedro.


<< Anterior Linguagem C Próxima >>


/MARMSX/CURSOS/C