martes, 28 de marzo de 2023

ESTRUCTURAS

 


Las estructuras de datos se emplean con el objetivo principal de organizar los datos contenidos dentro de la memoria del ordenador. Así, nuestra primera experiencia con estructuras comienza desde el momento mismo en que usamos en nuestros programas variables de tipos primitivos (char, short, int, float, etc). A la memoria del ordenador se le puede considerar como un gran bloque compuesto por una serie de BYTES dispuestos secuencialmente uno detrás de otro. por ejemplo, si un ordenador posee una memoria de 128MB (128 megas) entonces se le puede leer o escribir desde el BYTE 0 hasta el BYTE 128MB - 1 ( 0000000H .. 7FFFFFFH )

La idea de ver la memoria como un serie de bytes es buena, sin embargo no es suficiente ya que en la misma podemos guardar números, cadenas de caracteres, funciones, objetos, etc. de tal manera que surge la necesidad de establecer los mecanismos adecuados para dar cuenta de la forma, tamaño y objetivo de los datos almacenados. Según el tipo de microprocesador, estos tienen la capacidad para manipular o direccionar estructuras compuestas por uno, dos, cuatro, etc, bytes; de donde se derivan los tipos que comunmente se conocen como: BYTE, WORD, DWORD, QWORD y TWORD.

La estructura mínima de información manipulable en un sistema de computación es el BIT el cual se agrupa normalmente en bloques de 8 para formar un BYTE. Cabe mencionar que los BITS no son direccionables directamente, sino a través de compuertas AND, OR, NOT, XOR, las cuales en C y C++ se escriben como &, |, ~ y ^, conocidos como "Bitwise operators" u "Operadores de manipulación de bits".

En C,C++ existe una serie de estructuras básicas o tipos primitivos, los cuales pueden ser usados por el programador para declarar variables, y también son el fundamento sobre el cual se crean estructuras complejas. El tamaño de los tipos primitivos no es estándar ya que los mismos dependen de factores tales como:
  • Tipo del microprocesador
  • El compilador
Sin embargo, en la actualidad, la mayoria de compiladores de C y C++ soportan los siguientes tipos con la longitud indicada

FUNCIONES

  Las funciones pueden reducir a en línea, lo que se hace que expandir el código original de la función.


Las funciones se descomponen simplificando los parámetros de manera individual al igual que el valor de retorno.


Entendemos que es el uso de la lengua que hace un hablante. En simples palabras, las funciones del lenguaje son los diferentes objetivos, propósitos y servicio que se le da al lenguaje al comunicarse, dándose una función del lenguaje por cada factor que tiene éste, en donde la función que prevalece es el factor en donde más se pone énfasis al comunicarse. Diversos lingüistas (Karl Bühler, Roman Jakobson, Michael Halliday ) han propuesto distintas clasificaciones de las funciones del lenguaje: Bühler propuso que existían únicamente tres funciones: La Representativa (por la cual se trasmiten informaciones objetivamente) La Expresiva o emotiva (que expresa sentimientos del emisor) La Conativa, mediante la que se influye en el receptor del mensaje a través de órdenes, mandatos o sugerencias ESTRUCTURAS El código intermedio no es el lenguaje de programación de ninguna máquina real, sino que corresponde a una máquina abstracta, que se debe de definir lo más general posible, de forma que sea posible traducir este código intermedio a cualquier máquina real. El objetivo del código intermedio es reducir el número de programas necesarios para construir traductores, y permitir más fácilmente la transportabilidad de unas máquinas a otras. Supóngase que se tienen n lenguajes, y se desea construir traductores entre ellos. Sería necesario construir n*(n-) traductores. Sin embargo si se construye un lenguaje intermedio, tan sólo son necesarios 2*n traductores.

Por ejemplo un fabricante de compiladores puede construir un compilador para diferentes máquinas objeto con tan sólo cambiar las dos últimas fases de la tarea de síntesis.

INSTRUCCIONES DE CONTROL

 Esta forma de programación sólo permite resolver problemas sencillos. Para resolver problemas más complejos, nos puede interesar que dependiendo de los valores de los datos, se ejecuten unas instrucciones u otras.

Las instrucciones condicionales nos van a permitir representar éste tipo de comportamiento. Sentencias IF y SWITCH. En otros casos, nos encontraremos con la necesidad de repetir una instrucción o instrucciones un número determinado de veces. En éstos casos utilizaremos instrucciones de control iterativas o repetitivas (ciclos). Sentencias WHILE, DO-WHILE y FOR.
Resultado de imagen para switch estructuraResultado de imagen para if

