假如有两个矩阵相加,如果维数不等,势必不成功,那么大家有什么好办法使程序报出错误呢?(最好的方法将得到100分!)

时间:2021-01-28 14:40:39
谢谢!
我想应该是个类来实现报错机制,不过没想到比较好的解决方法,谢谢!

19 个解决方案

#1


采用异常机制exception

#2


assert

#3


UP

#4


采用exception。

#5


总觉得异常不是个好的解决方法。

#6


别人的解决方法 :
      subroutine error(n)
c     -------------------------
c     error display and handling
c     n : the error number
c!
c     Copyright INRIA
      integer n
      include '../stack.h'

      integer num,imess,imode,errtyp,lct1
      logical trace
c
      call errmds(num,imess,imode)
      trace=.not.((num.lt.0.or.num.eq.n).and.imess.ne.0)
c
c     de-activate output control
      lct1=lct(1)
      lct(1)=0
c
      errtyp=0
      if(err1.eq.0.and.err2.eq.0) then
c     . locate the error in the current statement
        if(trace) call errloc(n)
c     . output error message
        if(.not.trace) lct(1)=-1
        call errmsg(n,errtyp)
        lct(1)=0
      endif
c
c     handle the error
      call errmgr(n,errtyp)
c
c     re-activate output control
      lct(1)=lct1
c
      return
      end

      subroutine errmgr(n,errtyp)
c     -------------------------
c     this routines handle errors: recursion stack cleaning, error
c     recovery, display of calling tree
c     n      : the error number
c     errtyp : error type (recoverable:0 or not:1)
c!
      include '../stack.h'
      integer errtyp,n
c
      integer sadr
c
      integer num,imess,imode,lunit
      integer l1,ilk,m,lk,km,k,ll,r,p,mode(2),lpts(6),pt0
      logical first,trace,pflag,erecmode
c
c      sadr(l)=(l/2)+1
c
      ll=lct(5)
      first=.true.
      lunit=wte
c
      call errmds(num,imess,imode)
      trace=.not.((num.lt.0.or.num.eq.n).and.imess.ne.0)
c
      erecmode=(num.eq.n.or.num.lt.0).and.imode.ne.0.and.imode.ne.3
c     
      pt0=0
      if(pt.le.pt0) goto 50
      if(erecmode) then
c     error recovery mode
         p=pt+1
c        . looking if error has occurred in execstr deff getf or comp
 20      p=p-1
         if(p.le.errpt) then
            pt0=pt
            goto 50
         endif
         if(rstk(p).eq.1001) then
c     .     error has occurred in an external
            errtyp=0
            pt0=p
         elseif(rstk(p).eq.502) then 
            if(rstk(p-1).eq.903) then
c     .     error has occurred in execstr
               errtyp=0
               pt0=p
            elseif(rstk(p-1).eq.904.or.rstk(p-1).eq.901) then
c     .     error has occurred in comp
               errtyp=0
               pt0=p
            else
               goto 20
            endif
         else
            goto 20
         endif
      endif


 30   continue
c
c depilement de l'environnement
      lct(4)=2
      pt=pt+1
 35   pt=pt-1
      if(pt.eq.pt0) goto 50
      r=rstk(pt)
      goto(36,36,37) r-500
      if(r.eq.904) then
         if (ids(2,pt).ne.0) then
c     .     getf(  'c') case, close the file
            mode(1)=0
            call clunit(-ids(2,pt),buf,mode)
         endif
      endif
      goto 35
c     
c     on depile une fonction
 36   call depfun(lunit,trace,first)
      goto 35
c     
c     on depile un exec ou une pause
 37   call depexec(lunit,trace,first,pflag)
      if(.not.pflag) goto 35
c     
 50   continue
      if(erecmode) then
         if(errtyp.eq.0) then
c     .     recoverable error
            top=toperr
            if(err2.eq.0) then
               err1=n
            else
               err1=err2
            endif
            err=0
         else
            comp(1)=0
            comp(3)=0
            err=n
         endif
      else
         comp(1)=0
         comp(3)=0
         err=n
      endif
      if(trace) call basout(io,lunit,' ')
c     
      return
      end

      subroutine errmsg(n,errtyp)
c     -------------------------
c     this routine displays the error message and set if the error is
c     recoverable by errcatch or not:
c     errtyp=0  : recoverable error
c     errtyp=1  : unrecoverable error
c
c     n : error number, if n execeeds the maximum error number this
c         routines displays the error message contained in buf
c!
      include '../stack.h'
      integer n,errtyp
      integer lunit,sadr,nl,io
      character line*340
c
c      sadr(l)=(l/2)+1
c
      ll=lct(5)
      lunit=wte
      errtyp=0
c
      call freemsgtable()
      call errstore(n)
      goto (
     +   1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
     +  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
     +  31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
     +  46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
     +  61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
     +  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
     +  91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,
     + 106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,
     + 121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
     + 136,137,138,139,140,141,142,143
     + ),n

      goto (
     +     200,201,202,203,204,205,206,207,208,209,
     +     210,211,212,213,214,215,216,217,218,219,
     +     220,221,222,223,224,225,226,227,228,229,
     +     230,231,232,233,234,235,236,237,238,239,
     +     240,241,242,243,244,245,246,247,248,249,
     +     250,251,252,253,254,255,256,257,258,259,
     +     260,261,262,263,264,265,266,267,268,269,
     +     270,271,272,273,274,275,276,277,278,279,
     +     280),n-199
      if(n.ge.10000) return
      goto 998
c
    1 call msgout(io,lunit,'incorrect assignment')
      go to 999
    2 call msgout(io,lunit,'invalid factor')
      errtyp=1
      go to 999
    3 call msgout(io,lunit,'waiting for right parenthesis')
      errtyp=1
      go to 999
    4 call cvname(ids(1,pt+1),buf,1)
      call msgout(io,lunit,'undefined variable : '//buf(1:nlgh))
      go to 999
    5 call msgout(io,lunit,'inconsistent column/row dimensions')
      go to 999
    6 call msgout(io,lunit,'inconsistent row/column dimensions')
      go to 999
    7 continue
      call msgout(io,lunit,
     $     'dot cannot be used as modifier for this operator')
      go to 999
    8 call msgout(io,lunit,'inconsistent addition')
      go to 999
    9 call msgout(io,lunit,'inconsistent subtraction')
      go to 999
 ... ...

C++用什么方法比较好呢?

#7


template<typename T,int M,int N>
class Matrix
{
  ...
}

其中T是矩阵中元素的类型,M、N作维。
然后重载operator + 就行了。

当你实例化Matrix的时候,只有T、M、N分别相同两个specification才算相同,以便相加。
这样就可以在编译期阻止这种行为,从而避免exception了。

#8


看大家的意思就只有编译期间阻止这种行为了。
其实我是想如果出错了,怎么返回错误信息?
这对跟踪来说不错的。可惜没想到好方法。
继续期待...

#9


解决方法:
1、assert(m==n),在矩阵相加时先保证维数相等。
2、exception,在矩阵相加前先判断维数是否相等,然后抛出异常,if(m!=n) throw string("m!=n");
3、矩阵相加前判断维数是否相等,不等则跳出程序,if(m!=n) abort().

建议用第二种exception异常方法。因为当程序无法正常进行时,比如矩阵维数不等不能正常运行时,程序为跳回到主调用程序,而被调用函数也就是矩阵相加函数根本不知道有过异常抛出,因此可以在主调用函数中修正此异常,使程序能顺利的运行。

#10


楼主觉得异常哪里不好?尽管使用上有些不便

#11


需要在每次用到代码的地方用try{...}catch{}来捕获, 其实我是想有错误显示出来,让客户知道哪里有错误了,不用修复.
觉得用异常比较别扭.

别人用C都能实现的功能,用C++反而觉得感觉有点奇怪!
用异常对程序的速度是否也是个考验呢?

#12


错误显示出来,在catch子块加cerr不行吗?

#13


不明白,为什么不能相加的两个东西要让他在运行时出错.

其实,在编译时期很容易发现这个错误的呀.

#14


学习,帮顶,楼主给点分我就能提高。^!^

#15


用assert(..);
或者用if - else

#16


楼上的方法不妥.

#17


请楼猪给点分,顶死楼猪.......
UP UP UP

#18


我认为目前 showlie(想长膘的小猪……)  的方法最好, 如果各位今天晚上没有新的方法提出来,那么我就发飙了~~~~~~~~~~~~

#19


如果大家没有异议, 100分就全归 showlie(想长膘的小猪……)  了.

#1


采用异常机制exception

#2


assert

#3


UP

#4


采用exception。

#5


总觉得异常不是个好的解决方法。

#6


别人的解决方法 :
      subroutine error(n)
c     -------------------------
c     error display and handling
c     n : the error number
c!
c     Copyright INRIA
      integer n
      include '../stack.h'

      integer num,imess,imode,errtyp,lct1
      logical trace
c
      call errmds(num,imess,imode)
      trace=.not.((num.lt.0.or.num.eq.n).and.imess.ne.0)
c
c     de-activate output control
      lct1=lct(1)
      lct(1)=0
c
      errtyp=0
      if(err1.eq.0.and.err2.eq.0) then
c     . locate the error in the current statement
        if(trace) call errloc(n)
c     . output error message
        if(.not.trace) lct(1)=-1
        call errmsg(n,errtyp)
        lct(1)=0
      endif
c
c     handle the error
      call errmgr(n,errtyp)
c
c     re-activate output control
      lct(1)=lct1
c
      return
      end

      subroutine errmgr(n,errtyp)
c     -------------------------
c     this routines handle errors: recursion stack cleaning, error
c     recovery, display of calling tree
c     n      : the error number
c     errtyp : error type (recoverable:0 or not:1)
c!
      include '../stack.h'
      integer errtyp,n
c
      integer sadr
c
      integer num,imess,imode,lunit
      integer l1,ilk,m,lk,km,k,ll,r,p,mode(2),lpts(6),pt0
      logical first,trace,pflag,erecmode
c
c      sadr(l)=(l/2)+1
c
      ll=lct(5)
      first=.true.
      lunit=wte
c
      call errmds(num,imess,imode)
      trace=.not.((num.lt.0.or.num.eq.n).and.imess.ne.0)
c
      erecmode=(num.eq.n.or.num.lt.0).and.imode.ne.0.and.imode.ne.3
c     
      pt0=0
      if(pt.le.pt0) goto 50
      if(erecmode) then
c     error recovery mode
         p=pt+1
c        . looking if error has occurred in execstr deff getf or comp
 20      p=p-1
         if(p.le.errpt) then
            pt0=pt
            goto 50
         endif
         if(rstk(p).eq.1001) then
c     .     error has occurred in an external
            errtyp=0
            pt0=p
         elseif(rstk(p).eq.502) then 
            if(rstk(p-1).eq.903) then
c     .     error has occurred in execstr
               errtyp=0
               pt0=p
            elseif(rstk(p-1).eq.904.or.rstk(p-1).eq.901) then
c     .     error has occurred in comp
               errtyp=0
               pt0=p
            else
               goto 20
            endif
         else
            goto 20
         endif
      endif


 30   continue
c
c depilement de l'environnement
      lct(4)=2
      pt=pt+1
 35   pt=pt-1
      if(pt.eq.pt0) goto 50
      r=rstk(pt)
      goto(36,36,37) r-500
      if(r.eq.904) then
         if (ids(2,pt).ne.0) then
c     .     getf(  'c') case, close the file
            mode(1)=0
            call clunit(-ids(2,pt),buf,mode)
         endif
      endif
      goto 35
c     
c     on depile une fonction
 36   call depfun(lunit,trace,first)
      goto 35
c     
c     on depile un exec ou une pause
 37   call depexec(lunit,trace,first,pflag)
      if(.not.pflag) goto 35
c     
 50   continue
      if(erecmode) then
         if(errtyp.eq.0) then
c     .     recoverable error
            top=toperr
            if(err2.eq.0) then
               err1=n
            else
               err1=err2
            endif
            err=0
         else
            comp(1)=0
            comp(3)=0
            err=n
         endif
      else
         comp(1)=0
         comp(3)=0
         err=n
      endif
      if(trace) call basout(io,lunit,' ')
c     
      return
      end

      subroutine errmsg(n,errtyp)
c     -------------------------
c     this routine displays the error message and set if the error is
c     recoverable by errcatch or not:
c     errtyp=0  : recoverable error
c     errtyp=1  : unrecoverable error
c
c     n : error number, if n execeeds the maximum error number this
c         routines displays the error message contained in buf
c!
      include '../stack.h'
      integer n,errtyp
      integer lunit,sadr,nl,io
      character line*340
c
c      sadr(l)=(l/2)+1
c
      ll=lct(5)
      lunit=wte
      errtyp=0
c
      call freemsgtable()
      call errstore(n)
      goto (
     +   1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
     +  16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
     +  31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
     +  46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
     +  61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
     +  76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
     +  91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,
     + 106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,
     + 121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
     + 136,137,138,139,140,141,142,143
     + ),n

      goto (
     +     200,201,202,203,204,205,206,207,208,209,
     +     210,211,212,213,214,215,216,217,218,219,
     +     220,221,222,223,224,225,226,227,228,229,
     +     230,231,232,233,234,235,236,237,238,239,
     +     240,241,242,243,244,245,246,247,248,249,
     +     250,251,252,253,254,255,256,257,258,259,
     +     260,261,262,263,264,265,266,267,268,269,
     +     270,271,272,273,274,275,276,277,278,279,
     +     280),n-199
      if(n.ge.10000) return
      goto 998
c
    1 call msgout(io,lunit,'incorrect assignment')
      go to 999
    2 call msgout(io,lunit,'invalid factor')
      errtyp=1
      go to 999
    3 call msgout(io,lunit,'waiting for right parenthesis')
      errtyp=1
      go to 999
    4 call cvname(ids(1,pt+1),buf,1)
      call msgout(io,lunit,'undefined variable : '//buf(1:nlgh))
      go to 999
    5 call msgout(io,lunit,'inconsistent column/row dimensions')
      go to 999
    6 call msgout(io,lunit,'inconsistent row/column dimensions')
      go to 999
    7 continue
      call msgout(io,lunit,
     $     'dot cannot be used as modifier for this operator')
      go to 999
    8 call msgout(io,lunit,'inconsistent addition')
      go to 999
    9 call msgout(io,lunit,'inconsistent subtraction')
      go to 999
 ... ...

C++用什么方法比较好呢?

#7


template<typename T,int M,int N>
class Matrix
{
  ...
}

其中T是矩阵中元素的类型,M、N作维。
然后重载operator + 就行了。

当你实例化Matrix的时候,只有T、M、N分别相同两个specification才算相同,以便相加。
这样就可以在编译期阻止这种行为,从而避免exception了。

#8


看大家的意思就只有编译期间阻止这种行为了。
其实我是想如果出错了,怎么返回错误信息?
这对跟踪来说不错的。可惜没想到好方法。
继续期待...

#9


解决方法:
1、assert(m==n),在矩阵相加时先保证维数相等。
2、exception,在矩阵相加前先判断维数是否相等,然后抛出异常,if(m!=n) throw string("m!=n");
3、矩阵相加前判断维数是否相等,不等则跳出程序,if(m!=n) abort().

建议用第二种exception异常方法。因为当程序无法正常进行时,比如矩阵维数不等不能正常运行时,程序为跳回到主调用程序,而被调用函数也就是矩阵相加函数根本不知道有过异常抛出,因此可以在主调用函数中修正此异常,使程序能顺利的运行。

#10


楼主觉得异常哪里不好?尽管使用上有些不便

#11


需要在每次用到代码的地方用try{...}catch{}来捕获, 其实我是想有错误显示出来,让客户知道哪里有错误了,不用修复.
觉得用异常比较别扭.

别人用C都能实现的功能,用C++反而觉得感觉有点奇怪!
用异常对程序的速度是否也是个考验呢?

#12


错误显示出来,在catch子块加cerr不行吗?

#13


不明白,为什么不能相加的两个东西要让他在运行时出错.

其实,在编译时期很容易发现这个错误的呀.

#14


学习,帮顶,楼主给点分我就能提高。^!^

#15


用assert(..);
或者用if - else

#16


楼上的方法不妥.

#17


请楼猪给点分,顶死楼猪.......
UP UP UP

#18


我认为目前 showlie(想长膘的小猪……)  的方法最好, 如果各位今天晚上没有新的方法提出来,那么我就发飙了~~~~~~~~~~~~

#19


如果大家没有异议, 100分就全归 showlie(想长膘的小猪……)  了.

#20