Доступ К Несуществующему Индексу Массива

Мне пришлось переписать код с одного языка на другой, и я обнаружил, что при доступе к несуществующему индексу массива разные языки ведут себя по-разному.

Подробности под катом.



Доступ к несуществующему индексу массива

Вот пример кода на языке структурированного текста, который используется для программирования промышленных контроллеров.

Программы на этом языке могут выполнять различные действия: от управления светофором до наблюдения за процессами на атомной электростанции.

Учтена специфика языка и платформы, поэтому код может выглядеть довольно необычно.

  
  
  
  
  
  
  
  
   

VAR i: INT; OUT: INT; IN: ARRAY [0.4] of INT:= 1, 2, 3, 4, 5; END_VAR OUT := 0; FOR i:= 0 TO 4 DO OUT := OUT + IN[i]; END_FOR;

Что делает эта программа? Считывает данные из входных сигналов и записывает управляющее действие в переменную OUT. Значение этой переменной будет 15. Теперь внесем в программу некоторую ошибку, а именно возьмем элемент по несуществующему индексу в массиве и посмотрим на результат.

VAR i: INT; OUT: INT; IN: ARRAY [0.4] of INT:= 1, 2, 3, 4, 5; END_VAR OUT := 0; FOR i:= -1 TO 4 DO OUT := OUT + IN[i]; END_FOR;

Значение в переменной OUT = 15
То есть то же самое, что и до ошибки.

Программа не выдала исключение, а просто проигнорировала несуществующий элемент. Такое поведение для нас вполне приемлемо, если мы случайно не обработали исключение и управляем аварийными стержнями ядерного реактора.

Эффект управления переменной OUT будет таким же, как и до ошибочного изменения индекса.

Если это кратковременный сбой, то система не отреагирует на ошибку и продолжит стабильно работать.

Теперь представим, что одну и ту же задачу выполняют разные программы на других языках программирования, и сравним результаты.

Код без ошибочного индекса выполняется одинаково во всех языках программирования и переменная OUT всегда имеет значение 15. Мы будем рассматривать только тот код, где закралась ошибка со стартовым значением индекса -1.

JavaScript



var IN = [ 1, 2, 3, 4, 5 ]; var OUT = 0; for (var i = -1; i <= 4; i++) { OUT += IN[i]; } console.log('OUT = '+ OUT);

ВЫХ = НЭН


Идти



package main import "fmt" func main() { IN := [5]int{ 1, 2, 3, 4, 5 } OUT := 0 for i := -1; i <= 4; i++ { OUT += IN[i] } fmt.Printf("OUT = %d", OUT) }

паника: ошибка выполнения: индекс вне диапазона


Джава



public class MyClass { public static void main(String args[]) { int[] IN = {1, 2, 3, 4, 5}; int OUT = 0; for (int i = -1; i <= 4; i++) OUT += IN[i]; System.out.printf("OUT = %d", OUT); } }

Исключение в потоке «основной» java.lang.ArrayIndexOutOfBoundsException: -1


PHP



<Эphp $IN = [1, 2, 3, 4, 5]; $OUT = 0; for ($i=-1; $i<=4; $i++) { $OUT += $IN[$i]; } echo('OUT = '.

$OUT);

ВЫХОД = 15 Примечание PHP: неопределенное смещение: -1


Питон 3



IN = [ 1, 2, 3, 4, 5 ]; OUT = 0; for i in range(-1, 5): OUT += IN[i]; print('OUT = {0:1d}'.

format(OUT));

ВЫХОД = 20
Python поддерживает отрицательные индексы, а нумерация начинается с конца массива.



С/С++



#include<stdio.h> int main() { int IN[]= {1,2,3,4,5}; int OUT=0; int i; for (i=-1; i<=4; i++) { OUT += IN[i]; } printf("OUT = %i", OUT); return 0; }

С языком C++ ситуация другая.

Если вы захотите проверить этот пример на популярных сайтах, вы получите следующие результаты: http://codepad.org

ВЫХ = -143484461
https://ideone.com/ и так далее.

ВЫХОД = 15
https://www.jdoodle.com
ВЫХОД=14
В этой статье я не буду вдаваться в подробности о том, какие компиляторы C/C++ на каких платформах используются на этих сайтах.

Буду очень рада, если вы поделитесь своим мнением в комментариях.



До-диез



using System; class Program { static void Main() { int[] IN = new int[] { 1, 2, 3, 4, 5 }; int OUT = 0; for (int i = -1; i <= 4; i++) { OUT += IN[i]; } Console.Write("OUT of IN + y = "+ OUT); } }

Необработанное исключение: System.IndexOutOfRangeException: индекс вышел за пределы массива.



выводы

При написании кода на любом языке программирования необходимо учитывать особенности работы со структурами данных в языке.

Также учтите все места кода, где программа может аварийно завершить работу.

Зачастую после исключения код программы уже невозможно вернуть на строку, где произошла ошибка, и важные действия могут быть выполнены ниже кода.

Поэтому не все языки подходят для решения тех или иных задач или требуют дополнительных проверок и веток кода.

Языки стандарта МЭК имеют защиту от примитивных программных ошибок, так как часто некому перезагрузить программу контроллера в случае сбоя, да и эта операция в некоторых ситуациях может оказаться фатальной.

Теги: #JavaScript #java #golang #Go #php #C++ #C++ #python #программирование

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.