INSTRUCCIONES DE ASIGNACIÓN

 La sintaxis general de la instrucción de asignación es:


nombre_de_la_variable = valor

El valor a la derecha del signo igual puede ser una constante, otra variable o una expresión que combine constantes y variables, pero siempre la variable y su valor deben ser del mismo tipo de dato.
Ejemplos:
edad% = 5
area! = 12.3
nombre$ = “Pedro”

Instrucciones de asignación compuesta

Las instrucciones de asignación compuesta realizan primero una operación en una expresión antes de asignarla a un elemento de programación. En el siguiente ejemplo se muestra uno de estos operadores, +=, que incrementa el valor de la variable del lado izquierdo del operador con el valor de la expresión de la derecha.
Una instrucción de asignación asigna el valor de una expresión a una variable. En general, si la variable que se va a asignar es una propiedad, la propiedad debe ser de lectura y escritura o de sólo escritura; en caso contrario, se produce un error de compilación. Si la variable es una variable de sólo lectura, la asignación debe producirse en un constructor Shared o un constructor de instancia apropiado para el tipo de la variable; en caso contrario, se producirá un error de compilación.

VARIABLES Y CONSTANTES

Las declaraciones de variables y constantes deben separarse de tal manera que queden las expresiones una por una de manera simple. Por ejemplo int a,b,c; se descompone a int a; int b; intc; respectivamente.

Una constate es un elemente de nombre con un valor predefinido, mientras que una  variable es un elemento de datos con nombre cuyo valor puede cambiar durante el curso de la ejecucion de un programa, estas pueden ser globales o locales.

Int

Tipo de datos entero ( + - seguido de 1 o más dígitos entre 0 y 9).

Real

Coma flotante (+- seguido de cero o más dígitos 0–9). Coma decimal seguida de 1 o más dígitos 0-9. Tenga en cuenta que todos los números se almacenan internamente como Float.

String

Cualquier cadena de caracteres Unicode válida especificada entre comillas.

Constantes

Una constante es un elemento de datos con nombre con un valor predefinido. No se puede cambiar el valor asignado a una constante predefinida. Las constantes predefinidas son:

NULL

Una referencia vacía. Parecido a un puntero vacío. Tenga en cuenta que no es lo mismo que una cadena de caracteres nula "".

TRUE

Equivalente al número 1.

FALSE

Equivalente al número 0.

ESQUEMA DE GENERACIÓN

Los esquemas de generación son las estrategias o acciones que se deberán realizarse y tomarse en cuenta en el momento de generar código intermedio.

Los esquemas de generación dependen de cada lenguaje. Tomaremos algunos esquemas de generación del lenguaje C.
Expresiones
Instrucciones de control
Para generar expresiones estas deben representarse de manera más simple y más literal para que su conversión sea más rápida.
Por ejemplo la traducción de operaciones aritméticas debe especificarse una por una, de tal forma que una expresión sea lo más mínimo posible
Son aquellas que asignan un valor a una variable o una expresionismo
X=23 ó Y=expresion
Instruccion de asignacion


Las funciones son un grupo de instrucciones con un propocito en general las cuales pueden recibir parametros, mientras que la estructura es un conjunto de datos elementales interelacionados que realizan siertas operaciones entre ellos
variables y constantes
Las declaraciones de variables y constantes deben separarse de tal manera que queden las expresiones una por una de manera simple
Los esquemas de generación son las estrategias o acciones que se deberán realizarse y tomarse en cuenta en el momento de generar código intermedio
Son aquellas que permiten modificar o varial el flujo de ejecucion de un programa, existen 3 tipos los cuales son :
Instrucciones condicionales o alternativas
Instrucciones de salto

Instrucciones repetitivas

miércoles, 22 de marzo de 2023

Cuádruplos

Es una estructura tipo registro con cuatros campos que se llaman:

Operador
Operando1
Operando2
Resultado
Operador
Operando1
Operando2
Resultado
*
C
D
T1
+
B
T1
T2
=
T2
A

Donde operando1, operando2 y resultado pueden ser constantes, identificadores y variables temporales definidos por el compilador mientras que operador representa una operación arbitraria.

  

EJEMPLO:
A := B + C * D
Esquemas de generación.
¿Que son?
 Los esquemas de generación son las estrategias o acciones que deberán realizarse y tomarse en cuenta en el momento de generar código intermedio.
Declaración de variables y constantes.
Las declaraciones de variables y constantes deben separarse de tal manera que queden las expresiones una por una de manera simple.



