*Fortran [#pbb06ff1]

-[[Fortran Wiki:http://fortranwiki.org/]]
--[[Fortran 2008 status:http://fortranwiki.org/fortran/show/Fortran+2008+status]]
--[[Fortran 2003 status:http://fortranwiki.org/fortran/show/Fortran+2003+status]]
-[[Fortran入門:http://www.nag-j.co.jp/fortran/]]
-[[Fortran 2003入門:http://www.nag-j.co.jp/fortran/fortran2003/]]
-[[インテル® Fortran Composer XE 2013 Linux* 版入門:http://nf.nci.org.au/facilities/software/intel-ct/13.5.192/Documentation/ja_JP/get_started_lf.htm]]
-[[インテル® Fortran コンパイラー XE 13.0 ユーザー・リファレンス・ガイド:http://nf.nci.org.au/facilities/software/intel-ct/13.5.192/Documentation/ja_JP/compiler_f/main_for/index.htm]]
-http://pic.dhe.ibm.com/infocenter/lnxpcomp/v121v141/index.jsp
-[[Cray Fortran Reference Manual:http://docs.cray.com/books/S-3901-81/]]
-[[Fortran2003のページ:http://www.geocities.jp/wjtcx143/fortran.html]]
-[[Tagged "Fortran2003" | ドウジンテイスウ.log:http://sage-t.tumblr.com/tagged/Fortran2003]]
-[[fortran66のブログ:http://fortran66.hatenablog.com/]]
-[[fortran66の日記:http://d.hatena.ne.jp/fortran66/]]
-[[Fortran日記:http://fortran.cscblog.jp/]]
-[[なんとなく始めたブログ: fortran:http://sak12.blogspot.jp/search/label/fortran]]
-[[Fortrantips:http://pmt.sakura.ne.jp/wiki/index.php?title=Fortrantips]]
-https://github.com/OpenFortranProject
-[[Fortran Archives - Moonmile Solutions Blog:http://www.moonmile.net/blog/archives/category/dev/fortran]]
-http://qiita.com/tags/fortran
-[[FortranからPythonへ:http://www.slideshare.net/shibukawa/fortranpython-presentation]]
-[[2.2 Fortran90/95入門 後半:http://exp.cs.kobe-u.ac.jp/wiki/comp_practice/index.php?2.2%20Fortran90%2F95%C6%FE%CC%E7%20%B8%E5%C8%BE]]
-[[Fortran90/95での引数の値渡し (Pass by value):http://sgks.blogspot.jp/2008/02/fortran9095-pass-by-value.html]]
-http://gcc.gnu.org/onlinedocs/gfortran/Interoperable-Subroutines-and-Functions.html
-http://software.intel.com/en-us/forums/topic/270769
-http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlf101a.doc%2Fxlflr%2Finterop-iso-c-binding-module.htm
-http://be.nucl.ap.titech.ac.jp/~koba/cgi-bin/moin.cgi/FORTRAN
-[[高速化プログラミング:http://fast-programming.aglk.net/]]
-[[Fortran 覚書:http://www.gcxx.jp/memo/?fortran]]
-[[Fortranスマートプログラミング:http://www.ile.osaka-u.ac.jp/research/cmp/text.html]] (PDF)
-[[Fortran 90/95 入門①:http://www.hucc.hokudai.ac.jp/~a10019/kosyu/pdf2/Fortran_1.pdf]] (PDF)
-[[Fortran 90/95 入門②:http://www.hucc.hokudai.ac.jp/~a10019/kosyu/pdf2/Fortran_2.pdf]] (PDF)
-[[データ解析のためのFortran90/95:http://web.agr.ehime-u.ac.jp/~kishou/Lecture/atmosphere/atmo06.htm]]
-[[Fortran90プログラミング:http://www7b.biglobe.ne.jp/~fortran/]]
-[[Fortran エラー処理で文番号を使わない方法 :http://seismon.blog85.fc2.com/blog-entry-90.html]]
-[[Fortran90で構造解析をしよう!:http://www.rcs.arch.t.u-tokyo.ac.jp/kusuhara/tips/linux/fortran.html]]
-[[Fortranでの配列の要素へのアクセス順序について:http://d.hatena.ne.jp/aldente39/20120209/1328800255]]
-[[MinGW Fortran でプログラミング Excelで使用:http://pub.ne.jp/TakeA/?entry_id=4584618]]
-[[計算機に関する雑多なTips:http://daweb.ism.ac.jp/~saitohm/top/_tRlEvpW.html]]
-[[Fortran 90 with Excel – gfortran example:http://sukhbinder.wordpress.com/2010/07/20/fortran-90-with-excel-gfortran-example/]]
-[[using gfortran to call windows api functions:http://compgroups.net/comp.lang.fortran/using-gfortran-to-call-windows-api-function/226148]]
-[[gfortran, DLL, underscore:http://stackoverflow.com/questions/1985819/gfortran-dll-underscore]]
-http://gcc.gnu.org/wiki/Coarray

**処理系 [#xfad745a]

-[[GNU Fortran (gfortran):http://gcc.gnu.org/wiki/GFortran]]
--[[Fortran2008Status - GCC Wiki:http://gcc.gnu.org/wiki/Fortran2008Status]]
--[[Fortran2003Status - GCC Wiki:http://gcc.gnu.org/wiki/Fortran2003Status]]
--http://gcc.gnu.org/onlinedocs/gfortran/Fortran-2003-and-2008-status.html
--Windows では [[MinGW]], [[Cygwin]], [[Strawberry Perl:http://strawberryperl.com/]] などに収録されています.
--OS X では [[High Performance Computing for Mac OS X:http://hpc.sourceforge.net/]] からバイナリが取得できます.
--http://gfortran.com/ gfortran daily builds
-[[Intel Fortran Compiler (ifort):http://software.intel.com/en-us/fortran-compilers]]
--http://software.intel.com/en-us/non-commercial-software-development (Linux, 非商用での使用のみ可)
--[[Fortran (Intel Parallel Studio) のインストール:http://pen.agbi.tsukuba.ac.jp/~RStiger/hiki2/?Fortran+%28Intel+Parallel+Studio+XE%29+%A4%CE%A5%A4%A5%F3%A5%B9%A5%C8]]
--[[ifort で最近良く使うコンパイルオプション:http://naturesflyers.blogspot.jp/2013/08/ifort.html]]

**Fortran 2008 の使い方 [#r3bbac60]

***使用可能な拡張子 [#d9d770b5]

GNU Fortran の場合は拡張子に .f90, .f95, .f03, .f08, .F90, .F95, .F03, .F08 などが使用できます.~
GNU Fortran と Intel Fortran Compiler を両方使用してプログラムを作成する場合は拡張子は .f90 または .F90 を使用することをおすめします.~

|自由形式 (free form)|.f90, .f95, .f03, .f08, .F90, .F95, .F03, .F08|
|固定形式 (fixed form)|.f, .for, .fpp, .ftn, .F, .FOR, .FPP, .FTN|

-http://gcc.gnu.org/onlinedocs/gfortran/GNU-Fortran-and-GCC.html
-http://nf.nci.org.au/facilities/software/intel-ct/13.5.192/Documentation/ja_JP/compiler_f/main_for/GUID-75F416C4-ADD7-41D0-AEFE-E61F50C04A82.htm

***標準出力,MessageBox に "Hello World" を出力 [#x79017be]

----
-helloworld.f90
----
 program hello_world
     implicit none
     print '(g0)', "Hello World"
 end program hello_world
----
 program hello_world
     use, intrinsic :: iso_fortran_env
     implicit none
     write(unit=output_unit, fmt='(g0)') "Hello World"
 end program hello_world
----
 module c_stdio
     use, intrinsic :: iso_c_binding
     implicit none
     private
     public :: c_puts
     interface
         subroutine c_puts(s) bind(c, name='puts')
             import
             character(kind=c_char), intent(in) :: s
         end subroutine c_puts
     end interface
 end module c_stdio
 
 program hello_world
     use, intrinsic :: iso_c_binding
     use c_stdio
     implicit none
     call c_puts("Hello World" // c_null_char)
 end program hello_world
----
 module c_windows
     use, intrinsic :: iso_c_binding
     implicit none
     private
     public :: c_MessageBoxA
     interface
         subroutine c_MessageBoxA(hWnd, lpText, lpCaption, uType) bind(c, name='MessageBoxA')
             import
             !gcc$ attributes stdcall :: c_MessageBoxA
             type(c_ptr), value :: hWnd
             character(kind=c_char), intent(in) :: lpText
             character(kind=c_char), intent(in) :: lpCaption
             integer(kind=c_int), value :: uType
         end subroutine c_MessageBoxA
     end interface
 end module c_windows
 
 program hello_world
     use, intrinsic :: iso_c_binding
     use c_windows
     implicit none
     call c_MessageBoxA(c_null_ptr, "Hello World" // c_null_char, "Hello World" // c_null_char, 0)
 end program hello_world
----
 module c_windows
     use, intrinsic :: iso_c_binding
     implicit none
     private
     public :: c_MessageBoxW
     interface
         subroutine c_MessageBoxW(hWnd, lpText, lpCaption, uType) bind(c, name='MessageBoxW')
             import
             !gcc$ attributes stdcall :: c_MessageBoxW
             type(c_ptr), value :: hWnd
             type(c_ptr), value :: lpText
             type(c_ptr), value :: lpCaption
             integer(kind=c_int), value :: uType
         end subroutine c_MessageBoxW
     end interface
 end module c_windows
 
 program hello_world
     use, intrinsic :: iso_c_binding
     use c_windows
     implicit none
     integer(kind=1), dimension(1:24), target :: hello_world_wchar = &
         & (/72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 32, 0, &
         &   87, 0, 111, 0, 114, 0, 108, 0, 100, 0,  0, 0/)! "Hello World" + "\0"
     call c_MessageBoxW(c_null_ptr, c_loc(hello_world_wchar), c_loc(hello_world_wchar), 0)
 end program hello_world
----

GNU Fortran 4.8.1 で動作確認しています.~
データの出力は print 文や write 文で行います.~
g0 編集記述子は print 文や write 文で整数や文字列などの任意の組み込み型に対して使用できます.~
print 文や write 文でフォーマットに * を指定して出力した場合は gfortran と ifort で出力フォーマットが異なる場合があるかもしれません.~
gfortran と ifort で出力フォーマットが異なるのを回避したい場合は * を使用せずに書式指定してください.~
C の puts 関数や Windows API の MessageBox 関数を呼び出して出力することもできます.~
Fortran の文字列は null 終端文字列ではないので C の関数に文字列を渡す場合は c_null_char を末尾に追加して渡す必要があります.~

 $ gfortran -Wall -Ofast -march=native -std=f2008 -static -o helloworld helloworld.f90
 $ ./helloworld

MinGW の gfortran でビルドしたバイナリで

-Windows PowerShell から実行するとなにも表示されない
-コマンド プロンプトから実行するとアプリケーションエラーが発生する

といった現象が発生する場合は

  $ gfortran -Wall -Ofast -march=native -std=f2008 -static -o helloworld helloworld.f90

のように -static オプションを追加してビルドすれば OK です.~

***標準出力に 1 から 100 までの和を出力 [#m969de65]

----
-sum100.f90
----
 program sum_from_1_to_100
     implicit none
     integer(kind=4) :: i
     print '(g0, g0)', "Sum from 1 to 100 = ", sum((/(i, i = 1, 100)/))
 end program sum_from_1_to_100
----

配列要素の足し算をする場合は sum 関数を使用すると便利です.~

***コマンドライン引数から整数 N を取得して標準出力に 1 から N までの和を出力 [#cd8aab45]

----
-nsum.f90
----
 program sum_from_1_to_n
     implicit none
     integer(kind=4) :: i, j
     integer(kind=4) :: n
     character(len=3) :: arg_length_format
     character(len=256) :: arg
     integer(kind=4) :: ios
 
     if (command_argument_count() == 0) then
         call usage()
         stop
     end if
 
     do i = 1, command_argument_count()
         call get_command_argument(i, arg)
         if (valid_number(arg) .eqv. .false.) then
             cycle
         end if
         write(unit=arg_length_format, fmt='(g0)') len_trim(arg)
         read(unit=arg, fmt='(i' // trim(arg_length_format) // ')', iostat=ios) n
         if (ios /= 0) then
             cycle
         end if
         if (n <= 0) then
             cycle
         else if (n > 0 .and. n < 65536) then
             block
                 integer(kind=4), dimension(:), allocatable :: n_array_4
                 allocate(n_array_4(1:n))
                 forall(j = 1:n) n_array_4(j:j) = j
                 print '(g0, g0, g0, g0)', "Sum from 1 to ", n, " = ", sum(n_array_4)
                 deallocate(n_array_4)
             end block
         else if (n >= 65536 .and. n <= huge(n)) then
             block
                 integer(kind=8), dimension(:), allocatable :: n_array_8
                 allocate(n_array_8(1:n))
                 forall(j = 1:n) n_array_8(j:j) = j
                 print '(g0, g0, g0, g0)', "Sum from 1 to ", n, " = ", sum(n_array_8)
                 deallocate(n_array_8)
             end block
         else
             cycle
         end if
     end do
 contains
     subroutine usage()
         use, intrinsic :: iso_fortran_env
         character(len=256) :: cmd
 
         call get_command(cmd)
         write(unit=error_unit, fmt='(g0, g0, g0)') "usage: ", trim(cmd), " N ..."
     end subroutine usage
 
     function valid_number(arg) result(ok)
         character(len=*), intent(in) :: arg
         integer(kind=4) :: i
         logical(kind=4) :: ok
 
         ok = .false.
         do i = 1, len_trim(arg)
             if (arg(i:i) < '0' .or. arg(i:i) > '9') then
                 ok = .false.
                 exit
             else
                 ok = .true.
             end if
         end do
     end function valid_number
 end program sum_from_1_to_n
----
 module c_stdlib
     use, intrinsic :: iso_c_binding
     implicit none
     private
     public :: c_atoi
     interface
         function c_atoi(s) result(i) bind(c, name='atoi')
             import
             character(kind=c_char), intent(in) :: s
             integer(kind=c_int) :: i
         end function c_atoi
     end interface
 end module c_stdlib
 
 program sum_from_1_to_n
     use, intrinsic :: iso_c_binding
     use c_stdlib
     implicit none
     integer(kind=4) :: i, j
     integer(kind=4) :: n
     character(len=256) :: arg
 
     if (command_argument_count() == 0) then
         call usage()
         stop
     end if
 
     do i = 1, command_argument_count()
         call get_command_argument(i, arg)
         n = c_atoi(trim(arg) // c_null_char)
         if (n <= 0) then
             cycle
         else if (n > 0 .and. n < 65536) then
             block
                 integer(kind=4), dimension(:), allocatable :: n_array_4
                 allocate(n_array_4(1:n))
                 forall(j = 1:n) n_array_4(j:j) = j
                 print '(g0, g0, g0, g0)', "Sum from 1 to ", n, " = ", sum(n_array_4)
                 deallocate(n_array_4)
             end block
         else if (n >= 65536 .and. n <= huge(n)) then
             block
                 integer(kind=8), dimension(:), allocatable :: n_array_8
                 allocate(n_array_8(1:n))
                 forall(j = 1:n) n_array_8(j:j) = j
                 print '(g0, g0, g0, g0)', "Sum from 1 to ", n, " = ", sum(n_array_8)
                 deallocate(n_array_8)
             end block
         else
             cycle
         end if
     end do
 contains
     subroutine usage()
         use, intrinsic :: iso_fortran_env
         character(len=256) :: cmd
 
         call get_command(cmd)
         write(unit=error_unit, fmt='(g0, g0, g0)') "usage: ", trim(cmd), " N ..."
     end subroutine usage
 end program sum_from_1_to_n
----

文字列から数値への変換は read 文で行います.~
C の atoi 関数で文字列から数値へ変換することもできます.~
数値から文字列への変換は write 文で行います.~
大きな数で正確な演算結果が必要な場合は[[多倍長整数ライブラリ:http://ja.wikipedia.org/wiki/%E4%BB%BB%E6%84%8F%E7%B2%BE%E5%BA%A6%E6%BC%94%E7%AE%97#.E3.83.A9.E3.82.A4.E3.83.96.E3.83.A9.E3.83.AA]]を使用してプログラムを作成することをおすすめします.~
多倍長整数を扱うライブラリとして例えば [[GMP:http://gmplib.org/]] があります.~
C で簡単に記述できます.~

----
-nsum.c
----
 // vim: ts=4 sw=4 expandtab:
 // gcc -Wall -Ofast -march=native -std=c11 -static -o nsum nsum.c -lgmp
 #include <ctype.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 #include <gmp.h>
 
 void usage(const char* restrict);
 bool valid_number(const char* restrict);
 void nsum(const char* restrict);
 
 void
 usage(const char* restrict s)
 {
     fprintf(stderr, "usage: %s N ...", s);
 }
 
 bool
 valid_number(const char* restrict s)
 {
     for (int i = 0; i < strlen(s); i++) {
         if (!isdigit(s[i])) {
             return false;
         }
     }
     return true;
 }
 
 void
 nsum(const char* restrict s)
 {
     mpz_t n;
     mpz_t k;
     mpz_t inc;
     mpz_t arg;
     mpz_init_set_str(inc, "1", 10);
     mpz_init_set_str(k, "1", 10);
     mpz_init_set_str(n, "0", 10);
     mpz_init_set_str(arg, s, 10);
     while (mpz_cmp(k, arg) <= 0) {
         mpz_add(n, n, k);
         mpz_add(k, k, inc);
     }
     gmp_printf("Sum from 1 to %Zd = %Zd\n", arg, n);
     mpz_clear(arg);
     mpz_clear(inc);
     mpz_clear(k);
     mpz_clear(n);
 }
 
 int
 main(int argc, char** argv)
 {
     if (argc < 2) {
         usage(argv[0]);
         return 2;
     }
 
     for (int i = 1; i < argc; i++) {
         if (valid_number(argv[i]) == false) {
             continue;
         }
         nsum(argv[i]);
     }
 
     return 0;
 }
----

**Python や C などのプログラミング言語から Fortran を呼び出す [#kaea5749]

-[[Calling Fortran from Python:http://www.sfu.ca/~mawerder/notes/calling_fortran_from_python.html]]
-[[Calling Fortran from C:http://www.sfu.ca/~mawerder/notes/calling_fortran_from_c.html]]
-[[f2pyを使ってfortranでpythonのモジュールを書く:http://qiita.com/airtoxin/items/b632f2b3f219610f3990]]
-[[PythonからFortranのサブルーチンを呼ぶ。:http://d.hatena.ne.jp/ignisan/20121017/p1]]