每当在提示下输入1时,我都会遇到分段错误
print*,"where would you like to buy/sell from/into (enter first number between 1 and ", &
size(energy(:,1)),"and second number between 1 and",size(energy(1,:)),")"
因此,我试图创建一个代表市场的简单程序,到目前为止,似乎其他一切都有效,除了1通过item_choice_I或item_choise_k传递到子例程buy_sell时。我对编程有些陌生,不知道如何修复这样的故障。
!subroutine section:
subroutine buy_sell(buyer,buyer_size,buyer_number,energy,item_choice_k,item_choice_i,exchange_ammount) !the market form has k then i
implicit none
integer,intent(in) :: item_choice_k,item_choice_i,exchange_ammount,buyer_size,buyer_number
integer,dimension(buyer_size) :: buyer !the amount the buyer has in savings
integer,intent(inout),dimension(10,10) :: energy
energy(item_choice_k,item_choice_i)=energy(item_choice_k,item_choice_i)-exchange_ammount !purchasing is thus positive exchange amount and selling is negative
buyer(buyer_number)=buyer(buyer_number)+exchange_ammount
end subroutine buy_sell
subroutine print_market(energy,k_size,i_size,buyer,buyer_size)
implicit none
integer,intent(in) :: k_size,i_size,buyer_size
integer,dimension(buyer_size) :: buyer
integer,dimension(k_size,i_size),intent(in) :: energy
integer :: k,i,l
do k=1,k_size
do i=1,i_size
print*,"the value of energy(",k,i,") is", energy(k,i)
enddo
enddo
print*," "
l=1
print*,"Buyer",l,"has",buyer(l),"energy units (user)"
do l=2,buyer_size
print*,"Buyer",l,"has",buyer(l),"energy units"
enddo
end subroutine print_market
subroutine user_buyer_interface(energy,k_size,i_size,buyer,buyer_size) !the user buyer is always the first element in the buyer list
integer,intent(in) :: k_size,i_size,buyer_size
integer,dimension(buyer_size) :: buyer
integer,dimension(k_size,i_size),intent(inout) :: energy
integer :: period,item_choice_k,item_choice_i,exchange_ammount,exchange_error,buyer1
character(len=3) :: choice_buy_sell
buyer1=buyer(1)
print*,"do you want to buy/sell this round?"
read (*,*) choice_buy_sell
if (choice_buy_sell/='yes' .or. choice_buy_sell/='no') then !stupid users, choose yes or no
do while (choice_buy_sell/='yes' .and. choice_buy_sell/='no') !beat them into submission
print*,"incorrect choice, try again."
read (*,*) choice_buy_sell
enddo
endif
if (choice_buy_sell=="yes") then !start buy/sell procedure
print*,"where would you like to buy/sell from/into (enter first number between 1 and ", &
size(energy(:,1)),"and second number between 1 and",size(energy(1,:)),")"
read (*,*) item_choice_k,item_choice_i !finds the required item in the list and records it
do while ((1>item_choice_k .or. item_choice_k>k_size) .or. (1>item_choice_i .or. item_choice_i>i_size)) !must enter available item
print*,"incorrect choice, try again."
read (*,*) item_choice_k,item_choice_i
enddo
print*,"how much do you want to buy/sell (positive for buy and negative for sell)?"
read (*,'(i10)',iostat=exchange_error) exchange_ammount !puts error associated with non integr in exchange_error, where 0 is non-error
do while (exchange_error/=0)
print*,"incorrect choice, try again."
read (*,'(i10)',iostat=exchange_error) exchange_ammount
enddo
call buy_sell(buyer,buyer_size,1,energy,item_choice_k,item_choice_i,exchange_ammount)
print*,"now let the other buyers have their turn"
else if (choice_buy_sell=="no") then
print*,"now let the other buyers have their turn"
endif
call print_market(energy,k_size,i_size,buyer,buyer_size)
end subroutine user_buyer_interface
subroutine automated_buyers(energy,k_size,i_size,buyer,buyer_size)
integer,intent(in) :: k_size,i_size,buyer_size
integer,dimension(k_size,i_size) :: energy
integer,dimension(buyer_size) :: buyer
real :: k_real,i_real,buy_real !real variables to put in random generator
integer :: h,ran_k,ran_i,ran_buy !integers taken from real random values previous
do h=2,buyer_size
call random_number(k_real)
call random_number(i_real)
call random_number(buy_real)
ran_k=floor(k_real*11)
ran_i=floor(i_real*11)
ran_buy=-5+floor(buy_real*11)
call buy_sell(buyer,buyer_size,h,energy,ran_k,ran_i,ran_buy)
enddo
end subroutine automated_buyers
!end subroutines
program market
implicit none
integer,dimension(10,10) :: energy
integer,dimension(10) :: buyer
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
integer :: k_size=size(energy(:,1)),i_size=size(energy(1,:)),buyer_size=size(buyer) !setup the size variables in the definition
do k=1,k_size
do i=1,i_size
energy(k,i)= 1 !setting up an array representing a market, putting in initial values
enddo
enddo
do l=1,buyer_size
buyer(l)=0
enddo
do period=1,10
call print_market(energy,k_size,i_size,buyer,buyer_size)
call user_buyer_interface(energy,k_size,i_size,buyer,buyer_size)
call automated_buyers(energy,k_size,i_size,buyer,buyer_size)
enddo
end program market
运行该程序时,应询问是否要买入/卖出,从哪里买入/卖出以及卖出多少,并应显示本轮买入的细节。但是,当程序运行时,在能量阵列的任一维度的选择中输入1,就会出现分割错误。如有任何帮助,我们将不胜感激。
您正在越界访问数组。这是导致此错误的最常见原因之一,所有编译器都有标志,可以自动为您检测问题,并指出问题发生的位置。我强烈建议你用自己的编译器学习如何做到这一点,如果你开始编程,它可以为你节省几个月的生命,而且在测试你的程序时,它将有助于发现可能未被发现的错误。以下是如何使用gfortran-神奇的标志是-fcheck=all:
ian@eris:~/work/stackoverflow$ gfortran -O -Wall -Wextra -fcheck=all -std=f2003 -g m.f90
m.f90:42:17:
integer :: period,item_choice_k,item_choice_i,exchange_ammount,exchange_error,buyer1
1
Warning: Unused variable ‘period’ declared at (1) [-Wunused-variable]
m.f90:108:68:
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
1
Warning: Unused variable ‘exchange_ammount’ declared at (1) [-Wunused-variable]
m.f90:108:83:
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
1
Warning: Unused variable ‘exchange_error’ declared at (1) [-Wunused-variable]
m.f90:108:51:
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
1
Warning: Unused variable ‘item_choice_i’ declared at (1) [-Wunused-variable]
m.f90:108:37:
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
1
Warning: Unused variable ‘item_choice_k’ declared at (1) [-Wunused-variable]
ian@eris:~/work/stackoverflow$ gfortran -O -Wall -Wextra -fcheck=all -std=f2003 -g m.f90
m.f90:42:17:
integer :: period,item_choice_k,item_choice_i,exchange_ammount,exchange_error,buyer1
1
Warning: Unused variable ‘period’ declared at (1) [-Wunused-variable]
m.f90:108:68:
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
1
Warning: Unused variable ‘exchange_ammount’ declared at (1) [-Wunused-variable]
m.f90:108:83:
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
1
Warning: Unused variable ‘exchange_error’ declared at (1) [-Wunused-variable]
m.f90:108:51:
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
1
Warning: Unused variable ‘item_choice_i’ declared at (1) [-Wunused-variable]
m.f90:108:37:
integer :: period,k,i,l,item_choice_k,item_choice_i,exchange_ammount,exchange_error
1
Warning: Unused variable ‘item_choice_k’ declared at (1) [-Wunused-variable]
ian@eris:~/work/stackoverflow$ ./a.out
the value of energy( 1 1 ) is 1
the value of energy( 1 2 ) is 1
the value of energy( 1 3 ) is 1
the value of energy( 1 4 ) is 1
the value of energy( 1 5 ) is 1
the value of energy( 1 6 ) is 1
the value of energy( 1 7 ) is 1
the value of energy( 1 8 ) is 1
the value of energy( 1 9 ) is 1
the value of energy( 1 10 ) is 1
the value of energy( 2 1 ) is 1
the value of energy( 2 2 ) is 1
the value of energy( 2 3 ) is 1
the value of energy( 2 4 ) is 1
the value of energy( 2 5 ) is 1
the value of energy( 2 6 ) is 1
the value of energy( 2 7 ) is 1
the value of energy( 2 8 ) is 1
the value of energy( 2 9 ) is 1
the value of energy( 2 10 ) is 1
the value of energy( 3 1 ) is 1
the value of energy( 3 2 ) is 1
the value of energy( 3 3 ) is 1
the value of energy( 3 4 ) is 1
the value of energy( 3 5 ) is 1
the value of energy( 3 6 ) is 1
the value of energy( 3 7 ) is 1
the value of energy( 3 8 ) is 1
the value of energy( 3 9 ) is 1
the value of energy( 3 10 ) is 1
the value of energy( 4 1 ) is 1
the value of energy( 4 2 ) is 1
the value of energy( 4 3 ) is 1
the value of energy( 4 4 ) is 1
the value of energy( 4 5 ) is 1
the value of energy( 4 6 ) is 1
the value of energy( 4 7 ) is 1
the value of energy( 4 8 ) is 1
the value of energy( 4 9 ) is 1
the value of energy( 4 10 ) is 1
the value of energy( 5 1 ) is 1
the value of energy( 5 2 ) is 1
the value of energy( 5 3 ) is 1
the value of energy( 5 4 ) is 1
the value of energy( 5 5 ) is 1
the value of energy( 5 6 ) is 1
the value of energy( 5 7 ) is 1
the value of energy( 5 8 ) is 1
the value of energy( 5 9 ) is 1
the value of energy( 5 10 ) is 1
the value of energy( 6 1 ) is 1
the value of energy( 6 2 ) is 1
the value of energy( 6 3 ) is 1
the value of energy( 6 4 ) is 1
the value of energy( 6 5 ) is 1
the value of energy( 6 6 ) is 1
the value of energy( 6 7 ) is 1
the value of energy( 6 8 ) is 1
the value of energy( 6 9 ) is 1
the value of energy( 6 10 ) is 1
the value of energy( 7 1 ) is 1
the value of energy( 7 2 ) is 1
the value of energy( 7 3 ) is 1
the value of energy( 7 4 ) is 1
the value of energy( 7 5 ) is 1
the value of energy( 7 6 ) is 1
the value of energy( 7 7 ) is 1
the value of energy( 7 8 ) is 1
the value of energy( 7 9 ) is 1
the value of energy( 7 10 ) is 1
the value of energy( 8 1 ) is 1
the value of energy( 8 2 ) is 1
the value of energy( 8 3 ) is 1
the value of energy( 8 4 ) is 1
the value of energy( 8 5 ) is 1
the value of energy( 8 6 ) is 1
the value of energy( 8 7 ) is 1
the value of energy( 8 8 ) is 1
the value of energy( 8 9 ) is 1
the value of energy( 8 10 ) is 1
the value of energy( 9 1 ) is 1
the value of energy( 9 2 ) is 1
the value of energy( 9 3 ) is 1
the value of energy( 9 4 ) is 1
the value of energy( 9 5 ) is 1
the value of energy( 9 6 ) is 1
the value of energy( 9 7 ) is 1
the value of energy( 9 8 ) is 1
the value of energy( 9 9 ) is 1
the value of energy( 9 10 ) is 1
the value of energy( 10 1 ) is 1
the value of energy( 10 2 ) is 1
the value of energy( 10 3 ) is 1
the value of energy( 10 4 ) is 1
the value of energy( 10 5 ) is 1
the value of energy( 10 6 ) is 1
the value of energy( 10 7 ) is 1
the value of energy( 10 8 ) is 1
the value of energy( 10 9 ) is 1
the value of energy( 10 10 ) is 1
Buyer 1 has 0 energy units (user)
Buyer 2 has 0 energy units
Buyer 3 has 0 energy units
Buyer 4 has 0 energy units
Buyer 5 has 0 energy units
Buyer 6 has 0 energy units
Buyer 7 has 0 energy units
Buyer 8 has 0 energy units
Buyer 9 has 0 energy units
Buyer 10 has 0 energy units
do you want to buy/sell this round?
yes
where would you like to buy/sell from/into (enter first number between 1 and 10 and second number between 1 and 10 )
1
10
how much do you want to buy/sell (positive for buy and negative for sell)?
1
now let the other buyers have their turn
the value of energy( 1 1 ) is 1
the value of energy( 1 2 ) is 1
the value of energy( 1 3 ) is 1
the value of energy( 1 4 ) is 1
the value of energy( 1 5 ) is 1
the value of energy( 1 6 ) is 1
the value of energy( 1 7 ) is 1
the value of energy( 1 8 ) is 1
the value of energy( 1 9 ) is 1
the value of energy( 1 10 ) is 0
the value of energy( 2 1 ) is 1
the value of energy( 2 2 ) is 1
the value of energy( 2 3 ) is 1
the value of energy( 2 4 ) is 1
the value of energy( 2 5 ) is 1
the value of energy( 2 6 ) is 1
the value of energy( 2 7 ) is 1
the value of energy( 2 8 ) is 1
the value of energy( 2 9 ) is 1
the value of energy( 2 10 ) is 1
the value of energy( 3 1 ) is 1
the value of energy( 3 2 ) is 1
the value of energy( 3 3 ) is 1
the value of energy( 3 4 ) is 1
the value of energy( 3 5 ) is 1
the value of energy( 3 6 ) is 1
the value of energy( 3 7 ) is 1
the value of energy( 3 8 ) is 1
the value of energy( 3 9 ) is 1
the value of energy( 3 10 ) is 1
the value of energy( 4 1 ) is 1
the value of energy( 4 2 ) is 1
the value of energy( 4 3 ) is 1
the value of energy( 4 4 ) is 1
the value of energy( 4 5 ) is 1
the value of energy( 4 6 ) is 1
the value of energy( 4 7 ) is 1
the value of energy( 4 8 ) is 1
the value of energy( 4 9 ) is 1
the value of energy( 4 10 ) is 1
the value of energy( 5 1 ) is 1
the value of energy( 5 2 ) is 1
the value of energy( 5 3 ) is 1
the value of energy( 5 4 ) is 1
the value of energy( 5 5 ) is 1
the value of energy( 5 6 ) is 1
the value of energy( 5 7 ) is 1
the value of energy( 5 8 ) is 1
the value of energy( 5 9 ) is 1
the value of energy( 5 10 ) is 1
the value of energy( 6 1 ) is 1
the value of energy( 6 2 ) is 1
the value of energy( 6 3 ) is 1
the value of energy( 6 4 ) is 1
the value of energy( 6 5 ) is 1
the value of energy( 6 6 ) is 1
the value of energy( 6 7 ) is 1
the value of energy( 6 8 ) is 1
the value of energy( 6 9 ) is 1
the value of energy( 6 10 ) is 1
the value of energy( 7 1 ) is 1
the value of energy( 7 2 ) is 1
the value of energy( 7 3 ) is 1
the value of energy( 7 4 ) is 1
the value of energy( 7 5 ) is 1
the value of energy( 7 6 ) is 1
the value of energy( 7 7 ) is 1
the value of energy( 7 8 ) is 1
the value of energy( 7 9 ) is 1
the value of energy( 7 10 ) is 1
the value of energy( 8 1 ) is 1
the value of energy( 8 2 ) is 1
the value of energy( 8 3 ) is 1
the value of energy( 8 4 ) is 1
the value of energy( 8 5 ) is 1
the value of energy( 8 6 ) is 1
the value of energy( 8 7 ) is 1
the value of energy( 8 8 ) is 1
the value of energy( 8 9 ) is 1
the value of energy( 8 10 ) is 1
the value of energy( 9 1 ) is 1
the value of energy( 9 2 ) is 1
the value of energy( 9 3 ) is 1
the value of energy( 9 4 ) is 1
the value of energy( 9 5 ) is 1
the value of energy( 9 6 ) is 1
the value of energy( 9 7 ) is 1
the value of energy( 9 8 ) is 1
the value of energy( 9 9 ) is 1
the value of energy( 9 10 ) is 1
the value of energy( 10 1 ) is 1
the value of energy( 10 2 ) is 1
the value of energy( 10 3 ) is 1
the value of energy( 10 4 ) is 1
the value of energy( 10 5 ) is 1
the value of energy( 10 6 ) is 1
the value of energy( 10 7 ) is 1
the value of energy( 10 8 ) is 1
the value of energy( 10 9 ) is 1
the value of energy( 10 10 ) is 1
Buyer 1 has 1 energy units (user)
Buyer 2 has 0 energy units
Buyer 3 has 0 energy units
Buyer 4 has 0 energy units
Buyer 5 has 0 energy units
Buyer 6 has 0 energy units
Buyer 7 has 0 energy units
Buyer 8 has 0 energy units
Buyer 9 has 0 energy units
Buyer 10 has 0 energy units
At line 9 of file m.f90
Fortran runtime error: Index '0' of dimension 1 of array 'energy' below lower bound of 1
Error termination. Backtrace:
#0 0x7f0741dac2da in ???
#1 0x7f0741dacec5 in ???
#2 0x7f0741dad297 in ???
#3 0x559df7cde202 in buy_sell_
at /home/ian/work/stackoverflow/m.f90:9
#4 0x559df7cde36b in automated_buyers_
at /home/ian/work/stackoverflow/m.f90:92
#5 0x559df7cdec9d in market
at /home/ian/work/stackoverflow/m.f90:124
#6 0x559df7cdecde in main
at /home/ian/work/stackoverflow/m.f90:127
ian@eris:~/work/stackoverflow$
查看末尾的回溯
At line 9 of file m.f90
Fortran runtime error: Index '0' of dimension 1 of array 'energy' below lower bound of 1
Error termination. Backtrace:
#0 0x7f0741dac2da in ???
#1 0x7f0741dacec5 in ???
#2 0x7f0741dad297 in ???
#3 0x559df7cde202 in buy_sell_
at /home/ian/work/stackoverflow/m.f90:9
#4 0x559df7cde36b in automated_buyers_
at /home/ian/work/stackoverflow/m.f90:92
#5 0x559df7cdec9d in market
at /home/ian/work/stackoverflow/m.f90:124
#6 0x559df7cdecde in main
at /home/ian/work/stackoverflow/m.f90:127
您可以看到问题是当从automated_buyers调用buy_sell:时
subroutine automated_buyers(energy,k_size,i_size,buyer,buyer_size)
integer,intent(in) :: k_size,i_size,buyer_size
integer,dimension(k_size,i_size) :: energy
integer,dimension(buyer_size) :: buyer
real :: k_real,i_real,buy_real !real variables to put in random generator
integer :: h,ran_k,ran_i,ran_buy !integers taken from real random values previous
do h=2,buyer_size
call random_number(k_real)
call random_number(i_real)
call random_number(buy_real)
ran_k=floor(k_real*11)
ran_i=floor(i_real*11)
ran_buy=-5+floor(buy_real*11)
call buy_sell(buyer,buyer_size,h,energy,ran_k,ran_i,ran_buy)
enddo
end subroutine automated_buyers
这表明了问题所在,如果k_real中的随机数小于1/11,则ran_k可以取值0。你可能想要的是
ran_k = Int( k_real * 10 ) + 1
请学习运行时检查,它们会让你的生活更轻松,学习使用调试器也会更轻松。但请注意,它们会减慢程序的速度,因此,虽然您应该在开发和调试代码时使用它们,但一旦您确定不再有错误(哈!),您就应该在没有它们的情况下重新编译,因为这样您的程序会运行得更快。