• Por ejemplo int a,b,c;
se descompone a int a;
int b; intc; respectivamente.
Las variables utilizadas en los programas se clasifican en dos tipos:
variables locales y variables globales.
Variables locales:
Aquella que está declarada para el programa o algoritmo completo.
 Para definir variables locales, la definición debe hacerse inmediatamente después de una llave de inicio ({), y la variable deja de existir fuera de la llave de fin(}) que corresponde a la llave de inicio después del cuál fue definida la variable.
Ejemplo:
{
int a,b;
a=5;
b=a + 100;
}
Variables globales:
Aquella que está declarada y definida dentro de una función y sólo es válida dentro de la misma función y no podrá utilizarse en otra parte del programa.
 Una variable global se declara fuera de cualquier función y primero que cualquier función que requiera de ella. Una variable se declara de la siguiente forma:
 tipo identificador1, identificador2..ident n;



Triplos

En la historia de los compiladores han sido utilizadas una amplia variedad de representaciones intermedias como lo es la siguiente clase de representación de código intermedio de un árbol de 3 direcciones,2 para los operandos y una para la ubicación del resultado. esta clase incluye un amplio numero de representaciones diferentes entre las cuales encontramos cuadruplos y triples. la principal diferencia entre estas notaciones y la notación postfija es que ellos incluyen referencias explicitas para los resultados de los cálculos intermedios, mientras que la notación posfija los resultados son implícitos al representarlos en una pila.

  1. La diferencia entre triples y cuadruplos es que con los triples es referenciado el valor intermedio hacia el numero del triple que lo creo, pero en los cuádruplos requiere que ellos tengan nombre implícitos.
  2. Los triples tienen una ventaja obvia de ser mas consistente, pero ellos dependen de su posición, y hacen que la optimización presente cambios de código mucho mas compleja.
Para evitar tener que introducir nombres temporales en la tabla de símbolos, se hace referencia a un valor temporal según la posición de la proposición que lo calcula. Las propias instrucciones representan el valor del nombre temporal. La implementación se hace mediante registros de solo tres campos (op, arg1, arg2).
  1. En la notación de tripletes se necesita menor espacio y el compilador no necesita generar los nombres temporales. Sin embargo, en esta notación, trasladar una proposición que defina un valor temporal exige que se modifiquen todas las referencias a esa proposición. Lo cual supone un inconveniente a la hora de optimizar el código, pues a menudo es necesario cambiar proposiciones de lugar.
  2. Una forma de solucionar esto consiste en listar las posiciones a las tripletas en lugar de listar las tripletas mismas. De esta manera, un optimizador podría mover una instrucción reordenando la lista, sin tener que mover las tripletas en si.

<operador>,<operando1>,<operando2>
 El resultado se asocia al número de tripleta
Ejemplo: W * X + (Y + Z)
1. *, W, X
2. +, Y, Z
3. +, (1), (2)
Control de flujo:
IF X>Y THEN Z=X ELSE Z=Y+1
1. >, X, Y
2. Saltar si falso, (1), 5
3. =, Z, X
4. Saltar,, 7
5. +, Y, 1
6. =, Z, (5)

|Problema La optimización supone mover tripletas y hay que recalcular las referencias.





Código P

El código P hace referencia a máquinas que utilizan o se auxilian de pilas para generar código objeto. 

En muchos caso la P se asociado a código portable el cual garantiza que el código compilado en una máquina se pueda ejecutar en otras.

Para garantizar la portabilidad del código se necesita que el lenguaje este estandarizado por algún instituto y que dicho código no tenga extensiones particulares. También se recomienda la no utilización de características especiales exclusivas de alguna arquitectura de computadoras en particular.

El código P comenzó como un código ensamblador objetivo estándar producido por varios compiladores Pascal en la década de 1970 y principios de la de 1980. Fue diseñado para código real para una máquina de pila hipotética la idea era hacer que los compiladores de Pascal se transportaran fácilmente requiriendo solo que se volviera a escribir el intérprete de la maquina P para una plataforma, el código P también a probado ser útil como código intermedio y sean utilizado varias extensiones y modificaciones del mismo en diversos compiladores de código nativo, la mayor parte para lenguaje tipo Pascal.


Como el código P fue diseñado para ser directamente ejecutable, contiene una descripción implícita de un ambiente de ejecución particular que incluye tamaños de datos, además de mucha información específica para la maquina P, que debe conocer si se desea que un programa de código P se comprensible. La máquina P está compuesta por una memoria de código, una memoria de datos no específica para variables nombre das y una pila para datos temporales, junto como cualquiera registro que sea necesario para mantener la pila y apoyar la ejecución.

