martes, 26 de febrero de 2013

ELEMENTOS LÉXICOS Y SINTAXIS


ELEMENTOS LÉXICOS DE C

Los elementos léxicos del lenguaje C son los que conforman el código fuente de un programa. Estos elementos son llamados tokens. Existen cinco tipos de tokens: Palabras claves, identificadores, constantes, operadores y separadores. El espacio en blanco requiere en algunos casos tokens separados.

PALABRAS CLAVE
Las palabras claves son identificadores especiales reservados para uso como parte del lenguaje de programación en sí mismo. No se pueden usar estas palabras claves para ningún otro propósito.


Aquí hay una lista de las palabras claves reconocidas por el ANSI C89:
auto break case char const continue default do double else enum
extern float for goto if int long register return short signed
sizeof static struct switch typedefunion unsigned void volatile while

El ISO C99 agrego las siguientes palabras claves:
     inline _Bool _Complex _Imaginary
Y las extensiones GNU agregan estas palabras claves:
__FUNCTION__ __PRETTY_FUNCTION__ __alignof __alignof__ __asm
__asm__ __attribute __attribute__ __builtin_offsetof
__builtin_va_arg __complex __complex__ __const __extension__
__func__ __imag __imag__ __inline __inline__ __label__ __null
__real __real__ __restrict __restrict__ __signed __signed__
__thread __typeof __volatile __volatile__

IDENTIFICADORES
Los identificadores son secuencias de caracteres usados para nombrar variables, funciones, nuevos tipos de datos y macros del preprocesador. Se pueden incluir letras, dígitos decimales y el carácter de subrayado '_' en los identificadores. El primer carácter de un identificador no puede ser un dígito.

Palabras en minúscula y mayúscula son distintas, por ejemplo foo y FOO son dos identificadores diferentes. 
CONSTANTES
Una constante es un valor literal numérico o carácter, como 5 o 'm'. Todas las constantes son de un tipo en particular; se puede usar un casting explicito para especificar el tipo de constante o dejar al compilador usar el tipo por defecto basado en el valor de la constante.
Constantes enteras
Una constante entera es una secuencia de dígitos con un prefijo opcional que denota la base de un número. Si la secuencia de dígitos es precedida por 0x o 0X, entonces la constante es considerada como un hexadecimal (base 16). El hexadecimal puede tomar los valores de 0 a 9 y las letras de A a F. Algunos ejemplos:

     0x2f
     0x88
     0xAB43
     0xAbCd
     0x1

Si el primer dígito es 0 (cero) y el siguiente carácter no es 'x' o 'X', entonces la constante es considerada como Octal (base 8). Los valores octales pueden solamente usar dígitos de 0 a 7. Algunos ejemplos:
     057
     012
     03
     0241

Si la secuencia de dígitos es precedida por 0b, entonces la constante es considerada como un binario (base 2). El binario puede tomar los valores de 0 y 1. Algunos ejemplos:
     0b00000001
     0b10101010
     0b11111111
     0b11001100

En otros casos la secuencia de dígitos es asumida como decimal (base 10). Los valores decimales pueden usar los dígitos de 0 a 9. Algunos ejemplos:
     459
     23901
     8
     12


Hay varios tipos de datos enteros como enteros cortos, enteros largos, enteros con signo y enteros sin signo. Para forzar que la constante entera sea de tipo long y/o unsigned, se debe colocar una o más letras al final de la constante.
u
U
      Tipo entero sin signo
l
L
      Tipo entero long

Por ejemplo, 45U es una constante entera sin signo. Se puede combinar letras: 45UL es una constante entera long sin signo. Las letras pueden ser usadas en cualquier orden.
Constantes carácter
Una constante carácter es usualmente un carácter simple encerrado con comillas simples, como 'Q'. Una constante carácter es de tipo entero por defecto.


Algunos caracteres, como la comilla simple, no pueden ser representados usando solamente un carácter. Para representar estos caracteres existen varias secuencias de escape que pueden ser usados:


\\   Backslash
\? signo de interrogación
\'    Comilla simple
\"   Comilla doble
\a   Alerta audible
\b   Espacio
\e   <ESC>
\f    Nueva hoja de papel
\n  Nueva línea
\r   Retorno
\t   Tabulación horizontal
\v   Tabulación vertical
\o, \oo, \ooo   Número octal
\xh, \xhh, \xhhh,... Número hexadecimal

Para usar cualquier secuenciad de estos caracteres de escape, la secuencia debe estar cerrada en comillas simples y tratarlo como si fuere cualquier otro carácter. Por ejemplo la letra m es 'm' y la nueva línea es '\n'.


La secuencia de escape de un número octal es el carácter backslash seguido por uno, dos o tres dígitos octales (0 a 7). Por ejemplo, 101 es el equivalente octal de 65, el cual es el código ASCII del carácter 'A'. Así, la constante carácter '\101' es lo mismo que el carácter constante 'A'.

Números reales constantes
Una número real constante es una valor que representa un número fraccional (punto flotante). Este consiste en una secuencia de dígitos la cual representa la parte entera, un punto decimal y una secuencia de dígitos la cual representa la parte fraccional.

La parte entera o la parte fraccional pueden ser omitidas, pero no ambas. Aquí hay algunos ejemplos: 
     double a, b, c, d, e, f;
    
     a = 4.7;    
     b = 4.;    
     c = 4;    
     d = .7;    
     e = 0.7;
Un número real constante puede ser seguido por un e o E y un exponente entero. El exponente puede ser positivo o negativo. 
     double x, y;
    
     x = 5e2;   /* x es 5 * 100, or 500.0. */
    y = 5e-2;  /* y es 5 * (1/100, or 0.05. */

Se puede colocar una letra al final de un número real constante para hacer que sea de un tipo particular. Si se coloca la letra F o f, el número real constante es de tipo flotante. Si se coloca un L o l, el tipo es long double. Si no se coloca una letra, entonces el tipo es double.

Constante cadena
Una constante tipo cadena es una secuencia de cero o más caracteres, dígitos, y secuencias de escape encerradas en doble comillas. Una constante cadena es de tipo "arreglo de caracteres". Todas las constantes cadenas contienen un carácter de terminación null ( \0) como último carácter. Las cadenas son almacenadas como arreglos de caracteres, con un atributo de tamaño inherente. El carácter de terminación null indica a las funciones que procesan cadenas la terminación de las cadenas.


Una cadena no puede contener doble comillas. Para incluir las doble comillas en una cadena se usa la secuencia de escape \". Aquí hay algunos ejemplos:


     /* Esta es una cadena simple. */
     "tutti frutti ice cream"
    
     /* Esta cadena será concatenada, como la de arriba. */
     "tutti " "frutti" " ice " "cream"
    
     /* El uso de dos secuencias de escape. */
     "\"hello, world!\""

Si una cadena es muy larga para llenar una línea, se puede usar un backslash \ para dividir en líneas separadas.
     "Este es un ejemplo de una cadena divida por \
     dos líneas."

Las cadenas adyacentes son automáticamente concatenadas, así si se escribe dos cadenas separadas por múltiples líneas, estas serán unidas.
     "Este es un ejemplo de una cadena divida por "
     "dos líneas."

Es lo mismo que
     "Este es un ejemplo de una cadena divida por \
     dos líneas."

Insertar un carácter de nueva línea en la cadena, hace que la cadena se impresa en dos diferentes líneas.

     printf ("potato\nknish");

Imprime 
     potato
     knish

OPERADORES
Los operadores son un tipo de tokens que pueden aparecer en las expresiones, e indican al compilador la realización de determinadas operaciones matemáticas, lógicas y numéricas . Se aplican a variables u otros objetos denominados operandos y su efecto es una combinación de las siguientes acciones:
  • Producir un resultado-valor
  • Alterar un operando
  • Designar un objeto o función.
