Programar em C/Variáveis: diferenças entre revisões

[edição não verificada][edição não verificada]
Conteúdo apagado Conteúdo adicionado
Edudobay (discussão | contribs)
Edudobay (discussão | contribs)
Removida "Modificadores de acesso"
Linha 91:
 
<div style="background-color: #ddffdd; padding: 10px; margin: 20px;">'''Nota''' Você pode abreviar <tt>short int</tt> e <tt>long int</tt> para simplesmente <tt>short</tt> e <tt>long</tt>, respectivamente.</div>
 
=== Modificadores de acesso ===
 
Estes modificadores, como o próprio nome indica, mudam a maneira com a qual a variável é acessada e modificada.Alguns dos exemplos usam conceitos que só serão abordados nas seções seguintes, então você pode deixar esta seção para depois se assim o desejar.
 
==== const ====
 
O modificador '''<tt>const</tt>''' faz com que a variável não possa ser modificada no programa. Como o nome já sugere é útil para se declarar constantes. Poderíamos ter, por exemplo:
 
const float PI = 3.1415;
 
Podemos ver pelo exemplo que as variáveis com o modificador const podem ser inicializadas. Mas PI não poderia ser alterado em qualquer outra parte do programa. Se o programador tentar modificar PI o compilador gerará um erro de compilação.
 
Outro uso de '''const''', aliás muito comum que o outro, é evitar que um parâmetro de uma função seja alterado pela função. Isto é muito útil no caso de um [[Programar em C: Ponteiros|ponteiro]], pois o conteúdo de um ponteiro pode ser alterado por uma função. Para proteger o ponteiro contra alterações, basta declarar o parâmetro como const. Veja o exemplo a seguir (ele contém vários conceitos que só serão abordados nas seções seguintes):
 
<!-- Melhorar este exemplo! Usar ponteiros neste caso não é exatamente útil. -->
#include <stdio.h>
int sqr (const int *num);
int main(void)
{
int a = 10;
int b;
b = sqr(&a);
}
int sqr (const int *num)
{
return ((*num)*(*num));
}
 
No exemplo, <var>num</var> está protegido contra alterações. Isto quer dizer que, se tentássemos fazer
 
*num = 10;
 
dentro da função <tt>sqr()</tt>, o compilador daria uma mensagem de erro.
 
==== volatile ====
 
O modificador '''<tt>volatile</tt>''' diz ao compilador que a variável em questão pode ser alterada sem que este seja avisado. Isto evita "bugs" que poderiam ocorrer se o compilador tentasse fazer uma otimização no código que não é segura quando a memória é modificada externamente.
 
Digamos que, por exemplo, tenhamos uma variável que o BIOS do computador altera de minuto em minuto (um relógio, por exemplo). Seria importante que declarássemos esta variável como <tt>volatile</tt>.
 
Um uso importante de variáveis <tt>volatile</tt> é em aplicações com várias ''threads'' (linhas de execução), onde a memória é compartilhada por vários pedaços de código que são executados simultaneamente.
 
==== extern ====
 
O modificador '''<tt>extern</tt>''' diz ao compilador que a variável indicada foi declarada em outro arquivo que não podemos incluir diretamente, por exemplo o código de uma biblioteca padrão. Isso é importante pois, se não colocarmos o modificador '''extern''', o compilador irá declarar uma nova variável com o nome especificado, "ocultando" a variável que realmente desejamos usar. E se simplesmente não declarássemos a variável, já sabemos que o compilador não saberia o tamanho da variável.
 
Quando o compilador encontra o modificador '''extern''', ele marca a variável como não resolvida, e o montador se encarregará de substituir o endereço correto da variável.
 
extern float sum;
extern int count;
float returnSum (void)
{
count++;
return sum;
}
 
Neste exemplo, o compilador irá saber que <var>count</var> e <var>sum</var> estão sendo usados no arquivo mas que foram declarados em outro.
 
Uma variável externa freqüentemente usada é a variável <var>errno</var> (declarada no arquivo-cabeçalho errno.h), que indica o último código de erro encontrado na execução de uma função da biblioteca padrão ou do sistema.
 
==== static ====
 
O funcionamento das variáveis declaradas como '''<tt>static</tt>''' depende se estas são globais ou locais.
 
* Variáveis globais <tt>static</tt> 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 módulos (arquivos). Isto é util se quisermos isolar pedaços de um programa para evitar mudanças acidentais em variáveis globais. Isso é um tipo de ''encapsulamento'' &mdash; que é, simplificadamente, o ato de não permitir que uma variável seja modificada diretamente, mas apenas por meio de uma função.
* Variáveis locais estáticas 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 pode guardar dados na memória (RAM) e nos registradores internos do processador. As variáveis (assim como o programa como um todo) costumam ser armazenadas na memória. O modificador <tt>register</tt> diz ao compilador que a variável em questão deve ser, se possível, guardada em um registrador da CPU.
 
Vamos agora ressaltar vários pontos importantes:
 
* '''Porque usar <tt>register?</tt>''' 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. No entanto, a maioria dos compiladores otimizantes atuais usa registradores da CPU para variáveis, então o uso de <tt>register</tt> é freqüentemente desnecessário.
* '''Em que tipo de variável podemos usar o <tt>register</tt>?''' Antes da criação do padrão ANSI C, <tt>register</tt> aplicava-se apenas aos tipos <tt>int</tt> e <tt>char</tt>, mas o padrão atual permite o uso de <tt>register</tt> para qualquer um dos quatro tipos fundamentais. É claro que seqüências de caracteres, arrays e estruturas também não podem ser guardadas nos registradores da CPU por serem grandes demais.
* '''<tt>register</tt> é um ''pedido'' que o programador faz ao compilador.''' Este não precisa ser atendido necessariamente, e alguns compiladores até ignoram o modificador ''register'', o que é permitido pelo padrão C.
* '''<tt>register</tt> não pode ser usado em variáveis globais''', pois isto implicaria em um registrador da CPU ficar o tempo todo ocupado por essa variável.
 
Um exemplo do uso do register é dado a seguir:
 
int main (void)
{
register int count;
for (count = 0; count < 10; count++)
{
...
}
return 0;
}
 
O loop acima, em compiladores que não guardam variáveis em registradores por padrão, deve 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.
 
== Literais ==
Linha 207 ⟶ 102:
* Literais de caracteres devem vir entre aspas simples (') e conter a representação de apenas um caractere<sup>1</sup>. Usos válidos seriam: 'c', '\n', '\x1b', '\033'. Se você quiser usar a aspa simples como caractere, preceda-a com uma barra invertida: <tt>'<nowiki>\'</nowiki>'</tt>.
 
* Literais de strings devem vir entre aspas duplas ("). Para usar aspas duplas dentro de strings, preceda-as com barra invertida: <tt>"Ele disse \"Olá\"."</tt>. Note que um literal de string adiciona o caractere nulo (<tt>\0</tt>) ao final da string, pois ele é, em C, a maneira de delimitar o final de uma string.
 
== Notas de rodapé ==