Delphi (lenguaje de programación)
La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la
versión revisada el 8 de enero de 2020; las comprobaciones requieren
103 ediciones .
Delfos |
---|
|
clase de idioma |
imperativo , estructurado , orientado a objetos , orientado a componentes , de alto nivel |
Apareció en |
1986 ( 1986 ) |
Autor |
Anders Hejlsberg |
extensión de archivo |
.pas, .dpr, .dpk, .pp, .dproj, .dfm, .fmx, .bpl |
Liberar |
Delphi 11.1 Alexandria [1] (15 de marzo de 2022 ) ( 2022-03-15 ) |
sistema de tipos |
estático , fuerte |
Implementaciones principales |
Borland/Inprise/Codegear/Embarcadero Delphi ; Borland Kylix ; pascual libre |
sido influenciado |
Objeto Pascal , C++ |
influenciado |
C# , Java [1] |
Sitio web |
embarcadero.com/ru/produ… |
Plataforma |
x86, x64, BRAZO |
sistema operativo |
Windows , macOS , iOS , Android , Linux |
Delphi (Delphi, pronunciado /ˈdɘlˌfi:/ [2] ) es un lenguaje de programación imperativo, estructurado , orientado a objetos y de alto nivel con fuerte tipado estático de variables. El área principal de uso es escribir software de aplicación.
Este lenguaje de programación es un dialecto del lenguaje Object Pascal . Object Pascal originalmente se refería a un lenguaje ligeramente diferente que fue desarrollado en Apple en 1986 por el grupo de Larry Tesler [3] . Sin embargo, a partir de Delphi 7 [4] , los libros blancos de Borland comenzaron a usar el nombre Delphi para referirse al lenguaje antes conocido como Object Pascal .
Plataforma de destino
Inicialmente, el entorno de desarrollo de Delphi estaba destinado exclusivamente al desarrollo de aplicaciones de Microsoft Windows , luego se implementó una variante para plataformas Linux (con la marca Kylix ), sin embargo, después del lanzamiento de Kylix 3 en 2002, su desarrollo se suspendió y el soporte para Microsoft Pronto se anunció .NET , que, a su vez, se suspendió con el lanzamiento de Delphi 2007.
Actualmente, junto con el soporte para el desarrollo de programas de 32 y 64 bits para Windows, es posible crear aplicaciones para Apple macOS (comenzando con Embarcadero Delphi XE2), iOS (incluyendo un simulador, comenzando con XE4 utilizando su propio compilador), Google Android (a partir de Delphi XE5) [5] , así como Linux Server x64 (a partir de la versión 10.2 Tokio).
Una implementación independiente de terceros del entorno de desarrollo del proyecto Lazarus ( Free Pascal , cuando se compila en modo de compatibilidad con Delphi) permite que se utilice para crear aplicaciones Delphi para plataformas como Linux , macOS y Windows CE .
También ha habido intentos de utilizar el lenguaje en proyectos GNU (por ejemplo, Notepad GNU ) y de escribir un compilador para GCC ( GNU Pascal ).
Se utiliza para escribir servicios de Internet de IIS.
Filosofía y diferencias con los lenguajes de programación aplicados populares
Al crear el lenguaje (y aquí la diferencia cualitativa con el lenguaje C), la tarea no era asegurar el máximo rendimiento del código ejecutable o la concisión del código fuente para ahorrar RAM. Inicialmente, el lenguaje se centró en la armonía y la alta legibilidad, ya que estaba destinado a enseñar la disciplina de la programación. Esta delgadez inicial más tarde, tanto a medida que crecía el hardware como como resultado de la aparición de nuevos paradigmas, facilitó la extensión del lenguaje con nuevas construcciones.
Por lo tanto, la complejidad del objeto C ++, en comparación con C, ha crecido de manera muy significativa y dificultó su estudio como el primer lenguaje de programación, lo que no se puede decir sobre Object Pascal en relación con Pascal.
Las siguientes son algunas de las diferencias entre las construcciones de sintaxis de Delphi y la familia de lenguajes tipo C (C/C++/Java/C#):
- En Delphi, el inicio formal de cualquier programa es claramente distinto de otras secciones de código y debe ubicarse en un archivo fuente específico con la extensión dpr, el único dentro del proyecto (mientras que otros archivos fuente del programa tienen la extensión pas).
programa Proyecto32 ;
{$CONSOLA DE TIPO DE APLICACIÓN}
{$R *.res}
utiliza
el sistema . utilidades de sistema ;
comenzar a
probar
{ TODO -oUser -cConsole Main: Inserte el código aquí }
excepto
en E : Exception do
Writeln ( E . ClassName , ': ' , E . Message ) ;
fin ;
fin _
En los lenguajes de programación tipo C, una función global o un método estático con un nombre mainy una determinada lista de parámetros se suele utilizar como entrada, y dicha función se puede ubicar en cualquiera de los archivos fuente del proyecto.
- En Delphi, los identificadores de tipos, variables y palabras clave se leen sin distinguir entre mayúsculas y minúsculas : por ejemplo, un identificador SomeVares totalmente equivalente a somevar. Los identificadores que distinguen entre mayúsculas y minúsculas al comienzo de la era de las computadoras aceleraron el proceso de compilación y también permitieron el uso de nombres muy cortos, que a veces se diferenciaban solo en mayúsculas y minúsculas.
Y aunque por ahora ambas prácticas, el uso de varios identificadores que difieren solo en mayúsculas y minúsculas, así como su excesiva concisión, están condenadas y no recomendadas para su uso, casi todos los lenguajes derivados de C - C + +, Java, C # - distinguen entre mayúsculas y minúsculas , lo que, por un lado, requiere mucho cuidado al declarar y usar identificadores y, por otro lado, te obliga a escribir un código más estricto cuando cada variable tiene un nombre bien definido (las variaciones entre mayúsculas y minúsculas pueden causar confusión y errores).
- En Delphi, en los archivos fuente .pas (que, por regla general, contienen el cuerpo principal del programa), se introduce una división estricta en la sección de interfaz y la sección de implementación a nivel de idioma. La parte de la interfaz contiene solo declaraciones de tipo y método, mientras que el código de implementación en la parte de la interfaz no está permitido en el nivel de compilación. Una separación similar también es característica de los lenguajes C / C ++, donde, en el marco del paradigma cultural y de programación, se introduce una separación en el encabezado y los archivos de implementación reales, pero tal separación no se proporciona en el lenguaje o el compilador. nivel.
En C# y Java, esta separación se pierde por completo: la implementación de un método, por regla general, sigue inmediatamente después de su declaración. La encapsulación se proporciona solo por la pertenencia del método a uno u otro ámbito. Se utilizan herramientas especiales para ver solo la parte de la interfaz del módulo de código fuente.
- En Delphi, un método o función está claramente definido por las palabras clave reservadas procedureo function, mientras que en lenguajes similares a C, la distinción se hace mediante una palabra clave que especifica el tipo del valor de retorno://
Procedimiento Delphi HacerAlgo ( aParam : Integer ) ; //no devuelve una
función de valor Calcular ( aParam1 , aParam2 : Integer ) : Integer ; //devuelve un resultado entero
//C#
void HacerAlgo ( int aParam ); // no devuelve un valor
{
// código
}
int Calculate ( int aParam1 , aParam2 ); // devuelve un resultado entero
{
// código
}
Las más difíciles en C#/C++ son construcciones como declarar el tipo “puntero a método”:
//C++: declaración de tipo pCalc, un puntero a una función miembro que toma dos parámetros enteros y devuelve un resultado entero
typedef int ( TSomeClass ::* pCalc )( int , int );
En el ejemplo anterior, la declaración de tipo difiere de la declaración de variable con la palabra clave typedef, el nombre de tipo pCalc, se especifica en medio de la expresión, entre paréntesis.
//C#: declaración de tipo pCalc, un puntero a una función miembro que toma dos parámetros enteros y devuelve un resultado entero
público delegado int pCalc ( int aParam1 , int aParam2 );
En el ejemplo anterior, la declaración de tipo difiere de la declaración de variable con una palabra clave especial delegate, el nombre del tipo se especifica en medio de la expresión.
//
Tipo Delphi pCalc = función ( aParam1 , aParam2 : Integer ) : Entero del objeto ;
En el ejemplo anterior, la declaración de tipo difiere de la declaración de una variable con una palabra clave especial type, el uso de un signo igual (en el caso de una variable, se usan dos puntos), el nombre del tipo viene inmediatamente después de la palabra clave.
- En Delphi, el principio y el final de un bloque de programa se marcan con las palabras clave beginy end, mientras que en los lenguajes de programación tipo C se utilizan llaves para este propósito: {}. Por lo tanto, quizás Delphi logre una mejor legibilidad del código para las personas con discapacidad visual. Por otro lado, las llaves pueden resultar más intuitivas visualmente, sirviendo como pictograma .//C#
if ( bVal ) {
// código que consta de varias instrucciones
}
if ( bVal2 ) /* código que consta de una instrucción */ ;
En el ejemplo anterior, las llaves denotan una declaración compuesta, es decir, un bloque de declaraciones. Dado que se permite una expresión sin llaves en un comando de
bifurcación para una declaración única, se requieren paréntesis para una expresión condicional . En expresiones condicionales complejas, el número de paréntesis anidados puede ser grande.
//Delphi
si bVal entonces comienza //
fin del código de múltiples instrucciones
; si bVal2 entonces (* código de instrucción único *) ;
En Delphi, la expresión condicional siempre está separada de la siguiente declaración por la palabra clave then, lo que elimina la necesidad de encerrar la condición entre paréntesis.
- En lenguajes similares a C, para esta separación, el bucle condicional se encierra entre paréntesis:while ( condición ) { // bucle con "precondición"
// cuerpo del bucle
};
do {
// cuerpo de otro ciclo
} while ( condición2 ); // final del bucle con una "postcondición", el cuerpo se ejecuta al menos una vez
En Delphi, los bucles con una
precondición y una
poscondición difieren más: el final de un bucle con una poscondición es más difícil de confundir con el comienzo de un bucle con una precondición. Pero a veces tal distinción puede causar confusión (debe recordarse que la condición de salidauntil se especifica en el bucle ).
while condition do begin //la condición para continuar el ciclo es la verdad de la expresión que sigue a la palabra while, como C/C#
//
final del cuerpo del ciclo ;
repetir //comienzo del bucle con postcondición
//cuerpo del bucle
hasta que no sea condición2 ; //la verdad de la expresión que sigue a la palabra hasta es la condición para SALIR del ciclo, en contraste con C/C#
- En Delphi, la operación de asignar un valor a una variable se denota con dos puntos con un signo de igual :=, que se toma de la notación matemática. Un signo igual sin dos puntos es un operador de prueba de igualdad que devuelve un valor booleano. Por el contrario, en lenguajes similares a C, el operador de asignación es un signo igual único y el operador de prueba de igualdad es un signo doble, ==. Debido al hecho de que en estos lenguajes de programación la asignación es solo una expresión que devuelve el valor de la variable de la izquierda, los siguientes errores que no son obvios para un principiante no son tan raros:// C++
int iVal = 12 ;
mientras ( iVal = 1 ) {
// de acuerdo con la intención del programador, este cuerpo de ciclo no debe ejecutarse si iVal tiene un valor diferente a uno en la entrada
// sin embargo, como resultado de un reemplazo erróneo del signo == con un solo =, iVal será asignó el valor 1, y el ciclo será infinito
}
En Delphi, tal error es imposible, aunque solo sea porque la asignación en este idioma es una operación que no devuelve un valor.
- En Delphi, la programación orientada a objetos y a objetos, aunque fomentada, no es la única posible. Por lo tanto, está permitido (a diferencia de C#) declarar y usar funciones y variables globales o estáticas.
El lenguaje C# se ve obligado a ser objeto. Las funciones globales, sin referencia a una clase, están prohibidas. Los tipos de valor, como structs struct, se heredan del tipo genérico de C#, aunque ellos mismos no se pueden heredar (es decir, la herencia de estructuras no está permitida en C#). Sin embargo, las instancias de las clases de C# son tipos de referencia implícitos, al igual que en Delphi.
Dado que las llamadas al sistema en Windows (como, de hecho, en los sistemas POSIX como Linux, Mac OS) son formalmente no objeto, la interacción del código C # con ellas es difícil incluso sin tener en cuenta el diferente paradigma de gestión de la vida útil de las variables en la memoria. . Delphi no tiene tales restricciones.
A pesar de este paradigma centrado en objetos, C# carece del concepto de un constructor virtual, es decir, crea una instancia de una clase cuyo tipo exacto no se conoce en tiempo de compilación, pero solo se conoce la clase base de esa instancia. En parte, este inconveniente se puede compensar mediante el uso de interfaces o la reflexión, pero estas soluciones no son estándar para el idioma.
type
TAnimal = class abstract
protected
FPersonalName : string ;
constructor público
Create ( const PersonalName : string ) ; virtuales ; abstracto ; función GetSpecieName : cadena ; virtuales ; abstracto ; // devuelve la especie biológica del animal property Name : string read FPersonalName ; fin ;
TAnimalClass = clase de TAnimal ; // metaclase que puede referirse a cualquier clase que herede de TAnimal
...
function CreateAnAnimal ( const FactAnimalClass : TAnimalClass ; const Name : string ) : TAnimal ;
comenzar
Resultado := FactAnimalClass . Crear ( Nombre ) ; // la función no sabe qué tipo de animal se creará, aunque se conoce el "apodo". La implementación concreta de la vista está oculta.
fin ;
Además, a diferencia de C# y C++, donde la llamada al constructor de la clase base se realiza necesariamente antes de ingresar al cuerpo del constructor de la clase heredada, en Delphi esta llamada se realiza de forma explícita. Por lo tanto, puede posponerse u omitirse por completo para fines especiales. Obviamente, a diferencia de C#, es posible controlar las excepciones en los constructores base.
- Para la implementación más flexible y eficiente del enfoque orientado a objetos, Delphi introdujo dos mecanismos de llamada polimórficos: virtual clásico y dinámico : si en el caso de una llamada virtual clásica, las direcciones de todas las funciones virtuales estarán contenidas en la tabla de métodos virtuales. de cada clase, entonces, en el caso de una llamada dinámica, un puntero a un método existe solo en la tabla de la clase en la que se definió o anuló.
Así, para llamar dinámicamente desde la clase D a un método de la clase A redefinido en B, será necesario buscar en las tablas de métodos de las clases D, A y B.
Esta optimización tiene como objetivo reducir el tamaño de la memoria estática ocupada por las tablas de métodos. Los ahorros pueden ser significativos para jerarquías de clases largas con una gran cantidad de métodos virtuales. En lenguajes tipo C, no se utilizan llamadas polimórficas dinámicas.
- A diferencia de C#, el lenguaje Delphi permite la creación (inicialización) de una instancia de una clase que contiene métodos abstractos (sin implementación). Para excluir la posibilidad de crear una instancia de una clase, no es suficiente declarar métodos abstractos en ella. La palabra clave abstracta debe usarse en la declaración de clase. Por lo tanto, en la actualidad, las clases que tienen métodos abstractos (a diferencia de las primeras implementaciones de Delphi) no se consideran abstractas. Usando el mecanismo de función virtual, el código de una clase base que tiene métodos abstractos determina en tiempo de ejecución si un método abstracto en particular se anula en la instancia real de la clase y, dependiendo de esto, llama al método anulado o lanza una excepción EAbstractError.
Delphi también permite que cualquier método virtual concreto de una clase base sea anulado por uno abstracto en una clase descendiente:
tipo
TMyBase = clase ( TObject )
función A : entero ; virtuales ; // el método A tiene un cuerpo implementado en la sección
final de implementación ;
TMyDerived = clase ( TMyBase )
función A : entero ; anular ; abstracto ; // el método se anula como abstracto, no tiene cuerpo,
// y al mismo tiempo anula (oculta) el implementado en la clase base
end ;
procedimiento Prueba ;
var m : TMyBase ;
comenzar
m := TMyDerived . crear ; // hemos creado una clase con un método abstracto
m . un ; // la llamada a A es polimórfica y obtenemos un EAbstractError al intentar ejecutar el método abstracto
end ;
- A diferencia de C++, el lenguaje C# tiene el concepto de propiedades de clase heredado de Delphi: pseudo-campos, que, en algunos casos, pueden, de manera más intuitiva, en comparación con los métodos, reflejar y también cambiar el estado de un objeto.public class Date { //este ejemplo está tomado de [http://msdn.microsoft.com/en-us/library/w86s7x04.aspx msdn]
private int month = 7 ; // almacén de respaldo
public int Mes {
get { return mes ; }
set {
if (( valor > 0 ) && ( valor < 13 )) {
mes = valor ;
}
} //conjunto
} //prop
} //clase
Un código fuente similar en Delphi podría verse así:
tipo
TDate = class
private
FMonth : Integer ;
procedimiento protegido
SetMonth ( Const Value : Integer ) ; // implementación en la sección de implementación public property Month : Integer read FMonth write SetMonth ; fin ;
Antes de proceder a una comparación de la implementación de las propiedades del lenguaje, observamos que la comparación de estos dos ejemplos muestra claramente que el lenguaje C# provoca, en primer lugar, el abuso de las llaves (que no da tanto miedo en vista de la brevedad de sus escritura) y, en segundo lugar, los especificadores de acceso obligatorio al montón para cada miembro de la clase; en Delphi (como en C++), una vez que se declara un especificador, se aplica a todos los miembros posteriores. Además, si en Delphi es posible vincular una propiedad a un valor de campo, en C# siempre se proporcionan métodos de acceso que utilizan corchetes de comando compuestos (excepto para las propiedades automáticas). Estos métodos, a diferencia de Delphi, no se pueden declarar virtuales, ni se pueden llamar directamente.
Un accesor en C# siempre se refiere a una y solo una propiedad, mientras que en Delphi esta declaración generalmente no es cierta. Además, el mismo método se puede utilizar para implementar el acceso a propiedades significativamente diferentes:
tipo
TRectangle = class
private
FCoordinates : array [ 0 .. 3 ] de Longint ;
función GetCoordinate ( Índice : Entero ) : Entero largo ;
procedimiento SetCoordinate ( Índice : Entero ; Valor : Entero largo ) ;
propiedad pública
Izquierda : Índice de entero largo 0 lectura GetCoordinate escritura SetCoordinate ; propiedad Arriba : Entero largo índice 1 leer GetCoordinate escribir SetCoordinate ; propiedad Derecha : Entero largo índice 2 leer GetCoordinate escribir SetCoordinate ; propiedad Abajo : Índice de entero largo 3 leer GetCoordinate escribir SetCoordinate ;
propiedad Coordenadas [ Índice : Entero ] : Entero largo leer ObtenerCoordenadas escribir EstablecerCoordinadas ;
fin ;
Tanto Delphi como C# permiten el uso de propiedades indexadas: en este caso, la sintaxis para acceder a dicha propiedad es similar a acceder a un elemento de matriz. Sin embargo, mientras que en Delphi el número de propiedades indexadas, así como el número de indexadores, puede ser arbitrario, en C# el indexador se aplica solo a una propiedad predeterminada especial. Además, en Delphi, una propiedad predeterminada no solo puede indexarse, sino que también puede sobrecargarse con un tipo de indexador:
TMyObject = función protegida de clase
getStr ( Nombre : cadena ) : cadena ; virtuales ; función getStrByIx ( índice : entero ) : cadena ; virtuales ; función getBy2Indicies ( X , Y : Integer ) : cadena ; virtuales ; propiedad pública Valor [ Nombre : cadena ] : cadena read getStr ; predeterminado ; valor de la propiedad [ índice : entero ] : cadena de lectura getStrByIx ; predeterminado ; propiedad Valor [ X , Y : Integer ] : cadena de lectura getBy2Indicies ; predeterminado ; // fin del numero ;
- Los lenguajes Java y C# se diseñaron originalmente para escribir programas que se ejecutan en un entorno gestionado donde el entorno gestiona la vida útil de los objetos: por lo que no se permite la gestión manual de la memoria. La conveniencia y seguridad de este enfoque tiene un impacto negativo en el rendimiento.
Ventajas y desventajas de la recolección de basura.
Las plataformas .NET y Java han simplificado enormemente el desarrollo de programas al introducir un "recolector de basura", que permite al programador no preocuparse por liberar la memoria ocupada por objetos que han quedado fuera del alcance del código del programa en ejecución. Esto, por un lado, redujo significativamente el problema de las llamadas "fugas de memoria" (cuando los datos que ya son innecesarios e inalcanzables debido a la pérdida de la dirección ocupan RAM), pero, por otro lado, requirió la plataforma para implementar un algoritmo de "recolección de basura" complejo y que requiere muchos recursos, que tradicionalmente se implementa para encontrar objetos accesibles y liberar el resto. En la práctica, para realizar un análisis exhaustivo de la accesibilidad de los objetos, el recolector de basura en algunos momentos suspende el programa (todos sus subprocesos), lo que conduce a una pérdida de capacidad de respuesta a corto plazo. La frecuencia y duración de dichas paradas depende directamente de la cantidad de RAM disponible (siempre que haya memoria libre, el recolector de basura intenta no realizar análisis de bloqueo), así como de la cantidad de objetos involucrados en el programa (por lo tanto, es mejor tener algunos objetos "grandes" que muchos, pequeños).
La situación empeora a medida que crece el número de subprocesos involucrados en el programa, porque un análisis exhaustivo de accesibilidad requiere una parada completa. Así, el beneficio evidente -resolver el problema de las "fugas de memoria" y, en general, la gestión automática de la vida útil de los objetos- dio lugar al problema implícito de los "fallos" de escalado y rendimiento. Este problema es sutil en programas simples, pero a medida que crece la complejidad y el tamaño del código base, se vuelve más y más agudo, es decir, en la etapa final de desarrollo. Los sistemas de software complejos, por regla general, tienen requisitos de referencia y capacidad de respuesta en tiempo real.
Más precisamente, cuando el recolector de basura tiene 5 veces más memoria de la que necesita, su rendimiento es igual o ligeramente mejor que la gestión directa de memoria. Sin embargo, el rendimiento del recolector de basura se degrada rápidamente cuando necesita trabajar con caderas pequeñas. Con 3 tamaños de memoria requerida, es en promedio un 17 % más lento y con 2 tamaños es un 70 % más lento. Además, el recolector de basura es más propenso a la paginación si la memoria está desfragmentada. Bajo tales condiciones, todos los recolectores de basura que hemos probado son un orden de magnitud más lentos que la administración directa de memoria.Drew Crawford - Por qué las aplicaciones web móviles son lentas
Los intentos de reducir los gastos generales de la recolección de elementos no utilizados pueden conducir a una distorsión significativa del estilo de programación [6] [7] .
No existe una gestión de memoria automática en Delphi: (en los compiladores de lenguaje clásico ) las instancias de clase se crean y eliminan manualmente, mientras que para algunos tipos (interfaces, cadenas y matrices dinámicas) se utiliza el mecanismo de conteo de referencias. Ninguno de estos enfoques, en términos generales, garantiza la ausencia de fugas de memoria, pero, por otro lado, el problema de la capacidad de respuesta no es relevante, la sobrecarga de tiempo de administración de memoria es pequeña y, lo que es más importante, obvia. Además, en ausencia de fugas, la cantidad total de RAM utilizada es significativamente menor que la de aplicaciones similares que dependen del recolector de basura.
Historia de la lengua
Object Pascal es el resultado del desarrollo del lenguaje Turbo Pascal , que, a su vez, se desarrolló a partir del lenguaje Pascal . Pascal era un lenguaje completamente procedimental , Turbo Pascal, a partir de la versión 5.5, agregó propiedades orientadas a objetos a Pascal e identificación dinámica de tipos de datos a Object Pascal con la capacidad de acceder a metadatos de clase (es decir, describir clases y sus miembros) en código compilado, también llamado introspección ; esta tecnología se denominó RTTI . Dado que todas las clases heredan las funciones de la clase base TObject, cualquier puntero a un objeto se puede convertir en él, después de lo cual se pueden usar el método ClassType y la función TypeInfo, que proporcionarán introspección.
Además, una propiedad distintiva de Object Pascal de C ++ es que los objetos se ubican en la memoria dinámica de forma predeterminada. Sin embargo, puede invalidar los métodos virtuales NewInstance y FreeInstance de la clase TObject. Por lo tanto, absolutamente cualquier clase puede cumplir el "deseo" "donde quiero, allí me acostaré". En consecuencia, se organiza el "amontonamiento múltiple".
Object Pascal (Delphi) es el resultado de una extensión funcional de Turbo Pascal [8] .
Delphi tuvo un gran impacto en el concepto del lenguaje C# para la plataforma .NET . Muchos de sus elementos y soluciones conceptuales se han incorporado a C#. Una de las razones es la transferencia de Anders Hejlsberg , uno de los principales desarrolladores de Delphi, de Borland Ltd. en Microsoft Corp.
- La versión 8 es capaz de generar bytecode exclusivamente para la plataforma .NET. Este es el primer entorno enfocado al desarrollo de aplicaciones multilingües (solo para la plataforma .NET);
- Las versiones posteriores (indicadas por año de lanzamiento, en lugar de números de serie, como ocurría antes) pueden crear aplicaciones Win32 y código de bytes para la plataforma .NET.
Delphi para .NET es un entorno de desarrollo Delphi , así como el lenguaje Delphi (Object Pascal), enfocado al desarrollo de aplicaciones para .NET.
La primera versión de un entorno de desarrollo completo de Delphi para .NET fue Delphi 8. Permitía escribir aplicaciones solo para .NET. Delphi 2006 es compatible con la tecnología MDA con ECO (Enterprise Core Objects) versión 3.0.
En marzo de 2006, Borland decidió dejar de mejorar los entornos de desarrollo integrados JBuilder , Delphi y C ++ Builder debido a la falta de rentabilidad de esta dirección. Se planeó vender el sector IDE de la empresa. Un grupo de partidarios del software libre organizó una recaudación de fondos para comprar los derechos del entorno de desarrollo y el compilador de Borland [9] .
Sin embargo, en noviembre del mismo año se tomó la decisión de no vender el negocio de IDE. No obstante, el desarrollo de los productos IDE ahora estará a cargo de una nueva empresa, CodeGear, que estará completamente controlada financieramente por Borland.
En agosto de 2006, Borland lanzó una versión ligera de RAD Studio llamada Turbo: Turbo Delphi (para Win32 y .NET), Turbo C#, Turbo C++.
En marzo de 2008, se anunció el final del desarrollo de esta línea de productos.
En marzo de 2007, CodeGear complació a los usuarios con una línea actualizada de Delphi 2007 para productos Win32 y el lanzamiento de un producto Delphi 2007 para PHP completamente nuevo.
En junio de 2007, CodeGear presentó sus planes para el futuro, es decir, publicó la llamada hoja de ruta [10] .
El 25 de agosto de 2008, Embarcadero, el nuevo propietario de CodeGear, publicó un comunicado de prensa sobre Delphi para Win32 2009 [11] . La versión trajo muchas innovaciones al lenguaje, como [12] :
- De forma predeterminada, compatibilidad completa con Unicode en todas las partes del idioma, VCL y RTL; reemplazando las llamadas a todas las funciones de la API de Windows con contrapartes de Unicode (es decir, MessageBox llama a MessageBoxW, no a MessageBoxA).
- Tipos genéricos , también son genéricos .
- Métodos anónimos .
- Nueva directiva del compilador $POINTERMATH [ON|OFF].
- La función Salir ahora puede aceptar parámetros según el tipo de función.
Lanzado en 2011, Delphi XE2 agregó un compilador Win64 y una compilación cruzada para los sistemas operativos de Apple (MacOS X, iOS).
Lanzado en 2013, Delphi XE5 proporcionó compilación cruzada de aplicaciones para dispositivos ARM/Android.
Compiladores
- Embarcadero Delphi (anteriormente CodeGear Delphi y Borland Delphi) es probablemente el compilador más conocido que es el sucesor de Borland Pascal y Turbo Pascal . Usado por Win16 (Delphi 1), Win32 (Delphi 2 y posteriores), Win64 (Delphi 16 (XE2) y posteriores) y .NET 1.x, 2.0 (Delphi 8, Delphi 2005-Delphi 2007). La compatibilidad con .NET se dividió posteriormente en un producto separado conocido como Oxygene (incompatible con Delphi) .
- Free Pascal (FPC) es un compilador gratuito de Object Pascal que admite varios dialectos de Pascal, incluido Turbo Pascal (con algunas advertencias), Delphi y dialectos nativos. Actualmente, FPC puede generar código para procesadores x86 , x86-64 , PowerPC , SPARC y ARM , así como para varios sistemas operativos, incluidos Microsoft Windows , Linux , FreeBSD , Mac OS . Hay varios entornos de desarrollo de software para FPC (uno de los representantes más famosos es Lazarus ).
- GNU Pascal (una versión desarrollada por separado de GCC ). No tiene como objetivo continuar la serie de dialectos de Delphi como parte de Pascal, pero, sin embargo, contiene el modo de compatibilidad de Borland Pascal y es muy lento para adaptarse a los componentes del lenguaje Delphi. No es adecuado para compilar grandes proyectos que contengan código Delphi, pero la mayoría de los sistemas operativos y arquitecturas lo admiten.
- Oxygene (anteriormente conocido como Chrome ) es un compilador de lenguaje compatible con Delphi limitado que está integrado en Microsoft Visual Studio . También disponible como compilador de línea de comandos CLI gratuito . Utiliza .NET y monoplataformas. Anteriormente vendido bajo la marca Embarcadero Delphi Prism.
- MIDletPascal es un lenguaje de programación con una sintaxis similar a Delphi y un compilador del mismo nombre que convierte el código fuente en bytecode Java compacto y rápido .
- PocketStudio es un IDE basado en Pascal para Palm OS .
- Virtual Pascal : compilador gratuito e IDE de texto para Win32, OS/2 y Linux. En ese momento, muy rápido y muy compatible (las construcciones de Delphi 5 son parcialmente compatibles). Exteriormente es muy similar al entorno de texto de Borland Pascal 7, aunque no hay gráficos compatibles con él, por ejemplo. Sin embargo, el desarrollo terminó en 2004 y el código fuente no estaba abierto. Desde entonces, FPC ha ido mucho más lejos y, en general, es mejor para la programación. Sin embargo, VP sigue siendo una muy buena opción para un reemplazo rápido de versiones aún más obsoletas de Borland Pascal para escuelas / institutos, dado el trabajo nativo en Win32 sin problemas con las codificaciones rusas.
Sintaxis del lenguaje
El sistema de tipos
El sistema de tipos en Delphi es estricto , estático .
Una breve lista de tipos admitidos
Se admiten los siguientes tipos de datos :
- entero, con signo y sin signo: Byte, Shortint, Word, Smallint, Cardinal,Integer, UInt64, Int64
- tipos de enumeración definidos por el usuario
- tipos reales Simple, Doble, Extendido (solo x86-32, en Win64 Extendido = Doble), tipo Real48 heredado, trabajando en modo de emulación de enteros. El tipo Currencyes real de precisión fija.
- líneas. El tipo string se asigna automáticamente en la memoria, con recuento de referencias y el paradigma de copia en escritura. En versiones posteriores de Delphi, los caracteres son de doble byte, compatibles con Unicode. AnsiString es una implementación similar para cadenas con un ancho de carácter de un byte. Tales cadenas contienen información sobre la codificación en el campo de servicio. Los compiladores de Windows de versiones anteriores tienen un tipo WideStringque es totalmente compatible con el tipo BSTRdel Modelo de objetos componentes . También se permite el uso de cadenas con una longitud fija que no supere los 255 caracteres de un solo byte. Se permiten tipos de cadena primitivos, estilo C: PCharyPWideChar
- arreglos Longitud fija unidimensional, multidimensional, así como dinámica similar, con conteo de referencia.
- conjuntos formados por elementos del tipo enumeración. El tamaño máximo de dicha enumeración es de 256 elementos.
- entradas _ Tipo estructural (valor) sin soporte de herencia. A partir de Delphi 2006, se ha agregado soporte para encapsulación, métodos y propiedades. Sobrecarga del operador. A partir de Delphi 10.3 Rio, se ha agregado la capacidad de crear constructores para escritura.
- Clases y clases genéricas (generics). Un tipo de referencia implícito. Compatibilidad con encapsulación, herencia, polimorfismo, incluidos constructores virtuales, atributos, parámetros genéricos para una clase y métodos individuales, y envío de métodos por índice. Una clase puede implementar una o más interfaces, incluso indirectamente al delegar la implementación de una interfaz a una propiedad o campo. No se admite la herencia múltiple.
- Punteros a funciones y métodos, así como punteros a funciones anónimas.
- Los tipos son metaclases que contienen un puntero al tipo de un objeto (pero no al objeto en sí). Introducido principalmente para implementar constructores virtuales y serialización automática.
- interfaces Compatible con COM (en el compilador de Windows), heredado del mismo ancestro. No se admite la herencia múltiple.
- Dispinterfaces, para trabajar con interfaces IDispatch en modo de enlace tardío.
- Tipos de variantes Variant yOleVariant — tipo con escritura dinámica.
- Objetos antiguos mantenidos por compatibilidad con Turbo Pascal. A diferencia de una instancia de una clase, un objeto se puede asignar en la pila o de forma estática. .
Lista de operadores separados por un espacio::= + — * / div mod not and or with xor shl shr ^ = <> >= <= < > @ in is as
Lista corta de operadores
- Aritmética: + — * / div modSuma, resta, multiplicación, división (que da un resultado real), división de enteros, extracción de resto.
El tipo de retorno distingue entre los operadores de división de enteros ( divy mod) y el operador /. Este último, aplicado tanto a operandos enteros como reales, siempre da como resultado un tipo real. El operador de suma +también se usa para la concatenación de cadenas (cuando se usan los tipos de cadenas integrados).
- Binario /lógico: not and or xorInversión (negación), "Y", "O", "O" exclusivo. El tipo de operación (binaria o lógica) depende del tipo del primer operando.
Los operadores de bits de tipos enteros también incluyen shl, shr - operadores de desplazamiento, cuyo significado corresponde a los comandos del mismo nombre de los procesadores Intel x86.
- Operadores ordinales (operadores de comparación) = <> > < >= <= — igualdades, desigualdades (corresponde al operador !=en lenguajes similares a C), mayor que, menor que, no menor, no más — se aplican a todos los tipos ordinales y reales y devuelven un valor de tipoboolean
- Los operadores de conjuntos incluyen + - * in la suma, la resta, la intersección de conjuntos y el operador de prueba de ocurrencia, que se utilizan para manipular el tipo de conjunto incorporado. Los tres primeros devuelven el tipo del conjunto, el último devuelve el tipo booleano.
Un ejemplo del uso del operador in
escriba
TDayOfWeek = ( lunes , martes , miércoles , jueves , viernes , sábado , domingo ) ; //establecer tipo de enumeración
TDays = conjunto de TDayOfWeek ; //se establece el tipo
var
day : TDayOfWeek ;
días : TDays ;
esMiDía : Booleano ;
comenzar
dias := [ Domingo , Martes , Sabado ] ;
día := lunes ;
isMyDay := día en días ; // el operador in devuelve un valor booleano, tomando como primer operando un valor de tipo "set element" y como segundo operando un valor de tipo "set"
end ;
- Operadores de conversión de tipo () as is : conversión incondicional, conversión segura de objetos y tipos de interfaz, y operador de prueba de membresía de tipo (devuelve un valor booleano). La conversión incondicional (insegura) se usa en un estilo funcional (el identificador de tipo se escribe a la izquierda, la expresión se escribe entre paréntesis a la derecha) y se aplica a tipos ordinales, reales, de estructura, de referencia y de cadena. Al mismo tiempo, para los tipos de referencia (incluidas las referencias implícitas) , no hay conversión real, sino solo una nueva interpretación de los mismos datos.
Los operadores asy isse aplican a tipos que permiten un comportamiento polimórfico: instancias e interfaces de clase. El primero da como resultado una conversión de tipo segura (en el sentido de la imposibilidad de mala interpretación), y el segundo prueba el soporte de una instancia de una clase o interfaz de alguna clase o interfaz. Recuerde que, a diferencia de C#, una conversión fallida por parte de un operador asgenera una excepción.
- Operadores de referencia ^ @ : se utilizan para trabajar con punteros.
El operador ^desreferencia el puntero. El operador @hace lo contrario, devolviendo la dirección de la variable. Las operaciones simples de suma y resta se admiten en punteros escritos, dado el tamaño de los tipos a los que apuntan ( aritmética de puntero
inteligente ).
- Operador de asignación :=. En Delphi, el operador de asignación no forma una expresión, sino una operación, por lo que no se permiten asignaciones de "encadenamiento".
En Object Pascal, las clases son tipos de datos especiales que se utilizan para describir objetos. En consecuencia, un objeto que tiene el tipo de una clase es una instancia de esta clase o una variable de este tipo.
Una clase es un tipo especial que tiene elementos como campos, propiedades y métodos. Los campos de clase son similares a los campos de registro y se utilizan para almacenar información sobre un objeto. Los métodos son procedimientos y funciones que normalmente se utilizan para procesar campos. Las propiedades son intermedias entre campos y métodos.
Características del lenguaje orientadas a objetos
Combinar y ocultar datos de objetos, así como métodos que los procesan, dentro de una clase concreta del usuario se denomina encapsulación.
Al crear nuevos objetos, la capacidad de obtener todas las propiedades y métodos de sus ancestros se denomina herencia. Dichos objetos heredan después de su creación todos los campos, propiedades, eventos, métodos, etc. de sus ancestros. La herencia a menudo ahorra a los desarrolladores el trabajo de rutina y les permite comenzar a desarrollar algo nuevo rápidamente. A diferencia de C++, Delphi no permite la herencia múltiple. En Delphi es posible agregar métodos a una clase o registro utilizando el llamado class helper o record helper (class helper o record helper), el cual, al no ser descendiente de la clase o registro que se modifica, puede agregar métodos adicionales. a ellos Un ejemplo es la entrada auxiliar TStringHelper declarada en el módulo System.SysUtils.
Delphi implementa el modelo de polimorfismo clásico adoptado en los lenguajes de programación aplicados , cuando los métodos de la clase base, así como las variables de referencia del tipo de clase base, pueden manipular instancias de clases descendientes según el contrato especificado en la clase base. El contrato en este caso es la declaración de métodos abstractos en la clase base.
Ejemplos
Estructura del programa
Cada programa escrito en el lenguaje Delphi consta de un encabezado de programa (programa NewApplication;), un campo de módulos usados Uses (por ejemplo, Uses Windows, Messages, SysUtils, etc.), que pueden no estar incluidos en la estructura misma, como así como bloques de descripción y ejecuciones (comienzan con un operador compuesto begin y terminan con end.).
programa Proyecto1 ; // Cabecera del programa, con su nombre "Proyecto1"
usa
Forms ,
Unit1 en 'Unit1.pas' {Form1} ; // módulos que están conectados al proyecto y utilizados por el programa
{$R *.res}
comenzar
la aplicación . inicializar ; // Inicializar la aplicación
Aplicación . CreateForm ( TForm1 , Form1 ) ; // Crear
aplicación de formulario/ventana . correr ; // Lanzar y ejecutar
end .
Ejemplo #1
Mostrando el mensaje "¡Hola, mundo!" en la aplicación de consola Delphi
programa Holamundo ; //nombre del programa
{$APPTYPE CONSOLE} //directiva al compilador para crear una aplicación de consola
begin
writeln ( '¡Hola, mundo!' ) ; //mensaje de salida ¡Hola, mundo!
readln ; //espera a que el usuario presione una tecla
end . // fin del programa
Ejemplo #2
Mostrando el mensaje "¡Hola, mundo!" en una aplicación GUI de Delphi de 32 bits
...
procedimiento TForm1 . Button1Click ( Remitente : TObject ) ; //El controlador de eventos OnClick generado automáticamente
comienza
ShowMessage ( '¡Hola, mundo!' ) ; //mensaje de salida ¡Hola, mundo!
fin ; //fin del procedimiento
...
Ejemplo #3
Crear dinámicamente una lista de cadenas y escribirla en un archivo.
// Manejador del evento que ocurre cuando se crea el formulario
Procedimiento MainForm TMainForm . FormCreate ( Remitente : TObject ) ;
var
// Declarar una variable de tipo TStrings (lista de cadenas).
Cuerdas : TStrings ;
begin
// Creación (asignación de memoria y llenado con valores iniciales) de un objeto de tipo TStringList.
// TStringList es un descendiente de TStrings que implementa sus métodos abstractos para almacenar cadenas en la memoria.
Cuerdas := TStringList . crear ;
intente
// Agregar una cadena.
cuerdas _ Agregar ( 'Línea a agregar.' ) ;
// Guardar todas las líneas en un archivo.
cuerdas _ SaveToFile ( 'C:\Strings.txt' ) ;
finalmente
// Desasignar la memoria del objeto y borrar su referencia para evitar el acceso no intencional a la memoria no asignada.
LibreYNil ( Cadenas ) ;
fin ;
fin ;
Extensiones de archivo
- .pas - código fuente del módulo (pascal)
- .dpr - código fuente del proyecto (pascal)
- .dproj — código fuente del proyecto (xml)
- .dproj.local — código fuente del proyecto (xml)
- .dfm - código fuente del formulario
- .dpk - paquete de código fuente del proyecto
- .bpl - paquete compilado
- .dcu - módulo compilado
- .exe - aplicación compilada
- .res - recursos
- .dsk - enlaces de archivo
- .identcache - asociaciones de archivos en caché
Software notable de Delphi
Entre los muchos productos de software comunes escritos en Delphi, uno puede encontrar [13] :
- Productos de Embarcadero: Embarcadero Delphi , Embarcadero C++ Builder , Borland JBuilder 1 y 2 versiones.
- Administración y desarrollo de bases de datos: MySQL Tools , IBExpert , Open Server.
- Software de ingeniería: Altium Designer , SprutCAM .
- Administradores de archivos: Total Commander , Frigate , ViewFD , FreeCommander .
- Visores de gráficos: FastStone Image Viewer , FuturixImager , drComRead .
- Editores gráficos: IcoFX .
- Reproductores de video y audio: Light Alloy , The KMPlayer , AIMP , X-Amp , Nata Player .
- Programas de mensajería instantánea: QIP 2012 , R&Q , The Bat! , PopTray , FeedDemon , MyChat , Skype (antes de la compra de Microsoft ).
- Clientes de red de intercambio de archivos: Shareman , Ares Galaxy.
- Producción musical: FL Studio , Guitar Pro (hasta la versión 6.0).
- Desarrollo de software: Dev-C++ , DUnit , Game Maker , Inno Setup , PyScripter , PE Explorer
- Desarrollo web: Macromedia HomeSite , PHPEdit.
- Editores de texto: BirEdit , Notepad GNU , Bred (hasta Bred 3), PSPad .
- Contabilidad y fiscalidad: Mercury-ERP , " Budget 21 ", " Sail ", AVARDA (hasta versión 6.x inclusive), r_keeper , Traider Alpha.
- Sistema electrónico de colas " MAXIMA " [14] .
- Programas para almacenamiento y procesamiento de imágenes médicas Makhaon Worsktation , Makhaon Storage
- Software de animación : Pivot Stickfigure Animator .
- Programas para la compresión de datos : ALZip , PowerArchiver , IZArc .
- Búsqueda y destrucción de spyware y malware: Spybot - Search & Destroy .
- Juegos de PC: Age of Wonders , " Space Rangers ", Space Rangers HD: Revolution , Venom. Codename: Outbreak , Space Empires V , "La verdad sobre la Novena Compañía ".
- Lanzador de aplicaciones portátil: PortableApps .
- Desfragmentador de disco: SmartDefrag .
- Varias utilidades del sistema: TreeSize .
- Terminal para trabajar con puerto COM: TerminalTMB.
Crítica
Críticas al lenguaje en las primeras etapas de desarrollo
La historia de la crítica a Pascal se remonta a 1981 y al trabajo de Brian Kernighan [15] , cuyos argumentos en su mayoría se han vuelto obsoletos a medida que el lenguaje ha evolucionado.
Innovaciones para la compilación en plataformas móviles
Algunos cambios de lenguaje implementados por Embarcadero (desarrollador de lenguaje) en los llamados compiladores Delphi NextGen rompieron intencionalmente la compatibilidad con la base de código fuente acumulada. Estos cambios fueron recibidos negativamente por una amplia gama de desarrolladores experimentados de Delphi porque, aunque acercaron el lenguaje al paradigma del lenguaje .NET, rompieron la tradición de alta compatibilidad con versiones anteriores y dificultaron mucho más la transferencia del código fuente existente al software. para plataformas móviles. Los siguientes cambios desafiaron el propio paradigma del desarrollo multiplataforma y de fuente única promovido por Embarcadero.
- introducción de la indexación de cadenas de caracteres de base cero
Desde Pascal, el tipo de cadena integrado se ha indexado históricamente con una base de uno: el elemento "nulo" de la cadena devuelve la longitud de la cadena. A medida que se introdujeron nuevos tipos de cadenas ("largas" y "unicode"), se mantuvo este orden de indexación, lo que proporcionó una portabilidad casi perfecta del código base a versiones actualizadas del lenguaje. Sin embargo, con la introducción de la compilación nextgen, el paradigma cambió: en los nuevos compiladores, las cadenas comenzaron a indexarse en base cero, como en la familia de lenguajes tipo C (C ++, C #, Java), mientras que en los compiladores "clásicos" para Windows y Mac OS se ha guardado el paradigma de la indexación única.
- introducción de un mecanismo de conteo de referencia no alternativo para instancias de clase
Históricamente, las clases y sus instancias son tipos de estructura de referencia implícita. Sin embargo, la administración de por vida de una instancia de clase se realizó originalmente de forma manual, llamando explícitamente al constructor y al destructor (o método Free()), y esta función se conserva (a partir de 2018) en las versiones clásicas de los compiladores. El conteo de referencias funcionó solo para clases que implementan interfaces y, además, solo en el caso de que dichas clases se manipularan a través de variables del tipo de interfaz.
Antes de la versión 10.4, los compiladores para plataformas móviles introdujeron el recuento de referencias para todas las instancias de las clases, lo que cambió fundamentalmente el paradigma de la gestión de la vida útil de los objetos, ya que la gestión "manual" es prácticamente (excepto en algunas técnicas muy avanzadas) incompatible con el nuevo paradigma.
Desde la versión 10.4, se ha introducido un mecanismo de gestión de memoria unificada [16] , cuando se utiliza la implementación clásica de gestión de memoria de objetos para dispositivos móviles, escritorio y servidor. El modelo de gestión de memoria ARC se mantuvo para gestionar cadenas y referencias de tipo de interfaz en todas las plataformas.
Lenta evolución de los medios lingüísticos
Muchos desarrolladores ven el conservadurismo de Delphi como una virtud que hace que el código sea altamente portátil y también hace que el lenguaje sea más fácil de entender para los programadores novatos.
Sin embargo, en la actualidad la situación es tal que casi todos los años aparecen (y ganan popularidad) nuevas tecnologías, paradigmas e incluso lenguajes de programación. El desarrollo de herramientas de lenguaje no siempre implica el rechazo de la retrocompatibilidad.
Un buen ejemplo de este enfoque es
una introducción tardía al lenguaje de declarar variables locales dentro de un bloque
Antes de la versión 33.0 del compilador (Delphi 10.3 Rio), la declaración de una variable local tenía que preceder a la primera instrucción del código de función y no se permite la inicialización de variables locales (pila) en el sitio de declaración. La inferencia de tipos también era imposible.
En comparación, la declaración de una variable local en cualquier lugar de una función se admitía de forma nativa en C y fue heredada por casi todos los lenguajes que se adhirieron al estilo similar a C: C ++, C #, Java, etc.
La introducción de esta función de lenguaje en Delphi se discutió durante mucho tiempo, pero en ese momento no llegó a la comprensión de los desarrolladores del lenguaje.
Al mismo tiempo, declarar variables locales dentro de un bloque, a excepción de las operaciones de bucle For, puede complicar la legibilidad del código de proyectos grandes.
Notas
- ↑ Anuncio de disponibilidad de RAD Studio 11.1 Alexandria . Archivado desde el original el 20 de abril de 2022. Consultado el 12 de abril de 2022.
- ↑ La pronunciación "del-phi" domina en el Reino Unido: una variante de pronunciación característica del Reino Unido (inglés) (enlace inaccesible) . Diccionario en línea Merriam-Webster . Merriam Webster. Consultado el 1 de octubre de 2008. Archivado desde el original el 21 de agosto de 2011. , y en los EE . UU . - "del-fi": una variante de la pronunciación característica de los Estados Unidos (inglés) (enlace inaccesible) . Diccionario en línea Merriam-Webster . Merriam Webster. Consultado el 1 de octubre de 2008. Archivado desde el original el 21 de agosto de 2011.
- ↑ David T. Craig. Apple Lisa Computer: Historia de Apple y Pascal . (indefinido)
- ↑ Descripción general del lenguaje Delphi (enlace descendente)
- ↑ ejecutado directamente en el procesador ARM )
- ↑ Dmitry Ivanov - Cuentos de optimización prematura en YouTube , a partir de las 35:40
- ↑ Roman Elizarov - Millones de citas por segundo en Java puro en YouTube , a partir de las 58:59
- ↑ Esto se indica mediante las designaciones de versión del compilador. Entonces, en Delphi 7, el compilador tiene un número de versión de 15.0 (la última versión de Borland Pascal / Turbo Pascal fue designada 7.0, en Delphi 1 el compilador tiene la versión 8.0, en Delphi 2 - 9.0, etc. El número de versión 11.0 es el compilador Pascal, que formaba parte del entorno C++ Builder ).
- ↑ Página predeterminada de Parallels Plesk Panel Archivada el 5 de diciembre de 2006.
- ↑ Hoja de ruta de Delphi y C++Builder (enlace descendente) . Consultado el 18 de julio de 2007. Archivado desde el original el 10 de octubre de 2007. (indefinido)
- ↑ Herramientas de base de datos y software para desarrolladores | Embarcadero Technologies (enlace no disponible) . Fecha de acceso: 25 de agosto de 2008. Archivado desde el original el 29 de agosto de 2008. (indefinido)
- ↑ Delfos de Embarcadero | Archivado desde el original el 10 de julio de 2008. Software de desarrollo de aplicaciones RAD
- ↑ Aplicaciones de buena calidad creadas con Delphi - Programación de Delphi Archivado el 30 de junio de 2011 en Wayback Machine .
- ↑ Sistema electrónico de colas MAXIMA . mtg-biz.ru. Fecha de acceso: 5 de enero de 2017. Archivado desde el original el 6 de enero de 2017. (indefinido)
- ↑ Por qué Pascal no es mi lenguaje de programación favorito . Fecha de acceso: 23 de mayo de 2016. Archivado desde el original el 28 de abril de 2009. (indefinido)
- ↑ Novedades en RAD Studio 10.4 Sídney - RAD Studio - Productos .features-tabs ul.nav.nav-tabs Novedades en RAD Studio 10.4 RAD Studio 10.4 ofrece soporte nativo de Windows de alto rendimiento significativamente mejorado, mayor productividad con blazing ) ? . Web de Embarcaderos . Consultado el 15 de septiembre de 2020. Archivado desde el original el 16 de septiembre de 2020. (indefinido)
Literatura
Enlaces