Nano Hash - криптовалюты, майнинг, программирование

Печать массива целых чисел приводит к странному выводу в Аде

Я создал простую программу на языке Ada, которая позволяет пользователю заполнить массив максимум 100 неотрицательными и ненулевыми целыми числами, а затем распечатать их. Когда я вызываю функцию для вывода чисел, она их выводит, но в то же время выводит кучу странных и, казалось бы, случайных чисел. Какую ошибку я допустил в своем коде, из-за которой программа выводит такие странные результаты? Я впервые пишу на Аде. Например, когда я заполняю пустой массив числами [1,2,3,4,5], он выводит следующее:

    1
          2
          3
          4
          5
      32624
  911328835
      32624
  911328836
      32624
   67043328
  134217726
  134217726
 2013265921
  134217726
  134217726
  134217726
   67043328
  909181968
      32624
 2114692683
      89452
  914381552
      32624
 1543503876
          2
         14
          2
         14

Я использую компилятор gnatmake в Ubuntu, и при компиляции исходного кода он не выдает никаких сообщений об ошибках/предупреждениях.

Вот мой исходный код, я знаю, что мне, вероятно, не нужно использовать отдельные функции, но я все равно реализовал их для целей обучения.

with Ada.Containers.Vectors;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
use Ada.Containers;


procedure thing is 
type Vector is array (1..100) of Integer;
A: Vector;--array doesn't need to be completely filled up

K: Integer;
--array filling function below
function mkarr return Vector is --asks user to fill empty array with positive and non zero integers

begin

Ada.Text_IO.Put ("enter numbers to fill array, negative or 0 will stop process: ");
for I in 1..100 loop
    Ada.Integer_Text_IO.Get(K);
    if K>0 then
        A(I) := K;
    end if;
    if K<=0 then
        return A;
    end if;

end loop;
return A;
end;




--array printing prodcedure below
procedure printarr(A: in out Vector) is
begin
    for I in A'Range loop
    if A(I)>0 then
        Ada.Integer_Text_IO.Put(A(I));
        New_Line(1);
    end if;
    end loop;
end printarr;



B: Vector := mkarr;


--main method below
begin



printarr(A);
end thing;
03.05.2020

  • Быстрое исправление: A: Vector := (others => 0); Затем почитайте, чтобы понять, как и почему это работает. Лучше: заставить mkarr возвращать вектор правильного размера (что легко и не требует Ada.Containers. 03.05.2020

Ответы:


1

В mkarr вы используете 0 или отрицательное значение, чтобы отметить конец ввода, но вы не сохраняете это значение в массиве. Если какой-либо мусор, хранящийся в массиве после окончания введенных вами значений, оказывается положительным, нет никакого способа сказать, что это недопустимое значение.

В printarr, если вы встречаете 0 или отрицательное значение, вы не печатаете его, но продолжаете печатать оставшиеся положительные значения (которые являются мусором).

Если вы сохраните значение дозорного в mkarr и прекратите печать в printarr, когда встретите дозорный, программа должна работать.

Некоторые другие примечания:

A и K используются только внутри mkarr. Они должны быть локальными для mkarr.

Вы никогда не используете Ada.Containers.Vectors. Вы можете удалить соответствующие директивы with и use.

Для более продвинутого использования вы можете заставить mkarr возвращать массив, содержащий только введенные данные, сделав Vector неограниченным типом массива и возвращая срез. Еще проще определить массив фиксированной длины внутри mkarr. Разрешить произвольное количество входных данных сложнее, но Ada.Containers, вероятно, хороший способ сделать это. (Отказ от ответственности: я не смотрел на Ada.Containers.)

03.05.2020

2

Расширение ответа Кейта: вам нужен результат переменной длины, поэтому более похожий на Ada способ - использовать "неограниченный множество":

type Vector is array (Positive range <>) of Integer;

Это означает, что вы можете создавать экземпляры массива любого размера, если границы положительны: 1 .. 100, 42 .. 43 и т. д. Вы даже можете создать массив нулевой длины, указав последнюю границу ( называется ’Last) меньше первого (называется ’First). В этом особом случае вам разрешено использовать ’Last за пределами диапазона типа индекса (в данном случае 0 или даже -42, если вы хотите запутать людей!).

function mkarr return Vector is

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

   Result : Vector (1 .. 100);

Нам нужно знать, сколько элементов.

   Last : Natural := Result'First - 1;

Более или менее, как прежде,

   K : Integer;
begin
   Ada.Text_IO.Put
     ("enter numbers to fill array, negative or 0 will stop process: ");
   for I in Result'Range loop

Мы можем вернуть массив, содержащий не более Result’Length элементов.

      Ada.Integer_Text_IO.Get (K);
      if K > 0 then

Мы можем добавить еще один элемент.

         Last := Last + 1;
         Result (Last) := K;
      else

Элементов меньше 100, поэтому верните только этот фрагмент.

         return Result (Result'First .. Last);
      end if;
   end loop;

Мы накопили 100 результатов, поэтому верните их все.

   return Result;
end mkarr;
03.05.2020
  • Чтобы сделать вещи более похожими на Ada, можно было бы иметь компоненты массива подтипа Positive и переименовать Count в Last подтипа Natural, поскольку в общем случае это последний используемый индекс, который может отличаться от количества добавленных значений. . 04.05.2020
  • @JeffreyR.Carter, хорошие моменты; Я принял Last, но оставил компоненты массива как Integer, потому что это был выбор ОП. 04.05.2020

  • 3

    Как отмечено здесь, в вашем примере упоминается Ada.Containers.Vectors без дополнительной ссылки на пакет. Если вы ищете такое решение, обсуждайте его здесь, вы можете сначала создать универсальный пакет Vectors, чтобы получить изменяемый размер контейнера целых чисел:

    package Integer_Container is new Vectors (Natural, Integer);
    

    Ваша функция для создания массива может затем объявить Vector с именем A и инициализировать его элементы и длину определенными значениями:

    function Make_Array (Size : Count_Type) return Vector is
    A : Vector := To_Vector (New_Item => -1, Length => Size);
    …
    

    Вы можете использовать итерацию< /a> в Ada 2012, чтобы упростить сбор данных в Make_Array:

    for E of A loop
       Get (K);
       if K > 0 then
          E := K;
       else
          exit;
       end if;
    end loop;
    

    Точно так же procedure Print_Array (A : in Vector) может зацикливаться следующим образом:

    for E of A loop
       Put (E, 4);
    end loop;
    

    Типичное использование может выглядеть примерно так:

    Print_Array (Make_Array (42));
    

    Дополнительную информацию можно найти здесь и < href="https://stackoverflow.com/search?tab=votes&q=%5Bada%5D%20Ada.Containers.Vectors">здесь.

    04.05.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..