Lenguaje de Programación

Computadora: Es un dispositivo electrónico utilizado para procesar información y obtener resultados. Los datos y la información se pueden introducir en la computadora como entrada (input) y a continuación se procesan para producir una salida (output).

Programa: Es el conjunto de instrucciones escritas de algún lenguaje de programación y que ejecutadas secuencialmente resuelven un problema especifico.

Lenguaje: Es una serie de símbolos que sir ven para transmitir uno o mas mensajes (ideas) entre dos entidades diferentes. A la transmisión de mensajes se le conoce comúnmente como comunicación.

Lenguajes de Programación: Es un conjunto de símbolos, caracteres y reglas que le permiten a las personas comunicarse con la computadora. Los lenguajes de programación tienen un conjunto de instrucciones que nos permiten realizar operaciones de entrada/salida, calculo, manipulación de textos, lógica/comparación y almacenamiento/recuperación.

Clasificación de los Lenguajes de Programación

Lenguaje Maquina: Son aquellos cuyas instrucciones son directamente entendibles por la computadora y no necesitan traducción posterior para que el CPU pueda comprender y ejecutar el programa. Las instrucciones en lenguaje maquinan se expresan en términos de la unidad de memoria mas pequeña el bit (dígito binario 0 o 1).

Lenguaje de Bajo Nivel (Ensamblador): En este lenguaje las instrucciones se escriben en códigos alfabéticos conocidos como mnemotécnicos para las operaciones y direcciones simbólicas.

Lenguaje de Alto Nivel: Los lenguajes de programación de alto nivel son aquellos en los que las instrucciones o sentencias a la computadora son escritas con palabras similares a los lenguajes humanos (en general en ingles), lo que facilita la escritura y comprensión del programa.

Programación Estructurada

La programación estructurada es una teoría orientada a mejorar la claridad, calidad y tiempo de desarrollo utilizando únicamente subrutinas o funciones. Esta basada en el teorema del programa estructurado propuesto por Böhm y Jacopini.

Este conjunto de técnicas permite desarrollar algoritmos fáciles de escribir, verificar, leer y modificar. La programación estructurada utiliza:

  • Diseño descendente. Consiste en diseñar los algoritmos en etapas, yendo de los conceptos generales a los de detalle. El diseño descendente se verá completado y ampliado con el modular.
  • Recursos abstractos. En cada descomposición de una acción compleja se supone que todas las partes resultantes están ya resueltas, posponiendo su realización para el siguiente refinamiento.
  • Estructuras básicas. Los algoritmos deberán ser escritos utilizando únicamente tres tipos de estructuras básicas.

Elementos de un programa

Ambientes de desarrollo (IDE)

El ambiente de desarrollo integral (IDE en ingles) se refiere a todo aquel entorno de programación que estemos empleando como herramienta para escribir y diseñar nuestros programas. Generalmente se cuenta con un editor de textos, algunas herramientas de diseño y un menú de opciones que nos permite compilar y ejecutar los programas.

Los IDE están formados por un entorno de programación que ha sido empaquetado como un programa de aplicación, es decir, consiste en un editor de código, un compilador, un depurador y un constructor de interfaz gráfica GUI. Los IDE pueden ser aplicaciones por sí solas o pueden ser parte de aplicaciones existentes.

Los IDE proveen un marco de trabajo amigable para la mayoría de los lenguajes de programación tales como C++, Python, Java, C#, Delphi, Visual Basic, etc. En algunos lenguajes, un IDE puede funcionar como un sistema en tiempo de ejecución, en donde se permite utilizar el lenguaje de programación en forma interactiva, sin necesidad de trabajo orientado a archivos de texto, como es el caso de Smalltalk u Objective-C.

Es posible que un mismo IDE pueda funcionar con varios lenguajes de programación. Inherente al ambiente de desarrollo se encuentra el compilador, parte indispensable para la construcción de programas, cada compañía es responsable de diseñar/construir su propio compilador de C, siempre y cuando cumpla con los estándares establecidos por ANSI/C. Borland y Microsoft, por lo general distribuyen el compilador junto con su ambiente de desarrollo, pero es posible adquirir sus compiladores de forma gratuita en la red, con el inconveniente de no contar con un ambiente de desarrollo (IDE).

También es posible adquirir en Internet otras versiones de compiladores libres como GNU GCC disponible en todas las variantes de GNU/Linux y UNIX, e inclusive para Windows, generalmente estos compiladores trabajan en consola, pero debido a su enorme integración y versatilidad, son fáciles de combinar con cualquier IDE no comercial.

