Un programa C sencillo consiste por lo menos de una función que debe estar presente en todo programa elaborado en lenguaje C, la función principal main(). Los enunciados propios sobre lo que deberá ser llevado a cabo por la función son encerrados entre un corchete de apertura “{” y un corchete de cierre “}”:
main() /* el nombre de cualquier función C incluye paréntesis */Los programas pueden incluír directivas de preprocesador y más de una función. Las definiciones de las funciones se siguen una adelante de la otra. No es válido incrustar la definición de una función dentro de la definición de otra función. La ejecución de un programa C siempre comienza al principio de la función main() sin importar el orden en el que aparezcan las funciones dentro del programa:
{ /* corchete de apertura */
int n; /* enunciado de declaración */
for (n = 1; n < 20; n++)
printf("%d %d\n", n, 2n+1);
} /* corchete de cierre de la función */
main() {En funciones que tengan argumentos, los argumentos son declarados antes de que empiece el cuerpo de la función, marcado por los corchetes de apertura y de cierre, como se ejemplifica arriba.
int n;
for (n = 1; n < LIMITE; n++)
printf("%d %d\n", n, impar(n) );
/* invocación de la función impar(n) */
} /* fin de la función main() */
impar(k) { /* esta función tiene un argumento, que es k */
int k; /* declaración del argumento como de tipo int */
{ /* inicio de la definición de la función */
int j; /* declaración de variables internas */
j = 2*k + 1;
return( j );
} /* fin de la función impar() */
ENUNCIADOS
Los enunciados sencillos consisten de una instrucción seguida de un semicolon:
float x; /* enunciado de declaración del tipo de una variable */
x = 51.84925; /* enunciado de asignación de valor a una variable */
ponercaracter('A'); /* enunciado de función */
Los enunciados estructurados típicamente consisten de alguna palabra clave (if, while, etcétera) seguidos de una condición encerrada entre paréntesis seguida por un enunciado (véase más abajo CONTROL DE FLUJO):
if ( numeroid == 5143 )
salario = salario * bonificacion;
Un enunciado compuesto consiste de uno o más enunciados encerrados entre corchetes. Cuenta como un enunciado y es usado en enunciados estructurados para permitir la inclusión de más de una acción en el enunciado:
if ( numeroid == 8391 )
{
salario = salario * bonificacion;
estado = estado + 1;
}
TIPOS FUNDAMENTALES
Las variables aparecen en dos variedades básicas: enteros y punto flotante (no todos los compiladores reconocen todos los tipos de variables que se citan abajo):
Tipos enteros
charTipos punto-flotante
signed char
unsigned char
short
int
long
unsigned
unsigned int
unsigned short
unsigned long
float
double
long double
CLASES DE ALMACENAMIENTO
Las variables poseen una de las siguientes clases de almacenamiento:
autoLas variables auto y register son creadas cada vez que la función que las contiene es invocada, y se desvanecen cada vez que la ejecución de la función termina. Las otras variables son persistentes y duran todo el tiempo que tarda en ejecutarse el programa.
register
extern
static
DECLARACION DE VARIABLES
Una variable puede ser univaluada (variable escalar) o puede contener varios valores (un arreglo estilo array). Una variable tiene un tipo (int, char, etc.) y una clase de almacenamiento (auto, static, etc.) como se acaba de asentar arriba. Un enunciado de declaración declara estos atributos. (En forma predeterminada, una variable es de clase de almacenamiento auto si es declarada dentro de una función, y es extern si es declarada fuera de una función.) Una forma general de declarar una variable escalar es la siguiente:
clase-de-almacenamiento especificador-de-tipo nombre-de-variable;
Para indicar un arreglo array, continúese el nombre de la variable con paréntesis cuadrados “[” y “]” conteniendo el número de elementos:
float porcentajes[125];
Las variables en una función usualmente son declaradas después del corchete de apertura:
main() {Las variables escalares pueden ser inicializadas al llevarse a cabo la declaración de las mismas:
int n; /* auto, en forma predeterminada */
static float valor;
char nombre[80]; /* arreglo de 80 valores char */
int n = 16; /* n es declarada de tipo int y fijada en 16 */
Los arreglos tipo array pueden ser inicializados únicamente si son de clase de almacenamiento extern o static. Si se omite el tamaño del arreglo, el tamaño es determinado contando el número de elementos proporcionados en la inicialización del arreglo:
static int codigos[6] = {9, 1, 1, 5, 3, 7};
static int etiquetas[] = {6, 2, 8, 4};
/* el array etiquetas tiene cuatro elementos */
Un arreglo char puede ser inicializado como una hilera:
static char nombre[] = "Armando Martinez";
Se usa el operador de indirección (*) para declarar apuntadores (punteros):
int *pn; /* pn es un puntero hacia un entero */
ESTRUCTURAS
Una estructura es un objeto de datos capaz de contener más de un tipo de valor. Una plantilla (template) de estructura establece el tipo de datos que una estructura puede contener. La definición de una estructura es encerrada entre corchetes. Una etiqueta de estructura dá un nombre abreviado para la forma. Una variable de estructura es aquella cuyo tipo está dado por una plantilla de estructura. La plantilla debe incluir una etiqueta o un nombre de variable o ambos.
Sin etiqueta.- Aquí se declara una variable variedades como una estructura de la forma indicada. No se usa ninguna etiqueta, y el nombre de la variable sigue inmediatamente a la definición de la estructura:
struct {Con etiqueta.- Alternativamente, úsese un nombre de etiqueta antes del corchete de apertura, entonces úsese el nombre de etiqueta en la declaración de la variable:
float volumen;
float masa;
char nombre[50];
} variedades; /* variedades es una variable de estructura */
struct tortugas { /* tortugas es el nombre de la etiqueta */Las estructuras arriba indicadas son de la forma tortugas.
float volumen;
float masa;
char nombre[50];
};
struct tortugas golfina Galapagos;
/* declaración de dos estructuras */
struct tortugas tipos[15]; /* un arreglo de 15 estructuras */
CONTROL DE FLUJO
Bucles
Bucle while:
while (condicion)
enunciado
Ejemplo:
while ( n++ < 15)
x = x + 4;
Bucle for:
for (inicialización; prueba; actualización)
enunciado
Ejemplo:
for ( i = 0; i < 20; i++ )
printf("%d %d\n", i, 2*i + 1);
Bucle do while:
do
enunciado
while (condición );
Ejemplo:
do
printf("Hola, mundo\n");
while ( n++ < 40 );
RAMIFICACIONES (BRANCHING)
Formas if:
- if ( expresión )
enunciado
- if ( expresión )
enunciado
else
enunciado
- if ( expresión )
enunciado
else
enunciado
else
enunciado
if ( monto < 125 )
precio = 45;
else (monto > 125 )
precio = 40;
switch:
switch ( expresión )
enunciado
{
case etiqueta1: enunciado1
case etiqueta2: enunciado2
......
default : enunciado
}
Ejemplo:
switch ( letra )
enunciado
{
case 'a': avar++;
break;
case 'b': bvar++;
break;
case 'c': cvar++;
break;
default : restvar++;
}
SALTOS
- break es usado dentro de un bucle o en un switch. Ocasiona que el control del programa se brinque el resto del bucle y que continúe con la instrucción que sigue al bucle o a switch.
- continue es usado dentro de un bucle. Ocasiona que el control del programa se brinque el resto del bucle y que empiece al siguiente ciclo del bucle.
- goto ocasiona que el control del programa se brinque a un enunciado que lleva la etiqueta mencionada. Una etiqueta de enunciado es seguida de un colon (:).
top : ch = getchar(); /* top es una etiqueta */
...
if ( ch != 'clase')
goto top;
PRECEDENCIA DE OPERADORES
En casos en donde puede haber ambigüedad en la evaluación de una expresión o en el sentido del flujo de un programa, como en la expresión aritmética:
a + 2/b + d
que puede interpretarse de dos maneras distintas ya sea como:
a + (2/b) + d
o como:
(a + 2)/(b + d)
la precedencia de operadores permite eliminar la ambigüedad que pueda haber, recomendándose en casos como el ejemplo que se acaba de mostrar el uso abundante de paréntesis para fijar un orden de operaciones en virtud de que lo que se encuentre dentro de paréntesis es evaluado primero.
Prioridad de operadores | Descripción |
( ) { } -> . | Paréntesis, corchetes, operador de membresía indirecta operador de membresía |
! ~ ++ -- - (type) &
sizeof (ocho operadores, todos unarios) |
Operador NOT lógico, negación lógica bit-por-bit, operador de incremento unitario, operador de decremento unitario, cambio de signo aritmético, operador de cambio de tipo, operador de domiciliamiento, evaluación de tamaño |
* / % | Operadores aritméticos: multiplicación, división, operador de residuo aritmético |
+ - | Operadores aritméticos: suma de operandos, resta de operandos |
<< >> | Desplazamiento de bits, bit-por- bit, desplazamiento hacia la izquierda, desplazamiento hacia la derecha |
< <= >= | Menor que, menor o igual que, mayor o igual que |
= = != | Igualdad comparativa, no igualdad |
& (AND de bits) | Operador AND bit-por-bit |
^ (OR-EXCLUSIVO de bits) | Operador OR-EXCLUSIVO bit-por-bit |
¦ (OR de bits) | Operador OR bit-por-bit |
&& | Operador AND lógico |
¦ ¦ | Operador OR lógico |
? : | Operador condicional actuando sobre el operando situado a la izquierda del "?" y tomando el valor del operando situado entre el "?" y el colon ":" o el valor situado a la derecha del colon ":" dependiendo de que el primer operando sea cierto o falso |
= += - = *= /* %= | Asignación de valor a variable, sumación e igualación, resta e igualación, multiplicación e igualación, división e igualación, asignación de residuo de cociente |
, | Operador coma, usado en inicializaciones múltiples en bucles del tipo for |
FORMATOS PARA printf()
printf( hileradecontrol, expresión1, expresión2, ... );
La hileradecontrol (encerrada entre comillas dobles) consiste de caracteres (alfabéticos y numéricos) a ser imprimidos literalmente al pie de la letra y de especificaciones de conversión que empiezan todas con el símbolo %. Debe de haber una conversión de especificación para cada valor de expresión que será imprimido. El valor de cada expresión es imprimido en el lugar indicado por la especificación de conversión.
Las especificaciones básicas de conversión son:
Identificador | Acción (en la salida) |
%d | Imprimir un número entero |
%u | Imprimir un número entero sin signo aritmético |
%f | Imprimir un número de punto flotante (con punto decimal) |
%e | Imprimir un número de punto flotante en formato exponencial |
%g | Escoger entre %e y %f dependiendo del tamaño del número |
%c | Imprimir un caracter |
%s | Imprimir una hilera de caracteres (string) |
%o | Imprimir un entero octal sin signo aritmético |
%x | Imprimir un entero hexadecimal sin signo aritmético |
Se pueden poner modificadores después del % para indicar anchura de campo, precisión, y justificación, y si un int es de tipo long:
%10d - imprimir un entero en un campo con una anchura de diez espacios
%6.2f - imprimir dos lugares decimales, anchura de campo = 6
%-6d - imprimir un entero justificado hacia la izquierda
%ld - imprimir un entero de tipo long
Ejemplo:
printf("La puntuacion de %s es %d de 100.\n", nombre, puntuacion);
puede producir algo como lo siguiente:
La puntuacion de Regina es 5 de 100.
FORMATOS PARA scanf()
La función scanf( ) funciona de modo muy parecido a la función printf(). Estas son las diferencia principales que hay entre ambas:
- Los argumentos que siguen a la hilera de control tienen que ser domicilios. Pueden usar el operador de domiciliamiento, como en &n, o pueden ser nombres de arreglos de hileras (arrays), que son punteros (apuntadores) hacia el primer elemento del arreglo.
- No hay una opción %g.
- Tanto %e como %f trabajan del mismo modo, aceptando cualquier formato.
- Existe una especificación de conversión %h para leer enteros del tipo short.
- El modificador * hace que se salte hacia el siguiente valor, por ejemplo, %*d significa pasar encima saltando hacia el siguiente valor.
int n;
char graduandos[50];
scanf("%d %s", &n, titulo);