Aprendendo C
111 pág.

Aprendendo C


DisciplinaProgramação I20.659 materiais240.196 seguidores
Pré-visualização28 páginas
locais do C são auto por definição. 
extern 
O extern define variáveis que serão usadas em um arquivo apesar de terem sido 
declaradas em outro. Ao contrário dos programas até aqui vistos, podemos ter programas de 
vários milhares de linhas. Estes podem ser divididos em vários arquivos (módulos) que serão 
compilados separadamente. Digamos que para um programa grande tenhamos duas variáveis 
globais: um inteiro count e um float sum. Estas variáveis são declaradas normalmente em 
um dos módulos do programa. Por exemplo: 
int count; 
float sum; 
main (void) 
{ 
... 
return 0; 
} 
Num outro módulo do programa temos uma rotina que deve usar as variáveis globais 
acima. Digamos que a rotina que queremos se chama RetornaCount() e retorna o valor atual 
de count. O problema é que este módulo será compilado em separado e não tomará 
conhecimento dos outros módulos. O que fazer? Será que funcionaria se fizermos assim: 
int count; /* errado */ 
float sum; 
int RetornaCount (void) 
{ 
return count; 
} 
Não. O módulo compilaria sem problema, mas, na hora que fizermos a linkagem (união 
dos módulos já compilados para gerar o executável) vamos nos deparar com uma mensagem 
de erro dizendo que as variáveis globais count e sum foram declaradas mais de uma vez. A 
maneira correta de se escrever o módulo com a função RetornaCount() é: 
extern int count; /* certo */ 
extern float sum; 
int RetornaCount (void) 
{ 
return count; 
} 
Assim, o compilador irá saber que count e sum estão sendo usados no bloco mas que 
foram declarados em outro. 
static 
O funcionamento das variáveis declaradas como static depende se estas são globais ou 
locais. 
Variáveis globais static funcionam como variáveis globais dentro de um módulo, ou seja, 
são variáveis globais que não são (e nem podem ser) conhecidas em outros modulos. Isto é 
88 
util se quisermos isolar pedaços de um programa para evitar mudanças acidentais em variáveis 
globais. 
Variáveis locais static são variáveis cujo valor é mantido de uma chamada da função 
para a outra. Veja o exemplo: 
int count (void) 
{ 
static int num=0; 
num++; 
return num; 
} 
A função count() retorna o número de vezes que ela já foi chamada. Veja que a variável 
local int é inicializada. Esta inicialização só vale para a primeira vez que a função é chamada 
pois num deve manter o seu valor de uma chamada para a outra. O que a função faz é 
incrementar num a cada chamada e retornar o seu valor. A melhor maneira de se entender 
esta variável local static é implementando. Veja por si mesmo, executando seu próprio 
programa que use este conceito. 
register 
O computador tem a memória principal e os registradores da CPU. As variáveis (assim 
como o programa como um todo) são armazenados na memória. O modificador register diz ao 
compilador que a variável em questão deve ser, se possível, usada em um registrador da CPU. 
Vamos agora ressaltar vários pontos importantes. Em primeiro lugar, porque usar o 
register? Variáveis nos registradores da CPU vão ser acessadas em um tempo muito menor 
pois os registradores são muito mais rápidos que a memória. Em segundo lugar, em que tipo 
de variável usar o register? O register não pode ser usado em variáveis globais. Isto 
implicaria que um registrador da CPU ficaria o tempo todo ocupado por conta de uma variável. 
Os tipos de dados onde é mais aconselhado o uso do register são os tipos char e int, mas 
pode-se usá-lo em qualquer tipo de dado. Em terceiro lugar, o register é um pedido que o 
programador faz ao compilador. Este não precisa ser atendido necessariamente. 
Um exemplo do uso do register é dado: 
main (void) 
{ 
register int count; 
for (count=0;count<10;count++) 
 { 
 ... 
 } 
return 0; 
} 
O loop for acima será executado mais rapidamente do que seria se não usássemos o 
register. Este é o uso mais recomendável para o register: uma variável que será usada 
muitas vezes em seguida. 
 
 
Auto-Avaliação 
Veja como você está: 
89 
Considerando o conceito e finalidade dos modificadores de tipo, relacione as afirmativas 
com as palavras reservadas correspondentes (todas as afirmativas devem ser preenchidas com 
o número relacionado ao modificador correspondente, e existe pelo menos uma afirmativa para 
cada modificador): 
 (1)const (3)extern (5)register (7)void 
 (2)volatile (4)static (6)auto 
