Programación: datos y operaciones básicas

Recupero la serie Programación, que la tenía un poco abandonada últimamente tras ese paréntesis para hablar de gcc, gdb, etc. Si lo recuerdas, en los artículos previos a esos sobre herramientas, aprendimos lo básico sobre la programación: lenguajes de alto nivel, lenguajes de bajo nivel, proceso de compilación, las etapas de la programación, lo que era un algoritmo, etc. Recuerda que todo está orientado al lenguaje de programación C, que es el que estoy usando como referencia.

Pues bien, tras esos pasos previos que entiendo que son indispensables, ahora vamos a comenzar a aprender el lenguaje C. Y lo haremos empezando por los tipos de datos que se pueden manejar y las operaciones esenciales que podrás usar en tus códigos fuente. Igualmente aprenderás a identificar y diferenciar los elementos elementales del programa: palabras reservadas, variables, constantes, funciones, etc.

Ingredientes

Richard Stallman hizo una analogía entre las recetas y el código fuente de los programas que me gustó, por eso vamos a ver esos «ingredientes» necesarios para tu receta en C.

Si no entiendes algo, no te preocupes, con los próximos artículos con ejemplos prácticos lo entenderás todo mejor…

Preprocesador de C

¿Recuerdas el diagrama que puse cuando hablamos del proceso de compilación? Se incluía el preprocesador de C. Él será el encargado primero de manipular el texto o código fuente previamente a la compilación. Lo que hará es limpiar los comentarios, reemplazar todos los valores existentes en las directivas por lo necesario para generar el código objeto, etc.

Aunque siempre se escriben las directivas destinadas al preprocesador al principio del programa, no es estrictamente necesario. Se pueden poner en cualquier parte del código.

#include Sirve para incluir un fichero especificado, como los de cabecera para llamar a bibliotecas. Por ejemplo:

#include <stdio.h>

#include «nombre.h»

En el primer caso busca el .h en los directorios estándar. En el segundo buscará primero en el directorio actual de trabajo.

#define Define macros y constantes simbólicas. Por ejemplo:

#define ANCHO 38

#define LARGO (ANCHO + 47)

También existen macros predefinidos. En ANSI C, se reconocen 5 de ellos. __DATE__ para describir fecha tipo mmm/dd/aaaa, __TIME__ para la hora hh:mm:ss, __FILE__ para el nombre del fichero fuente actual, __LINE__ sustituye al número de línea actual, y __STDC__ que verifica que todo el código esté en ANSI.

#if

#elif

#else

#endif

Para formar directivas condicionales. Por ejemplo:

#if expresión1

instrucción;

#elif expresión2

instrucción;

#else

instrucción;

#endif

#ifdef Comprueba si el identificador está definido. Por ejemplo:

#ifdef identificador

#ifndef Comprueba si el identificador no está definido.
#line Cambia contenidos del fichero de mensajes de compilación, donde se registran los errores. Por ejemplo:

#line 60 «mensaje»

Entonces, en caso de haber un error aparecería algo así:

mensaje(60): warning C4013…

#undef Anula la definición LINE/FILE, es decir, borra la definición de un identificador creado con #define previamente. Por ejemplo:

#undef identificador

#error Se emplea para abortar una compilación y mostrar un mensaje de error. Por ejemplo, si quieres crear un programa que de error si PSICINA no ha sido definida como directriz, entonces:

#if !defined(PISCINA)

#Error PSICINA no definida

#endif

#pragma Pasa opciones al compilador. Cada compilador podrá definir las suyas propias.

También se puede usar \ al final de una línea para partir directivas si ocupan más de una linea, # como operador cadena para macros que tienen parámetros, y ## como concatenador para unir tokens…

Bibliotecas

A estas alturas, si lees el blog con frecuencia, ya deberías saber qué es una biblioteca. Pues bien, en ANSI C puedes usar gran cantidad de ellas. 24 ficheros de cabecera están incluidos en las estándares. Para no alargar demasiado este artículo, si quieres saber cuáles son, las tienes aquí. En los próximos ejemplos iremos usando algunas de ellas para que veas mejor para qué sirven…

A parte de esas, también puedes usar las tuyas propias o las del entorno o sistema operativo para el que estés desarrollando. Por ejemplo, POSIX/SUS tiene otras…

Identificadores

Con un identificador se puede bautizar o dar nombre a variables, constantes, tipos de datos, procedimientos, nombres de funciones, etc. Para crear estos nombres, de debe respetar algunas reglas:

  • Puedes usar todas las letras minúsculas de la a-z y mayúsculas de A-Z. Además, cuenta con case-sensitive, es decir, diferencia entre mayúsculas y minúsculas. Por tanto, nombre, Nombre, NOMBRE y noMbre las reconocerá como diferentes…
  • Los números de 0-9
  • No se aceptan espacios, pero puedes unir con _
  • Siempre deben comenzar por una letra o _