Algunos links a IDE’s que pueden ser útiles en este curso son:

Dev C/C++ – http://www.bloodshed.net/

Code::Blocks – https://www.codeblocks.org/<;

Visual Studio Code – https://code.visualstudio.com/

CLion – https://www.jetbrains.com/es-es/clion/

Zinjal – http://zinjai.sourceforge.net/

Características del Lenguaje C

El lenguaje C se conoce como un lenguaje compilado. Este tipo de lenguajes convierten el código fuente en un fichero objeto y éste en un fichero ejecutable. Este es el caso del lenguaje C.

El lenguaje C es un lenguaje de nivel medio, ya que combina elementos de lenguaje de alto nivel con la funcionalidad del lenguaje ensamblador. Es un lenguaje estructurado, ya que permite crear procedimientos en bloques dentro de otros procedimientos. Hay que destacar que el C es un lenguaje portable, ya que permite utilizar el mismo código en diferentes equipos y sistemas informáticos: el lenguaje es independiente de la arquitectura de cualquier máquina en particular.

Por último, se puede decir que el C es un lenguaje relativamente pequeño; se puede describir en poco espacio y aprender rápidamente.

Estructura de un programa en C

Todo programa en C consta de una o más funciones, y la función principal se conoce como main. El programa comienza en la función main, desde la cual es posible llamar a otras funciones.

Cada función estará formada por el prototipo de la función (tipo de dato de la función, nombre de la misma y la lista de argumentos -si los hubiese-), la declaración de las variables a utilizar y la secuencia de sentencias a ejecutar. Ejemplo:

 

Comentarios

Para poner comentarios en un programa escrito en C se utiliza los símbolos /* y */:

/* Este es un ejemplo de comentario */

/* Un comentario también puede

estar escrito en varias líneas */

El símbolo /* se coloca al principio del comentario y el símbolo */ al final.

El comentario, contenido entre estos dos símbolos, no será tenido en cuenta por el compilador.

Palabras clave (primitivas del lenguaje)

Existen una serie de palabras reservadas, con una finalidad determinada dentro del lenguaje de programación, que no se pueden utilizar como identificadores. Algunas de estas palabras son:

Identificadores

El primer carácter de un identificador no puede ser un número, es decir que debe ser una letra o el símbolo _ Se diferencian las mayúsculas de las minúsculas, así num, Num y nuM son distintos identificadores.

A continuación se observan algunos ejemplos de identificadores válidos y no válidos:

Tipos de datos

En ‘C’ existen básicamente cuatro tipos de datos, aunque también se puede definir tipos de datos propios a partir de los tipos originales. A continuación se detalla su nombre, el tamaño que ocupa en memoria y el rango de sus posibles valores.

 

Calificadores de tipos de datos

Los calificadores de tipo tienen la misión de modificar el rango de valores de un determinado tipo de variable.

Estos calificadores son cuatro:

  • signed

Le indica a la variable que va a llevar signo. Es el utilizado por defecto.

 

 

 

 

  • unsigned

Le indica a la variable que no va a llevar signo (valor absoluto).

 

 

 

  • short

Rango de valores en formato corto (limitado). Es el utilizado por defecto.

 

 

 

  • long

Rango de valores en formato largo (ampliado).

 

 

 

También es posible combinar calificadores entre sí.

Variables

Una variable sólo puede pertenecer a un tipo de dato. Para poder utilizar una variable, primero tiene que ser declarada:

          [calificador] <tipo> <nombre>

Es posible inicializar y declarar más de una variable del mismo tipo en la misma sentencia:

[calificador] <tipo> <nombre1>,<nombre2>=<valor>,<nombre3>=<valor>,<nombre4>

Ejemplo:

int num1=4,num2,num3=6;

¿Dónde se declaran?

Las variables pueden ser de dos tipos según el lugar en que las declaremos: globales o locales. La variable global se declara antes de la función main( ). Puede ser utilizada en cualquier parte del programa y se destruye al finalizar éste.

La variable local se declara después de la main( ), en la función en que vaya a ser utilizada. Sólo existe dentro de la función en que se declara y se destruye al finalizar dicha función.

 

 

 

 

 

Constantes

Para indicar al compilador que se trata de una constante, se utiliza la directiva #define:

          #define <identificador> <valor>

Observe que no se indica el punto y coma de final de sentencia ni tampoco el tipo de dato.

 

 

 

 

 

Secuencias de escape

