Файл: Классификация языков программирования (Критерии выбора среды и языка разработки программ).pdf
Добавлен: 28.03.2023
Просмотров: 44
Скачиваний: 2
К критериям выбора языка программирования я считаю стоит отнести такие как:
Скорость работы конечного продукта. Требовательным к скорости выполнения могут быть программы с большим объемом математических вычислений, например моделирование физических систем, расчеты экономических данных, вывод трехмерной графики и так далее. Для данных целей хорошо подходят компилируемые языки: Assembler, C/C++, Fortran и т.д. после компиляции программа не требует ничего лишнего и содержит в себе машинные команды, которые выполняются без дополнительных задержек. Схема работы таких программ: Программа исполняется сразу, не требуя дополнительных библиотек; программа помимо своего кода содержит вызовы библиотек с машинным кодом (системные и входящие в проект), кроме исполнения собственных команд, программа вызывает функции из библиотек; так же программа может работать через прослойку из драйверов, которые в свою очередь написаны на языках низкого уровня и работают быстро.
Объем занимаемой оперативной памяти. Данное требование чаше всего актуально, когда программа разрабатывается для встраиваемых систем, мобильных платформ, микроконтроллеров и т.д. В данном случае чем меньше памяти использует программа на данном языке – тем лучше. Сюда можно отнести языки: Assembler, C/C++, Objective-C и т.д. список подобен скорости работы, обусловлено это тем что чем меньше функциональных блоков в схеме исполнения, тем меньше памяти компьютера использует программа.
Скорость разработки программы. Данное требование актуально для разработки программ, которые нужно сделать в короткий срок. Сюда подходят высокоуровневые языки. Java, Flash и т.д. На данных языках время разработки существенно сокращается за счет обилия сторонних библиотек, максимально понятного синтаксиса, и подобного. Скорость выполнения программ, написанных на высокоуровневых языках, существенно падает, так как программа находится в виде байт-кода. И для его исполнения нужен анализатор, который должен транслировать байт-код в машинный «на лету», при этом потратив много времени на точный анализ инструкций.
Ориентированность на пользователя. Тут в свою очередь необходимо понимать с кем программа должна работать в первую очередь, компьютер или человек. Так как для работы с человеком, программа должна обладать хорошо продуманной графической частью, которая отвечает требованиям дизайна и юзабилити. На разработку графической части уходит достаточно много времени, так как разработка графического интерфейса отличается немалой сложностью. Сложность в том что вывод графики – это приличное количество математических расчетов, а отсюда следует что требуется и хорошая скорость выполнения программы, а из-за сложности разработки присутствует необходимость в высокоуровневом языке. Для данных задач хорошо подходит C++/C# одновременно и высокоуровневые, и скоростью выполнения на них. Если программа ориентирована в первую очередь на работу с компьютером с минимальным воздействием пользователя, тогда выбор должен ложится в сторону быстрых языков (Assembler, C)
Кроссплатформенность – возможность работы программы на различных платформах, в различных ОС с минимальными изменениями. В этой сфере можно выделить такие языки как: Java, C++, C#, Flash с различными библиотеками.
Java создавалась с тем условием что программы на данном языке должны работать на любой платформе, где есть JVM (Java Virtual Machine). Программы на Java вообще не требуют никаких изменений. После компиляции получается «.jar» файл, который будет работать и на Windows, и на Mac OS, и на Linux, а также в любом другом месте, где присутствует JVM. С C++ несколько иначе, на чистом C++ написать кроссплатформенную программу довольно трудно, у кода возникает обширная избыточность и достоинство в скорости выполнения теряется. Обычно используют кроссплатформенные библиотеки, такие как «Qt», которые позволяют достичь принципа «один код на все платформы», однако программу для каждой платформы придется компилировать отдельно и разными компиляторами. Сюда также можно включить и интерпретируемые языки, скриптовые языки – для их работы нужно наличие интерпретатора языка в системе. Данные языки довольно удобны в плане разработки, но медлительны. Так же достаточно большое потребление памяти компьютера.
Скорость внесения изменений и скорость тестирования
Если проект быстро развивается, в него постоянно вносят изменения. Тогда выбор должен падать на высокоуровневые языки, где любой функциональный блок можно переписать. Так как заниматься дебажить, например C++ намного проще, чем Assembler. Но тут очень много тонкостей, которые по большей части находятся в языке, сколь в разработчике с его стилем программирования и компиляторах, которые он использует. Так же и язык вносит свою долю, так или иначе упрощая или усложняя работу программиста.
Для меня что-то конкретное отнести к критериям выбора среды разработки довольно сложно, так как для каждого конкретного языка программирования по большей части существует своя среда разработки, она же IDE, и для каждого разработчика эта своя которая ему более удобна. Конечно, никто не запрещает пользоваться обычным блокнотом, но в то же время уже для каждого языка программирования есть своя IDE которая заточена на работу с ним, что упрощает и ускоряет разработку на выбранном языке программирования. На пример для работы с языками для платформы .NET Framework, по моему счету отлично подходит Visual Studio. В ней есть все что необходимо для работы с данной платформой, и IntelliSense – технология автодополнения Microsoft которая дописывает название функции или переменной при вводе начальных букв, что в разы ускоряет разработку и программы. Подсветка синтаксиса, что упрощает написание и чтение программного кода. Возможность отладки написанной программы, конечно, возможность проверить программу это отличный способ, найти и устранить ошибки, которые были допущены при разработке.
Возможность IDE настраивать под себя, считаю отличным дополнением к IDE, так как это позволяет более комфортно чувствовать себя при работе с данной IDE, ну и в некотором случае ускорении разработки программы, так в некоторых IDE можно добавлять свои шаблоны различных классов и функций, которые можно вставлять в несколько нажатий, а не писать их или искать и копировать уже разработанный функционал.
На данный момент я пользуюсь Visual Studio Code, это редактор который можно настроить по функционалу ни чуть не уступающий Visual Studio, с помощью всевозможных расширений которые разрабатываются, как Microsoft, так и сообществом, которое пользуется данным редактором, так же достоинством данного редактором является возможность использования данного редактора на различных платформах: Windows, Linux, MacOS
Существенным плюсом для данного редактора является сохранение внесенных изменений, что позволяет не беспокоиться о том что какой то участок кода мог был потерян, в каких то критических ситуациях, например как непредвиденное завершение работы операционной системы, полностью позволяет не беспокоится за потраченные часы. А возможность полной кастомизации данного редактора, позволяет подстроить его под себя и свои нужды.
Исходя из этих под тем, можно сказать следующее, на данный момент очень большой выбор языков программирования, которые подходят под те или иные задачи и у каждого языка есть свои тонкости, которые следует учитывать, например что большие программы могут состоять из подпрограмм которые написаны на разных языках в зависимости от нужд данной подпрограммы. К примеру, программы где необходим высокая скорость работы программы, пишут в основном на низкоуровневых языка, а графическая составляющая на высокоуровневых и более медленных. По моему мнению языки C и C++ это очень универсальные языки, огромным количеством библиотек с отличной скоростью работы и своими плюсами. Но у этих языков есть конечно и свой недостаток, это то, что за свою универсальность они платятся тем, что они сложны в освоении и нюансы.
На счет Java, не смотря на его универсальность и простоту освоения, у данного языка есть свой недостаток, который порой перекрывает, простоту разработки под различные платформы, это то что он платится своей скоростью работы, от сюда следует его ограничения, например большие программы на нем можно написать, но работать они будут довольно медленно, а так же высокое требование к аппаратному обеспечению.
Скриптовые и интерпретируемые языки, хорошо подходят для разработки автоматизации различных действий, а так же при встраивании в другие языки.
Про Assembler я бы что-то и рассказал, но я еще не проявил желания в его изучении, так как считаю его для меня одним из самых сложных в освоении языков. Но в свою очередь это один из самых производительных языков, если все правильно написать и использовать.
В данную главу хочу внести несколько примеров из разных языков.
Змейка написанная на C:
#include <stdio.h>
#include <conio.h>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
#define SIZEX 65
#define SIZEY 20
#define MAXSIZE_SNAKE 100
int foodPosX = -1, foodPosY = -1, foodIsLive;
int score = 0, life = 1;
void textAttr(int color) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
void checkBody(int curX, int curY, int snake[2][MAXSIZE_SNAKE]) {
int i;
for (i = 1; i < MAXSIZE_SNAKE; ++i) {
if (snake[0][i] == curX && snake[1][i] == curY) {
life = 0;
break;
}
}
}
void gotoxy(int x, int y) {
COORD c = { x, y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void updateScore(int x, int y) { // x + 2 y
gotoxy(x + 2, y);
printf("Score: %d", score);
gotoxy(x + 2, y + 1);
printf("Food: ");
textAttr(0x0C);
printf(" %c", 3);
textAttr(0x07);
}
void printCreator(int x, int y) { // x + 2 y
gotoxy(x + 2, y);
printf("Created");
gotoxy(x + 2, y + 1);
printf("By RedZvER");
}
void printFood(int maxX, int maxY) {
int posX, posY;
posX = rand() % maxX + 1;
posY = rand() % maxY + 1;
if (posX > 0 && posX < maxX - 1 && posY > 0 && posY < maxY - 1) {
gotoxy(posX, posY);
textAttr(0x0C);
printf("%c", 3);
textAttr(0x07);
if (foodPosX != -1 && foodPosY != -1) {
gotoxy(foodPosX, foodPosY);
printf(" ");
}
foodPosX = posX;
foodPosY = posY;
foodIsLive = 1;
}
}
void printBorder(int sizeX, int sizeY) {
int i, j;
for (i = 0; i < sizeY; ++i) {
for (j = 0; j < sizeX; ++j)
printf("%c", (i == 0 || j == 0 || j == sizeX - 1 || i == sizeY - 1) ? (textAttr(0x0A), '#') : ' ');
textAttr(0x07);
printf("\n");
}
}
int main() {
srand((unsigned)time(NULL)); rand();
int key, dx = 1, dy = 0;
int l, r, u, d;
int i;
foodIsLive = l = u = d = 0;
r = 1;
printBorder(SIZEX, SIZEY);
updateScore(SIZEX, 0);
printCreator(SIZEX, 5);
int tSize = 5;
int m[2][MAXSIZE_SNAKE]; // [x,y] [ MAXSIZE_SNAKE ]
m[0][0] = 40; m[1][0] = 12;
m[0][1] = 39; m[1][1] = 12;
m[0][2] = 38; m[1][2] = 12;
m[0][3] = 37; m[1][3] = 12;
m[0][4] = 36; m[1][4] = 12;
while (1) {
gotoxy(m[0][0], m[1][0]);
textAttr(0x0e);
putchar(1);
//print snake body
for (i = 1; i < tSize; ++i) {
gotoxy(m[0][i], m[1][i]);
putchar('o');
}
textAttr(0x07);
if (_kbhit() != 0) {
key = _getch();
if (key == 27) break;
if (key == 32) { gotoxy(0, SIZEY); system("pause"); }
if (key == 0) key = _getch();
if (key == 75 && !r) { dy = 0; dx = -1; u = d = r = 0; l = 1; }
if (key == 77 && !l) { dy = 0; dx = 1; u = d = l = 0; r = 1; }
if (key == 72 && !u) { dy = -1; dx = 0; l = r = u = 0; d = 1; }
if (key == 80 && !d) { dy = 1; dx = 0; l = r = d = 0; u = 1; }
}
if (m[0][0] == foodPosX && m[1][0] == foodPosY) {
tSize++;
score += 5;
foodIsLive = 0;
updateScore(SIZEX, 0);
}
gotoxy(m[0][tSize - 1], m[1][tSize - 1]);
putchar(' ');
for (i = tSize - 1; i > 0; i--)
{
m[0][i] = m[0][i - 1];
m[1][i] = m[1][i - 1];
}
m[0][0] += dx; m[1][0] += dy;
checkBody(m[0][0], m[1][0], m);
if (m[0][0] <= 0 || m[0][0] >= SIZEX - 1 || m[1][0] <= 0 || m[1][0] >= SIZEY - 1 || life == 0) {
break;
}
if (foodIsLive == 0) {
printFood(SIZEX - 1, SIZEY - 1);
}
Sleep(90);
}
gotoxy(0, SIZEY + 1);
printf("Game Over\nScore: %d\n", score);
system("pause");
return 0;
}
Автоатака на C#
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class AutoAttack : MonoBehaviour {
public float attackRadius;
[Range(0,360)]
public float attackAngle;
public float attackSpeed;
public LayerMask obstacleMask;
public GameObject _Fire, _Water, _Earth, _Wind;
public GameObject orb_Spot;
public float fire_speed, water_speed, earth_speed;
public float degreePerSecond = 40f;
[HideInInspector]
public List<Transform> visibleTargets = new List<Transform>();
[HideInInspector]
public int edgeResolveIterations;
[HideInInspector]
public float edgeDstThreshold;
public float meshResolution = 1f;
public MeshFilter viewMeshFilter;
Mesh viewMesh;
public float maskCutawayDst = 0.1f;
public GameObject attackTarget;
private Vector3 targetPos;
public MagesAttackType.MageType type;
private Vector3 doAttackAngle;
public void SetAutoAttackType(string _type)
{
type = (MagesAttackType.MageType)Enum.Parse(typeof(MagesAttackType.MageType), _type, true);
Debug.Log(type.ToString());
}
void Start () {
viewMesh = new Mesh ();
viewMesh.name = "View Mesh";
viewMeshFilter.mesh = viewMesh;
StartCoroutine("FindTargetWithDelay", 0.2f);
StartCoroutine("AutoAttackEnum");
}
IEnumerator FindTargetWithDelay(float delay)
{
while (true)
{
yield return new WaitForSeconds(delay);
FindVisibleTargets();
}
}
/*
void LateUpdate () {
DrawFieldOfAttack();
}*/
void FindVisibleTargets()
{
visibleTargets.Clear();
Collider[] targetsInAttackRadius = Physics.OverlapSphere(transform.position, attackRadius);
float closest_dst = attackRadius;
GameObject closest_go = null;
int count_ia = 0;
for (int i = 0; i < targetsInAttackRadius.Length; i++)
{
GameObject target = targetsInAttackRadius[i].gameObject;
if (target.tag != "Enemy") continue;
Transform t_target = target.transform;
Vector3 dirToTarget = (t_target.position - transform.position).normalized;
if (Vector3.Angle(transform.forward, dirToTarget) < attackAngle / 2)
{
float dstToTarget = Vector3.Distance(transform.position, t_target.position);
if (!Physics.Raycast(transform.position, dirToTarget, dstToTarget, obstacleMask))
{
count_ia++;
visibleTargets.Add(t_target);
if (dstToTarget < closest_dst)
{
doAttackAngle = dirToTarget;
closest_dst = dstToTarget;
closest_go = target;
}
}
}
}
if (count_ia == 0)
{
attackTarget = null;
}
else
{
attackTarget = closest_go;
}
}
public GameObject getGameObjType(MagesAttackType.MageType type)
{
switch (type)
{
case MagesAttackType.MageType.None:
return null;
case MagesAttackType.MageType.Fire:
return _Fire;
case MagesAttackType.MageType.Water:
return _Water;
case MagesAttackType.MageType.Earth:
return _Earth;
case MagesAttackType.MageType.Wind:
return _Wind;
default:
return null;
}
}
public float getSpeedObjType(MagesAttackType.MageType type)
{
switch (type)
{
case MagesAttackType.MageType.None:
return 0f;
case MagesAttackType.MageType.Fire:
return fire_speed;
case MagesAttackType.MageType.Water:
return water_speed;
case MagesAttackType.MageType.Earth:
return earth_speed;
case MagesAttackType.MageType.Wind:
return 0f;
default:
return 0f;
}
}
IEnumerator AutoAttackEnum()
{
while (true)
{
yield return new WaitForSeconds(attackSpeed);
if (attackTarget != null)
{
if (getGameObjType(type) != null)
{
// start rotate
Quaternion start_rot = transform.rotation;
Vector3 dir = Vector3.ProjectOnPlane(attackTarget.transform.position - transform.position, Vector3.up);
Quaternion target_rot = Quaternion.LookRotation(dir);
float elapsed_time = 0f;