diff --git a/404.html b/404.html index 22f126c..4db8345 100644 --- a/404.html +++ b/404.html @@ -85,7 +85,7 @@ diff --git a/ch01-00-getting-started.html b/ch01-00-getting-started.html index b690202..718c626 100644 --- a/ch01-00-getting-started.html +++ b/ch01-00-getting-started.html @@ -84,7 +84,7 @@ diff --git a/ch01-01-install-compiler.html b/ch01-01-install-compiler.html index ec548f0..c08d1f6 100644 --- a/ch01-01-install-compiler.html +++ b/ch01-01-install-compiler.html @@ -84,7 +84,7 @@ diff --git a/ch01-02-gfortran.html b/ch01-02-gfortran.html index 1510369..761e810 100644 --- a/ch01-02-gfortran.html +++ b/ch01-02-gfortran.html @@ -84,7 +84,7 @@ diff --git a/ch01-03-fpm.html b/ch01-03-fpm.html index 8150180..180ce51 100644 --- a/ch01-03-fpm.html +++ b/ch01-03-fpm.html @@ -84,7 +84,7 @@ diff --git a/ch02-00-first-fortran.html b/ch02-00-first-fortran.html index f5d837c..cdd7b14 100644 --- a/ch02-00-first-fortran.html +++ b/ch02-00-first-fortran.html @@ -84,7 +84,7 @@ diff --git a/ch02-01-program-unit.html b/ch02-01-program-unit.html index 4a64008..a8bb4e1 100644 --- a/ch02-01-program-unit.html +++ b/ch02-01-program-unit.html @@ -84,7 +84,7 @@ diff --git a/ch03-00-declaration.html b/ch03-00-declaration.html index b991748..2497d1e 100644 --- a/ch03-00-declaration.html +++ b/ch03-00-declaration.html @@ -84,7 +84,7 @@ diff --git a/ch03-01-precision.html b/ch03-01-precision.html index 2b43fa3..9bc966b 100644 --- a/ch03-01-precision.html +++ b/ch03-01-precision.html @@ -84,7 +84,7 @@ diff --git a/ch03-02-operation.html b/ch03-02-operation.html index 2b233f5..327baf4 100644 --- a/ch03-02-operation.html +++ b/ch03-02-operation.html @@ -84,7 +84,7 @@ diff --git a/ch03-03-array.html b/ch03-03-array.html index bcfc4ae..6e1b538 100644 --- a/ch03-03-array.html +++ b/ch03-03-array.html @@ -84,7 +84,7 @@ diff --git a/ch03-04-character-array.html b/ch03-04-character-array.html index 72c369f..ac0fc4b 100644 --- a/ch03-04-character-array.html +++ b/ch03-04-character-array.html @@ -84,7 +84,7 @@ diff --git a/ch04-00-if.html b/ch04-00-if.html index 849d642..d05d9b0 100644 --- a/ch04-00-if.html +++ b/ch04-00-if.html @@ -84,7 +84,7 @@ diff --git a/ch04-01-select.html b/ch04-01-select.html index cc43f84..1d5f3d2 100644 --- a/ch04-01-select.html +++ b/ch04-01-select.html @@ -84,7 +84,7 @@ diff --git a/ch04-02-do.html b/ch04-02-do.html index 0fac5f8..33ba98a 100644 --- a/ch04-02-do.html +++ b/ch04-02-do.html @@ -84,7 +84,7 @@ diff --git a/ch04-03-do-array.html b/ch04-03-do-array.html index c148253..94fcc36 100644 --- a/ch04-03-do-array.html +++ b/ch04-03-do-array.html @@ -84,7 +84,7 @@ diff --git a/ch05-00-function.html b/ch05-00-function.html index e12ebdf..fa99c0b 100644 --- a/ch05-00-function.html +++ b/ch05-00-function.html @@ -84,7 +84,7 @@ diff --git a/ch05-01-subroutine.html b/ch05-01-subroutine.html index d88b25f..7dcb47e 100644 --- a/ch05-01-subroutine.html +++ b/ch05-01-subroutine.html @@ -84,7 +84,7 @@ diff --git a/ch05-02-funckeyword.html b/ch05-02-funckeyword.html index 3b0a001..64574db 100644 --- a/ch05-02-funckeyword.html +++ b/ch05-02-funckeyword.html @@ -84,7 +84,7 @@ diff --git a/ch05-03-callback.html b/ch05-03-callback.html index a2c4dcc..d9ad9ea 100644 --- a/ch05-03-callback.html +++ b/ch05-03-callback.html @@ -84,7 +84,7 @@ diff --git a/ch05-04-module.html b/ch05-04-module.html index e1a6b1c..4f2a85c 100644 --- a/ch05-04-module.html +++ b/ch05-04-module.html @@ -84,7 +84,7 @@ diff --git a/ch05-05-overload.html b/ch05-05-overload.html index 1c5cd6f..c4bde31 100644 --- a/ch05-05-overload.html +++ b/ch05-05-overload.html @@ -84,7 +84,7 @@ diff --git a/ch06-00-file.html b/ch06-00-file.html index 5cde779..8055e83 100644 --- a/ch06-00-file.html +++ b/ch06-00-file.html @@ -84,7 +84,7 @@ diff --git a/ch06-01-format.html b/ch06-01-format.html index bc0d3da..20c218f 100644 --- a/ch06-01-format.html +++ b/ch06-01-format.html @@ -84,7 +84,7 @@ diff --git a/ch07-00-type.html b/ch07-00-type.html index 50405ab..0c84366 100644 --- a/ch07-00-type.html +++ b/ch07-00-type.html @@ -84,7 +84,7 @@ diff --git a/ch07-01-procbind.html b/ch07-01-procbind.html index f23f497..e8c12ae 100644 --- a/ch07-01-procbind.html +++ b/ch07-01-procbind.html @@ -84,7 +84,7 @@ diff --git a/ch07-02-typeoverload.html b/ch07-02-typeoverload.html index d6800bf..61b65e5 100644 --- a/ch07-02-typeoverload.html +++ b/ch07-02-typeoverload.html @@ -84,7 +84,7 @@ diff --git a/ch08-00-pointer.html b/ch08-00-pointer.html index c288e3e..d73ac51 100644 --- a/ch08-00-pointer.html +++ b/ch08-00-pointer.html @@ -84,7 +84,7 @@ diff --git a/ch08-01-memory.html b/ch08-01-memory.html index 6d944e0..4b71d6f 100644 --- a/ch08-01-memory.html +++ b/ch08-01-memory.html @@ -84,7 +84,7 @@ @@ -186,7 +186,7 @@

内存安全 - @@ -200,7 +200,7 @@

内存安全 - diff --git a/ch08-02-procpointer.html b/ch08-02-procpointer.html new file mode 100644 index 0000000..44c174d --- /dev/null +++ b/ch08-02-procpointer.html @@ -0,0 +1,287 @@ + + + + + + 过程指针 - 现代Fortran程序设计 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + +
+
+

过程指针

+

指针也可以指向过程,这时候需要先声明指针的接口,用于限制指针的类型,也就是在之前的章节中我们提到的abstract interface

+
module proc_pointer_mod
+    implicit none
+    abstract interface
+        real(8) function func1d(x) result(res)
+            real(8),intent(in)::x
+        end function func1d
+    end interface
+contains
+    real(8) function mysin(x) result(res)
+        real(8),intent(in)::x
+        res=sin(x)
+    end function mysin
+    real(8) function myexp(x) result(res)
+        real(8),intent(in)::x
+        res=exp(x)
+    end function myexp
+    real(8) function mycos(x) result(res)
+        real(8),intent(in)::x
+        res=cos(x)
+    end function mycos
+end module proc_pointer_mod
+
+program main
+    use proc_pointer_mod
+    implicit none
+    procedure(func1d),pointer::ptr=>null()
+    ptr=>mysin
+    write(*,*)ptr(1.0_8)
+    ptr=>myexp
+    write(*,*)ptr(1.0_8)
+    ptr=>mycos
+    write(*,*)ptr(1.0_8)
+end program main
+
+
    +
  • 不能使用过程指针指向通用函数名。由于Fortran的内置函数都是经过重载的通用函数,所以也不能用过程指针指向内置函数
  • +
+

如果定义一个过程指针数组,则需要使用到自定义类型,同时也要指定nopass关键字,用来表示不需要绑定该类型作为第一个虚参传递。

+
module proc_pointer_mod
+    implicit none
+    abstract interface
+        real(8) function func1d(x) result(res)
+            real(8),intent(in)::x
+        end function func1d
+    end interface
+    type ptrfunc
+        procedure(func1d),pointer,nopass::ptr
+    end type ptrfunc
+contains
+    real(8) function mysin(x) result(res)
+        real(8),intent(in)::x
+        res=sin(x)
+    end function mysin
+    real(8) function myexp(x) result(res)
+        real(8),intent(in)::x
+        res=exp(x)
+    end function myexp
+    real(8) function mycos(x) result(res)
+        real(8),intent(in)::x
+        res=cos(x)
+    end function mycos
+end module proc_pointer_mod
+
+program main
+    use proc_pointer_mod
+    implicit none
+    type(ptrfunc)::a(3)
+    integer::i
+    a(1)%ptr=>mysin
+    a(2)%ptr=>myexp
+    a(3)%ptr=>mycos
+    write(*,*)(a(i)%ptr(1.0_8),i=1,3) !此处使用隐式循环输出
+end program main
+
+
    +
  • 使用过程指针后,一些操作需要转向运行时确定,所以编译器无法进行更加激进的优化(内联inline),代码的运行速度有可能会降低。
  • +
+

习题

+
    +
  • 思考为什么不使用procedure(func1d),pointer::ptr(:)来定义过程指针数组
  • +
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + diff --git a/index.html b/index.html index 4046f08..9846cab 100644 --- a/index.html +++ b/index.html @@ -84,7 +84,7 @@ diff --git a/mdbook-cheat-sheet.html b/mdbook-cheat-sheet.html index 394f569..59152f1 100644 --- a/mdbook-cheat-sheet.html +++ b/mdbook-cheat-sheet.html @@ -84,7 +84,7 @@ @@ -181,7 +181,7 @@

数学公式 - @@ -192,7 +192,7 @@

数学公式