Ciertos caracteres no representados gráficamente se pueden representar mediante lo que se conoce como secuencia de escape.

A continuación se observa una tabla de las más significativas:

\n     salto de línea

\b     retroceso

\t     tabulación horizontal

\v     tabulación vertical

\\     contrabarra

\f     salto de página

\’     apóstrofe

\”     comillas dobles

\0    fin de una cadena de caracteres

 

 

 

 

 

Inclusión de librerías

En la programación en C es posible utilizar funciones que no esten incluídas en el propio programa. Para ello se utiliza la directiva #include, que permite añadir a un programa librerías o funciones que se encuentran en otros ficheros.

Para indicar al compilador que se va a incluir ficheros externos se tiene dos maneras (siempre antes de las declaraciones).

1. Indicándole al compilador la ruta donde se encuentra el fichero.

#include “misfunc.h”

#include “c:\includes\misfunc.h”

2. Indicando que se encuentran en el directorio por defecto del compilador.

#include <misfunc.h>

Operadores

Operadores aritméticos

Binarios:

+ Suma                      – Resta

* Multiplicación           / División

% Módulo (resto)

y los unarios:

++ Incremento (suma 1)

– – Decremento (resta 1)

– Cambio de signo

Operadores de asignación

En el lenguaje C existen expresiones de asignación, para las cuales se utilizan los siguientes operadores:

De ellos, el más utilizado es el operador de asignación (=) y su sintaxis es la siguiente:

<nombre_de_la_variable> = <expresión>;

Operadores y precedencia

Un operador es un símbolo (+, -, *, /, etc.) que tiene una función predefinida (suma, resta, multiplicación, etc.) y que recibe sus argumentos de manera infija (3+5), prefija (+35) o postfija (35+).

Cuando realizamos ciertas operaciones con expresiones y sentencias, se ven involucrados varios operadores, y en ciertos casos se emplean paréntesis para delimitar cuales sentencias se llevaran a cabo antes que otras, por ejemplo:

La sentencia, x = y + (z * 2) deja claro que primero será necesario realizar una multiplicación de z * 2, y posteriormente una suma de dicho resultado con y, gracias a la precedencia de operaciones, no es necesario realizar la operación empleando paréntesis para delimitar la secuencia exacta de operaciones, ya que la multiplicación siempre será realizada antes que una suma, debido a su nivel de prioridad, de manera que x = y + z * 2 generará el mismo resultado.

A continuación se presenta una lista con el nivel de precedencia de los operadores involucrados en el lenguaje C, algunos de ellos ya le resultaran familiares y algunos otros no, pero serán abordados con detenimiento en su momento (mas adelante).

De manera que una sentencia como 3+2 >= 5+0, realizara primero la operación de suma en ambas partes y posteriormente realizara la comparación.

Recuerde que el uso de los paréntesis ayuda a asociar y delimitar la precedencia de las operaciones, los programadores novatos suelen hacer mucho uso de paréntesis para delimitar la prioridad de las acciones, pero con el tiempo su habilidad para el cálculo de expresiones crece considerablemente.

Existen otro tipo de Operadores, a los cuales les llamamos “operadores especiales”:

Manejo de expresiones

Una expresión es una combinación de variables, llamadas a función y operadores que resultan en un valor simple. Como ya vimos en la parte anterior la inicialización de variables ó expresión de asignación, es la expresión más simple que puede existir:

x = 2;

En este caso se una asigna un valor entero a una variable x. A la parte izquierda de la expresión de asignación se le conoce como lvalue, es decir, valor izquierdo y rvalue al del lado derecho. De esta forma queda claro que el valor del lado derecho deberá ser una variable y el lado derecho será una variable, constante numérica o el resultado de una operación de manera que la operación se lleva a cabo de derecha a izquierda y nunca de otra forma.

Expresiones Aritméticas

Las operaciones de suma (+), resta (-), multiplicación (*) y división (/) literalmente corresponden a sus respectivas operaciones matemáticas. A excepción de la operación modulo, que nos da el residuo de dos valores, representada por el operador %:

x = (y + z) * 2

Existen además algunos operadores llamados de asignación compuesta que permiten modificar el valor de una variable llevando a cabo una operación en la que se ve involucrado el valor actual de esa variable. Los operadores de éste tipo son +=, -=, *=, /=, %=, y se emplean así:

x += y que equivale a la expresión x = x + y