( ) informa ao compilador que o valor da variável não pode ser alterado por nenhum comando 
do programa, mas que pode ser inicializado 
( ) informa ao compilador que nenhum valor será devolvido pela função 
( ) informa ao compilador que a variável pode ser modificada por algum evento que não está 
sob o controle do programa 
( ) avisa ao compilador que as variáveis que o seguem já foram declaradas em outro lugar 
( ) torna a variável permanente, mantendo seu valor entre chamadas 
( ) útil ao escrever funções generalizadas e funções de biblioteca que podem ser usadas por 
outros programadores, pois permite esconder porções do programa de outras partes do código, 
evitando assim o uso de variável global 
( ) quando apontadores forem passados para a função, garante que nenhum código na 
função poderá modificar os objetos apontados 
( ) armazena o valor da variável em um registrador da CPU, acelerando operações 
( ) usada para declarar variáveis locais automáticas, mas muito pouco usada por já ser o 
padrão (default) 
( ) avisa ao compilador que a variável em questão sera largamente usada e deve permanecer 
acessível da forma mais eficiente possível 
( ) permite ao compilador conhecer a variável sem criar armazenamento para ela novamente 
em outro modulo 
 
Conversão de Tipos 
Em atribuições no C temos o seguinte formato: 
destino=orígem; 
Se o destino e a orígem são de tipos diferentes o compilador faz uma conversão entre os 
tipos. Nem todas as conversões são possíveis. O primeiro ponto a ser ressaltado é que o valor 
de origem é convertido para o valor de destino antes de ser atribuído e não o contrário. 
É importante lembrar que quando convertemos um tipo numérico para outro nós nunca 
ganhamos precisão. Nós podemos perder precisão ou no máximo manter a precisão anterior. 
Isto pode ser entendido de uma outra forma. Quando convertemos um número não estamos 
introduzindo no sistema nenhuma informação adicional. Isto implica que nunca vamos ganhar 
precisão. 
Abaixo vemos uma tabela de conversões numéricas com perda de precisão, para um 
compilador com palavra de 16 bits: 
 
De Para Informação Perdida 
unsigned char char Valores maiores que 127 são alterados 
short int char Os 8 bits de mais alta ordem 
int char Os 8 bits de mais alta ordem 
long int char Os 24 bits de mais alta ordem 
90 
long int short int Os 16 bits de mais alta ordem 
long int int Os 16 bits de mais alta ordem 
float int Precisão - resultado arredondado 
double float Precisão - resultado arredondado 
long double double Precisão - resultado arredondado 
Modificadores de Funções 
A forma geral de uma função é, como já foi visto, 
tipo_de_retorno nome_da_função (declaração_de_parâmetros) 
{ 
corpo_da_função 
} 
Uma função pode aceitar um modificador de tipo. Este vai modificar o modo como a 
função opera na passagem de parâmetros. A forma geral da função ficaria então: 
modificador_de_tipo tipo_de_retorno nome_da_função (declaração_de_parâmetros) 
{ 
corpo_da_função 
} 
O nosso curso não aborda detalhes do funcionamento interno de funções. Para saber 
mais, consulte o manual do seu compilador ou algum livro especializado. 
pascal 
Faz com que a função use a convenção de funções da linguagem de programação Pascal. 
Isto faz com que as funções sejam compatíveis com programas