Ejemplos
y = a + b;
En esta sentencia, el operador suma + produce un valor nuevo, pero no altera ninguno de los operandos (a y b); a su vez, el nuevo valor es asignado a la variable y mediante el operador de asignación. En este caso el operando de la izquierda sí se ve alterado.
x++;
Aquí el operador postincremento ++ produce un nuevo valor que es aplicado sobre el propio operando, de forma que queda alterado. Cuando un operador altera un operando se dice que tiene efectos laterales.
Nota: por lo general, los operadores aparecen a la derecha de expresiones de asignación (por ejemplo: y = 2 * y + x), pero en ocasiones estos "efectos laterales" se utilizan para conseguir expresiones muy compactas y de un cierto nivel de sofisticación, que incluso no necesitan del operador de asignación para producir el resultado. En estos casos su lógica es un poco más difícil de seguir que cuando estos efectos no se utilizan directamente
(Ver ejemplo).
z = (*fptr)(x, y);
Aquí, el operador de indirección * es aplicado sobre el operando fptr que es un puntero-a-función. El resultado es un designador de función al que se aplica el operador ( ) de invocación de función con dos operandos x e y que actúan como argumentos. A su vez el resultado de este operador (invocación de función) es utilizado como argumento derecho del operador de asignación = que finalmente modifica uno de sus operandos (el operando izquierdo z).
  Clasificación
C++ dispone de un conjunto muy rico de operadores que se pueden clasificar en unitarios, binarios y ternarios, según que necesiten uno, dos o tres operandos. Los operadores unitarios (denominados también unarios) se clasifican en dos tipos según la posición del operador (representado aquí por @) respecto del operando (representado aquí por n):
@n: Operador prefijo.  Ejemplo:  ++x
n@:  Operador posfijo.  Ejemplo:  x++

Antes de seguir refiriéndonos a ellos, tal vez sean procedentes un par observaciones que más adelante nos ayudarán a comprender mejor algunos conceptos:
  • Los operadores pueden (en cierta forma) considerarse como funciones que tienen un álgebra un tanto especial. De hecho, al tratar la sobrecarga de operadores, veremos que precisamente la forma en que se definen es mediante una función, la función-operador. En este sentido podríamos imaginar que la expresión y = a + b es otra forma de representar algo como: y = suma(a, b). Del mismo modo, la asignación x = y sería algo así: asigna(x, y). Siguiendo con nuestra analogía, podríamos suponer que los operadores unitarios, binarios y ternarios serían funciones que aceptarían unos, dos o tres argumentos respectivamente y que la sobrecarga de operadores no es sino una forma encubierta de sobrecarga de funciones.
  • Aunque las funciones C++ se designan con identificadores (nombres) que siguen las reglas generales ya señaladas , estas seudo-funciones se identifican con símbolos ( +, =, ::, *, ->, etc.) . Muchos de ellos están compuesto de un solo token (que puede estar repetido + y ++) aunque los hay de dos. Estos últimos son: new [], delete [],  () y [].
  • Antes de realizar la operación encomendada, los operadores pueden modificar el tipo de los operandos para que sean homogéneos, de forma que la operación pueda realizarse. Por ejemplo, al indicar i + f donde i sea un entero y f un float. Estas promociones se denominan conversiones estándar y son realizadas automáticamente por el compilador, pero deben ser tenidas en cuenta para evitar sorpresas.
  En general los operadores aceptan un tipo de operando determinado y específico, produciendo y/o modificando un valor de acuerdo con ciertas reglas, pero C++ permite redefinir la mayoría de ellos. Es decir, permite que puedan aceptar otro tipo de operandos y seguir otro comportamiento sin que pierdan el sentido y comportamiento originales cuando se usan con los operandos normales (los tipos básicos preconstruidos en el lenguaje). Esta circunstancia recibe el nombre de sobrecarga del operador.
 PUNTUADORES