Ejemplos




miércoles, 15 de marzo de 2023

TRADUCCION

 

Polish Notation (PN)

 What Does Polish Notation (PN) Mean?

Polish notation is a notation form for expressing arithmetic, logic, and algebraic equations. Its most basic distinguishing feature is that operators are placed on the left of their operands. If the operator has a defined fixed number of operands, the syntax does not require brackets or parenthesis to lessen ambiguity.

Polish notation is also known as prefix notation, prefix Polish notation, normal Polish notation, Warsaw notation, and Lukasiewicz notation.

Techopedia explains Polish Notation (PN)

Polish notation was invented in 1924 by Jan Lukasiewicz, a Polish logician, and philosopher, in order to simplify sentential logic. The idea is simply to have a parenthesis-free notation that makes each equation shorter and easier to parse in terms of defining the evaluation priority of the operators.

Example:

Infix notation with parenthesis: (3 + 2) * (5 – 1)

Polish notation: * + 3 2 – 5 1

When used as the syntax for programming language interpreters, Polish notation can be readily parsed into an abstract syntax tree and stored in a stack. In traditional infix notation with brackets, the equation has to be parsed, the brackets removed, and the operator and operands repositioned. This is not the case with Polish notation, which is why LISP and other related languages use this notation to define their syntax.

Que significa notacion polaca (NP)

La notacion polaca es una forma de notacion para expresar ecuaciones aritmeticas, logicas y algebraicas. Su mas caracteristica mas distinguida es que los operadores son puestos a la izquerda de su operandos. Si los operadores tienen numeros compuestos definidos, la sintaxis no requiere parentesis para hacerlo menos ambigua.

Notacion Polaca (NP) Explicada Por Techopedia

La notacion polaca fue inventada en 1924 por Jan Lukasiewicz, un philosofo y logistico Polaco, para poder simplificar la logica setencial. La idea es tener una notacion libre de parentesis que hace cada ecuacion mas corta y facil de analizar en terminos de defenir la prioridad evaluativa de los operadores.

Ejemplo:

Notacion infica con parentesis: (3 + 2) X (5 - 1)

Notacion Polaca: X + 3 2 - 5 1

Cuando es usado para la sintaxis para interpretes de lenguaje de programacion, La notacion polaca puede ser facilmente analizada en un arbol abstracto syntactica y guardado en una pila. En la notacion infja tradicional con corchetes, la ecuacion tiene que ser analizada, los corchetes ser removidos, y reposicionar los operadores y operandos. Este no es el caso con la Notacion Polaca, y es por eso que la LISP y otros lenguajes relacionados usa notacion para definir sus syntaxis

Generación de código intermedio

La generación de código tiene como objetivo generar el ejecutable que después emplearía el usuario. Sin embargo, es habitual que el producto del compilador no sea directamente un fichero ejecutable. Es bastante más común que sea un fichero en lenguaje ensamblador. De esta manera, se evitan problemas como tener que medir el tamaño exacto de las instrucciones o llevar la cuenta de sus direcciones. Además, es muy probable que el código generado tenga referencias a objetos externos como funciones de biblioteca. Estas referencias externas serían resueltas por el enlazador o el cargador.



Existen diversos tipos de códigos intermedios que varían en cuanto a su sencillez, lo próximos que están a las maquinas reales y lo fácil que es trabajar con ellos. Nosotros nos centraremos en un tipo de código que se parece bastante al lenguaje ensamblador. Existen otros tipos de código intermedio que representan los programas como árboles o grafos. También existen representaciones mixtas que combinan grafos o árboles y representaciones lineales.

La administración de la memoria se da en esta etapa.

Se debe considerar tanto la memoria estática como dinámica, y en esta se utilizan generalmente pilas.

• Los lenguajes intermedios generalmente tienen árboles de derivación más pequeños que su contraparte original.

• Se puede representar un árbol sintáctico con un Grafo Dirigdo Acíclico (GDA).

• La notación postfija es una manera linealizada de representar un árbol sintáctico.

 

• a := b*-c+b*-c

• abc -*bc -*+=

• x := y op z

• x+y*z

• t1:=y*z

• t2:=x+t1






Por ejemplo:

a = b + c * d;

El generador de código intermedio, tratar de dividir esta expresión en sub-expresiones y, a continuación, generar el código correspondiente.

r1 = c * d;
r2 = b + r1; 
r3 = r2 + r1;
a = r3

R que se utilizan como registros en el programa de destino.