Por ejemplo:

Mal Bien
«Y» X
6area suma1
mis-arch num_3
error cuenta PRODUCTO_NUEVO
$var _tiempo

Por otro lado, los símbolos soportados en el código solo son: -, /, &, ?, ‘, |, (), [], {}, :, ;, _, ^, <>, ~, #, =, *, %, !, \, @, $, y también el punto, coma y espacio.

Tipos de datos y sistemas numéricos

Los programas en C pueden trabajar con diferentes tipos de datos:, tanto simples (enteros, reales, lógicos o booleanos [true/false], caracteres) o compuestos por varios simples. Los tipos básicos son:

int Entero. Ocupa 2 bytes y va desde el -32.768 a 32.767
float Flotante. Ocupa 4 bytes y va desde el 3,4 E-38 a 3,4 E+38
double Flotante de precisión doble. Ocupa 8 bytes y va desde 1,7 E-308 a 1,7 E+308
char Caracter o cadenas. De 1 byte (8 bits). De -127 a 127
void Ocupa 0 bytes, es un valor vacío. Es frecuente usarlo en la función main, que no regresa nada ni tiene parámetros. Por ejemplo: void main() o void main(void).

Se puede usar también long para valores de longitud mayor, y sizeof para indicar el tamaño exacto en bytes de un tipo.

Otros lenguajes usan Unicode, etc., pero aquí también sería interesante conocer ANSI

Sería interesante también que conozcas los caracteres ASCII para consultarlos por si los necesitas, y los sistemas numéricos que puedes emplear en los códigos. Los sistemas son binario (base 2), decimal (base 10), octal (base 8) y hexadecimal (base 16).

Variables

Una variable es un dato cuyo valor (de alguno de los tipos vistos en el apartado anterior) puede variar a lo largo de la ejecución del programa. Es decir, es un valor almacenado en la memoria que puede variar, ya sea por alguna operación previa que afecte al valor de dicha variable o porque los datos se deban insertar por el usuario, etc. La variable tendrá un identificador asignado. Por ejemplo, sum puede ser una variable en este programa y será diferente en función de los valores de las otras variables que debe introducir un usuario (num1 y num2):

#include <stdio.h>

int main()
{
          int sum, num1, num2;
          printf("Introduce un número: ");
          scanf("%d", &num1);
          printf("Introduce otro número: ");
          scanf("%d", &num2);

          suma = num1+num2;
          prinft("El resultado de la suma es: %d",  suma);
          return 0;
}

La variable debe declararse siempre, o el compilador dará un código de error al intentar compilarlo. Muchos de los errores típicos son olvidar declarar una variable o teclear mal el nombre y que no coincida. Además, se declarará en un lugar específico según el tipo:

  • Global: fuera de todos los subprogramas o funciones.
  • Local: dentro de un subprograma o función. También puede hacerse dentro de un bloque, de una función o como parámetro formal.

Ten en cuenta también que cuando se declara una variable se reserva un espacio de memoria para ella. El espacio ocupado dependerá del tipo de dato usado. Por ejemplo, si es un entero como en el caso de suma, entonces será de 2 bytes. Por ahora no entraré en temas de segmentación y paginación… con eso es suficiente, pero es posible que en la serie sobre CPUs veamos algo más adelante.

Constantes

Similar a la variable, también con un identificador, pero en este caso, la constante permanecerá siempre con el mismo valor (de ahí su nombre). También pueden ser de diversos tipos como las variables, y se almacenarán en su espacio correspondiente de memoria que le asigne el compilador al generar las instrucciones, datos y direcciones de memoria en el binario generado.

Puedes usar const o macros para definirlas. Por ejemplo:

#define MAX 100
const float PI = 3.14

Operadores

Los operadores son símbolos que permiten relacionar datos en una expresión y evaluar el resultado. Pueden ser de tipo aritmético, lógico, relacionales y de asignación.

Los aritméticos son:

+ Suma
Resta
* Multiplica
/ Divide
% Resto de una división
pow Potencia

Los de incremento y decremento son

++ Incrementa. Por ejemplo i++ usa el valor actual de i  en la expresión donde se encuentra i, y luego lo incrementa en 1. En cambio, ++i incrementa i en 1 y luego se utiliza el nuevo valor de i en la expresión en la que se encuentra i.
Decrementa. Sirve lo dicho anteriormente, en función de si usas –i o i–

Los lógicos son:

&& AND (Y)
|| OR (O)
! NOT o negación

Los relacionales son:

> Mayor que
< Menor que
== Igual que
>= Mayor o igual que
<= Menor o igual que
!= Distinto a

Los de asignación sirven para asignar el resultado de una expresión a una variable. Por ejemplo, el caso de la suma anterior lo era, ya que se asignaba el valor a la variable suma de num1+num2. Otors ejemplos:

= En este caso promedio pasa a valer la media de edades:

