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:
- 123 - Valor inteiro direto.
- 123u - Valor inteiro não sinalizado.
- 0x123 - Valor em hexadecimal (zero, seguido de xis).
- O123 - Valor em octal (letra O no inicio).
- 123l - Valor longo.
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.