Los signos de puntuación del lenguaje C++ juegan el mismo papel que sus homónimos en el lenguaje natural escrito. Conocidos también como puntuadores, son los que se citan a continuación. La mayoría de ellos tienen un doble uso y en ocasiones funcionan también como operadores.
[ ]  ( )  { }  ,  ;  :  ...  *  =  #  !  %  ^  &  –  +  |  ~  \  '  "  <  >  ?  .  /  
 Corchetes  [ ]
Los corchetes indican subíndices de matrices uni y multi dimensionales.
char ch, str[] = "Cadena de caracteres";
int mat[3][4];           // Matriz de 3 x 4
ch = str[3];             // cuarto elemento
 Paréntesis  ( )
Los paréntesis sirven para agrupar expresiones; alterar la precedencia normal de los operadores y su asociatividad; aislar expresiones condicionales; indicar llamadas a funciones, y señalar los parámetros de estas. La sintaxis de C++ exige indefectiblemente el uso de paréntesis en múltiples ocasiones. En los ejemplos que siguen se muestran algunos usos.
d = c * (a + b);        // modifica la precedencia normal
if (d == z) ++x;        // imprescindible en la sentencia if
for (x =1; x<10; x++)   // imprescindible en la sentencia for
func();                 // señala llamada a función
int func();             // declara función
int (*fptr)();          // declara puntero a función
fptr = func;            // asigna valor al puntero.
Observe que en el último caso, la ausencia de paréntesis equivale a &func 
Se recomienda el uso de paréntesis en las macro-definiciones para evitar problemas potenciales en la expansión. Por ejemplo:
#define CUBO(x) ((x) * (x) * (x))
 Llaves  { }
Los pares de llaves { } señalan el comienzo y final de una sentencia compuesta, es decir, bloques de código (grupos de sentencias que son tratadas como una unidad). Constituyen el segundo paso (después de las sentencias) en la estructuración y compartimentación del código C++:
if (d == z) 
{
   ++x;
   func();
}

Un bloque es una sentencia compuesta, se trata de una sucesión (que puede estar vacía) de sentencias delimitadas por un par de corchetes { }.  Desde el punto de vista sintáctico, un bloque puede ser considerado como una sola sentencia.  Juega un papel importante en el ámbito (scope) de los identificadores, puesto que un identificador declarado dentro de un bloque tiene un ámbito que comienza en el punto de la declaración y termina en el corchete final. Sin embargo, el mismo identificador puede ser ocultado por otro del mismo nombre declarado en un bloque interior al primero.
Dentro de las posibilidades de memoria, los bloques pueden ser anidados a cualquier nivel (profundidad).
Después del corchete de cierre } no se necesita el punto y coma ; de fin de sentencia
if (statement)
   {...};           // punto y coma ilegal !!
else
Nota: las llaves sirven también en C++ para otros usos distintos de la pura delimitación de bloques de código. Por ejemplo, en la definición de estructuras, uniones y clases, en cuyo caso si puede ser necesaria la inclusión del punto y coma después de la llave de cierre }
 Coma  ,
La coma como puntuador se utiliza para separar los elementos en las listas de parámetros de una función:
void func(int n, float f, char ch);
La coma se usa también como un operador en las expresiones con coma . Es posible mezclar los dos usos (separador en lista de parámetros y operador), pero deben usarse paréntesis para distinguirlos.
 Punto y coma  ;
El punto y coma ; es el signo de fin de sentencia. Cualquier expresión legal C++ terminada por un punto y coma (incluyendo la expresión vacía - un punto y coma aislado-) es interpretado como una sentencia, conocidas como sentencia-expresión .  La expresión se evalúa y el resultado se descarta; si no tiene efectos colaterales, C++ la ignora.
a + b;     // evalúa a + b, descarta el resultado
++a;       // efecto lateral en 'a', se descarta el valor ++a
;          // expresión vacía = sentencia nula
El punto y coma se usa a veces para crear sentencias nulas:
for (i = 0; i < n; i++) 
{
   ;    // sentencia nula (hacer nada)
}
 Dos puntos  :