promedio = edad1+edad2/2

+= Se emplea para x = x + algo. Por ejemplo: s+=10 equivale a s = s+10
-= Se emplea para x = x – algo. Por ejemplo: y-=12 equivale a y = y-12
*= Igual a los anteriores, pero multiplicando.
/= Igual pero dividiendo.
%= Lo mismo para el resto.

También existe un operador condicional como sustituto de if…else, es ?. Por ejemplo, esto sería equivalente:

#Siempre que a>3, b toma el valor 5

b = (a<3) ? 5 : 10;

if (a<3) b = 5;

else b=10;

Importante la prioridad, ya que al ser operaciones matemáticas se tiene prioridad según el símbolo empleado, las agrupaciones tendrán prioridad, etc.

1º Asociación Con () y [], de izquierda a derecha
2º Monarios Con -,++,–,!,sizeof(), de derecha a izquierda
3º Otros aritméticos Con *, /, %, de izquierda a derecha
4º Suma y resta Con +, -, de izquierda a derecha
5º Relacionales Con <,<=, >, >=, de izquierda a derecha
6º Igualdad Con == y !=, de izquierda a derecha
7º AND Con &&, de izquierda a derecha
8º OR Con ||, de izquierda a derecha
9º Condicional Con ?:, de derecha a izquierda
10º Asignación Con =, +=, -=, *=, /=, %=, de derecha a izquierda

Por ejempo, si tienes lo siguiente:

total = num1 + (num2 – num3 * x) + y/2

Lo que primero hará es multiplicar num3 y x. Lugo divide y/2. También se resta el resultado de num3*x a num2. Después se suma el resultado dentro del paréntesis a num1 y finalmente todo eso se suma al resultado de y/2. El resultado es asignado a la variable total.

Secuencias de escape

En cuanto a las secuencias de escape, tienes estas:

\a Hace un sonido de alerta
\b Retroceso o espacio hacia atrás
\t Tabula el texto de forma horizontal
\n Cambia de línea el texto que va detrás de esta secuencia
\v Hace una tabulación en vertical del texto
\f El texto tras esta secuencia se muestra en una nueva página
\r Retroceso de carro. Es el valor 013 de ASCII
Comillas. Corresponde al ASCII 034
\’ Comillas simple o apóstrofo. Código ASCII 039
\? Para poner el signo de interrogación en el código
\\ Para insertar la barra invertida
\0 Valor nulo o null. Es el ASCII 000
\ooo Permite insertar el número octal «ooo» de tres dígitos
\xhh Permite insertar un número hexadecimal hh (de cualquier cantidad de dígitos)

Expresiones

Una expresión simplemente es el resultado de unir varios operandos (variables o constantes) mediante operadores. Por ejemplo, sum=num1+num2 sería una expresión.

Palabras reservadas

Son palabras reservadas las que no se pueden usar para identificadores, ya que están reservadas por el lenguaje para otros usos:

  • ada
  • asm
  • auto
  • break
  • case
  • char
  • const
  • continue
  • default
  • do
  • double
  • else
  • entry
  • enum
  • extern
  • far
  • float
  • for
  • fortran
  • goto
  • huge
  • sizeof
  • if
  • static
  • int
  • struct
  • long
  • switch
  • near
  • typedef
  • pascal
  • union
  • register unsigned
  • return
  • void
  • short
  • volatile
  • signed
  • while

Además de estas, estarán también las de algunas funciones que aportan las bibliotecas, como scanf, printf, etc., que tampoco puedes usar como identificadores. Ya estudiaremos más adelante para qué sirve cada una…

Comentarios

Los comentarios son el texto que quieres que el compilador ignore, pero que es necesario para hacer una breve explicación de una parte del programa o para que otro desarrollador entienda mejor lo que se ha pretendido hacer, etc. Se puede usar dos formas para insertarlos:

/* Cuando el texto ocupa más de una línea puedes usar este método encerrando entre estos símbolos todo lo que quieras que se tome como comentario */

//Para una nota más breve puedes usar esto al comienzo del comentario...

Conversión de tipos

Si has usado varios tipos de datos en una misma expresión, el compilador los transformará todos a un tipo para poder realizar la operación. El tipo al que transformará dependerá de la prioridad de cada uno de los tipos (mayor prioridad el de más a la derecha):

char > int > unsigned int > long > unsigned long > float > double > long double

En el siguiente veremos cómo está constituido un programa y  algunas estructuras básicas, y una vez hecho eso, ya podrás empezar a crear tus primeras recetas… Iré publicando más entradas sobre programación con ejemplos prácticos que incluirán el algoritmo, pseudocódigo y el código fuente. 😉

Isaac

Apasionado de la computación y la tecnología en general. Siempre intentando desaprender para apreHender.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

A %d blogueros les gusta esto:

Si continuas utilizando este sitio aceptas el uso de cookies. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar