admin管理员组

文章数量:1125904

I'm learning Ada, and I wrote a function to calculate the factorial of a number and a simple program to call it. However, depending on the way I format the display of the result, my variable gets a different value.

Here's the content of my files:

factorial.ads
function Factorial (n : in out Natural) return Natural;
factorial.adb
function Factorial (n : in out Natural) return Natural is
   n_fac : Natural := 0;
begin
   if n = 0 or n = 1 then
      n_fac := 1;
   else
      n_fac := n;
      loop
         n_fac := n_fac * Integer'Pred(n);
         n := n - 1;
         exit when n = 1;
      end loop;
   end if;

   return n_fac;
end Factorial;
show_factorial.adb
with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Factorial;

procedure Show_Factorial is
   A : Natural := 4;
begin
   --  First block
   Put_Line ("-- First block --");
   Put ("Factorial of" & Integer'Image(A) & " is ");
   A := factorial(A);  --  In between Put procedures to save 
   --                       one variable declaration
   Put (                                         A, Width => 0);

   --  Post-execution check
   New_Line;
   Put_Line ("A is" & Integer'Image(A));

   --  Reset variable
   New_Line;
   Put_Line ("-- Var reset --");
   A := 4;
   Put_Line ("A becomes" & Integer'Image(A));
   New_Line;

   --  Second block
   Put_Line ("-- Second block --");
   Put ("Factorial of" & Integer'Image(A) & " is ");
   Put (                               factorial(A), Width => 0);
   A := factorial(A);

   --  Post-execution check
   New_Line;
   Put_Line ("A is" & Integer'Image(A));
end Show_Factorial;

Executing the program above gives me the following output:

-- First block --
Factorial of 4 is 24
A is 24

-- Var reset --
A becomes 4

-- Second block --
Factorial of 4 is 24
A is 1

As the formal parameter of my function Factorial is an in out parameter, I was expecting it would alter the value of A unconditionally after being called, but that is not the case as seen from the terminal output. I would expect it to become 4 at least, since that's its initial value, but it somehow becomes 1 of all things!

Why does A become 1 in the second block even if I explicitly assign it the return value of the Factorial function?

I'm learning Ada, and I wrote a function to calculate the factorial of a number and a simple program to call it. However, depending on the way I format the display of the result, my variable gets a different value.

Here's the content of my files:

factorial.ads
function Factorial (n : in out Natural) return Natural;
factorial.adb
function Factorial (n : in out Natural) return Natural is
   n_fac : Natural := 0;
begin
   if n = 0 or n = 1 then
      n_fac := 1;
   else
      n_fac := n;
      loop
         n_fac := n_fac * Integer'Pred(n);
         n := n - 1;
         exit when n = 1;
      end loop;
   end if;

   return n_fac;
end Factorial;
show_factorial.adb
with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Factorial;

procedure Show_Factorial is
   A : Natural := 4;
begin
   --  First block
   Put_Line ("-- First block --");
   Put ("Factorial of" & Integer'Image(A) & " is ");
   A := factorial(A);  --  In between Put procedures to save 
   --                       one variable declaration
   Put (                                         A, Width => 0);

   --  Post-execution check
   New_Line;
   Put_Line ("A is" & Integer'Image(A));

   --  Reset variable
   New_Line;
   Put_Line ("-- Var reset --");
   A := 4;
   Put_Line ("A becomes" & Integer'Image(A));
   New_Line;

   --  Second block
   Put_Line ("-- Second block --");
   Put ("Factorial of" & Integer'Image(A) & " is ");
   Put (                               factorial(A), Width => 0);
   A := factorial(A);

   --  Post-execution check
   New_Line;
   Put_Line ("A is" & Integer'Image(A));
end Show_Factorial;

Executing the program above gives me the following output:

-- First block --
Factorial of 4 is 24
A is 24

-- Var reset --
A becomes 4

-- Second block --
Factorial of 4 is 24
A is 1

As the formal parameter of my function Factorial is an in out parameter, I was expecting it would alter the value of A unconditionally after being called, but that is not the case as seen from the terminal output. I would expect it to become 4 at least, since that's its initial value, but it somehow becomes 1 of all things!

Why does A become 1 in the second block even if I explicitly assign it the return value of the Factorial function?

Share Improve this question asked Jan 9 at 2:59 Effective_Set_3418Effective_Set_3418 112 bronze badges New contributor Effective_Set_3418 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Add a comment  | 

2 Answers 2

Reset to default 3

It looks like it comes from your line:

    Put (                               factorial(A), Width => 0);

Which sets A back to 1 since it is an in out parameter and you don't save the result of that function call back to A

Then your next call to Factorial: A := factorial(A); Calculates the factorial of 1, which is 1.

This in Factorial:

      loop
         n_fac := n_fac * Integer'Pred(n);
         n := n - 1;
         exit when n = 1;
      end loop;

Originally, Ada functions couldn’t have in out parameters: this confusion is why (and why it’s still a bad idea in most cases).

本文标签: adaIs the Put procedure altering the value of my variableStack Overflow