Los dos puntos se utilizan para señalar sentencias etiquetadas :
comienzo:    x=0;    // comienzo es la etiqueta
...
goto comienzo;
 Puntos suspensivos  ...
Los puntos suspensivos, también llamados elipsis, son tres puntos, seguidos y sin espacios intermedios; tienen varios usos en C++.
Se utilizan en las relaciones de argumentos formales de las funciones, cuando estas pueden aceptar un número variable de argumentos o pueden ser de tipo variable . Por ejemplo:
void func(int n, char ch,...);
Este prototipo de función declara que func está definida de modo que debe ser llamada con, al menos, dos argumentos: un int y un char. Además puede tener un cierto número de argumentos adicionales (puede omitirse la coma antes de la elipsis).
Se utiliza también para indicar que un manejador de excepciones ("handler") puede capturar una excepción de cualquier tipo.  Ejemplo:
try {           // bloque-intento
  ...
}
catch (...) {   // captura cualquier excepción
  cout << "Se ha producido una excepción!" << endl;
  ...
}

Nota: como podéis ver, en ocasiones, mi uso particular en los ejemplos de los tres puntos, es para indicar cualquier número de sentencias. Espero que no sea motivo de confusión. Desde luego, en el caso anterior sería más correcta la notación:
try {             // bloque-intento
  // ...
}
  catch (...) {   // captura cualquier excepción
  cout << "Se ha producido una excepción!" << endl;
  // ...
}
 Asterisco  *
El asterisco * puede ser utilizado en C++ de tres formas: como una declaración de tipo de variable (variable de puntero ; como operador de indirección (también llamado operador de de referencia  y como operador de multiplicación.
Ejemplos:
char* char_ptr;     // declara puntero a carácter
x = *int_ptr;       // operador de indirección
l = 2 * 3.14 * r;   // operador multiplicación

 Signo igual  =
El signo igual = separa la declaración de variables de las listas de inicialización:
char array[5] = { 1, 2, 3, 4, 5 };
Recordemos que, al contrario que en C, donde las declaraciones no pueden estar precedidas por ningún código, deben ir al principio, en C++, las declaraciones de cualquier tipo pueden aparecer en cualquier punto del código (con algunas restricciones).
En la lista de argumentos de una función, el signo igual indica el valor por defecto para un parámetro:
int f(int i = 0) { ... }  // el valor por defecto de k es cero
El signo igual es también utilizado como operador de asignación.  Ejemplo:
x = y;
z += 5;
 Almohadilla  #
Si la almohadilla # aparecen en el primer carácter (distinto de espacio en blanco) de una línea, señala directivas de preproceso .  En este caso, es un operador específico de la fase de preproceso del código fuente. Significa una opción del preprocesador que no tiene porqué estar asociada necesariamente a generación de código.  Las directivas se sitúan generalmente al comienzo del programa, aunque legalmente pueden aparecer en cualquier punto.
Ejemplos de directivas de preproceso:
# (null directive)
#define NULO \0
#include <stdio.h>















SINTAXIS
La sintaxis de un lenguaje de programación es el conjunto de reglas que debemos seguir para que el compilador sea capaz de reconocer nuestro programa como un programa C válido.
SINTAXIS DEL LENGUAJE C

  * Los bloques de código se marcan con las llaves {…}. Son equivalentes al inicio y fin del pseudocódigo.
  * Todas las instrucciones terminan con un punto y coma ( ; )
  * Los identificadores de variables, funciones, etc., no pueden empezar con un número ni contener espacios o símbolos especiales, salvo el de subrayado ( _ )
  * Los caracteres se encierran entre comillas simples ( ‘…’ )
  * Las cadenas de caracteres se encierran entre comillas dobles ( “…” )
  * El lenguaje es sensitivo a las mayúsculas. Es decir, no es lo mismo escribir main() que MAIN() o Main

El punto y coma
El punto y coma es uno de los símbolos más usados en C, C++; y se usa con el fin de indicar el final de una línea de instrucción. El punto y coma es de uso obligatorio.

Ejemplo
´´´´´´
clrscr(); //Limpiar pantalla, funciona solo con la librería conio de Borland C++
x = a + b;


El punto y coma se usa también para separar contadores, condicionales e incrementadores dentro de un sentencia for

ejemplo
for (i=0; i < 10; i++) cout << i;


Separador de bloque
Un bloque es un grupo de instrucciones contenidas entre los símbolos de llave izquierda '{' y llave derecha '}', su uso es obligatorio en la definición de funciones, y opcionalmente pueden aparecer en cualquier otra parte del programa.

Ejemplos
// aquí, las llaves son opcionales ya que dentro
// del ciclo for hay solamente una instrucción.
for (i=0; i < 10; i++) { cout << i; }
Espacios y tabuladores
Usar caracteres extras de espaciado o tabuladores (caracteres tab ) es un mecanismo que nos permite ordenar de manera más clara el código del programa que estemos escribiendo, sin embargo, el uso de estos es opcional ya que el compilador ignora la presencia de los mismos. Por ejemplo, el segundo de los ejemplos anteriores se podría escribir como:
for (int i=0; i < 10; i++) { cout << i * x; x++; }
y el compilador no pondría ningún reparo.












VARIABLES Y CONSTANTES


VARIABLES

Una variable permite el almacenamiento de datos en la memoria. Es una abstracción que permite referirnos a una zona de memoria mediante un nombre (su identificador). Todas las variables tienen asociadas un tipo que determina los valores que pueden almacenarse y las operaciones que pueden efectuarse con los datos de ese tipo. Además, el término variable indica que el contenido de esa zona de memoria puede modificarse durante la ejecución del programa.
Nombres de variables
Los nombres que pueden asignarse a las variables deben regirse por unas normas básicas:
  • Pueden contener letras, dígitos y el carácter de subrayado (_).
  • No pueden empezar con un número: deben comenzar por una letra o con el carácter de subrayado (_).
Finalmente, recordar que, como identificador que es, el nombre de una variable es sensible a las mayúsculas y no pueden coincidir con una palabra reservada a no ser que tenga el prefijo @, aunque no es una práctica recomendada.
Declaración de variables
Antes de usar una variable se debe declarar. La declaración de una variable indica al compilador el nombre de la variable y su tipo. Una declaración permite que se pueda reservar memoria para esa variable y restringir el espacio (cantidad de memoria) que requiere, los valores que pueden asignársele y las operaciones en las que puede intervenir.
La sintaxis de una declaración es sencilla: tan sólo hay que especificar el tipo de la variable y el nombre que se le asocia. La declaración debe concluir con el carácter punto y coma. Por ejemplo, si vamos a emplear una variable para guardar en ella el valor del área de un círculo debemos:
  • Darle un nombre significativo: Área
  • Asociarle un tipo: dado que puede tener decimales y no se requiere una gran precisión, bastará con el tipo float.

float Área;
Cuando se van a declarar múltiples variables del mismo tipo no es necesario que cada declaración se haga por separado, pueden agruparse en la misma línea compartiendo el tipo. Por ejemplo, las declaraciones:

float Radio;
float Área;
pueden simplificarse en una línea:
float Radio, Área;
De la misma manera pueden declararse e inicializarse variables en una sola línea:
   int a=1, b=2, c, d=4;
No existe ninguna zona predeterminada en el código para la declaración de variables, la única restricción es que la declaración debe realizarse antes de su uso.
No es conveniente abusar de la declaración múltiple de variables en una línea. Desde el punto de vista de la legibilidad es preferible, por regla general, que cada variable se declare separadamente y que la declaración vaya acompañada de un breve comentario:
float Radio; 
// Radio del circulo del cual se calcula el área.
float Área;   // Área del circulo
Acceso a variables
Una variable se usa para asignarle un valor (acceso de escritura) o para utilizar el valor almacenado (acceso de lectura).
Una vez declarada una variable debe recibir algún valor (es su misión, después de todo). Este valor lo puede recibir de algún dispositivo (flujo de entrada) o como resultado de evaluar una expresión. La manera más simple de proporcionar un valor a una variable es emplear la instrucción de asignación:
Radio = 10.0F;
En el ejemplo se asigna el valor (literal entero) 10 a la variable Radio. El valor que tuviera almacenado la variable Radio se pierde, quedando fijado a 10.
En la misma línea de la declaración puede asignarse un valor a la variable, por lo que declaración e inicialización:
float Radio;   // Declaración
Radio = 10.0F; // Inicialización
pueden simplificarse en una sola línea:
float Radio = 10.0F;   // Declaración e Inicialización
La manera más simple de leer el valor de una variable es emplearla como parte de una expresión, por ejemplo, en la parte derecha de una instrucción de asignación:
Área = 2 * 3.1416F * Radio * Radio;
La variable Radio (su valor) se emplea en la expresión 2 * 3.1416 * Radio * Radio para calcular el área de un círculo de radio Radio. Una vez calculado el valor de la expresión, éste se asigna a la variable Área.
Otra manera de acceder al valor de una variable para lectura es emplearla como el argumento de una instrucción de escritura WriteLine. Por ejemplo,
Console.WriteLine(Área);
mostrará en la consola el valor de la variable
Área.
Leer el valor de una variable no modifica el contenido de la variable.
A modo de resumen, un programa que calcula y muestra el área de un círculo de radio 10 es el siguiente:

Calculo del área de un círculo (1)
using System;
class Area1
{
   static void Main(string[] args)
   {
      float Radio = 10.0F;     
      float Area = Area = 2 * 3.1416F * Radio * Radio; 
      Console.WriteLine(Area);
      Console.ReadLine();
   }
}
Como puede parecer evidente, emplear una variable que no ha sido declarada produce un error en tiempo de compilación. En C#, además, hay que asignarle un valor antes de utilizarla. Si no se hace se genera un error en tiempo de compilación ya que esta comprobación (igual que ocurre en Java) se efectúa por el compilador.

void f()
{
  int i;
  Console.WriteLine(i); 
  // Error: uso de la variable local no asignada 'i'
}

TAMAÑO DE UNA VARIABLE
Cuando definimos una variable debemos saber con prioridad si va a almacenar una cantidad de bits pequeña o grande. Si la variable es de tipo entero (int) y almacena un número mayor del rango que tiene este tipo de dato, se producirá un overflow. A la hora de hacer un programa debemos ser previsores e intentar poner el tipo de dato con un rango que soporte las posibles cifras a introducir en ese programa.
Por ello es bueno conocer la forma de averiguar el rango de un tipo de dato, puesto que sabérselos de memoria es imposible.

EJEMPLOS DE VARIABLE
Las variables en el lenguaje c pueden ser de diferentes tipos de datos, de acuerdo a la necesidad de almacenar datos que surja al momento del desarrollo del programa.

El lenguaje C diferencia MAYUSCULAS y minúsculas, por lo que no es lo mismo  VARIABLE1 que variable1 ni que VariAble1.
La declaración de variables en C se realiza de la siguiente manera:
tipo_dato nombre;
Ejemplos:
            char letra;
            int edad;
            float costo;
También se pueden declarar varias variables de un mismo tipo en una sola línea de la siguiente forma:
tipo_dato variable1,variable2, variable3 , ... , variableN;
Ejemplos:
            int hora, minutos, segundos, numero;
            float radio, perimetro, area, costo;
            char letra1, letra2, letra3;

También podemos asignarle un valor a la variable al momento de declararla:
tipo_dato variable1=valor1;
Ejemplos:
            int hora=19, minutos=0, segundos=11;
            char letraConocida='a', letraDesconocida;
            float precioPizza=10.75, precioSoda=1.25;

CONSTANTES
Una constante se define de manera parecida a una variable: modeliza una zona de memoria que puede almacenar un valor de un tipo determinado. La diferencia reside en que esa zona de memoria (su contenido) no puede modificarse en la ejecución del programa. El valor de la constante se asigna en la declaración.
Sintácticamente se especifica que un dato es constante al preceder con la palabra reservada const su declaración. Por ejemplo, para declarar una constante de tipo float llamada PI y asignarle el valor (constante) 3.1416 se escribirá:
const float PI = 3.1416;
Solo se puede consultar el valor de una constante, nunca se debe intentar modificarlo porque se produciría un error en tiempo de compilación. Por ejemplo, la siguiente instrucción:
Área = 2 * PI * Radio * Radio;
Utiliza la constante
PI
declarada anteriormente, usando su valor para evaluar una expresión.
Podemos modificar el programa anterior para que utilice la constante PI:


Existen cuatro tipos distintos de constantes.
·         ENTERAS
·         DE COMA FLOTANTE
·         DE CARÁCTER
·         DE CADENA DE CARACTERES

Ø  LAS CONSTANTES ENTERAS:
 Este tipo de constantes pueden estar escritas en tres tipos de sistemas numéricos, como son el decimal, octal, y hexagesimal.
Si la constante emieza por cero esta sería una constante entera escrita en octal( sólo llevará del 0 al 7).
Si la constante empieza por 0 o x será una constante entera escrita en hexadecimal ( 0>9>F).
En caso de no cumplirse con estas condiciones anteriores estaríamos ante una constante entera decimal.
Ø  LAS CONSTANTES DE COMA FLOTANTE:
Distinguen la parte decimal de la entera por un punto, para el añadido de exponentes usa la letra “E”.
Ø  LAS CONTANTES DE CARÁCTER:
 Se representa el valor de la constante encerrado entre apóstrofos.
Ø  LAS CONSTANTES EN CADENA:
 Almacena una cadena de caracteres que está encerrada entre comillas.

CALCULO DEL AREA DE UN CÍRCULO
using System;
class Area2
{
   static void Main(string[] args)
   {
      const float PI = 3.1416F;  
      float Radio = 10.0F;     
      float Area = 2 * PI * Radio * Radio; 
      Console.WriteLine(Area);
      Console.ReadLine();
   }
}

Ámbito de variables y constantes
El ámbito (del inglés scope) de una variable y/o constante indica en qué partes del código es lícito su uso.
En C# el ámbito abarca desde el lugar de su declaración hasta donde termina el bloque en el que fue declarada.
En el ámbito de una variable no puede declararse otra variable con el mismo nombre (aunque sea en un bloque interno, algo que si está permitido en C++):
   static void Main(string[] args)
   {
      float Radio = 10.0F;     
      ...
      if (Radio > 0){
         float Radio = 20.0F;
              // Error: No se puede declarar una variable
              // local denominada 'Radio' en este ámbito.
      }
      ...
   }

 EJEMPLOS  DE CONSTANTES

Las constantes en lenguaje C se definen de la siguiente forma:
#define NOMBRE valor
Ejemplos:
            #define PI 3.14
            #define TAMANIO 100
            #define CARACTER 'u'
A diferencia de las variables, sólo se puede crear una cosntante por línea de código y debe asignársele un valor al momento de definirse la misma, ya que las constantes jamás cambian su valor.
Ubicación de las variables y constantes en un programa en C
Las constantes se definen después de la inclusión de los archivos cabecera, y las variables deben ser declaradas al inicio de la función principal (main()).
Ejemplo:
//Inclusión de cabeceras
#include <stdio.h>
//Definición de constantes
#define CONSTANTE1 16
#define CONSTANTE2 20
void main()
{
            //Declaración de variables
            int variable1=123, variable2=456;
            char caracter1='a';
            float f;
}