开发者

What is the problem with my code for multiplying two numbers in a different way using Bash?

This is my first time using Bash, so bear with me. I'm using Git Bash in Windows for a college project, trying to rewrite some C code that provides an alternate way of multiplying two numbers "a" and "b" to produce "c". This is what I came up with:

#!/bin/bash

declare -i a
declare -i b
declare -i c=0
declare -i i=0    # 开发者_StackOverflow社区not sure if i have to initialize this as 0?
echo "Please enter a number: "
read a
echo "Please enter a number: "
read b

for i in {1..b}
do
    let "c += a"
done

echo "$a x $b = $c"

I think part of the problem is in the for loop, that it only executes once. This is my first time using Bash, and if anyone could find the fault in my knowledge, that would be all I need.


There are problems with your loop:

  • You can't use {1..b}. Even if you had {1..$b} it wouldn't work because you would need an eval. It's easiest to use the seq command instead.
  • Your let syntax is incorrect.

Try this:

for i in $(seq 1 $b)
do
    let c+=$a
done

Also, it's not necessary to declare or initialise i.


for i in {1..b}
won't work, because 'b' isn't interpreted as a variable but a character to iterate to.
For instance {a..c} expands to a b c.
To make the brace expansion work:
for i in $(eval echo "{1..$b}")

The let "c += a" won't work either.
let c+=$a might work, but I like ((c+=a)) better.

Another way is this:
for ((i = 1; i <= b; i++))
do
    ((c += a))
done

(might need to put #!/bin/bash at the top of your script, because sh does less than bash.)


Of course, bash already has multiplication, but I guess you knew that ...

If the absence of "seq" is your issue, you can replace it with something more portable, like

c=0

# Print an endless sequence of lines
yes |
# Only take the first $b lines
head -n "$b" |
# Add line number as prefix for each line
nl |
# Read the numbers into i, and the rest of the line into a dummy variable
while read i dummy; do
    # Update the value of c: add line number
    c=`expr "$c" + "$i"`
    echo "$c"
done |
# Read the last number from the while loop
tail -n 1

This should be portable to any Bourne-compatible shell. The while ... echo ... done | tail -n 1 trick is necessary only if the value of c is not exported outside the while loop, as is the case in some, but not all, Bource shells.

You can implement a seq replacement with a Perl one-liner, but then you might as well write all of this in Perl (or awk, or Python, or what have you).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