También existen los operadores de incremento y decremento, que reducen o incrementan una unidad al valor almacenado en la variable. Una de las características más interesantes de este operador es que puede ser usado de dos maneras, en prefijo y postfijo, esto quiere decir que el operador podrá aparecer respectivamente antes (++id) o después (id++) del identificador, y usados en una expresión simple realiza la misma operación en cualquiera de sus dos versiones, pero usado en conjunto con otras expresiones o sentencias tendrá un comportamiento diferente.

Expresiones Relacionales

Para realizar la comparación entre dos expresiones empleamos los operadores relacionales que nos indican algún tipo de relación entre dos entidades, ya sea de igualdad o desigualdad, y cuyo resultado de la operación siempre será un valor booleano (cierto/falso). A continuación se muestran los operadores relacionales disponibles en C, para el caso de x = 3, y = 1 y z = 2:

Expresiones lógicas

Los operadores boléanos nos permiten construir expresiones más complejas en las que se encuentran involucradas condiciones formadas por las palabras “y”, “o” y “no”. Por ejemplo, es cierto el hecho de que “5 > 3 y 5 < 7”.

La expresión lógica “y” (conjunción) es representada por el operador &&, y es usado para combinar dos valores boléanos, y el resultado es también un valor booleano. Para éste caso el resultado será cierto si ambos valores son ciertos, en cualquier otro caso el resultado será falso. Por otro lado, la expresión “o” (disyunción) es representada por el operador ||, de manera que la expresión será cierta siempre y cuando alguno de los componentes de la expresión sea cierta. Finalmente la expresión lógica “no”, también conocida como negación, es un operador unario representado por el operador ! y se antepone al operando, el resultado de aplicar este operador es invertir el valor del operando, cambiando el valor de cierto a falso y viceversa.

Los operadores lógicos generan una interesante relación de resultados que suele ser representada en forma de tabla (tablas de verdad), es importante recordar que los operadores lógicos evaluaran la expresión relacional y le darán un valor de certeza o falsedad según sea el caso, por ejemplo:

Suponga que se requiere saber si un empleado cataloga para un incremento salarial, si su antigüedad es mayor a 10 años y cuenta con una edad mayor a 40 años, el operador lógico podría simplificar esta tarea, expresando la relación algorítmicamente:

Las tablas de verdad nos podrían ayudar a visualizar el resultado de manera mas eficiente. En la tabla de verdad de la conjunción (and lógico), en caso de que alguno de los elementos en la expresión resulte falso, todo el enunciado será falso:

Suponga otro caso para el incremento salarial donde pretendemos ser mas flexibles y otorgar dicho incremento en caso de que cualquiera de los dos valores involucrados sea mayor al limite, es decir, incrementar el salario si la antigüedad es mayor a 10 años, o la edad es mayor a 40.

Nuevamente las tablas de verdad nos podrían ayudar a visualizar el resultado de manera mas eficiente. En la disyunción (or lógico), en caso de que alguno de los elementos en la expresión resulte cierto, todo el enunciado será cierto:

El operador de negación suele ser utilizado para invertir el resultado de una expresión lógica, de manera que lo que sea falso se convertirá en cierto y viceversa.

Operador Condicional

Es un operador ternario que permite realizar operaciones de asignación de manera muy sencilla y eficiente, su sintaxis es la siguiente:

<expresión-booleana> ? <expresión-1> : <expresión-2>

La expresión booleana es evaluada, de manera que, si el valor resultante es cierto la expresión-1 será asignada, en caso contrario la expresión-2 será seleccionada. Por ejemplo:

valor = ( n % 4 == 0 ) ? ( n * 2 ) : ( n++ );

La sentencia anterior realiza lo siguiente; primero evalúa que el residuo de n entre 4 sea igual a cero ( n % 4 == 0 ), en caso de ser cierta la expresión booleana, el resultado de ( n * 2 ) es asignado a valor, en caso contrario n es asignado, y enseguida n se incrementa( n++ ). Cabe mencionar que los paréntesis en este ejemplo no son necesarios, pero facilitan la explicación.

Conversión de tipos de datos

En algunas ocasiones es necesario almacenar el resultado de una expresión en una variable de un tipo distinto, por ejemplo, cuando cuando los dos operandos de una división (/) son enteros, pero aun así, de su evaluación se quiere obtener un valor real, es necesario realizar un casting (o conversión de tipo).

Sintaxis es:

( <tipo_de_dato> ) <expresión>;

De esta forma, se consigue cambiar el tipo de dato del valor resultante de evaluar la <expresión> a un <tipo_de_dato> deseado. Ejemplo: Para cambiar un valor entero a flotante: