Fortran - คู่มือฉบับย่อ
Fortran ซึ่งมาจาก Formula Translating System เป็นภาษาโปรแกรมที่จำเป็นสำหรับวัตถุประสงค์ทั่วไป ใช้สำหรับการคำนวณตัวเลขและวิทยาศาสตร์
Fortran ได้รับการพัฒนาโดย IBM ในปี 1950 สำหรับการใช้งานทางวิทยาศาสตร์และวิศวกรรม Fortran ปกครองพื้นที่การเขียนโปรแกรมนี้มาเป็นเวลานานและได้รับความนิยมอย่างมากสำหรับการประมวลผลประสิทธิภาพสูงเนื่องจาก
รองรับ -
- การวิเคราะห์เชิงตัวเลขและการคำนวณทางวิทยาศาสตร์
- การเขียนโปรแกรมที่มีโครงสร้าง
- การเขียนโปรแกรมอาร์เรย์
- การเขียนโปรแกรมแบบโมดูล
- การเขียนโปรแกรมทั่วไป
- การประมวลผลประสิทธิภาพสูงบนซูเปอร์คอมพิวเตอร์
- การเขียนโปรแกรมเชิงวัตถุ
- การเขียนโปรแกรมพร้อมกัน
- ระดับการพกพาที่เหมาะสมระหว่างระบบคอมพิวเตอร์
ข้อมูลเกี่ยวกับ Fortran
Fortran ถูกสร้างขึ้นโดยทีมงานซึ่งนำโดย John Backus ที่ IBM ในปีพ. ศ. 2500
ในขั้นต้นชื่อที่ใช้เขียนด้วยตัวพิมพ์ใหญ่ทั้งหมด แต่มาตรฐานและการใช้งานในปัจจุบันกำหนดให้อักษรตัวแรกเป็นตัวพิมพ์ใหญ่เท่านั้น
Fortran ย่อมาจาก FORmula TRANslator
เดิมพัฒนาขึ้นสำหรับการคำนวณทางวิทยาศาสตร์มีการสนับสนุนสตริงอักขระและโครงสร้างอื่น ๆ ที่จำเป็นสำหรับการเขียนโปรแกรมวัตถุประสงค์ทั่วไปอย่าง จำกัด มาก
ส่วนขยายและการพัฒนาในภายหลังทำให้เป็นภาษาโปรแกรมระดับสูงพร้อมความสะดวกในการพกพา
เวอร์ชันดั้งเดิม Fortran I, II และ III ถือว่าล้าสมัยแล้ว
เวอร์ชันที่เก่าที่สุดที่ยังใช้อยู่คือ Fortran IV และ Fortran 66
เวอร์ชันที่ใช้กันมากที่สุดในปัจจุบัน ได้แก่ Fortran 77, Fortran 90 และ Fortran 95
Fortran 77 เพิ่มสตริงเป็นประเภทที่แตกต่างกัน
Fortran 90 เพิ่มเธรดประเภทต่างๆและการประมวลผลอาร์เรย์โดยตรง
การตั้งค่า Fortran ใน Windows
G95 เป็นคอมไพเลอร์หลายองค์ประกอบของ GNU Fortran ซึ่งใช้สำหรับการตั้งค่า Fortran ใน Windows เวอร์ชัน windows เลียนแบบสภาพแวดล้อม unix โดยใช้ MingW ภายใต้ windows โปรแกรมติดตั้งจะดูแลและเพิ่ม g95 ให้กับตัวแปร windows PATH โดยอัตโนมัติ
คุณสามารถรับ G95 เวอร์ชันเสถียรได้จากที่นี่
วิธีใช้ G95
ระหว่างการติดตั้ง g95จะถูกเพิ่มลงในตัวแปร PATH ของคุณโดยอัตโนมัติหากคุณเลือกตัวเลือก“ แนะนำ” ซึ่งหมายความว่าคุณสามารถเปิดหน้าต่างพรอมต์คำสั่งใหม่แล้วพิมพ์“ g95” เพื่อเปิดคอมไพเลอร์ ค้นหาคำสั่งพื้นฐานด้านล่างเพื่อเริ่มต้นใช้งาน
ซีเนียร์ No | คำสั่งและคำอธิบาย |
---|---|
1 | g95 –c hello.f90 คอมไพล์ hello.f90 ไปยังอ็อบเจ็กต์ไฟล์ชื่อ hello.o |
2 | g95 hello.f90 รวบรวม hello.f90 และเชื่อมโยงเพื่อสร้าง a.out ที่ปฏิบัติการได้ |
3 | g95 -c h1.f90 h2.f90 h3.f90 รวบรวมไฟล์ต้นฉบับหลายไฟล์ หากทุกอย่างเป็นไปด้วยดีอ็อบเจ็กต์ไฟล์ h1.o, h2.o และ h3.o จะถูกสร้างขึ้น |
4 | g95 -o hello h1.f90 h2.f90 h3.f90 รวบรวมไฟล์ต้นฉบับหลายไฟล์และเชื่อมโยงเข้าด้วยกันกับไฟล์ปฏิบัติการชื่อ 'hello' |
ตัวเลือกบรรทัดคำสั่งสำหรับ G95
-c Compile only, do not run the linker.
-o Specify the name of the output file, either an object file or the executable.
สามารถระบุซอร์สไฟล์และอ็อบเจ็กต์หลายไฟล์พร้อมกัน ไฟล์ Fortran จะระบุด้วยชื่อที่ลงท้ายด้วย ".f", ".F", ".for", ".FOR", ".f90", ".F90", ".f95", ".F95", " f03 "และ" .F03 " สามารถระบุไฟล์ต้นฉบับได้หลายไฟล์ ไฟล์ออบเจ็กต์สามารถระบุได้เช่นกันและจะเชื่อมโยงกับไฟล์ปฏิบัติการ
โปรแกรม Fortran ประกอบด้วยชุดของหน่วยโปรแกรมเช่นโปรแกรมหลักโมดูลและโปรแกรมย่อยหรือโพรซีเดอร์ภายนอก
แต่ละโปรแกรมประกอบด้วยโปรแกรมหลักหนึ่งโปรแกรมและอาจมีหรือไม่มีหน่วยโปรแกรมอื่นก็ได้ ไวยากรณ์ของโปรแกรมหลักมีดังนี้ -
program program_name
implicit none
! type declaration statements
! executable statements
end program program_name
โปรแกรมง่ายๆใน Fortran
มาเขียนโปรแกรมที่เพิ่มตัวเลขสองตัวแล้วพิมพ์ผลลัพธ์ -
program addNumbers
! This simple program adds two numbers
implicit none
! Type declarations
real :: a, b, result
! Executable statements
a = 12.0
b = 15.0
result = a + b
print *, 'The total is ', result
end program addNumbers
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
The total is 27.0000000
โปรดทราบว่า -
โปรแกรม Fortran ทั้งหมดเริ่มต้นด้วยคีย์เวิร์ด program และลงท้ายด้วยคำหลัก end program, ตามด้วยชื่อของโปรแกรม
implicit noneคำสั่งอนุญาตให้คอมไพเลอร์ตรวจสอบว่าประเภทตัวแปรทั้งหมดของคุณได้รับการประกาศอย่างถูกต้อง คุณต้องใช้implicit none เมื่อเริ่มต้นทุกโปรแกรม
ข้อคิดเห็นใน Fortran เริ่มต้นด้วยเครื่องหมายอัศเจรีย์ (!) เนื่องจากอักขระทั้งหมดหลังจากนี้ (ยกเว้นในสตริงอักขระ) จะถูกละเว้นโดยคอมไพลเลอร์
print * คำสั่งแสดงข้อมูลบนหน้าจอ
การเยื้องบรรทัดรหัสเป็นแนวทางปฏิบัติที่ดีในการทำให้โปรแกรมอ่านได้
Fortran อนุญาตให้ใช้ทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก Fortran ไม่คำนึงถึงขนาดตัวพิมพ์ยกเว้นตัวอักษรสตริง
พื้นฐาน
basic character set ของ Fortran ประกอบด้วย -
- ตัวอักษร A ... Z และ a ... z
- หลัก 0 ... 9
- เครื่องหมายขีดล่าง (_) อักขระ
- อักขระพิเศษ =: + blank - * / () [],. $ '! "% &; <>?
Tokensสร้างขึ้นจากอักขระในชุดอักขระพื้นฐาน โทเค็นอาจเป็นคีย์เวิร์ดตัวระบุค่าคงที่สตริงลิเทอรัลหรือสัญลักษณ์
คำสั่งของโปรแกรมสร้างขึ้นจากโทเค็น
ตัวระบุ
ตัวระบุคือชื่อที่ใช้เพื่อระบุตัวแปรโพรซีเดอร์หรือรายการอื่น ๆ ที่ผู้ใช้กำหนดเอง ชื่อใน Fortran ต้องเป็นไปตามกฎต่อไปนี้ -
ต้องมีความยาวไม่เกิน 31 อักขระ
ต้องประกอบด้วยอักขระที่เป็นตัวอักษรและตัวเลข (ตัวอักษรทั้งหมดของตัวอักษรและตัวเลข 0 ถึง 9) และขีดล่าง (_)
อักขระตัวแรกของชื่อต้องเป็นตัวอักษร
ชื่อไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่
คำหลัก
คำหลักเป็นคำพิเศษสงวนไว้สำหรับภาษา คำสงวนเหล่านี้ไม่สามารถใช้เป็นตัวระบุหรือชื่อได้
ตารางต่อไปนี้แสดงรายการคีย์เวิร์ด Fortran -
คีย์เวิร์ดที่ไม่ใช่ I / O | ||||
---|---|---|---|---|
จัดสรรได้ | จัดสรร | กำหนด | มอบหมาย | บล็อกข้อมูล |
โทร | กรณี | ตัวละคร | เรื่องธรรมดา | ซับซ้อน |
ประกอบด้วย | ดำเนินการต่อ | วงจร | ข้อมูล | ยกเลิกการจัดสรร |
ค่าเริ่มต้น | ทำ | ความแม่นยำสองเท่า | อื่น | อื่นถ้า |
ที่อื่น | สิ้นสุดข้อมูลบล็อก | จบ | ฟังก์ชันสิ้นสุด | สิ้นสุดถ้า |
สิ้นสุดอินเทอร์เฟซ | โมดูลท้าย | โปรแกรมสิ้นสุด | สิ้นสุดการเลือก | สิ้นสุดรูทีนย่อย |
ประเภทสิ้นสุด | จบที่ไหน | รายการ | ความเท่าเทียมกัน | ทางออก |
ภายนอก | ฟังก์ชัน | ไปที่ | ถ้า | โดยปริยาย |
ใน | inout | จำนวนเต็ม | เจตนา | อินเตอร์เฟซ |
เนื้อแท้ | ชนิด | เลน | ตรรกะ | โมดูล |
ชื่อรายการ | ทำให้เป็นโมฆะ | เท่านั้น | ตัวดำเนินการ | ไม่จำเป็น |
ออก | พารามิเตอร์ | หยุด | ตัวชี้ | เอกชน |
โปรแกรม | สาธารณะ | จริง | เรียกซ้ำ | ผลลัพธ์ |
กลับ | บันทึก | เลือกกรณี | หยุด | รูทีนย่อย |
เป้าหมาย | แล้ว | ชนิด | ประเภท () | ใช้ |
ที่ไหน | ในขณะที่ | |||
คำหลักที่เกี่ยวข้องกับ I / O | ||||
backspace | ปิด | endfile | รูปแบบ | สอบถาม |
เปิด | พิมพ์ | อ่าน | ย้อนกลับ | เขียน |
Fortran มีประเภทข้อมูลภายในห้าประเภทอย่างไรก็ตามคุณสามารถรับประเภทข้อมูลของคุณเองได้เช่นกัน ห้าประเภทที่แท้จริงคือ -
- ประเภทจำนวนเต็ม
- ประเภทจริง
- ประเภทที่ซับซ้อน
- ประเภทตรรกะ
- ประเภทตัวละคร
ประเภทจำนวนเต็ม
ชนิดจำนวนเต็มสามารถเก็บได้เฉพาะค่าจำนวนเต็ม ตัวอย่างต่อไปนี้แยกค่าที่ใหญ่ที่สุดที่สามารถถือเป็นจำนวนเต็มสี่ไบต์ตามปกติ -
program testingInt
implicit none
integer :: largeval
print *, huge(largeval)
end program testingInt
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
2147483647
โปรดทราบว่าไฟล์ huge()ฟังก์ชันให้จำนวนมากที่สุดที่สามารถถือได้โดยชนิดข้อมูลจำนวนเต็มเฉพาะ คุณยังสามารถระบุจำนวนไบต์โดยใช้kindตัวระบุ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
program testingInt
implicit none
!two byte integer
integer(kind = 2) :: shortval
!four byte integer
integer(kind = 4) :: longval
!eight byte integer
integer(kind = 8) :: verylongval
!sixteen byte integer
integer(kind = 16) :: veryverylongval
!default integer
integer :: defval
print *, huge(shortval)
print *, huge(longval)
print *, huge(verylongval)
print *, huge(veryverylongval)
print *, huge(defval)
end program testingInt
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
ประเภทจริง
จะเก็บตัวเลขทศนิยมเช่น 2.0, 3.1415, -100.876 เป็นต้น
ตามเนื้อผ้ามีจริงสองประเภทที่แตกต่างกันค่าเริ่มต้น real พิมพ์และ double precision ประเภท.
อย่างไรก็ตาม Fortran 90/95 ให้การควบคุมความแม่นยำของชนิดข้อมูลจริงและจำนวนเต็มมากขึ้นผ่านไฟล์ kind ตัวระบุซึ่งเราจะศึกษาในบทที่เกี่ยวกับตัวเลข
ตัวอย่างต่อไปนี้แสดงการใช้ประเภทข้อมูลจริง -
program division
implicit none
! Define real variables
real :: p, q, realRes
! Define integer variables
integer :: i, j, intRes
! Assigning values
p = 2.0
q = 3.0
i = 2
j = 3
! floating point division
realRes = p/q
intRes = i/j
print *, realRes
print *, intRes
end program division
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
0.666666687
0
ประเภทที่ซับซ้อน
ใช้สำหรับจัดเก็บจำนวนเชิงซ้อน จำนวนเชิงซ้อนมี 2 ส่วนคือส่วนจริงและส่วนจินตภาพ หน่วยเก็บข้อมูลตัวเลขสองหน่วยต่อเนื่องกันจะจัดเก็บสองส่วนนี้
ตัวอย่างเช่นจำนวนเชิงซ้อน (3.0, -5.0) เท่ากับ 3.0 - 5.0i
เราจะพูดถึงประเภทที่ซับซ้อนโดยละเอียดในบท Numbers
ประเภทตรรกะ
มีเพียงสองค่าตรรกะ: .true. และ .false.
ประเภทตัวละคร
ประเภทอักขระเก็บอักขระและสตริง ความยาวของสตริงสามารถระบุได้โดยตัวระบุ len หากไม่ได้ระบุความยาวแสดงว่าเป็น 1
For example,
character (len = 40) :: name
name = “Zara Ali”
การแสดงออก, name(1:4) จะให้สตริงย่อย“ Zara”
การพิมพ์โดยนัย
Fortran เวอร์ชันเก่าอนุญาตให้ใช้คุณลักษณะที่เรียกว่าการพิมพ์โดยนัยกล่าวคือคุณไม่จำเป็นต้องประกาศตัวแปรก่อนใช้งาน หากไม่มีการประกาศตัวแปรอักษรตัวแรกของชื่อจะเป็นตัวกำหนดประเภท
ชื่อตัวแปรที่ขึ้นต้นด้วย i, j, k, l, m หรือ n ถือเป็นตัวแปรจำนวนเต็มและอื่น ๆ เป็นตัวแปรจริง อย่างไรก็ตามคุณต้องประกาศตัวแปรทั้งหมดเนื่องจากเป็นการเขียนโปรแกรมที่ดี เพื่อที่คุณจะเริ่มโปรแกรมของคุณด้วยคำสั่ง -
implicit none
คำสั่งนี้จะปิดการพิมพ์โดยนัย
ตัวแปรไม่ใช่อะไรนอกจากชื่อที่กำหนดให้กับพื้นที่จัดเก็บที่โปรแกรมของเราสามารถจัดการได้ ตัวแปรแต่ละตัวควรมีประเภทเฉพาะซึ่งกำหนดขนาดและรูปแบบของหน่วยความจำของตัวแปร ช่วงของค่าที่สามารถเก็บไว้ในหน่วยความจำนั้น และชุดของการดำเนินการที่สามารถนำไปใช้กับตัวแปร
ชื่อของตัวแปรสามารถประกอบด้วยตัวอักษรตัวเลขและอักขระขีดล่าง ชื่อใน Fortran ต้องเป็นไปตามกฎต่อไปนี้ -
ต้องมีความยาวไม่เกิน 31 อักขระ
ต้องประกอบด้วยอักขระที่เป็นตัวอักษรและตัวเลข (ตัวอักษรทั้งหมดของตัวอักษรและตัวเลข 0 ถึง 9) และขีดล่าง (_)
อักขระตัวแรกของชื่อต้องเป็นตัวอักษร
ชื่อไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่
ตามประเภทพื้นฐานที่อธิบายไว้ในบทที่แล้วต่อไปนี้เป็นประเภทตัวแปร -
ซีเนียร์ No | ประเภทและคำอธิบาย |
---|---|
1 | Integer สามารถเก็บได้เฉพาะค่าจำนวนเต็ม |
2 | Real มันเก็บตัวเลขจุดลอย |
3 | Complex ใช้สำหรับจัดเก็บจำนวนเชิงซ้อน |
4 | Logical มันเก็บค่าบูลีนเชิงตรรกะ |
5 | Character มันเก็บอักขระหรือสตริง |
การประกาศตัวแปร
ตัวแปรจะถูกประกาศที่จุดเริ่มต้นของโปรแกรม (หรือโปรแกรมย่อย) ในคำสั่งประเภทประกาศ
ไวยากรณ์สำหรับการประกาศตัวแปรมีดังนี้ -
type-specifier :: variable_name
ตัวอย่างเช่น
integer :: total
real :: average
complex :: cx
logical :: done
character(len = 80) :: message ! a string of 80 characters
หลังจากนั้นคุณสามารถกำหนดค่าให้กับตัวแปรเหล่านี้เช่น
total = 20000
average = 1666.67
done = .true.
message = “A big Hello from Tutorials Point”
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
คุณยังสามารถใช้ฟังก์ชันภายใน cmplx, เพื่อกำหนดค่าให้กับตัวแปรที่ซับซ้อน -
cx = cmplx (1.0/2.0, -7.0) ! cx = 0.5 – 7.0i
cx = cmplx (x, y) ! cx = x + yi
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการประกาศตัวแปรการกำหนดและการแสดงผลบนหน้าจอ -
program variableTesting
implicit none
! declaring variables
integer :: total
real :: average
complex :: cx
logical :: done
character(len=80) :: message ! a string of 80 characters
!assigning values
total = 20000
average = 1666.67
done = .true.
message = "A big Hello from Tutorials Point"
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
Print *, total
Print *, average
Print *, cx
Print *, done
Print *, message
end program variableTesting
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
20000
1666.67004
(3.00000000, 5.00000000 )
T
A big Hello from Tutorials Point
ค่าคงที่หมายถึงค่าคงที่ซึ่งโปรแกรมไม่สามารถเปลี่ยนแปลงได้ในระหว่างการดำเนินการ ค่าคงที่เหล่านี้เรียกอีกอย่างว่าliterals.
ค่าคงที่อาจเป็นชนิดข้อมูลพื้นฐานใด ๆ เช่นค่าคงที่จำนวนเต็มค่าคงที่ลอยค่าคงที่ของอักขระค่าคงที่เชิงซ้อนหรือตัวอักษรสตริง ค่าคงที่ตรรกะมีเพียงสองค่า:.true. และ .false.
ค่าคงที่ได้รับการปฏิบัติเช่นเดียวกับตัวแปรทั่วไปยกเว้นว่าไม่สามารถแก้ไขค่าได้หลังจากนิยามแล้ว
ชื่อค่าคงที่และตัวอักษร
ค่าคงที่มีสองประเภท -
- ค่าคงที่ตามตัวอักษร
- ค่าคงที่ที่มีชื่อ
ค่าคงที่ตามตัวอักษรมีค่า แต่ไม่มีชื่อ
ตัวอย่างเช่นต่อไปนี้เป็นค่าคงที่ตามตัวอักษร -
ประเภท | ตัวอย่าง |
---|---|
ค่าคงที่ของจำนวนเต็ม | 0 1-1 300 123456789 |
ค่าคงที่จริง | 0.0 1.0 -1.0 123.456 7.1E + 10 -52.715E-30 |
ค่าคงที่ที่ซับซ้อน | (0.0, 0.0) (-123.456E + 30, 987.654E-29) |
ค่าคงที่ตรรกะ | .true. .false. |
ค่าคงที่ของอักขระ | "PQR" "ก" "123'abc $% # @!" "คำพูด" "" "PQR" ก "123" abc $% # @! " 'เครื่องหมายวรรคตอน' '' |
ค่าคงที่ที่ตั้งชื่อมีค่าเช่นเดียวกับชื่อ
ควรประกาศค่าคงที่ที่มีชื่อไว้ที่จุดเริ่มต้นของโปรแกรมหรือขั้นตอนเช่นเดียวกับการประกาศประเภทตัวแปรโดยระบุชื่อและประเภท ค่าคงที่ที่ระบุชื่อจะประกาศด้วยแอตทริบิวต์พารามิเตอร์ ตัวอย่างเช่น,
real, parameter :: pi = 3.1415927
ตัวอย่าง
โปรแกรมต่อไปนี้จะคำนวณการกระจัดเนื่องจากการเคลื่อนที่ในแนวดิ่งภายใต้แรงโน้มถ่วง
program gravitationalDisp
! this program calculates vertical motion under gravity
implicit none
! gravitational acceleration
real, parameter :: g = 9.81
! variable declaration
real :: s ! displacement
real :: t ! time
real :: u ! initial speed
! assigning values
t = 5.0
u = 50
! displacement
s = u * t - g * (t**2) / 2
! output
print *, "Time = ", t
print *, 'Displacement = ',s
end program gravitationalDisp
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
Time = 5.00000000
Displacement = 127.374992
ตัวดำเนินการคือสัญลักษณ์ที่บอกให้คอมไพเลอร์ดำเนินการจัดการทางคณิตศาสตร์หรือตรรกะเฉพาะ Fortran มีตัวดำเนินการประเภทต่อไปนี้ -
- ตัวดำเนินการเลขคณิต
- ตัวดำเนินการเชิงสัมพันธ์
- ตัวดำเนินการทางตรรกะ
ให้เราดูตัวดำเนินการเหล่านี้ทั้งหมดทีละตัว
ตัวดำเนินการเลขคณิต
ตารางต่อไปนี้แสดงตัวดำเนินการเลขคณิตทั้งหมดที่ Fortran สนับสนุน สมมติตัวแปรA ถือ 5 และตัวแปร B ถือ 3 แล้ว -
แสดงตัวอย่าง
ตัวดำเนินการ | คำอธิบาย | ตัวอย่าง |
---|---|---|
+ | ตัวดำเนินการเพิ่มเติมเพิ่มตัวถูกดำเนินการสองตัว | A + B จะให้ 8 |
- | Subtraction Operator ลบตัวถูกดำเนินการที่สองออกจากตัวดำเนินการตัวแรก | A - B จะให้ 2 |
* | ตัวดำเนินการคูณคูณตัวถูกดำเนินการทั้งสอง | A * B จะให้ 15 |
/ | Division Operator หารตัวเศษด้วย de-numerator | A / B จะให้ 1 |
** | Exponentiation Operator ยกตัวถูกดำเนินการหนึ่งตัวขึ้นสู่อำนาจของอีกตัวหนึ่ง | A ** B จะให้ 125 |
ตัวดำเนินการเชิงสัมพันธ์
ตารางต่อไปนี้แสดงตัวดำเนินการเชิงสัมพันธ์ทั้งหมดที่ Fortran สนับสนุน สมมติตัวแปรA ถือ 10 และตัวแปร B ถือ 20 แล้ว -
แสดงตัวอย่าง
ตัวดำเนินการ | เทียบเท่า | คำอธิบาย | ตัวอย่าง |
---|---|---|---|
== | .eq. | ตรวจสอบว่าค่าของตัวถูกดำเนินการสองค่าเท่ากันหรือไม่ถ้าใช่เงื่อนไขจะกลายเป็นจริง | (A == B) ไม่เป็นความจริง |
/ = | .ne. | ตรวจสอบว่าค่าของตัวถูกดำเนินการสองค่าเท่ากันหรือไม่หากค่าไม่เท่ากันเงื่อนไขจะกลายเป็นจริง | (A! = B) เป็นจริง |
> | .gt. | ตรวจสอบว่าค่าของตัวถูกดำเนินการด้านซ้ายมากกว่าค่าของตัวถูกดำเนินการด้านขวาหรือไม่ถ้าใช่เงื่อนไขจะกลายเป็นจริง | (A> B) ไม่เป็นความจริง |
< | .lt. | ตรวจสอบว่าค่าของตัวถูกดำเนินการด้านซ้ายน้อยกว่าค่าของตัวถูกดำเนินการด้านขวาหรือไม่ถ้าใช่เงื่อนไขจะกลายเป็นจริง | (A <B) เป็นจริง |
> = | .ge. | ตรวจสอบว่าค่าของตัวถูกดำเนินการด้านซ้ายมากกว่าหรือเท่ากับค่าของตัวถูกดำเนินการด้านขวาหรือไม่ถ้าใช่เงื่อนไขจะกลายเป็นจริง | (A> = B) ไม่เป็นความจริง |
<= | .le. | ตรวจสอบว่าค่าของตัวถูกดำเนินการด้านซ้ายน้อยกว่าหรือเท่ากับค่าของตัวถูกดำเนินการด้านขวาหรือไม่ถ้าใช่เงื่อนไขจะกลายเป็นจริง | (A <= B) เป็นจริง |
ตัวดำเนินการทางตรรกะ
ตัวดำเนินการทางตรรกะใน Fortran ทำงานเฉพาะกับค่าตรรกะ. true และ. false.
ตารางต่อไปนี้แสดงตัวดำเนินการทางตรรกะทั้งหมดที่ Fortran สนับสนุน สมมติตัวแปร A ถือ. true และตัวแปร B ถือ. false แล้ว -
แสดงตัวอย่าง
ตัวดำเนินการ | คำอธิบาย | ตัวอย่าง |
---|---|---|
.และ. | เรียกว่าตัวดำเนินการ Logical AND หากตัวถูกดำเนินการทั้งสองไม่ใช่ศูนย์เงื่อนไขจะกลายเป็นจริง | (A. และ. B) เป็นเท็จ |
.หรือ. | เรียกว่า Logical OR Operator หากตัวถูกดำเนินการสองตัวใดตัวหนึ่งไม่เป็นศูนย์เงื่อนไขจะกลายเป็นจริง | (อ. ข.) เป็นความจริง |
.ไม่. | เรียกว่า Logical NOT Operator ใช้เพื่อย้อนกลับสถานะตรรกะของตัวถูกดำเนินการ หากเงื่อนไขเป็นจริงตัวดำเนินการ Logical NOT จะสร้างเท็จ | ! (A. and. B) เป็นความจริง |
.eqv. | เรียกว่าตัวดำเนินการเทียบเท่าเชิงตรรกะ ใช้เพื่อตรวจสอบความเท่าเทียมกันของค่าตรรกะสองค่า | (A .eqv. B) เป็นเท็จ |
.neqv. | เรียกว่า Logical NON-EQUIVALENT Operator ใช้เพื่อตรวจสอบความไม่เท่ากันของค่าตรรกะสองค่า | (A .neqv. B) เป็นจริง |
ลำดับความสำคัญของตัวดำเนินการใน Fortran
ลำดับความสำคัญของตัวดำเนินการกำหนดการจัดกลุ่มคำศัพท์ในนิพจน์ สิ่งนี้มีผลต่อวิธีการประเมินนิพจน์ ตัวดำเนินการบางอย่างมีลำดับความสำคัญสูงกว่าผู้อื่น ตัวอย่างเช่นตัวดำเนินการคูณมีลำดับความสำคัญสูงกว่าตัวดำเนินการบวก
ตัวอย่างเช่น x = 7 + 3 * 2; ที่นี่ x ถูกกำหนดให้เป็น 13 ไม่ใช่ 20 เนื่องจากตัวดำเนินการ * มีลำดับความสำคัญสูงกว่า + ดังนั้นจึงได้รับการคูณด้วย 3 * 2 ก่อนแล้วจึงเพิ่มเป็น 7
ที่นี่ตัวดำเนินการที่มีลำดับความสำคัญสูงสุดจะปรากฏที่ด้านบนสุดของตารางตัวดำเนินการที่มีค่าต่ำสุดจะปรากฏที่ด้านล่าง ภายในนิพจน์ตัวดำเนินการที่มีลำดับความสำคัญสูงกว่าจะได้รับการประเมินก่อน
แสดงตัวอย่าง
ประเภท | ตัวดำเนินการ | ความสัมพันธ์ |
---|---|---|
ไม่ใช่ตรรกะและเครื่องหมายลบ | .ไม่. (-) | จากซ้ายไปขวา |
การยกกำลัง | ** | จากซ้ายไปขวา |
หลายหลาก | * / | จากซ้ายไปขวา |
สารเติมแต่ง | + - | จากซ้ายไปขวา |
เชิงสัมพันธ์ | <<=>> = | จากซ้ายไปขวา |
ความเท่าเทียมกัน | == / = | จากซ้ายไปขวา |
ตรรกะ AND | .และ. | จากซ้ายไปขวา |
ตรรกะหรือ | .หรือ. | จากซ้ายไปขวา |
การมอบหมายงาน | = | จากขวาไปซ้าย |
โครงสร้างการตัดสินใจกำหนดให้โปรแกรมเมอร์ระบุเงื่อนไขอย่างน้อยหนึ่งเงื่อนไขที่จะประเมินหรือทดสอบโดยโปรแกรมพร้อมกับคำสั่งหรือคำสั่งที่จะดำเนินการหากเงื่อนไขถูกกำหนดให้เป็นจริงและเป็นทางเลือกที่จะดำเนินการคำสั่งอื่น ๆ หาก เงื่อนไขถูกกำหนดให้เป็นเท็จ
ต่อไปนี้เป็นรูปแบบทั่วไปของโครงสร้างการตัดสินใจทั่วไปที่พบในภาษาโปรแกรมส่วนใหญ่ -
Fortran มีโครงสร้างการตัดสินใจประเภทต่อไปนี้
ซีเนียร์ No | คำชี้แจงและคำอธิบาย |
---|---|
1 | ถ้า…แล้วสร้าง อัน if… then… end if คำสั่งประกอบด้วยนิพจน์ตรรกะตามด้วยคำสั่งอย่างน้อยหนึ่งคำสั่ง |
2 | ถ้า ... แล้ว ... อื่นสร้าง อัน if… then ตามด้วยคำสั่งก็ได้ else statement, ซึ่งดำเนินการเมื่อนิพจน์ตรรกะเป็นเท็จ |
3 | if ... else if ... else คำชี้แจง อัน if โครงสร้างคำสั่งสามารถมีทางเลือกได้ตั้งแต่หนึ่งรายการขึ้นไป else-ifโครงสร้าง เมื่อif เงื่อนไขล้มเหลวตามมาทันที else-ifถูกดำเนินการ เมื่อelse-if ยังล้มเหลวผู้สืบทอด else-if คำสั่ง (ถ้ามี) ถูกดำเนินการและอื่น ๆ |
4 | ซ้อนกันถ้าสร้าง คุณสามารถใช้ if หรือ else if คำสั่งภายในอื่น if หรือ else if คำสั่ง (s) |
5 | เลือกโครงสร้างกรณี ก select case คำสั่งอนุญาตให้ทดสอบตัวแปรเพื่อความเท่าเทียมกับรายการค่า |
6 | สร้างกรณีเลือกที่ซ้อนกัน คุณสามารถใช้ select case คำสั่งภายในอื่น select case คำสั่ง (s) |
อาจมีสถานการณ์เมื่อคุณต้องดำเนินการบล็อกรหัสหลาย ๆ ครั้ง โดยทั่วไปคำสั่งจะดำเนินการตามลำดับ: คำสั่งแรกในฟังก์ชันจะถูกเรียกใช้งานก่อนตามด้วยคำสั่งที่สองและอื่น ๆ
ภาษาโปรแกรมจัดเตรียมโครงสร้างการควบคุมต่างๆที่ช่วยให้เส้นทางการดำเนินการซับซ้อนมากขึ้น
คำสั่งวนซ้ำช่วยให้เราดำเนินการคำสั่งหรือกลุ่มของคำสั่งได้หลายครั้งและต่อไปนี้เป็นรูปแบบทั่วไปของคำสั่งลูปในภาษาโปรแกรมส่วนใหญ่ -
Fortran มีโครงสร้างลูปประเภทต่อไปนี้เพื่อจัดการกับข้อกำหนดการวนซ้ำ คลิกลิงก์ต่อไปนี้เพื่อตรวจสอบรายละเอียด
ซีเนียร์ No | ประเภทห่วงและคำอธิบาย |
---|---|
1 | ทำวน โครงสร้างนี้ช่วยให้คำสั่งหรือชุดของคำสั่งสามารถดำเนินการซ้ำ ๆ ได้ในขณะที่เงื่อนไขที่กำหนดเป็นจริง |
2 | ทำในขณะที่วนซ้ำ ทำซ้ำคำสั่งหรือกลุ่มของคำสั่งในขณะที่เงื่อนไขที่กำหนดเป็นจริง จะทดสอบเงื่อนไขก่อนที่จะดำเนินการร่างกายลูป |
3 | ลูปที่ซ้อนกัน คุณสามารถใช้การสร้างลูปอย่างน้อยหนึ่งรายการภายในโครงสร้างลูปอื่น ๆ |
คำสั่งควบคุมลูป
คำสั่งควบคุมแบบวนซ้ำเปลี่ยนการดำเนินการจากลำดับปกติ เมื่อการดำเนินการออกจากขอบเขตอ็อบเจ็กต์อัตโนมัติทั้งหมดที่สร้างขึ้นในขอบเขตนั้นจะถูกทำลาย
Fortran สนับสนุนคำสั่งควบคุมต่อไปนี้ คลิกลิงก์ต่อไปนี้เพื่อตรวจสอบรายละเอียด
ซีเนียร์ No | คำชี้แจงและคำอธิบายการควบคุม |
---|---|
1 | ทางออก หากดำเนินการคำสั่ง exit ลูปจะออกและการดำเนินการของโปรแกรมจะดำเนินต่อไปที่คำสั่งที่เรียกใช้งานได้แรกหลังจากคำสั่ง end do |
2 | วงจร หากมีการดำเนินการคำสั่งวงจรโปรแกรมจะทำงานต่อเมื่อเริ่มต้นการทำซ้ำครั้งถัดไป |
3 | หยุด หากคุณต้องการหยุดการทำงานของโปรแกรมคุณสามารถแทรกคำสั่งหยุดได้ |
ตัวเลขใน Fortran แสดงด้วยข้อมูลภายในสามประเภท -
- ประเภทจำนวนเต็ม
- ประเภทจริง
- ประเภทที่ซับซ้อน
ประเภทจำนวนเต็ม
ชนิดจำนวนเต็มสามารถเก็บได้เฉพาะค่าจำนวนเต็ม ตัวอย่างต่อไปนี้จะแยกค่าที่ใหญ่ที่สุดที่สามารถถือเป็นจำนวนเต็มสี่ไบต์ตามปกติ
program testingInt
implicit none
integer :: largeval
print *, huge(largeval)
end program testingInt
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
2147483647
โปรดทราบว่าไฟล์ huge()ฟังก์ชันให้จำนวนมากที่สุดที่สามารถถือได้โดยชนิดข้อมูลจำนวนเต็มเฉพาะ คุณยังสามารถระบุจำนวนไบต์โดยใช้kindตัวระบุ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
program testingInt
implicit none
!two byte integer
integer(kind = 2) :: shortval
!four byte integer
integer(kind = 4) :: longval
!eight byte integer
integer(kind = 8) :: verylongval
!sixteen byte integer
integer(kind = 16) :: veryverylongval
!default integer
integer :: defval
print *, huge(shortval)
print *, huge(longval)
print *, huge(verylongval)
print *, huge(veryverylongval)
print *, huge(defval)
end program testingInt
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
ประเภทจริง
จะเก็บตัวเลขทศนิยมเช่น 2.0, 3.1415, -100.876 เป็นต้น
ตามเนื้อผ้ามีสองอย่างที่แตกต่างกัน real ประเภท: ประเภทจริงเริ่มต้นและ double precision ประเภท.
อย่างไรก็ตาม Fortran 90/95 ให้การควบคุมความแม่นยำของชนิดข้อมูลจริงและจำนวนเต็มมากขึ้นผ่านไฟล์ kind ตัวระบุซึ่งเราจะศึกษาในไม่ช้า
ตัวอย่างต่อไปนี้แสดงการใช้ประเภทข้อมูลจริง -
program division
implicit none
! Define real variables
real :: p, q, realRes
! Define integer variables
integer :: i, j, intRes
! Assigning values
p = 2.0
q = 3.0
i = 2
j = 3
! floating point division
realRes = p/q
intRes = i/j
print *, realRes
print *, intRes
end program division
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
0.666666687
0
ประเภทที่ซับซ้อน
ใช้สำหรับจัดเก็บจำนวนเชิงซ้อน จำนวนเชิงซ้อนมี 2 ส่วนคือส่วนจริงและส่วนจินตภาพ หน่วยเก็บข้อมูลตัวเลขสองหน่วยต่อเนื่องกันจะจัดเก็บสองส่วนนี้
ตัวอย่างเช่นจำนวนเชิงซ้อน (3.0, -5.0) เท่ากับ 3.0 - 5.0i
ฟังก์ชันทั่วไป cmplx()สร้างจำนวนเชิงซ้อน สร้างผลลัพธ์ว่าใครเป็นส่วนจริงและส่วนจินตภาพเป็นความแม่นยำเดียวโดยไม่คำนึงถึงประเภทของอาร์กิวเมนต์อินพุต
program createComplex
implicit none
integer :: i = 10
real :: x = 5.17
print *, cmplx(i, x)
end program createComplex
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
(10.0000000, 5.17000008)
โปรแกรมต่อไปนี้แสดงให้เห็นถึงการคำนวณจำนวนเชิงซ้อน -
program ComplexArithmatic
implicit none
complex, parameter :: i = (0, 1) ! sqrt(-1)
complex :: x, y, z
x = (7, 8);
y = (5, -7)
write(*,*) i * x * y
z = x + y
print *, "z = x + y = ", z
z = x - y
print *, "z = x - y = ", z
z = x * y
print *, "z = x * y = ", z
z = x / y
print *, "z = x / y = ", z
end program ComplexArithmatic
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
(9.00000000, 91.0000000)
z = x + y = (12.0000000, 1.00000000)
z = x - y = (2.00000000, 15.0000000)
z = x * y = (91.0000000, -9.00000000)
z = x / y = (-0.283783793, 1.20270276)
ช่วงความแม่นยำและขนาดของตัวเลข
ช่วงของตัวเลขจำนวนเต็มความแม่นยำและขนาดของตัวเลขทศนิยมขึ้นอยู่กับจำนวนบิตที่จัดสรรให้กับชนิดข้อมูลเฉพาะ
ตารางต่อไปนี้แสดงจำนวนบิตและช่วงสำหรับจำนวนเต็ม -
จำนวนบิต | ค่าสูงสุด | เหตุผล |
---|---|---|
64 | 9,223,372,036,854,774,807 | (2 ** 63) –1 |
32 | 2,147,483,647 | (2 ** 31) –1 |
ตารางต่อไปนี้แสดงจำนวนบิตค่าที่น้อยที่สุดและมากที่สุดและความแม่นยำของจำนวนจริง
จำนวนบิต | มูลค่าที่ใหญ่ที่สุด | ค่าน้อยที่สุด | ความแม่นยำ |
---|---|---|---|
64 | 0.8E + 308 | 0.5E – 308 | 15–18 |
32 | 1.7E + 38 | 0.3E – 38 | 6-9 |
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e+40
y = 3.73e+40
z = x * y
print *, z
end program rangePrecision
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
x = 1.5e+40
1
Error : Real constant overflows its kind at (1)
main.f95:5.12:
y = 3.73e+40
1
Error : Real constant overflows its kind at (1)
ตอนนี้ให้เราใช้ตัวเลขที่น้อยลง -
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e+20
y = 3.73e+20
z = x * y
print *, z
z = x/y
print *, z
end program rangePrecision
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Infinity
0.402144760
ตอนนี้มาดู underflow -
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e-30
y = 3.73e-60
z = x * y
print *, z
z = x/y
print *, z
end program rangePrecision
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
y = 3.73e-60
1
Warning : Real constant underflows its kind at (1)
Executing the program....
$demo
0.00000000E+00
Infinity
ตัวระบุชนิด
ในการเขียนโปรแกรมทางวิทยาศาสตร์มักจะต้องทราบช่วงและความแม่นยำของข้อมูลของแพลตฟอร์มฮาร์ดแวร์ที่กำลังทำงานอยู่
ฟังก์ชันที่แท้จริง kind() ช่วยให้คุณสามารถสอบถามรายละเอียดของการแสดงข้อมูลของฮาร์ดแวร์ก่อนที่จะรันโปรแกรม
program kindCheck
implicit none
integer :: i
real :: r
complex :: cp
print *,' Integer ', kind(i)
print *,' Real ', kind(r)
print *,' Complex ', kind(cp)
end program kindCheck
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Integer 4
Real 4
Complex 4
คุณยังสามารถตรวจสอบประเภทข้อมูลทั้งหมดได้ -
program checkKind
implicit none
integer :: i
real :: r
character :: c
logical :: lg
complex :: cp
print *,' Integer ', kind(i)
print *,' Real ', kind(r)
print *,' Complex ', kind(cp)
print *,' Character ', kind(c)
print *,' Logical ', kind(lg)
end program checkKind
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Integer 4
Real 4
Complex 4
Character 1
Logical 4
ภาษา Fortran สามารถถือว่าอักขระเป็นอักขระเดี่ยวหรือสตริงที่ต่อเนื่องกัน
อักขระอาจเป็นสัญลักษณ์ใด ๆ ที่นำมาจากชุดอักขระพื้นฐานเช่นจากตัวอักษรตัวเลขทศนิยมขีดล่างและอักขระพิเศษ 21 ตัว
ค่าคงที่ของอักขระคือสตริงอักขระที่มีค่าคงที่
ชนิดข้อมูลที่แท้จริง characterเก็บอักขระและสตริง ความยาวของสตริงสามารถระบุได้โดยlenตัวระบุ หากไม่ได้ระบุความยาวก็คือ 1. คุณสามารถอ้างถึงอักขระแต่ละตัวภายในสตริงที่อ้างอิงตามตำแหน่ง อักขระทางซ้ายสุดอยู่ที่ตำแหน่ง 1
การประกาศตัวละคร
การประกาศข้อมูลประเภทอักขระจะเหมือนกับตัวแปรอื่น ๆ -
type-specifier :: variable_name
ตัวอย่างเช่น,
character :: reply, sex
คุณสามารถกำหนดค่าเช่น
reply = ‘N’
sex = ‘F’
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการประกาศและการใช้ชนิดข้อมูลอักขระ -
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 25)::greetings
title = 'Mr. '
firstname = 'Rowan '
surname = 'Atkinson'
greetings = 'A big hello from Mr. Bean'
print *, 'Here is ', title, firstname, surname
print *, greetings
end program hello
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
การต่ออักขระ
ตัวดำเนินการเชื่อมต่อ // เชื่อมต่ออักขระ
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 40):: name
character(len = 25)::greetings
title = 'Mr. '
firstname = 'Rowan '
surname = 'Atkinson'
name = title//firstname//surname
greetings = 'A big hello from Mr. Bean'
print *, 'Here is ', name
print *, greetings
end program hello
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Here is Mr.Rowan Atkinson
A big hello from Mr.Bean
ฟังก์ชั่นตัวละครบางอย่าง
ตารางต่อไปนี้แสดงฟังก์ชันอักขระที่ใช้บ่อยพร้อมกับคำอธิบาย -
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | len(string) ส่งกลับความยาวของสตริงอักขระ |
2 | index(string,sustring) มันกำหนดตำแหน่งของสตริงย่อยในสตริงอื่นส่งคืน 0 หากไม่พบ |
3 | achar(int) จะแปลงจำนวนเต็มเป็นอักขระ |
4 | iachar(c) มันจะแปลงอักขระเป็นจำนวนเต็ม |
5 | trim(string) ส่งคืนสตริงโดยลบช่องว่างต่อท้ายออก |
6 | scan(string, chars) โดยจะค้นหา "สตริง" จากซ้ายไปขวา (ยกเว้น back = .true.) สำหรับการเกิดครั้งแรกของอักขระใด ๆ ที่อยู่ใน "ตัวอักษร" จะส่งคืนจำนวนเต็มที่ให้ตำแหน่งของอักขระนั้นหรือเป็นศูนย์หากไม่พบอักขระใดใน "ตัวอักษร" |
7 | verify(string, chars) มันจะสแกน "สตริง" จากซ้ายไปขวา (ยกเว้น back = .true.) สำหรับการเกิดครั้งแรกของอักขระใด ๆ ที่ไม่มีอยู่ใน "ตัวอักษร" จะส่งคืนจำนวนเต็มที่ให้ตำแหน่งของอักขระนั้นหรือเป็นศูนย์หากพบเฉพาะอักขระใน "ตัวอักษร" |
8 | adjustl(string) เหลือเพียงแสดงอักขระที่มีอยู่ใน "สตริง" |
9 | adjustr(string) มันแสดงตัวอักษรที่มีอยู่ใน "สตริง" อย่างถูกต้อง |
10 | len_trim(string) ส่งคืนจำนวนเต็มเท่ากับความยาวของ "string" (len (string)) ลบด้วยจำนวนช่องว่างต่อท้าย |
11 | repeat(string,ncopy) ส่งคืนสตริงที่มีความยาวเท่ากับ "ncopy" คูณความยาวของ "สตริง" และมีสำเนา "สตริง" ที่ต่อกัน "ncopy" |
ตัวอย่าง 1
ตัวอย่างนี้แสดงการใช้ไฟล์ index ฟังก์ชัน -
program testingChars
implicit none
character (80) :: text
integer :: i
text = 'The intrinsic data type character stores characters and strings.'
i=index(text,'character')
if (i /= 0) then
print *, ' The word character found at position ',i
print *, ' in text: ', text
end if
end program testingChars
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
The word character found at position 25
in text : The intrinsic data type character stores characters and strings.
ตัวอย่าง 2
ตัวอย่างนี้แสดงให้เห็นถึงการใช้ไฟล์ trim ฟังก์ชัน -
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
print *, 'Here is', title, firstname, surname
print *, 'Here is', trim(title),' ',trim(firstname),' ', trim(surname)
end program hello
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Here isMr. Rowan Atkinson
Here isMr. Rowan Atkinson
ตัวอย่างที่ 3
ตัวอย่างนี้แสดงให้เห็นถึงการใช้ achar ฟังก์ชัน -
program testingChars
implicit none
character:: ch
integer:: i
do i = 65, 90
ch = achar(i)
print*, i, ' ', ch
end do
end program testingChars
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
65 A
66 B
67 C
68 D
69 E
70 F
71 G
72 H
73 I
74 J
75 K
76 L
77 M
78 N
79 O
80 P
81 Q
82 R
83 S
84 T
85 U
86 V
87 W
88 X
89 Y
90 Z
การตรวจสอบลำดับคำศัพท์ของอักขระ
ฟังก์ชันต่อไปนี้กำหนดลำดับคำศัพท์ของอักขระ -
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | lle(char, char) เปรียบเทียบว่าอักขระตัวแรกมีศัพท์น้อยกว่าหรือเท่ากับตัวที่สองหรือไม่ |
2 | lge(char, char) เปรียบเทียบว่าอักขระตัวแรกมีค่ามากกว่าหรือเท่ากับตัวที่สองหรือไม่ |
3 | lgt(char, char) เปรียบเทียบว่าอักขระตัวแรกมีค่ามากกว่าตัวที่สองหรือไม่ |
4 | llt(char, char) เปรียบเทียบว่าอักขระตัวแรกมีศัพท์น้อยกว่าตัวที่สองหรือไม่ |
Example 4
ฟังก์ชันต่อไปนี้แสดงให้เห็นถึงการใช้งาน -
program testingChars
implicit none
character:: a, b, c
a = 'A'
b = 'a'
c = 'B'
if(lgt(a,b)) then
print *, 'A is lexically greater than a'
else
print *, 'a is lexically greater than A'
end if
if(lgt(a,c)) then
print *, 'A is lexically greater than B'
else
print *, 'B is lexically greater than A'
end if
if(llt(a,b)) then
print *, 'A is lexically less than a'
end if
if(llt(a,c)) then
print *, 'A is lexically less than B'
end if
end program testingChars
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
a is lexically greater than A
B is lexically greater than A
A is lexically less than a
A is lexically less than B
ภาษา Fortran สามารถถือว่าอักขระเป็นอักขระเดี่ยวหรือสตริงที่ต่อเนื่องกัน
สตริงอักขระอาจมีความยาวได้เพียงอักขระเดียวหรืออาจมีความยาวเป็นศูนย์ก็ได้ ใน Fortran ค่าคงที่ของอักขระจะได้รับระหว่างคู่ของเครื่องหมายคำพูดคู่หรือเดี่ยว
ชนิดข้อมูลที่แท้จริง characterเก็บอักขระและสตริง ความยาวของสตริงสามารถระบุได้โดยlen specifier. หากไม่ได้ระบุความยาวก็คือ 1. คุณสามารถอ้างถึงอักขระแต่ละตัวภายในสตริงที่อ้างอิงตามตำแหน่ง อักขระทางซ้ายสุดอยู่ที่ตำแหน่ง 1
การประกาศสตริง
การประกาศสตริงจะเหมือนกับตัวแปรอื่น ๆ -
type-specifier :: variable_name
ตัวอย่างเช่น,
Character(len = 20) :: firstname, surname
คุณสามารถกำหนดค่าเช่น
character (len = 40) :: name
name = “Zara Ali”
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงการประกาศและการใช้ชนิดข้อมูลอักขระ -
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
greetings = 'A big hello from Mr. Beans'
print *, 'Here is', title, firstname, surname
print *, greetings
end program hello
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Here isMr. Rowan Atkinson
A big hello from Mr. Bean
การต่อสตริง
ตัวดำเนินการเชื่อมต่อ // เชื่อมสตริงเข้าด้วยกัน
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 40):: name
character(len = 25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
name = title//firstname//surname
greetings = 'A big hello from Mr. Beans'
print *, 'Here is', name
print *, greetings
end program hello
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
การแยกสตริงย่อย
ใน Fortran คุณสามารถแยกสตริงย่อยออกจากสตริงได้โดยการสร้างดัชนีสตริงโดยให้จุดเริ่มต้นและดัชนีสิ้นสุดของสตริงย่อยในวงเล็บคู่หนึ่ง สิ่งนี้เรียกว่าตัวระบุขอบเขต
ตัวอย่างต่อไปนี้แสดงวิธีแยกสตริงย่อย 'world' ออกจากสตริง 'hello world' -
program subString
character(len = 11)::hello
hello = "Hello World"
print*, hello(7:11)
end program subString
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
World
ตัวอย่าง
ตัวอย่างต่อไปนี้ใช้ date_and_timeฟังก์ชันเพื่อให้สตริงวันที่และเวลา เราใช้ตัวระบุขอบเขตเพื่อแยกข้อมูลปีวันที่เดือนชั่วโมงนาทีและวินาทีออกจากกัน
program datetime
implicit none
character(len = 8) :: dateinfo ! ccyymmdd
character(len = 4) :: year, month*2, day*2
character(len = 10) :: timeinfo ! hhmmss.sss
character(len = 2) :: hour, minute, second*6
call date_and_time(dateinfo, timeinfo)
! let’s break dateinfo into year, month and day.
! dateinfo has a form of ccyymmdd, where cc = century, yy = year
! mm = month and dd = day
year = dateinfo(1:4)
month = dateinfo(5:6)
day = dateinfo(7:8)
print*, 'Date String:', dateinfo
print*, 'Year:', year
print *,'Month:', month
print *,'Day:', day
! let’s break timeinfo into hour, minute and second.
! timeinfo has a form of hhmmss.sss, where h = hour, m = minute
! and s = second
hour = timeinfo(1:2)
minute = timeinfo(3:4)
second = timeinfo(5:10)
print*, 'Time String:', timeinfo
print*, 'Hour:', hour
print*, 'Minute:', minute
print*, 'Second:', second
end program datetime
เมื่อคุณรวบรวมและดำเนินการโปรแกรมข้างต้นโปรแกรมจะให้ข้อมูลวันที่และเวลาโดยละเอียด -
Date String: 20140803
Year: 2014
Month: 08
Day: 03
Time String: 075835.466
Hour: 07
Minute: 58
Second: 35.466
การตัดแต่งสตริง
trim ฟังก์ชันรับสตริงและส่งคืนสตริงอินพุตหลังจากลบช่องว่างต่อท้ายทั้งหมด
ตัวอย่าง
program trimString
implicit none
character (len = *), parameter :: fname="Susanne", sname="Rizwan"
character (len = 20) :: fullname
fullname = fname//" "//sname !concatenating the strings
print*,fullname,", the beautiful dancer from the east!"
print*,trim(fullname),", the beautiful dancer from the east!"
end program trimString
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Susanne Rizwan , the beautiful dancer from the east!
Susanne Rizwan, the beautiful dancer from the east!
การปรับสตริงซ้ายและขวา
ฟังก์ชั่น adjustl รับสตริงและส่งคืนโดยการลบช่องว่างนำหน้าและต่อท้ายเป็นช่องว่างต่อท้าย
ฟังก์ชั่น adjustr รับสตริงและส่งคืนโดยการลบช่องว่างต่อท้ายและต่อท้ายเป็นช่องว่างนำหน้า
ตัวอย่าง
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 40):: name
character(len = 25):: greetings
title = 'Mr. '
firstname = 'Rowan'
surname = 'Atkinson'
greetings = 'A big hello from Mr. Beans'
name = adjustl(title)//adjustl(firstname)//adjustl(surname)
print *, 'Here is', name
print *, greetings
name = adjustr(title)//adjustr(firstname)//adjustr(surname)
print *, 'Here is', name
print *, greetings
name = trim(title)//trim(firstname)//trim(surname)
print *, 'Here is', name
print *, greetings
end program hello
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
Here is Mr.RowanAtkinson
A big hello from Mr. Bean
การค้นหา Substring ใน String
ฟังก์ชันดัชนีรับสองสตริงและตรวจสอบว่าสตริงที่สองเป็นสตริงย่อยของสตริงแรกหรือไม่ ถ้าอาร์กิวเมนต์ที่สองเป็นสตริงย่อยของอาร์กิวเมนต์แรกจะส่งคืนจำนวนเต็มซึ่งเป็นดัชนีเริ่มต้นของสตริงที่สองในสตริงแรกมิฉะนั้นจะส่งกลับค่าศูนย์
ตัวอย่าง
program hello
implicit none
character(len=30) :: myString
character(len=10) :: testString
myString = 'This is a test'
testString = 'test'
if(index(myString, testString) == 0)then
print *, 'test is not found'
else
print *, 'test is found at index: ', index(myString, testString)
end if
end program hello
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
test is found at index: 11
อาร์เรย์สามารถจัดเก็บคอลเลกชันตามลำดับที่มีขนาดคงที่ขององค์ประกอบประเภทเดียวกัน อาร์เรย์ใช้ในการจัดเก็บชุดข้อมูล แต่มักจะมีประโยชน์มากกว่าที่จะคิดว่าอาร์เรย์เป็นชุดของตัวแปรประเภทเดียวกัน
อาร์เรย์ทั้งหมดประกอบด้วยตำแหน่งหน่วยความจำที่อยู่ติดกัน ที่อยู่ต่ำสุดสอดคล้องกับองค์ประกอบแรกและที่อยู่สูงสุดขององค์ประกอบสุดท้าย
หมายเลข (1) | หมายเลข (2) | หมายเลข (3) | หมายเลข (4) | … |
อาร์เรย์สามารถเป็นมิติเดียว (เช่นเวกเตอร์) สองมิติ (เช่นเมทริกซ์) และฟอร์แทรนช่วยให้คุณสร้างอาร์เรย์ได้สูงสุด 7 มิติ
การประกาศอาร์เรย์
อาร์เรย์ถูกประกาศด้วย dimension แอตทริบิวต์
ตัวอย่างเช่นหากต้องการประกาศอาร์เรย์หนึ่งมิติที่มีชื่อว่า number ของจำนวนจริงที่มี 5 องค์ประกอบคุณต้องเขียน
real, dimension(5) :: numbers
แต่ละองค์ประกอบของอาร์เรย์ถูกอ้างอิงโดยการระบุตัวห้อย องค์ประกอบแรกของอาร์เรย์มีตัวห้อยหนึ่งตัว หมายเลขอาร์เรย์ประกอบด้วยตัวแปรจริงห้าตัว ได้แก่ ตัวเลข (1) ตัวเลข (2) ตัวเลข (3) ตัวเลข (4) และตัวเลข (5)
ในการสร้างอาร์เรย์สองมิติ 5 x 5 ของจำนวนเต็มชื่อเมทริกซ์คุณเขียน -
integer, dimension (5,5) :: matrix
คุณยังสามารถประกาศอาร์เรย์ที่มีขอบเขตล่างที่ชัดเจนได้เช่น -
real, dimension(2:6) :: numbers
integer, dimension (-3:2,0:4) :: matrix
การกำหนดค่า
คุณสามารถกำหนดค่าให้กับสมาชิกแต่ละคนเช่น
numbers(1) = 2.0
หรือคุณสามารถใช้การวนซ้ำ
do i =1,5
numbers(i) = i * 2.0
end do
องค์ประกอบอาร์เรย์หนึ่งมิติสามารถกำหนดค่าได้โดยตรงโดยใช้สัญลักษณ์รูปมือสั้น ๆ ที่เรียกว่าตัวสร้างอาร์เรย์เช่น
numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
please note that there are no spaces allowed between the brackets ‘( ‘and the back slash ‘/’
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิดที่กล่าวถึงข้างต้น
program arrayProg
real :: numbers(5) !one dimensional integer array
integer :: matrix(3,3), i , j !two dimensional real array
!assigning some values to the array numbers
do i=1,5
numbers(i) = i * 2.0
end do
!display the values
do i = 1, 5
Print *, numbers(i)
end do
!assigning some values to the array matrix
do i=1,3
do j = 1, 3
matrix(i, j) = i+j
end do
end do
!display the values
do i=1,3
do j = 1, 3
Print *, matrix(i,j)
end do
end do
!short hand assignment
numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
!display the values
do i = 1, 5
Print *, numbers(i)
end do
end program arrayProg
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
2.00000000
4.00000000
6.00000000
8.00000000
10.0000000
2
3
4
3
4
5
4
5
6
1.50000000
3.20000005
4.50000000
0.899999976
7.19999981
คำศัพท์ที่เกี่ยวข้องกับ Array
ตารางต่อไปนี้ให้คำศัพท์ที่เกี่ยวข้องกับอาร์เรย์ -
ระยะเวลา | ความหมาย |
---|---|
อันดับ | มันคือจำนวนมิติที่อาร์เรย์มี ตัวอย่างเช่นสำหรับอาร์เรย์ที่ชื่อเมทริกซ์อันดับคือ 2 และสำหรับอาร์เรย์ที่มีชื่อตัวเลขอันดับคือ 1 |
ขอบเขต | มันคือจำนวนองค์ประกอบตามมิติ ตัวอย่างเช่นหมายเลขอาร์เรย์มีขอบเขต 5 และอาร์เรย์ชื่อเมทริกซ์มีขอบเขต 3 ในทั้งสองมิติ |
รูปร่าง | รูปร่างของอาร์เรย์คืออาร์เรย์จำนวนเต็มหนึ่งมิติซึ่งมีจำนวนองค์ประกอบ (ขอบเขต) ในแต่ละมิติ ตัวอย่างเช่นสำหรับเมทริกซ์อาร์เรย์รูปร่างคือ (3, 3) และหมายเลขอาร์เรย์คือ (5) |
ขนาด | เป็นจำนวนองค์ประกอบที่อาร์เรย์ประกอบด้วย สำหรับเมทริกซ์อาร์เรย์คือ 9 และสำหรับหมายเลขอาร์เรย์คือ 5 |
การส่งอาร์เรย์ไปยังขั้นตอน
คุณสามารถส่งอาร์เรย์ไปยังโพรซีเดอร์เป็นอาร์กิวเมนต์ได้ ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
program arrayToProcedure
implicit none
integer, dimension (5) :: myArray
integer :: i
call fillArray (myArray)
call printArray(myArray)
end program arrayToProcedure
subroutine fillArray (a)
implicit none
integer, dimension (5), intent (out) :: a
! local variables
integer :: i
do i = 1, 5
a(i) = i
end do
end subroutine fillArray
subroutine printArray(a)
integer, dimension (5) :: a
integer::i
do i = 1, 5
Print *, a(i)
end do
end subroutine printArray
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
1
2
3
4
5
ในตัวอย่างข้างต้นรูทีนย่อย fillArray และ printArray สามารถถูกเรียกด้วยอาร์เรย์ที่มีมิติ 5 เท่านั้นอย่างไรก็ตามในการเขียนรูทีนย่อยที่สามารถใช้สำหรับอาร์เรย์ทุกขนาดคุณสามารถเขียนซ้ำได้โดยใช้เทคนิคต่อไปนี้ -
program arrayToProcedure
implicit none
integer, dimension (10) :: myArray
integer :: i
interface
subroutine fillArray (a)
integer, dimension(:), intent (out) :: a
integer :: i
end subroutine fillArray
subroutine printArray (a)
integer, dimension(:) :: a
integer :: i
end subroutine printArray
end interface
call fillArray (myArray)
call printArray(myArray)
end program arrayToProcedure
subroutine fillArray (a)
implicit none
integer,dimension (:), intent (out) :: a
! local variables
integer :: i, arraySize
arraySize = size(a)
do i = 1, arraySize
a(i) = i
end do
end subroutine fillArray
subroutine printArray(a)
implicit none
integer,dimension (:) :: a
integer::i, arraySize
arraySize = size(a)
do i = 1, arraySize
Print *, a(i)
end do
end subroutine printArray
โปรดทราบว่าโปรแกรมกำลังใช้ไฟล์ size เพื่อรับขนาดของอาร์เรย์
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
1
2
3
4
5
6
7
8
9
10
ส่วนอาร์เรย์
จนถึงตอนนี้เราได้อ้างถึงอาร์เรย์ทั้งหมดแล้ว Fortran ให้วิธีง่ายๆในการอ้างถึงองค์ประกอบต่างๆหรือส่วนของอาร์เรย์โดยใช้คำสั่งเดียว
ในการเข้าถึงส่วนอาร์เรย์คุณต้องระบุส่วนล่างและด้านบนของส่วนรวมทั้งการก้าว (ส่วนเพิ่ม) สำหรับมิติทั้งหมด สัญกรณ์นี้เรียกว่าsubscript triplet:
array ([lower]:[upper][:stride], ...)
เมื่อไม่มีการกล่าวถึงขอบเขตล่างและบนจะมีค่าเริ่มต้นเป็นขอบเขตที่คุณประกาศไว้และค่าก้าวย่างจะมีค่าเริ่มต้นเป็น 1
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
program arraySubsection
real, dimension(10) :: a, b
integer:: i, asize, bsize
a(1:7) = 5.0 ! a(1) to a(7) assigned 5.0
a(8:) = 0.0 ! rest are 0.0
b(2:10:2) = 3.9
b(1:9:2) = 2.5
!display
asize = size(a)
bsize = size(b)
do i = 1, asize
Print *, a(i)
end do
do i = 1, bsize
Print *, b(i)
end do
end program arraySubsection
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
0.00000000E+00
0.00000000E+00
0.00000000E+00
2.50000000
3.90000010
2.50000000
3.90000010
2.50000000
3.90000010
2.50000000
3.90000010
2.50000000
3.90000010
Array Intrinsic Functions
Fortran 90/95 มีขั้นตอนภายในหลายอย่าง สามารถแบ่งออกเป็น 7 ประเภท
การคูณเวกเตอร์และเมทริกซ์
Reduction
Inquiry
Construction
Reshape
Manipulation
Location
ก dynamic array คืออาร์เรย์ซึ่งไม่ทราบขนาดในเวลาคอมไพล์ แต่จะทราบในเวลาดำเนินการ
อาร์เรย์แบบไดนามิกถูกประกาศด้วยแอตทริบิวต์ allocatable.
ตัวอย่างเช่น,
real, dimension (:,:), allocatable :: darray
อันดับของอาร์เรย์กล่าวคือต้องมีการกล่าวถึงมิติในการจัดสรรหน่วยความจำให้กับอาร์เรย์ดังกล่าวคุณใช้ allocate ฟังก์ชัน
allocate ( darray(s1,s2) )
หลังจากใช้อาร์เรย์แล้วในโปรแกรมหน่วยความจำที่สร้างขึ้นควรได้รับการปลดปล่อยโดยใช้ deallocate ฟังก์ชัน
deallocate (darray)
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิดที่กล่าวถึงข้างต้น
program dynamic_array
implicit none
!rank is 2, but size not known
real, dimension (:,:), allocatable :: darray
integer :: s1, s2
integer :: i, j
print*, "Enter the size of the array:"
read*, s1, s2
! allocate memory
allocate ( darray(s1,s2) )
do i = 1, s1
do j = 1, s2
darray(i,j) = i*j
print*, "darray(",i,",",j,") = ", darray(i,j)
end do
end do
deallocate (darray)
end program dynamic_array
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
Enter the size of the array: 3,4
darray( 1 , 1 ) = 1.00000000
darray( 1 , 2 ) = 2.00000000
darray( 1 , 3 ) = 3.00000000
darray( 1 , 4 ) = 4.00000000
darray( 2 , 1 ) = 2.00000000
darray( 2 , 2 ) = 4.00000000
darray( 2 , 3 ) = 6.00000000
darray( 2 , 4 ) = 8.00000000
darray( 3 , 1 ) = 3.00000000
darray( 3 , 2 ) = 6.00000000
darray( 3 , 3 ) = 9.00000000
darray( 3 , 4 ) = 12.0000000
การใช้คำชี้แจงข้อมูล
data คำสั่งสามารถใช้สำหรับการเริ่มต้นอาร์เรย์มากกว่าหนึ่งอาร์เรย์หรือสำหรับการเริ่มต้นส่วนอาร์เรย์
ไวยากรณ์ของคำสั่งข้อมูลคือ -
data variable / list / ...
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
program dataStatement
implicit none
integer :: a(5), b(3,3), c(10),i, j
data a /7,8,9,10,11/
data b(1,:) /1,1,1/
data b(2,:)/2,2,2/
data b(3,:)/3,3,3/
data (c(i),i = 1,10,2) /4,5,6,7,8/
data (c(i),i = 2,10,2)/5*2/
Print *, 'The A array:'
do j = 1, 5
print*, a(j)
end do
Print *, 'The B array:'
do i = lbound(b,1), ubound(b,1)
write(*,*) (b(i,j), j = lbound(b,2), ubound(b,2))
end do
Print *, 'The C array:'
do j = 1, 10
print*, c(j)
end do
end program dataStatement
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
The A array:
7
8
9
10
11
The B array:
1 1 1
2 2 2
3 3 3
The C array:
4
2
5
2
6
2
7
2
8
2
การใช้ Where Statement
whereคำสั่งอนุญาตให้คุณใช้องค์ประกอบบางอย่างของอาร์เรย์ในนิพจน์ขึ้นอยู่กับผลลัพธ์ของเงื่อนไขทางตรรกะบางอย่าง อนุญาตให้ดำเนินการกับนิพจน์บนองค์ประกอบหากเงื่อนไขที่กำหนดเป็นจริง
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
program whereStatement
implicit none
integer :: a(3,5), i , j
do i = 1,3
do j = 1, 5
a(i,j) = j-i
end do
end do
Print *, 'The A array:'
do i = lbound(a,1), ubound(a,1)
write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
end do
where( a<0 )
a = 1
elsewhere
a = 5
end where
Print *, 'The A array:'
do i = lbound(a,1), ubound(a,1)
write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
end do
end program whereStatement
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
The A array:
0 1 2 3 4
-1 0 1 2 3
-2 -1 0 1 2
The A array:
5 5 5 5 5
1 5 5 5 5
1 1 5 5 5
Fortran ช่วยให้คุณกำหนดชนิดข้อมูลที่ได้รับ ชนิดข้อมูลที่ได้รับเรียกอีกอย่างว่าโครงสร้างและสามารถประกอบด้วยออบเจ็กต์ข้อมูลประเภทต่างๆ
ชนิดข้อมูลที่ได้มาใช้เพื่อแสดงระเบียน เช่นคุณต้องการติดตามหนังสือของคุณในห้องสมุดคุณอาจต้องการติดตามคุณลักษณะต่อไปนี้เกี่ยวกับหนังสือแต่ละเล่ม -
- Title
- Author
- Subject
- รหัสหนังสือ
การกำหนดชนิดข้อมูลที่ได้รับ
เพื่อกำหนดข้อมูลที่ได้รับ typeประเภทและ end typeมีการใช้งบ . คำสั่ง type กำหนดชนิดข้อมูลใหม่โดยมีสมาชิกมากกว่าหนึ่งคนสำหรับโปรแกรมของคุณ รูปแบบของคำสั่ง type คือ -
type type_name
declarations
end type
นี่คือวิธีที่คุณจะประกาศโครงสร้างหนังสือ -
type Books
character(len = 50) :: title
character(len = 50) :: author
character(len = 150) :: subject
integer :: book_id
end type Books
การเข้าถึงสมาชิกโครงสร้าง
ออบเจ็กต์ของชนิดข้อมูลที่ได้รับเรียกว่าโครงสร้าง
สามารถสร้างโครงสร้างประเภทหนังสือในคำสั่งประเภทเช่น -
type(Books) :: book1
ส่วนประกอบของโครงสร้างสามารถเข้าถึงได้โดยใช้อักขระตัวเลือกส่วนประกอบ (%) -
book1%title = "C Programming"
book1%author = "Nuha Ali"
book1%subject = "C Programming Tutorial"
book1%book_id = 6495407
Note that there are no spaces before and after the % symbol.
ตัวอย่าง
โปรแกรมต่อไปนี้แสดงให้เห็นถึงแนวคิดข้างต้น -
program deriveDataType
!type declaration
type Books
character(len = 50) :: title
character(len = 50) :: author
character(len = 150) :: subject
integer :: book_id
end type Books
!declaring type variables
type(Books) :: book1
type(Books) :: book2
!accessing the components of the structure
book1%title = "C Programming"
book1%author = "Nuha Ali"
book1%subject = "C Programming Tutorial"
book1%book_id = 6495407
book2%title = "Telecom Billing"
book2%author = "Zara Ali"
book2%subject = "Telecom Billing Tutorial"
book2%book_id = 6495700
!display book info
Print *, book1%title
Print *, book1%author
Print *, book1%subject
Print *, book1%book_id
Print *, book2%title
Print *, book2%author
Print *, book2%subject
Print *, book2%book_id
end program deriveDataType
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
C Programming
Nuha Ali
C Programming Tutorial
6495407
Telecom Billing
Zara Ali
Telecom Billing Tutorial
6495700
อาร์เรย์ของโครงสร้าง
คุณยังสามารถสร้างอาร์เรย์ของประเภทที่ได้รับ -
type(Books), dimension(2) :: list
แต่ละองค์ประกอบของอาร์เรย์สามารถเข้าถึงได้โดย -
list(1)%title = "C Programming"
list(1)%author = "Nuha Ali"
list(1)%subject = "C Programming Tutorial"
list(1)%book_id = 6495407
โปรแกรมต่อไปนี้แสดงให้เห็นถึงแนวคิด -
program deriveDataType
!type declaration
type Books
character(len = 50) :: title
character(len = 50) :: author
character(len = 150) :: subject
integer :: book_id
end type Books
!declaring array of books
type(Books), dimension(2) :: list
!accessing the components of the structure
list(1)%title = "C Programming"
list(1)%author = "Nuha Ali"
list(1)%subject = "C Programming Tutorial"
list(1)%book_id = 6495407
list(2)%title = "Telecom Billing"
list(2)%author = "Zara Ali"
list(2)%subject = "Telecom Billing Tutorial"
list(2)%book_id = 6495700
!display book info
Print *, list(1)%title
Print *, list(1)%author
Print *, list(1)%subject
Print *, list(1)%book_id
Print *, list(1)%title
Print *, list(2)%author
Print *, list(2)%subject
Print *, list(2)%book_id
end program deriveDataType
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
C Programming
Nuha Ali
C Programming Tutorial
6495407
C Programming
Zara Ali
Telecom Billing Tutorial
6495700
ในภาษาโปรแกรมส่วนใหญ่ตัวแปรตัวชี้จะเก็บที่อยู่หน่วยความจำของวัตถุ อย่างไรก็ตามใน Fortran ตัวชี้เป็นวัตถุข้อมูลที่มีฟังก์ชันมากกว่าการจัดเก็บที่อยู่หน่วยความจำ ประกอบด้วยข้อมูลเพิ่มเติมเกี่ยวกับออบเจ็กต์เฉพาะเช่นประเภทอันดับขอบเขตและที่อยู่หน่วยความจำ
ตัวชี้เชื่อมโยงกับเป้าหมายโดยการจัดสรรหรือการกำหนดตัวชี้
การประกาศตัวแปรตัวชี้
ตัวแปรตัวชี้ถูกประกาศด้วยแอตทริบิวต์ตัวชี้
ตัวอย่างต่อไปนี้แสดงการประกาศตัวแปรตัวชี้ -
integer, pointer :: p1 ! pointer to integer
real, pointer, dimension (:) :: pra ! pointer to 1-dim real array
real, pointer, dimension (:,:) :: pra2 ! pointer to 2-dim real array
ตัวชี้สามารถชี้ไปที่ -
พื้นที่ของหน่วยความจำที่จัดสรรแบบไดนามิก
ออบเจ็กต์ข้อมูลประเภทเดียวกับตัวชี้ที่มี target แอตทริบิวต์
การจัดสรรพื้นที่สำหรับตัวชี้
allocateคำสั่งอนุญาตให้คุณจัดสรรพื้นที่สำหรับวัตถุตัวชี้ ตัวอย่างเช่น -
program pointerExample
implicit none
integer, pointer :: p1
allocate(p1)
p1 = 1
Print *, p1
p1 = p1 + 4
Print *, p1
end program pointerExample
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
1
5
คุณควรล้างพื้นที่เก็บข้อมูลที่จัดสรรโดยไฟล์ deallocate เมื่อไม่จำเป็นต้องใช้อีกต่อไปและหลีกเลี่ยงการสะสมของพื้นที่หน่วยความจำที่ไม่ได้ใช้และใช้ไม่ได้
เป้าหมายและความสัมพันธ์
เป้าหมายเป็นตัวแปรปกติอีกตัวหนึ่งโดยมีพื้นที่ว่างสำหรับมัน ต้องประกาศตัวแปรเป้าหมายด้วยtarget แอตทริบิวต์
คุณเชื่อมโยงตัวแปรตัวชี้กับตัวแปรเป้าหมายโดยใช้ตัวดำเนินการเชื่อมโยง (=>)
ให้เราเขียนตัวอย่างก่อนหน้านี้ใหม่เพื่อแสดงแนวคิด -
program pointerExample
implicit none
integer, pointer :: p1
integer, target :: t1
p1=>t1
p1 = 1
Print *, p1
Print *, t1
p1 = p1 + 4
Print *, p1
Print *, t1
t1 = 8
Print *, p1
Print *, t1
end program pointerExample
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
1
1
5
5
8
8
ตัวชี้สามารถ -
- Undefined
- Associated
- Disassociated
ในโปรแกรมข้างต้นเรามี associatedตัวชี้ p1 กับเป้าหมาย t1 โดยใช้ตัวดำเนินการ => ฟังก์ชันที่เกี่ยวข้องทดสอบสถานะการเชื่อมโยงของตัวชี้
nullify คำสั่งยกเลิกการเชื่อมโยงตัวชี้จากเป้าหมาย
Nullify ไม่ทำให้เป้าหมายว่างเปล่าเนื่องจากอาจมีตัวชี้มากกว่าหนึ่งตัวชี้ไปที่เป้าหมายเดียวกัน อย่างไรก็ตามการล้างตัวชี้ยังหมายถึงการทำให้เป็นโมฆะด้วย
ตัวอย่าง 1
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
program pointerExample
implicit none
integer, pointer :: p1
integer, target :: t1
integer, target :: t2
p1=>t1
p1 = 1
Print *, p1
Print *, t1
p1 = p1 + 4
Print *, p1
Print *, t1
t1 = 8
Print *, p1
Print *, t1
nullify(p1)
Print *, t1
p1=>t2
Print *, associated(p1)
Print*, associated(p1, t1)
Print*, associated(p1, t2)
!what is the value of p1 at present
Print *, p1
Print *, t2
p1 = 10
Print *, p1
Print *, t2
end program pointerExample
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
1
1
5
5
8
8
8
T
F
T
952754640
952754640
10
10
โปรดทราบว่าทุกครั้งที่คุณเรียกใช้รหัสที่อยู่หน่วยความจำจะแตกต่างกัน
ตัวอย่าง 2
program pointerExample
implicit none
integer, pointer :: a, b
integer, target :: t
integer :: n
t = 1
a => t
t = 2
b => t
n = a + b
Print *, a, b, t, n
end program pointerExample
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
2 2 2 4
เราได้เห็นแล้วว่าเราสามารถอ่านข้อมูลจากแป้นพิมพ์โดยใช้ไฟล์ read * และแสดงผลลัพธ์ไปยังหน้าจอโดยใช้ไฟล์ print*คำสั่งตามลำดับ รูปแบบของอินพุต - เอาต์พุตนี้คือfree format I / O และเรียกว่า list-directed อินพุต - เอาต์พุต
I / O แบบง่ายรูปแบบฟรีมีรูปแบบ -
read(*,*) item1, item2, item3...
print *, item1, item2, item3
write(*,*) item1, item2, item3...
อย่างไรก็ตาม I / O ที่จัดรูปแบบจะช่วยให้คุณมีความยืดหยุ่นมากกว่าในการถ่ายโอนข้อมูล
อินพุตเอาต์พุตที่จัดรูปแบบ
อินพุตเอาต์พุตที่จัดรูปแบบมีไวยากรณ์ดังนี้ -
read fmt, variable_list
print fmt, variable_list
write fmt, variable_list
ที่ไหน
fmt คือข้อกำหนดรูปแบบ
รายการตัวแปรคือรายการของตัวแปรที่จะอ่านจากแป้นพิมพ์หรือเขียนบนหน้าจอ
ข้อกำหนดรูปแบบกำหนดวิธีการแสดงข้อมูลที่จัดรูปแบบ ประกอบด้วยสตริงที่มีรายการedit descriptors ในวงเล็บ
อัน edit descriptor ระบุรูปแบบที่แน่นอนตัวอย่างเช่นความกว้างตัวเลขหลังจุดทศนิยมเป็นต้นซึ่งอักขระและตัวเลขจะแสดง
ตัวอย่างเช่น
Print "(f6.3)", pi
ตารางต่อไปนี้อธิบายถึงตัวบ่งชี้ -
ตัวบอก | คำอธิบาย | ตัวอย่าง |
---|---|---|
ผม | ใช้สำหรับเอาต์พุตจำนวนเต็ม ซึ่งจะอยู่ในรูปแบบ 'rIw.m' โดยที่ความหมายของ r, w และ m ได้รับในตารางด้านล่าง ค่าจำนวนเต็มเป็นค่าที่ถูกต้องในเอลด์ของพวกเขา หากความกว้าง fi eld ไม่ใหญ่พอที่จะรองรับจำนวนเต็มดังนั้น fi eld จะถูกยกด้วยเครื่องหมายดอกจัน |
พิมพ์ "(3i5)", i, j, k |
ฉ | ใช้สำหรับเอาต์พุตจำนวนจริง ซึ่งจะอยู่ในรูปแบบ 'rFw.d' ซึ่งความหมายของ r, w และ d จะได้รับในตารางด้านล่าง คุณค่าที่แท้จริงเป็นสิ่งที่ถูกต้องในตัวของพวกเขา หากความกว้าง fi eld ไม่ใหญ่พอที่จะรองรับจำนวนจริงเครื่องหมาย fi eld จะขึ้นด้วยเครื่องหมายดอกจัน |
พิมพ์ "(f12.3)", pi |
จ | ใช้สำหรับเอาต์พุตจริงในสัญกรณ์เอกซ์โพเนนเชียล คำสั่ง descriptor 'E' อยู่ในรูปแบบ 'rEw.d' โดยที่ความหมายของ r, w และ d แสดงไว้ในตารางด้านล่าง คุณค่าที่แท้จริงเป็นสิ่งที่ถูกต้องในตัวของพวกเขา หากความกว้าง fi eld ไม่ใหญ่พอที่จะรองรับจำนวนจริงเครื่องหมาย fi eld จะขึ้นด้วยเครื่องหมายดอกจัน โปรดทราบว่าในการพิมพ์จำนวนจริงที่มีทศนิยมสามตำแหน่งจำเป็นต้องมีความกว้าง fi eld อย่างน้อยสิบตำแหน่ง หนึ่งสำหรับเครื่องหมายของแมนทิสซาสองสำหรับศูนย์สี่สำหรับแมนทิสซาและสองสำหรับเลขชี้กำลังนั้นเอง โดยทั่วไป w ≥ d + 7 |
พิมพ์ "(e10.3)", 123456.0 ให้ '0.123e + 06' |
ES | ใช้สำหรับผลลัพธ์จริง (สัญกรณ์วิทยาศาสตร์) ซึ่งจะอยู่ในรูปแบบ 'rESw.d' ซึ่งความหมายของ r, w และ d จะได้รับในตารางด้านล่าง ตัวบ่งชี้ 'E' ที่อธิบายไว้ข้างต้นมีความแตกต่างจากสัญกรณ์แบบดั้งเดิมที่รู้จักกันดีเล็กน้อย สัญกรณ์ Scienti fi c มี mantissa อยู่ในช่วง 1.0 ถึง 10.0 ซึ่งแตกต่างจาก E descriptor ซึ่งมี mantissa อยู่ในช่วง 0.1 ถึง 1.0 คุณค่าที่แท้จริงเป็นสิ่งที่ถูกต้องในตัวของพวกเขา หากความกว้าง fi eld ไม่ใหญ่พอที่จะรองรับจำนวนจริงเครื่องหมาย fi eld จะขึ้นด้วยเครื่องหมายดอกจัน นอกจากนี้ความกว้าง fi eld ต้องตรงตามนิพจน์ w ≥ d + 7 |
พิมพ์ "(es10.3)", 123456.0 ให้ '1.235e + 05' |
ก | ใช้สำหรับเอาต์พุตอักขระ ซึ่งจะอยู่ในรูปแบบ 'rAw' โดยที่ความหมายของ r และ w แสดงไว้ในตารางด้านล่าง ประเภทของตัวละครเป็นสิ่งที่ถูกต้องในเอลด์ของพวกเขา ถ้าความกว้าง fi eld ไม่ใหญ่พอที่จะรองรับสตริงอักขระดังนั้น fi eld จะถูกผูกด้วยอักขระ fi rst 'w' ของสตริง |
พิมพ์ "(a10)", str |
X | ใช้สำหรับเอาต์พุตช่องว่าง ซึ่งจะอยู่ในรูปแบบ 'nX' โดยที่ 'n' คือจำนวนช่องว่างที่ต้องการ |
พิมพ์ "(5x, a10)", str |
/ | Slash descriptor - ใช้เพื่อแทรกบรรทัดว่าง สิ่งนี้จะอยู่ในรูปแบบ '/' และบังคับให้เอาต์พุตข้อมูลถัดไปอยู่ในบรรทัดใหม่ |
พิมพ์ "(/, 5x, a10)", str |
สัญลักษณ์ต่อไปนี้ใช้กับตัวบอกรูปแบบ -
ซีเนียร์ No | สัญลักษณ์และคำอธิบาย |
---|---|
1 | c หมายเลขคอลัมน์ |
2 | d จำนวนหลักทางขวาของตำแหน่งทศนิยมสำหรับอินพุตหรือเอาต์พุตจริง |
3 | m จำนวนหลักขั้นต่ำที่จะแสดง |
4 | n จำนวนช่องว่างที่จะข้าม |
5 | r การนับซ้ำ - จำนวนครั้งในการใช้ตัวบอกหรือกลุ่มตัวบอก |
6 | w ความกว้างของฟิลด์ - จำนวนอักขระที่จะใช้สำหรับอินพุตหรือเอาต์พุต |
ตัวอย่าง 1
program printPi
pi = 3.141592653589793238
Print "(f6.3)", pi
Print "(f10.7)", pi
Print "(f20.15)", pi
Print "(e16.4)", pi/100
end program printPi
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
3.142
3.1415927
3.141592741012573
0.3142E-01
ตัวอย่าง 2
program printName
implicit none
character (len = 15) :: first_name
print *,' Enter your first name.'
print *,' Up to 20 characters, please'
read *,first_name
print "(1x,a)",first_name
end program printName
เมื่อคอมไพล์และรันโค้ดด้านบนจะให้ผลลัพธ์ดังนี้ (สมมติว่าผู้ใช้ป้อนชื่อ Zara)
Enter your first name.
Up to 20 characters, please
Zara
ตัวอย่างที่ 3
program formattedPrint
implicit none
real :: c = 1.2786456e-9, d = 0.1234567e3
integer :: n = 300789, k = 45, i = 2
character (len=15) :: str="Tutorials Point"
print "(i6)", k
print "(i6.3)", k
print "(3i10)", n, k, i
print "(i10,i3,i5)", n, k, i
print "(a15)",str
print "(f12.3)", d
print "(e12.4)", c
print '(/,3x,"n = ",i6, 3x, "d = ",f7.4)', n, d
end program formattedPrint
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
45
045
300789 45 2
300789 45 2
Tutorials Point
123.457
0.1279E-08
n = 300789 d = *******
คำชี้แจงรูปแบบ
คำสั่งรูปแบบช่วยให้คุณสามารถผสมและจับคู่อักขระจำนวนเต็มและผลลัพธ์จริงในคำสั่งเดียว ตัวอย่างต่อไปนี้แสดงให้เห็นถึงสิ่งนี้ -
program productDetails
implicit none
character (len = 15) :: name
integer :: id
real :: weight
name = 'Ardupilot'
id = 1
weight = 0.08
print *,' The product details are'
print 100
100 format (7x,'Name:', 7x, 'Id:', 1x, 'Weight:')
print 200, name, id, weight
200 format(1x, a, 2x, i3, 2x, f5.2)
end program productDetails
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
The product details are
Name: Id: Weight:
Ardupilot 1 0.08
Fortran ช่วยให้คุณอ่านข้อมูลและเขียนข้อมูลลงในไฟล์
ในบทสุดท้ายคุณได้เห็นวิธีอ่านข้อมูลและเขียนข้อมูลไปยังเทอร์มินัล ในบทนี้คุณจะศึกษาฟังก์ชันอินพุตและเอาต์พุตไฟล์ที่จัดทำโดย Fortran
คุณสามารถอ่านและเขียนลงในไฟล์ตั้งแต่หนึ่งไฟล์ขึ้นไป คำสั่งเปิดเขียนอ่านและปิดช่วยให้คุณบรรลุเป้าหมายนี้
การเปิดและปิดไฟล์
ก่อนใช้ไฟล์คุณต้องเปิดไฟล์ openคำสั่งใช้เพื่อเปิดไฟล์สำหรับอ่านหรือเขียน รูปแบบคำสั่งที่ง่ายที่สุดคือ -
open (unit = number, file = "name").
อย่างไรก็ตามคำสั่งเปิดอาจมีรูปแบบทั่วไป -
open (list-of-specifiers)
ตารางต่อไปนี้อธิบายตัวระบุที่ใช้บ่อยที่สุด -
ซีเนียร์ No | ตัวระบุและคำอธิบาย |
---|---|
1 | [UNIT=] u หมายเลขหน่วย u อาจเป็นตัวเลขใดก็ได้ในช่วง 9-99 และระบุไฟล์คุณสามารถเลือกหมายเลขใดก็ได้ แต่ทุกไฟล์ที่เปิดอยู่ในโปรแกรมต้องมีหมายเลขเฉพาะ |
2 | IOSTAT= ios เป็นตัวระบุสถานะ I / O และควรเป็นตัวแปรจำนวนเต็ม หากคำสั่งเปิดสำเร็จแล้วค่า ios ที่ส่งคืนจะเป็นศูนย์อื่นเป็นค่าที่ไม่ใช่ศูนย์ |
3 | ERR = err เป็นป้ายกำกับที่คอนโทรลกระโดดในกรณีที่เกิดข้อผิดพลาดใด ๆ |
4 | FILE = fname ชื่อไฟล์สตริงอักขระ |
5 | STATUS = sta จะแสดงสถานะก่อนหน้าของไฟล์ สตริงอักขระและสามารถมีค่าหนึ่งในสามค่า NEW, OLD หรือ SCRATCH ไฟล์เริ่มต้นถูกสร้างและลบเมื่อปิดหรือโปรแกรมสิ้นสุดลง |
6 | ACCESS = acc เป็นโหมดการเข้าถึงไฟล์ สามารถมีได้สองค่า SEQUENTIAL หรือ DIRECT ค่าเริ่มต้นคือ SEQUENTIAL |
7 | FORM = frm จะให้สถานะการจัดรูปแบบของไฟล์ สามารถมีค่าสองค่าที่จัดรูปแบบหรือไม่ถูกต้อง ค่าเริ่มต้นคือ UNFORMATTED |
8 | RECL = rl ระบุความยาวของแต่ละระเบียนในไฟล์การเข้าถึงโดยตรง |
หลังจากเปิดไฟล์แล้วไฟล์จะถูกเข้าถึงโดยคำสั่งอ่านและเขียน เมื่อเสร็จแล้วควรปิดโดยใช้ไฟล์close คำให้การ.
คำสั่งปิดมีไวยากรณ์ต่อไปนี้ -
close ([UNIT = ]u[,IOSTAT = ios,ERR = err,STATUS = sta])
โปรดทราบว่าพารามิเตอร์ในวงเล็บเป็นทางเลือก
Example
ตัวอย่างนี้สาธิตการเปิดไฟล์ใหม่สำหรับการเขียนข้อมูลบางอย่างลงในไฟล์
program outputdata
implicit none
real, dimension(100) :: x, y
real, dimension(100) :: p, q
integer :: i
! data
do i=1,100
x(i) = i * 0.1
y(i) = sin(x(i)) * (1-cos(x(i)/3.0))
end do
! output data into a file
open(1, file = 'data1.dat', status = 'new')
do i=1,100
write(1,*) x(i), y(i)
end do
close(1)
end program outputdata
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะสร้างไฟล์ data1.dat และเขียนค่าอาร์เรย์ x และ y ลงไป จากนั้นปิดไฟล์
การอ่านและเขียนลงในไฟล์
คำสั่ง read และ write ตามลำดับใช้สำหรับการอ่านและเขียนลงในไฟล์ตามลำดับ
พวกเขามีไวยากรณ์ต่อไปนี้ -
read ([UNIT = ]u, [FMT = ]fmt, IOSTAT = ios, ERR = err, END = s)
write([UNIT = ]u, [FMT = ]fmt, IOSTAT = ios, ERR = err, END = s)
ตัวระบุส่วนใหญ่ได้รับการกล่าวถึงแล้วในตารางด้านบน
ตัวระบุ END = s คือป้ายกำกับคำสั่งที่โปรแกรมจะกระโดดเมื่อถึงจุดสิ้นสุดของไฟล์
Example
ตัวอย่างนี้สาธิตการอ่านและเขียนลงในไฟล์
ในโปรแกรมนี้เราอ่านจากไฟล์เราสร้างในตัวอย่างสุดท้าย data1.dat และแสดงบนหน้าจอ
program outputdata
implicit none
real, dimension(100) :: x, y
real, dimension(100) :: p, q
integer :: i
! data
do i = 1,100
x(i) = i * 0.1
y(i) = sin(x(i)) * (1-cos(x(i)/3.0))
end do
! output data into a file
open(1, file = 'data1.dat', status='new')
do i = 1,100
write(1,*) x(i), y(i)
end do
close(1)
! opening the file for reading
open (2, file = 'data1.dat', status = 'old')
do i = 1,100
read(2,*) p(i), q(i)
end do
close(2)
do i = 1,100
write(*,*) p(i), q(i)
end do
end program outputdata
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -
0.100000001 5.54589933E-05
0.200000003 4.41325130E-04
0.300000012 1.47636665E-03
0.400000006 3.45637114E-03
0.500000000 6.64328877E-03
0.600000024 1.12552457E-02
0.699999988 1.74576249E-02
0.800000012 2.53552198E-02
0.900000036 3.49861123E-02
1.00000000 4.63171229E-02
1.10000002 5.92407547E-02
1.20000005 7.35742599E-02
1.30000007 8.90605897E-02
1.39999998 0.105371222
1.50000000 0.122110792
1.60000002 0.138823599
1.70000005 0.155002072
1.80000007 0.170096487
1.89999998 0.183526158
2.00000000 0.194692180
2.10000014 0.202990443
2.20000005 0.207826138
2.29999995 0.208628103
2.40000010 0.204863414
2.50000000 0.196052119
2.60000014 0.181780845
2.70000005 0.161716297
2.79999995 0.135617107
2.90000010 0.103344671
3.00000000 6.48725405E-02
3.10000014 2.02930309E-02
3.20000005 -3.01767997E-02
3.29999995 -8.61928314E-02
3.40000010 -0.147283033
3.50000000 -0.212848678
3.60000014 -0.282169819
3.70000005 -0.354410470
3.79999995 -0.428629100
3.90000010 -0.503789663
4.00000000 -0.578774154
4.09999990 -0.652400017
4.20000029 -0.723436713
4.30000019 -0.790623367
4.40000010 -0.852691114
4.50000000 -0.908382416
4.59999990 -0.956472993
4.70000029 -0.995793998
4.80000019 -1.02525222
4.90000010 -1.04385209
5.00000000 -1.05071592
5.09999990 -1.04510069
5.20000029 -1.02641726
5.30000019 -0.994243503
5.40000010 -0.948338211
5.50000000 -0.888650239
5.59999990 -0.815326691
5.70000029 -0.728716135
5.80000019 -0.629372001
5.90000010 -0.518047631
6.00000000 -0.395693362
6.09999990 -0.263447165
6.20000029 -0.122622721
6.30000019 2.53026206E-02
6.40000010 0.178709000
6.50000000 0.335851669
6.59999990 0.494883657
6.70000029 0.653881252
6.80000019 0.810866773
6.90000010 0.963840425
7.00000000 1.11080539
7.09999990 1.24979746
7.20000029 1.37891412
7.30000019 1.49633956
7.40000010 1.60037732
7.50000000 1.68947268
7.59999990 1.76223695
7.70000029 1.81747139
7.80000019 1.85418403
7.90000010 1.87160957
8.00000000 1.86922085
8.10000038 1.84674001
8.19999981 1.80414569
8.30000019 1.74167395
8.40000057 1.65982044
8.50000000 1.55933595
8.60000038 1.44121361
8.69999981 1.30668485
8.80000019 1.15719533
8.90000057 0.994394958
9.00000000 0.820112705
9.10000038 0.636327863
9.19999981 0.445154816
9.30000019 0.248800844
9.40000057 4.95488606E-02
9.50000000 -0.150278628
9.60000038 -0.348357052
9.69999981 -0.542378068
9.80000019 -0.730095863
9.90000057 -0.909344316
10.0000000 -1.07807255
ก procedureคือกลุ่มของคำสั่งที่ทำงานที่กำหนดไว้อย่างดีและสามารถเรียกใช้จากโปรแกรมของคุณ ข้อมูล (หรือข้อมูล) ถูกส่งผ่านไปยังโปรแกรมการเรียกไปยังโพรซีเดอร์เป็นอาร์กิวเมนต์
มีสองประเภทของขั้นตอน -
- Functions
- Subroutines
ฟังก์ชัน
ฟังก์ชันคือโพรซีเดอร์ที่ส่งคืนปริมาณเดียว ฟังก์ชันไม่ควรแก้ไขอาร์กิวเมนต์
ปริมาณที่ส่งคืนเรียกว่า function valueและแสดงด้วยชื่อฟังก์ชัน
Syntax
ไวยากรณ์สำหรับฟังก์ชันมีดังนี้ -
function name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end function [name]
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงฟังก์ชันที่ชื่อ area_of_circle คำนวณพื้นที่ของวงกลมที่มีรัศมี r
program calling_func
real :: a
a = area_of_circle(2.0)
Print *, "The area of a circle with radius 2.0 is"
Print *, a
end program calling_func
! this function computes the area of a circle with radius r
function area_of_circle (r)
! function result
implicit none
! dummy arguments
real :: area_of_circle
! local variables
real :: r
real :: pi
pi = 4 * atan (1.0)
area_of_circle = pi * r**2
end function area_of_circle
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
The area of a circle with radius 2.0 is
12.5663710
โปรดทราบว่า -
คุณต้องระบุ implicit none ทั้งในโปรแกรมหลักและขั้นตอน
อาร์กิวเมนต์ r ในฟังก์ชันที่เรียกนั้นเรียกว่า dummy argument.
ตัวเลือกผลลัพธ์
หากคุณต้องการให้เก็บค่าที่ส่งคืนในชื่ออื่นที่ไม่ใช่ชื่อฟังก์ชันคุณสามารถใช้ไฟล์ result ตัวเลือก
คุณสามารถระบุชื่อตัวแปรส่งคืนเป็น -
function name(arg1, arg2, ....) result (return_var_name)
[declarations, including those for the arguments]
[executable statements]
end function [name]
รูทีนย่อย
รูทีนย่อยไม่ส่งคืนค่า แต่สามารถแก้ไขอาร์กิวเมนต์ได้
Syntax
subroutine name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end subroutine [name]
เรียก Subroutine
คุณต้องเรียกใช้รูทีนย่อยโดยใช้ call คำให้การ.
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงนิยามและการใช้รูทีนย่อย swap ที่เปลี่ยนค่าของอาร์กิวเมนต์
program calling_func
implicit none
real :: a, b
a = 2.0
b = 3.0
Print *, "Before calling swap"
Print *, "a = ", a
Print *, "b = ", b
call swap(a, b)
Print *, "After calling swap"
Print *, "a = ", a
Print *, "b = ", b
end program calling_func
subroutine swap(x, y)
implicit none
real :: x, y, temp
temp = x
x = y
y = temp
end subroutine swap
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
การระบุเจตนาของอาร์กิวเมนต์
แอตทริบิวต์เจตนาช่วยให้คุณระบุความตั้งใจที่จะใช้อาร์กิวเมนต์ในโพรซีเดอร์ ตารางต่อไปนี้ระบุค่าของแอตทริบิวต์เจตนา -
มูลค่า | ใช้เป็น | คำอธิบาย |
---|---|---|
ใน | เจตนา (ใน) | ใช้เป็นค่าอินพุตไม่เปลี่ยนแปลงในฟังก์ชัน |
ออก | เจตนา (ออก) | ใช้เป็นค่าผลลัพธ์ซึ่งจะถูกเขียนทับ |
inout | เจตนา (เข้า) | อาร์กิวเมนต์มีทั้งใช้และเขียนทับ |
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
program calling_func
implicit none
real :: x, y, z, disc
x = 1.0
y = 5.0
z = 2.0
call intent_example(x, y, z, disc)
Print *, "The value of the discriminant is"
Print *, disc
end program calling_func
subroutine intent_example (a, b, c, d)
implicit none
! dummy arguments
real, intent (in) :: a
real, intent (in) :: b
real, intent (in) :: c
real, intent (out) :: d
d = b * b - 4.0 * a * c
end subroutine intent_example
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
The value of the discriminant is
17.0000000
ขั้นตอนการเรียกซ้ำ
การเรียกซ้ำเกิดขึ้นเมื่อภาษาโปรแกรมอนุญาตให้คุณเรียกใช้ฟังก์ชันภายในฟังก์ชันเดียวกัน เรียกว่าการเรียกซ้ำของฟังก์ชัน
เมื่อโพรซีเดอร์เรียกตัวเองโดยตรงหรือโดยอ้อมเรียกว่าโพรซีเดอร์แบบวนซ้ำ คุณควรประกาศขั้นตอนประเภทนี้โดยนำหน้าคำrecursive ก่อนการประกาศ
เมื่อใช้ฟังก์ชันแบบวนซ้ำไฟล์ result ต้องใช้ตัวเลือก
ต่อไปนี้เป็นตัวอย่างซึ่งคำนวณแฟกทอเรียลสำหรับจำนวนที่กำหนดโดยใช้ขั้นตอนการเรียกซ้ำ -
program calling_func
implicit none
integer :: i, f
i = 15
Print *, "The value of factorial 15 is"
f = myfactorial(15)
Print *, f
end program calling_func
! computes the factorial of n (n!)
recursive function myfactorial (n) result (fac)
! function result
implicit none
! dummy arguments
integer :: fac
integer, intent (in) :: n
select case (n)
case (0:1)
fac = 1
case default
fac = n * myfactorial (n-1)
end select
end function myfactorial
ขั้นตอนภายใน
เมื่อมีโพรซีเดอร์ภายในโปรแกรมเรียกว่าโพรซีเดอร์ภายในของโปรแกรม ไวยากรณ์สำหรับการมีโพรซีเดอร์ภายในมีดังนี้ -
program program_name
implicit none
! type declaration statements
! executable statements
. . .
contains
! internal procedures
. . .
end program program_name
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
program mainprog
implicit none
real :: a, b
a = 2.0
b = 3.0
Print *, "Before calling swap"
Print *, "a = ", a
Print *, "b = ", b
call swap(a, b)
Print *, "After calling swap"
Print *, "a = ", a
Print *, "b = ", b
contains
subroutine swap(x, y)
real :: x, y, temp
temp = x
x = y
y = temp
end subroutine swap
end program mainprog
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
โมดูลเปรียบเสมือนแพ็กเกจที่คุณสามารถเก็บฟังก์ชันและรูทีนย่อยของคุณไว้ได้ในกรณีที่คุณเขียนโปรแกรมขนาดใหญ่มากหรือฟังก์ชันหรือรูทีนย่อยของคุณสามารถใช้ในโปรแกรมได้มากกว่าหนึ่งโปรแกรม
โมดูลช่วยให้คุณสามารถแยกโปรแกรมของคุณระหว่างไฟล์ต่างๆ
โมดูลใช้สำหรับ -
โปรแกรมย่อยบรรจุภัณฑ์ข้อมูลและบล็อกอินเทอร์เฟซ
การกำหนดข้อมูลส่วนกลางที่สามารถใช้ได้กับรูทีนมากกว่าหนึ่งรายการ
การประกาศตัวแปรที่สามารถใช้ได้ภายในกิจวัตรที่คุณเลือก
การนำเข้าโมดูลทั้งหมดเพื่อใช้ในโปรแกรมหรือรูทีนย่อยอื่น
ไวยากรณ์ของโมดูล
โมดูลประกอบด้วยสองส่วน -
- ส่วนข้อมูลจำเพาะสำหรับการประกาศงบ
- มีส่วนสำหรับรูทีนย่อยและนิยามฟังก์ชัน
รูปแบบทั่วไปของโมดูลคือ -
module name
[statement declarations]
[contains [subroutine and function definitions] ]
end module [name]
การใช้โมดูลในโปรแกรมของคุณ
คุณสามารถรวมโมดูลในโปรแกรมหรือรูทีนย่อยโดยใช้คำสั่ง -
use name
โปรดทราบว่า
คุณสามารถเพิ่มโมดูลได้มากเท่าที่ต้องการโดยแต่ละโมดูลจะอยู่ในไฟล์แยกกันและคอมไพล์แยกกัน
โมดูลสามารถใช้ในโปรแกรมต่างๆได้
สามารถใช้โมดูลได้หลายครั้งในโปรแกรมเดียวกัน
ตัวแปรที่ประกาศในส่วนข้อมูลจำเพาะของโมดูลเป็นแบบโกลบอลสำหรับโมดูล
ตัวแปรที่ประกาศในโมดูลจะกลายเป็นตัวแปรส่วนกลางในโปรแกรมหรือรูทีนใด ๆ ที่ใช้โมดูล
คำสั่ง use สามารถปรากฏในโปรแกรมหลักหรือรูทีนย่อยหรือโมดูลอื่น ๆ ที่ใช้รูทีนหรือตัวแปรที่ประกาศในโมดูลเฉพาะ
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงแนวคิด -
module constants
implicit none
real, parameter :: pi = 3.1415926536
real, parameter :: e = 2.7182818285
contains
subroutine show_consts()
print*, "Pi = ", pi
print*, "e = ", e
end subroutine show_consts
end module constants
program module_example
use constants
implicit none
real :: x, ePowerx, area, radius
x = 2.0
radius = 7.0
ePowerx = e ** x
area = pi * radius**2
call show_consts()
print*, "e raised to the power of 2.0 = ", ePowerx
print*, "Area of a circle with radius 7.0 = ", area
end program module_example
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Pi = 3.14159274
e = 2.71828175
e raised to the power of 2.0 = 7.38905573
Area of a circle with radius 7.0 = 153.938049
การเข้าถึงตัวแปรและรูทีนย่อยในโมดูล
โดยค่าเริ่มต้นตัวแปรและรูทีนย่อยทั้งหมดในโมดูลจะพร้อมใช้งานสำหรับโปรแกรมที่ใช้โค้ดโมดูลโดย use คำให้การ.
อย่างไรก็ตามคุณสามารถควบคุมการเข้าถึงรหัสโมดูลโดยใช้ไฟล์ private และ publicคุณลักษณะ. เมื่อคุณประกาศตัวแปรหรือรูทีนย่อยบางส่วนเป็นไพรเวตจะไม่สามารถใช้ได้นอกโมดูล
ตัวอย่าง
ตัวอย่างต่อไปนี้แสดงแนวคิด -
ในตัวอย่างก่อนหน้านี้เรามีตัวแปรโมดูลสองตัว e และ pi. ให้เราทำให้เป็นส่วนตัวและสังเกตผลลัพธ์ -
module constants
implicit none
real, parameter,private :: pi = 3.1415926536
real, parameter, private :: e = 2.7182818285
contains
subroutine show_consts()
print*, "Pi = ", pi
print*, "e = ", e
end subroutine show_consts
end module constants
program module_example
use constants
implicit none
real :: x, ePowerx, area, radius
x = 2.0
radius = 7.0
ePowerx = e ** x
area = pi * radius**2
call show_consts()
print*, "e raised to the power of 2.0 = ", ePowerx
print*, "Area of a circle with radius 7.0 = ", area
end program module_example
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะมีข้อความแสดงข้อผิดพลาดดังต่อไปนี้ -
ePowerx = e ** x
1
Error: Symbol 'e' at (1) has no IMPLICIT type
main.f95:19.13:
area = pi * radius**2
1
Error: Symbol 'pi' at (1) has no IMPLICIT type
ตั้งแต่ e และ pi, ทั้งสองประกาศว่าเป็นส่วนตัวโปรแกรม module_example ไม่สามารถเข้าถึงตัวแปรเหล่านี้ได้อีกต่อไป
อย่างไรก็ตามรูทีนย่อยของโมดูลอื่น ๆ สามารถเข้าถึงได้ -
module constants
implicit none
real, parameter,private :: pi = 3.1415926536
real, parameter, private :: e = 2.7182818285
contains
subroutine show_consts()
print*, "Pi = ", pi
print*, "e = ", e
end subroutine show_consts
function ePowerx(x)result(ePx)
implicit none
real::x
real::ePx
ePx = e ** x
end function ePowerx
function areaCircle(r)result(a)
implicit none
real::r
real::a
a = pi * r**2
end function areaCircle
end module constants
program module_example
use constants
implicit none
call show_consts()
Print*, "e raised to the power of 2.0 = ", ePowerx(2.0)
print*, "Area of a circle with radius 7.0 = ", areaCircle(7.0)
end program module_example
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
Pi = 3.14159274
e = 2.71828175
e raised to the power of 2.0 = 7.38905573
Area of a circle with radius 7.0 = 153.938049
ฟังก์ชันภายในเป็นฟังก์ชันทั่วไปและสำคัญบางอย่างที่จัดเตรียมไว้ให้เป็นส่วนหนึ่งของภาษาฟอร์แทรน เราได้กล่าวถึงฟังก์ชันเหล่านี้บางส่วนแล้วในบทอาร์เรย์อักขระและสตริง
ฟังก์ชันภายในสามารถแบ่งได้เป็น -
- ฟังก์ชันตัวเลข
- ฟังก์ชันทางคณิตศาสตร์
- ฟังก์ชั่นการสอบถามตัวเลข
- ฟังก์ชันการจัดการจุดลอยตัว
- ฟังก์ชั่นการจัดการบิต
- ฟังก์ชั่นตัวละคร
- ชนิดฟังก์ชั่น
- ฟังก์ชั่นตรรกะ
- ฟังก์ชันอาร์เรย์
เราได้กล่าวถึงฟังก์ชันอาร์เรย์ในบทอาร์เรย์ ในส่วนต่อไปนี้เราให้คำอธิบายสั้น ๆ เกี่ยวกับฟังก์ชันเหล่านี้ทั้งหมดจากหมวดหมู่อื่น ๆ
ในคอลัมน์ชื่อฟังก์ชัน
- A แสดงถึงตัวแปรตัวเลขประเภทใดก็ได้
- R แทนตัวแปรจริงหรือจำนวนเต็ม
- X และ Y แสดงถึงตัวแปรจริง
- Z แสดงถึงตัวแปรที่ซับซ้อน
- W แทนตัวแปรจริงหรือซับซ้อน
ฟังก์ชันตัวเลข
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | ABS (A) ส่งคืนค่าสัมบูรณ์ของ A |
2 | AIMAG (Z) มันส่งคืนส่วนจินตภาพของจำนวนเชิงซ้อน Z |
3 | AINT (A [, KIND]) มันจะตัดทอนส่วนที่เป็นเศษส่วนของ A ไปทางศูนย์โดยส่งกลับจำนวนจริงจำนวนเต็ม |
4 | ANINT (A [, KIND]) ส่งคืนค่าจริงจำนวนเต็มที่ใกล้เคียงที่สุดหรือจำนวนเต็ม |
5 | CEILING (A [, KIND]) ส่งคืนจำนวนเต็มที่น้อยที่สุดที่มากกว่าหรือเท่ากับตัวเลข A |
6 | CMPLX (X [, Y, KIND]) มันแปลงตัวแปรจริง X และ Y เป็นจำนวนเชิงซ้อน X + iY ถ้าไม่มี Y จะใช้ 0 |
7 | CONJG (Z) มันจะคืนค่าคอนจูเกตที่ซับซ้อนของจำนวนเชิงซ้อน Z |
8 | DBLE (A) จะแปลง A เป็นจำนวนจริงที่มีความแม่นยำสองเท่า |
9 | DIM (X, Y) ส่งกลับผลต่างที่เป็นบวกของ X และ Y |
10 | DPROD (X, Y) ส่งคืนผลิตภัณฑ์จริงที่มีความแม่นยำสองเท่าของ X และ Y |
11 | FLOOR (A [, KIND]) ให้จำนวนเต็มที่มากที่สุดน้อยกว่าหรือเท่ากับจำนวน A |
12 | INT (A [, KIND]) มันจะแปลงตัวเลข (จริงหรือจำนวนเต็ม) เป็นจำนวนเต็มตัดทอนส่วนจริงให้เป็นศูนย์ |
13 | MAX (A1, A2 [, A3,...]) ส่งคืนค่าสูงสุดจากอาร์กิวเมนต์ทั้งหมดเป็นประเภทเดียวกัน |
14 | MIN (A1, A2 [, A3,...]) ส่งคืนค่าต่ำสุดจากอาร์กิวเมนต์ทั้งหมดเป็นประเภทเดียวกัน |
15 | MOD (A, P) ส่งคืนส่วนที่เหลือของ A ในการหารด้วย P อาร์กิวเมนต์ทั้งสองเป็นประเภทเดียวกัน (A-INT (A / P) * P) |
16 | MODULO (A, P) ส่งคืน A modulo P: (A-FLOOR (A / P) * P) |
17 | NINT (A [, KIND]) ส่งคืนจำนวนเต็มที่ใกล้เคียงที่สุดของจำนวน A |
18 | REAL (A [, KIND]) มันแปลงเป็นประเภทจริง |
19 | SIGN (A, B) จะส่งคืนค่าสัมบูรณ์ของ A คูณด้วยเครื่องหมาย P โดยทั่วไปจะโอนเครื่องหมายของ B เป็น A |
ตัวอย่าง
program numericFunctions
implicit none
! define constants
! define variables
real :: a, b
complex :: z
! values for a, b
a = 15.2345
b = -20.7689
write(*,*) 'abs(a): ',abs(a),' abs(b): ',abs(b)
write(*,*) 'aint(a): ',aint(a),' aint(b): ',aint(b)
write(*,*) 'ceiling(a): ',ceiling(a),' ceiling(b): ',ceiling(b)
write(*,*) 'floor(a): ',floor(a),' floor(b): ',floor(b)
z = cmplx(a, b)
write(*,*) 'z: ',z
end program numericFunctions
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
abs(a): 15.2344999 abs(b): 20.7688999
aint(a): 15.0000000 aint(b): -20.0000000
ceiling(a): 16 ceiling(b): -20
floor(a): 15 floor(b): -21
z: (15.2344999, -20.7688999)
ฟังก์ชันทางคณิตศาสตร์
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | ACOS (X) ส่งคืนค่าโคไซน์ผกผันในช่วง (0, π) เป็นเรเดียน |
2 | ASIN (X) ส่งคืนไซน์ผกผันในช่วง (-π / 2, π / 2) เป็นเรเดียน |
3 | ATAN (X) มันจะคืนค่าแทนเจนต์ผกผันในช่วง (-π / 2, π / 2) เป็นเรเดียน |
4 | ATAN2 (Y, X) มันจะคืนค่าแทนเจนต์ผกผันในช่วง (-π, π) เป็นเรเดียน |
5 | COS (X) ส่งคืนค่าโคไซน์ของอาร์กิวเมนต์เป็นเรเดียน |
6 | COSH (X) ส่งคืนค่าไฮเพอร์โบลิกโคไซน์ของอาร์กิวเมนต์เป็นเรเดียน |
7 | EXP (X) ส่งคืนค่าเอ็กซ์โพเนนเชียลของ X |
8 | LOG (X) ส่งคืนค่าลอการิทึมธรรมชาติของ X |
9 | LOG10 (X) ส่งคืนค่าลอการิทึมทั่วไป (ฐาน 10) ของ X |
10 | SIN (X) ส่งคืนค่าไซน์ของอาร์กิวเมนต์เป็นเรเดียน |
11 | SINH (X) ส่งคืนค่าไฮเพอร์โบลิกไซน์ของอาร์กิวเมนต์เป็นเรเดียน |
12 | SQRT (X) ส่งคืนค่ารากที่สองของ X |
13 | TAN (X) ส่งกลับค่าแทนเจนต์ของอาร์กิวเมนต์เป็นเรเดียน |
14 | TANH (X) ส่งคืนค่าแทนเจนต์ไฮเพอร์โบลิกของอาร์กิวเมนต์เป็นเรเดียน |
ตัวอย่าง
โปรแกรมต่อไปนี้คำนวณตำแหน่งแนวนอนและแนวตั้ง x และ y ตามลำดับของโพรเจกไทล์หลังจากเวลาผ่านไป t -
โดยที่ x = ut cos a และ y = ut sin a - g t2 / 2
program projectileMotion
implicit none
! define constants
real, parameter :: g = 9.8
real, parameter :: pi = 3.1415927
!define variables
real :: a, t, u, x, y
!values for a, t, and u
a = 45.0
t = 20.0
u = 10.0
! convert angle to radians
a = a * pi / 180.0
x = u * cos(a) * t
y = u * sin(a) * t - 0.5 * g * t * t
write(*,*) 'x: ',x,' y: ',y
end program projectileMotion
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นโปรแกรมจะให้ผลลัพธ์ดังต่อไปนี้ -
x: 141.421356 y: -1818.57861
ฟังก์ชั่นการสอบถามตัวเลข
ฟังก์ชันเหล่านี้ทำงานร่วมกับแบบจำลองจำนวนเต็มและเลขคณิตทศนิยม ฟังก์ชันจะส่งคืนคุณสมบัติของตัวเลขชนิดเดียวกับตัวแปร X ซึ่งอาจเป็นจริงและในบางกรณีจำนวนเต็ม
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | DIGITS (X) ส่งคืนจำนวนหลักสำคัญของแบบจำลอง |
2 | EPSILON (X) จะส่งคืนตัวเลขที่แทบจะเล็กน้อยเมื่อเทียบกับหนึ่ง กล่าวอีกนัยหนึ่งก็คือส่งคืนค่าที่น้อยที่สุดเช่น REAL (1.0, KIND (X)) + EPSILON (X) ไม่เท่ากับ REAL (1.0, KIND (X)) |
3 | HUGE (X) จะส่งกลับจำนวนมากที่สุดของแบบจำลอง |
4 | MAXEXPONENT (X) จะส่งกลับเลขชี้กำลังสูงสุดของแบบจำลอง |
5 | MINEXPONENT (X) จะส่งกลับเลขชี้กำลังต่ำสุดของแบบจำลอง |
6 | PRECISION (X) จะคืนค่าความแม่นยำทศนิยม |
7 | RADIX (X) ส่งคืนฐานของแบบจำลอง |
8 | RANGE (X) ส่งกลับช่วงเลขชี้กำลังทศนิยม |
9 | TINY (X) จะส่งคืนจำนวนบวกที่น้อยที่สุดของโมเดล |
ฟังก์ชันการจัดการจุดลอยตัว
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | EXPONENT (X) ส่งคืนส่วนเลขชี้กำลังของหมายเลขรุ่น |
2 | FRACTION (X) ส่งคืนส่วนที่เป็นเศษส่วนของตัวเลข |
3 | NEAREST (X, S) จะส่งคืนหมายเลขโปรเซสเซอร์ที่ใกล้เคียงที่สุดในทิศทางที่กำหนด |
4 | RRSPACING (X) จะส่งกลับซึ่งกันและกันของระยะห่างสัมพัทธ์ของหมายเลขรุ่นใกล้กับหมายเลขที่กำหนด |
5 | SCALE (X, I) มันคูณค่าจริงด้วยฐานเป็นเลขจำนวนเต็ม |
6 | SET_EXPONENT (X, I) จะส่งกลับส่วนเลขชี้กำลังของตัวเลข |
7 | SPACING (X) จะคืนค่าระยะห่างสัมบูรณ์ของหมายเลขรุ่นใกล้กับหมายเลขที่กำหนด |
ฟังก์ชั่นการจัดการบิต
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | BIT_SIZE (I) ส่งคืนจำนวนบิตของโมเดล |
2 | BTEST (I, POS) การทดสอบบิต |
3 | IAND (I, J) ตรรกะ AND |
4 | IBCLR (I, POS) ล้างบิต |
5 | IBITS (I, POS, LEN) การสกัดบิต |
6 | IBSET (I, POS) ตั้งค่าบิต |
7 | IEOR (I, J) พิเศษหรือ |
8 | IOR (I, J) รวมหรือ |
9 | ISHFT (I, SHIFT) กะตรรกะ |
10 | ISHFTC (I, SHIFT [, SIZE]) กะแบบวงกลม |
11 | NOT (I) ส่วนประกอบทางตรรกะ |
ฟังก์ชั่นตัวละคร
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | ACHAR (I) ส่งคืนอักขระ Ith ในลำดับการเรียง ASCII |
2 | ADJUSTL (STRING) มันปรับสตริงด้านซ้ายโดยการลบช่องว่างที่นำหน้าและแทรกช่องว่างต่อท้าย |
3 | ADJUSTR (STRING) จะปรับสตริงให้ถูกต้องโดยการลบช่องว่างต่อท้ายและแทรกช่องว่างที่นำหน้า |
4 | CHAR (I [, KIND]) มันส่งคืนอักขระ Ith ในลำดับการเรียงข้อมูลจำเพาะของเครื่อง |
5 | IACHAR (C) ส่งคืนตำแหน่งของอักขระในลำดับการเรียง ASCII |
6 | ICHAR (C) จะส่งคืนตำแหน่งของอักขระในลำดับการเรียงข้อมูลจำเพาะของเครื่อง (โปรเซสเซอร์) |
7 | INDEX (STRING, SUBSTRING [, BACK]) จะส่งคืนตำแหน่งซ้ายสุด (ขวาสุดถ้า BACK คือ. TRUE.) ตำแหน่งเริ่มต้นของ SUBSTRING ภายใน STRING |
8 | LEN (STRING) ส่งกลับความยาวของสตริง |
9 | LEN_TRIM (STRING) ส่งคืนความยาวของสตริงโดยไม่ต้องต่อท้ายอักขระว่าง |
10 | LGE (STRING_A, STRING_B) คำศัพท์ที่มากกว่าหรือเท่ากับ |
11 | LGT (STRING_A, STRING_B) ค่าเฉลี่ยมากกว่า |
12 | LLE (STRING_A, STRING_B) คำศัพท์น้อยกว่าหรือเท่ากับ |
13 | LLT (STRING_A, STRING_B) น้อยกว่า |
14 | REPEAT (STRING, NCOPIES) การเรียงต่อกันซ้ำ ๆ |
15 | SCAN (STRING, SET [, BACK]) จะคืนค่าดัชนีของตัวอักษรซ้ายสุด (ขวาสุดถ้า BACK เป็น. TRUE.) ของ STRING ที่เป็นของ SET หรือ 0 ถ้าไม่มีอยู่ |
16 | TRIM (STRING) ลบอักขระว่างต่อท้าย |
17 | VERIFY (STRING, SET [, BACK]) ตรวจสอบชุดของอักขระในสตริง |
ชนิดฟังก์ชั่น
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | KIND (X) มันส่งกลับค่าพารามิเตอร์ชนิดชนิด |
2 | SELECTED_INT_KIND (R) มันส่งคืนชนิดของพารามิเตอร์ type สำหรับช่วงเลขชี้กำลังที่ระบุ |
3 | SELECTED_REAL_KIND ([P, R]) ค่าพารามิเตอร์ประเภทชนิดจริงให้ความแม่นยำและช่วง |
ฟังก์ชันลอจิก
ซีเนียร์ No | ฟังก์ชั่นและคำอธิบาย |
---|---|
1 | LOGICAL (L [, KIND]) แปลงระหว่างอ็อบเจ็กต์ประเภทตรรกะด้วยพารามิเตอร์ชนิดที่แตกต่างกัน |
เราได้พูดคุยกันไปแล้วว่าใน Fortran เวอร์ชันเก่ามีสองตัว real ประเภท: ประเภทจริงเริ่มต้นและ double precision ประเภท.
อย่างไรก็ตาม Fortran 90/95 ให้การควบคุมความแม่นยำของชนิดข้อมูลจริงและจำนวนเต็มมากขึ้นผ่านไฟล์ kind specifie.
แอตทริบิวต์ชนิด
หมายเลขประเภทต่างๆจะถูกจัดเก็บแตกต่างกันในคอมพิวเตอร์ kindแอตทริบิวต์ช่วยให้คุณระบุวิธีการจัดเก็บหมายเลขภายใน ตัวอย่างเช่น,
real, kind = 2 :: a, b, c
real, kind = 4 :: e, f, g
integer, kind = 2 :: i, j, k
integer, kind = 3 :: l, m, n
ในการประกาศข้างต้นตัวแปรจริง e, f และ g มีความแม่นยำมากกว่าตัวแปรจริง a, b และ c ตัวแปรจำนวนเต็ม l, m และ n สามารถจัดเก็บค่าที่มากกว่าและมีตัวเลขสำหรับจัดเก็บมากกว่าตัวแปรจำนวนเต็ม i, j และ k แม้ว่าจะขึ้นอยู่กับเครื่อง
ตัวอย่าง
program kindSpecifier
implicit none
real(kind = 4) :: a, b, c
real(kind = 8) :: e, f, g
integer(kind = 2) :: i, j, k
integer(kind = 4) :: l, m, n
integer :: kind_a, kind_i, kind_e, kind_l
kind_a = kind(a)
kind_i = kind(i)
kind_e = kind(e)
kind_l = kind(l)
print *,'default kind for real is', kind_a
print *,'default kind for int is', kind_i
print *,'extended kind for real is', kind_e
print *,'default kind for int is', kind_l
end program kindSpecifier
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
default kind for real is 4
default kind for int is 2
extended kind for real is 8
default kind for int is 4
การสอบถามขนาดของตัวแปร
มีฟังก์ชันภายในจำนวนมากที่ช่วยให้คุณสามารถสอบถามขนาดของตัวเลขได้
ตัวอย่างเช่นไฟล์ bit_size(i)ฟังก์ชันภายในระบุจำนวนบิตที่ใช้สำหรับการจัดเก็บ สำหรับจำนวนจริงprecision(x) ฟังก์ชันภายในส่งกลับจำนวนหลักทศนิยมของความแม่นยำในขณะที่ range(x) ฟังก์ชันภายในส่งกลับช่วงทศนิยมของเลขชี้กำลัง
ตัวอย่าง
program getSize
implicit none
real (kind = 4) :: a
real (kind = 8) :: b
integer (kind = 2) :: i
integer (kind = 4) :: j
print *,'precision of real(4) =', precision(a)
print *,'precision of real(8) =', precision(b)
print *,'range of real(4) =', range(a)
print *,'range of real(8) =', range(b)
print *,'maximum exponent of real(4) =' , maxexponent(a)
print *,'maximum exponent of real(8) =' , maxexponent(b)
print *,'minimum exponent of real(4) =' , minexponent(a)
print *,'minimum exponent of real(8) =' , minexponent(b)
print *,'bits in integer(2) =' , bit_size(i)
print *,'bits in integer(4) =' , bit_size(j)
end program getSize
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
precision of real(4) = 6
precision of real(8) = 15
range of real(4) = 37
range of real(8) = 307
maximum exponent of real(4) = 128
maximum exponent of real(8) = 1024
minimum exponent of real(4) = -125
minimum exponent of real(8) = -1021
bits in integer(2) = 16
bits in integer(4) = 32
การได้รับมูลค่าชนิด
Fortran มีฟังก์ชันภายในอีกสองฟังก์ชันเพื่อให้ได้ค่าชนิดสำหรับความแม่นยำที่ต้องการของจำนวนเต็มและจำนวนจริง -
- selected_int_kind (r)
- selected_real_kind ([p, r])
ฟังก์ชัน selected_real_kind จะส่งคืนจำนวนเต็มซึ่งเป็นค่าพารามิเตอร์ชนิดชนิดที่จำเป็นสำหรับค่าความแม่นยำทศนิยมที่กำหนด p และช่วงเลขชี้กำลังทศนิยม r ความแม่นยำของทศนิยมคือจำนวนของหลักที่มีนัยสำคัญและช่วงเลขชี้กำลังทศนิยมจะระบุจำนวนที่แสดงน้อยที่สุดและใหญ่ที่สุด ช่วงจึงอยู่ระหว่าง 10-r ถึง 10 + r
ตัวอย่างเช่น selected_real_kind (p = 10, r = 99) ส่งคืนค่าชนิดที่จำเป็นสำหรับความแม่นยำของทศนิยม 10 ตำแหน่งและช่วงอย่างน้อย 10-99 ถึง 10 + 99
ตัวอย่าง
program getKind
implicit none
integer:: i
i = selected_real_kind (p = 10, r = 99)
print *,'selected_real_kind (p = 10, r = 99)', i
end program getKind
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นจะให้ผลลัพธ์ดังต่อไปนี้ -
selected_real_kind (p = 10, r = 99) 8
มีเครื่องมือและห้องสมุดต่างๆของ Fortran บางรายการฟรีและบางรายการเป็นบริการแบบชำระเงิน
ต่อไปนี้เป็นห้องสมุดฟรี -
- RANDLIB, ตัวเลขสุ่มและเครื่องกำเนิดการกระจายทางสถิติ
- BLAS
- EISPACK
- คู่มือ GAMS – NIST สำหรับซอฟต์แวร์คณิตศาสตร์ที่พร้อมใช้งาน
- กิจวัตรทางสถิติและอื่น ๆ จาก NIST
- LAPACK
- LINPACK
- MINPACK
- MUDPACK
- ห้องสมุดคณิตศาสตร์ NCAR
- คอลเลกชัน Netlib ของซอฟต์แวร์ทางคณิตศาสตร์เอกสารและฐานข้อมูล
- ODEPACK
- ODERPACK ชุดกิจวัตรสำหรับการจัดอันดับและการสั่งซื้อ
- Expokit สำหรับการคำนวณเมทริกซ์เอ็กซ์โปเนนเชียล
- SLATEC
- SPECFUN
- STARPAC
- ไลบรารีสถิติ StatLib
- TOMS
- การเรียงลำดับและการรวมสตริง
ห้องสมุดต่อไปนี้ไม่ฟรี -
- ห้องสมุดตัวเลข NAG Fortran
- ไลบรารี Visual Numerics IMSL
- สูตรตัวเลข
รูปแบบการเขียนโปรแกรมเป็นเรื่องของการปฏิบัติตามกฎบางประการในขณะที่พัฒนาโปรแกรม แนวทางปฏิบัติที่ดีเหล่านี้ให้คุณค่าเช่นความสามารถในการอ่านและความไม่ชัดเจนในโปรแกรมของคุณ
โปรแกรมที่ดีควรมีลักษณะดังนี้ -
- Readability
- โครงสร้างทางตรรกะที่เหมาะสม
- บันทึกย่อและความคิดเห็นที่อธิบายตนเอง
ตัวอย่างเช่นหากคุณแสดงความคิดเห็นดังต่อไปนี้จะช่วยไม่ได้มากนัก -
! loop from 1 to 10
do i = 1,10
อย่างไรก็ตามหากคุณกำลังคำนวณค่าสัมประสิทธิ์ทวินามและต้องการลูปนี้สำหรับ nCr ความคิดเห็นเช่นนี้จะเป็นประโยชน์ -
! loop to calculate nCr
do i = 1,10
บล็อกโค้ดเยื้องเพื่อทำให้โค้ดระดับต่างๆชัดเจน
รหัสตรวจสอบตัวเองเพื่อให้แน่ใจว่าจะไม่มีข้อผิดพลาดด้านตัวเลขเช่นการหารด้วยศูนย์รากที่สองของจำนวนจริงที่เป็นลบหรือลอการิทึมของจำนวนจริงที่เป็นลบ
รวมถึงรหัสเพื่อให้แน่ใจว่าตัวแปรไม่ใช้ค่าที่ผิดกฎหมายหรืออยู่นอกช่วงเช่นการตรวจสอบความถูกต้องของอินพุต
ไม่ตรวจสอบในที่ที่ไม่จำเป็นและทำให้การดำเนินการช้าลง ตัวอย่างเช่น -
real :: x
x = sin(y) + 1.0
if (x >= 0.0) then
z = sqrt(x)
end if
- เขียนโค้ดอย่างชัดเจนโดยใช้อัลกอริทึมที่เหมาะสม
- การแยกนิพจน์ยาวโดยใช้เครื่องหมายความต่อเนื่อง '&'
- สร้างชื่อตัวแปรที่มีความหมาย
เครื่องมือดีบักเกอร์ใช้เพื่อค้นหาข้อผิดพลาดในโปรแกรม
โปรแกรมดีบักเกอร์จะดำเนินการผ่านโค้ดและช่วยให้คุณตรวจสอบค่าในตัวแปรและออบเจ็กต์ข้อมูลอื่น ๆ ในระหว่างการทำงานของโปรแกรม
มันโหลดซอร์สโค้ดและคุณควรจะรันโปรแกรมภายในดีบักเกอร์ ดีบักเกอร์ดีบักโปรแกรมโดย -
- การตั้งค่าเบรกพอยต์
- ก้าวผ่านซอร์สโค้ด
- การตั้งจุดเฝ้าดู
เบรกพอยต์ระบุตำแหน่งที่โปรแกรมควรหยุดโดยเฉพาะหลังจากโค้ดบรรทัดวิกฤต การดำเนินการของโปรแกรมหลังจากตรวจสอบตัวแปรที่จุดพักแล้ว
โปรแกรมดีบักเกอร์ยังตรวจสอบซอร์สโค้ดทีละบรรทัด
จุดเฝ้าระวังคือจุดที่จำเป็นต้องตรวจสอบค่าของตัวแปรบางตัวโดยเฉพาะอย่างยิ่งหลังจากการดำเนินการอ่านหรือเขียน
ดีบักเกอร์ gdb
gdb debugger, GNU debugger มาพร้อมกับระบบปฏิบัติการ Linux สำหรับระบบ X windows gdb มาพร้อมกับอินเทอร์เฟซแบบกราฟิกและโปรแกรมชื่อ xxgdb
ตารางต่อไปนี้มีคำสั่งบางอย่างใน gdb -
คำสั่ง | วัตถุประสงค์ |
---|---|
หยุดพัก | การตั้งค่าเบรกพอยต์ |
วิ่ง | เริ่มดำเนินการ |
ต่อ | ดำเนินการต่อ |
ต่อไป | ดำเนินการเฉพาะซอร์สโค้ดบรรทัดถัดไปโดยไม่ต้องเข้าสู่การเรียกฟังก์ชันใด ๆ |
ขั้นตอน | ดำเนินการบรรทัดถัดไปของซอร์สโค้ดโดยเข้าสู่ฟังก์ชันในกรณีที่มีการเรียกใช้ฟังก์ชัน |
ดีบักเกอร์ dbx
มีดีบักเกอร์อีกตัวหนึ่งคือดีบักเกอร์ dbx สำหรับ Linux
ตารางต่อไปนี้มีคำสั่งบางคำสั่งใน dbx -
คำสั่ง | วัตถุประสงค์ |
---|---|
หยุด [var] | ตั้งค่าเบรกพอยต์เมื่อค่าของตัวแปร var เปลี่ยนแปลง |
หยุดใน [proc] | จะหยุดการดำเนินการเมื่อมีการป้อนโพรซีเดอร์ proc |
หยุดที่ [line] | ตั้งค่าเบรกพอยต์ที่บรรทัดที่ระบุ |
วิ่ง | เริ่มดำเนินการ |
ต่อ | ดำเนินการต่อ |
ต่อไป | ดำเนินการเฉพาะซอร์สโค้ดบรรทัดถัดไปโดยไม่ต้องเข้าสู่การเรียกฟังก์ชันใด ๆ |
ขั้นตอน | ดำเนินการบรรทัดถัดไปของซอร์สโค้ดโดยเข้าสู่ฟังก์ชันในกรณีที่มีการเรียกใช้ฟังก์ชัน |