Un código de dirección tiene un máximo de tres direcciones para calcular la expresión. Un código de dirección puede estar representado en dos formas : cuádruples y triples.




martes, 7 de marzo de 2023

FRACTAL

 ¿Qué es un fractal?

Un fractal es un objeto geométrico en el que se repite el mismo patrón a diferentes escalas y con diferente orientación. 

La expresión fractal viene del latín fractus, que significa fracturado, roto, irregular. La expresión y el concepto se atribuyen al matemático Benoit B. Mandelbrot, y aparecen como tal a finales de la década de los setenta y principios de los ochenta (Mandelbrot, 1977 y 1982). Anteriormente, los matemáticos Cantor y Peano, entre otros, definen objetos catalogables dentro de esta categoría, pero no son reconocidos como tales.

Características de los fractales

Los fractales son, por lo tanto, elementos calificados como semi geométricos (por su irregularidad no pertenecen a la geometría tradicional) que disponen de una estructura esencial que se reitera a distintas escalas.

El fractal puede ser creado por el hombre, incluso con intenciones artísticas, aunque también existen estructuras naturales que son fractales (como los copos de nieve).



¿Cuáles son los fractales en la naturaleza?

Resultado de imagen para ejemplos de fractales en la naturaleza
Las nubes, las montañas, el sistema circulatorio, las líneas costeras​ o los copos de nieve son fractales naturales. Esta representación es aproximada, pues las propiedades atribuidas a los objetos fractales ideales, como el detalle infinito, tienen límites en el mundo natural.

















lunes, 6 de marzo de 2023

Programa

 Programa

Notación polaca inversa

La notación polaca inversa (RPN) es una de las operaciones más comunes con las que puede enfrentarse un programador. Esta notación fue introducida en 1920 por el matemático Jan Łukasiewicz y fue desarrollada especialmente para reducir expresiones matemáticas extremadamente grandes. Además, este tipo de notación es actualmente muy usada en el mundo de las calculadoras científicas, por eso, te recomendamos que te quedes con nosotros para aprender a usarla correctamente.

¿Dónde o en qué tipo de operación matemática puedes toparte con una notación polaca inversa?
Este tipo de lenguaje matemático se encuentra generalmente en la aritmética, el álgebra y es un tipo de lenguaje operacional que cualquier ingeniero en sistemas debe conocer a la perfección. Con el paso del tiempo, este tipo de operación o expresión numérica fue considerado como una excelente alternativa para reducir significativamente el uso de memoria en un ordenador. Y desde que esto fue descubierto, su uso se ha extendido a todos los sistemas operativos del mundo. Gracias a esto, se puede programar rápidamente, dejando atrás una pérdida de tiempo significativa.
En la mayoría de los casos, un programador tarda más de lo esperado al momento de desarrollar las operaciones tanto de una aplicación como de un sistema operativo, página web, etc… Para aplicar la notación polaca inversa en la programación, se debe trabajar con la estructura de operaciones matemáticas LIFO (Last in first out). Este tipo de procedimientos radica en que no se debe colocar toda una operación de manera ordenada para encontrar ese resultado que estamos esperando. Lo más adecuado sería explicarlo con un ejemplo:
Supongamos que debemos programar una página de cambios de monedas internacionales automatizada, en primer lugar debemos colocar todos los argumentos, en este caso, trabajaremos con el dólar y el euro. Básicamente, la operación podría ser A x B = C suponiendo que A son dólares y B el valor del euro en dólares.
Al realizar la operación, obviamente tendremos como resultado los dólares que necesitaríamos para comprar una cantidad estimada de euros, pero al momento de programar la página, la operación debe ser automática. Es por esto que se aplica la notación polaca inversa, y en este caso, estaría expresada de la siguiente manera: A B x, de esta manera el resultado, que sería C, se aplicaría automáticamente en la página.

La notación polaca inversa (en inglés, Reverse Polish Notation, o RPN), es una forma alternativa de escribir expresiones matemáticas. Por ejemplo, la expresión "20 - (4 + 3) * 2" en RPN es "20 4 3 + 2 * -".

Para evaluar una expresión en RPN, usamos una lista auxiliar (inicialmente vacía) y recorremos la expresión de izquierda a derecha. Cada vez que encontramos un número, lo añadimos a la lista auxiliar. Cuando encontramos un operador, retiramos los dos números que hay al principio de la pila, utilizamos el operador con ellos y los quitamos de la lista y le añadimos el resultado. Cuando alcancemos el final de la expresión, debemos tener un solo número en la lista auxiliar si la expresión estaba bien formada, y éste representa el resultado de la expresión. 



Codigo