# ภาษาเบรนฟัก
ภาษาเบรนฟัก  คือภาษาโปรแกรมเชิงความลับที่มีจุดเด่นในเรื่องการทำซอร์สโค้ดและคอมไพเลอร์ให้เล็กที่สุด ออกแบบขึ้นเพื่อท้าทายและสร้างความสับสนให้โปรแกรมเมอร์ แต่ไม่เหมาะสำหรับใช้งานในทางปฏิบัติ ชื่อของภาษาเบรนฟักในภาษาอังกฤษมักจะถูกปิดบังให้เป็น brainf*ck หรือ brainfsck เพื่อหลีกเลี่ยงคำว่า fuck ที่มักถือกันว่าเป็นคำหยาบ และจะไม่มีการเน้นอักษรตัวใหญ่ที่ตัว b เมื่อไม่ใช่ต้นประโยค ถึงแม้จะเป็นชื่อเฉพาะก็ตาม

 ประวัติ 
ภาษาเบรนฟักสร้างขึ้นในปี พ.ศ. 2536 (ค.ศ. 1993) โดยอูร์บัน มึลเลอร์ (Urban Müller) ด้วยความตั้งใจที่จะออกแบบภาษาโปรแกรมให้คอมไพเลอร์มีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้ ซึ่งได้รับแรงบันดาลใจจากคอมไพเลอร์ของภาษาฟอลซ์ (FALSE) ที่มีขนาดเพียง 1,024 ไบต์Wouter's False page ในขณะที่คอมไพเลอร์ของภาษาเบรนฟักมีขนาดเล็กกว่าคือไม่เกิน 200 ไบต์ (บางรุ่นมีขนาดเพียง 125 ไบต์Brainfuck compiler in 125 bytes) นอกจากนี้มึลเลอร์ยังสร้างคอมไพเลอร์ของภาษานี้สำหรับคอมพิวเตอร์อะมิก้า (Amiga) อีกด้วย

 รูปแบบการเขียนและการทำงาน 
ภาษาเบรนฟักประกอบด้วยคำสั่งเพียง 8 ชนิด เขียนแทนด้วยอักษรหนึ่งตัวต่อหนึ่งคำสั่ง โปรแกรมภาษาเบรนฟักจะทำงานตามคำสั่งไปทีละตัวอักษร ในขณะที่อักษรอื่นที่ปรากฏจะถูกข้ามไป อักษรทั้ง 8 ตัวมีความหมายที่เทียบเท่ากับภาษาซีสามารถแจกแจงได้ดังนี้

 คำสั่ง ความหมาย โค้ดภาษาซีที่เทียบเท่า* > เพิ่มพอยเตอร์ขึ้นหนึ่ง (ย้ายพอยเตอร์ไปยังเซลล์ถัดไป) ++ptr; < ลดพอยเตอร์ลงหนึ่ง (ย้ายพอยเตอร์ไปยังเซลล์ก่อนหน้า) --ptr + เพิ่มค่าในพอยเตอร์ขึ้นหนึ่ง ++(*ptr); - ลดค่าในพอยเตอร์ลงหนึ่ง --(*ptr); . แสดงผลเป็นอักษรตามรหัสแอสกีจากค่าในพอยเตอร์ putchar(*ptr); , รับข้อมูลอักษรเข้าและเก็บค่ารหัสแอสกีลงในพอยเตอร์ *ptr=getchar; [ กระโดดไปยัง ] ถ้าค่าในพอยเตอร์เป็นศูนย์ while (*ptr) { ] กระโดดไปยัง [ ถ้าค่าในพอยเตอร์ไม่เป็นศูนย์ }

 * จากตาราง สมมติว่า ptr เป็นพอยเตอร์ประเภท unsigned char* และได้กำหนดค่าให้ชี้ไปยังอาร์เรย์ที่มีสมาชิกเป็นศูนย์แล้ว

ภาษาเบรนฟักทำงานบนอาร์เรย์ขนาด 30,000 เซลล์ (ช่อง) โดยมีตัวแปรพอยเตอร์ที่เคลื่อนย้ายได้เป็นตัวชี้ตำแหน่งเซลล์ปัจจุบัน เมื่อเริ่มต้นโปรแกรม ทุกเซลล์จะมีข้อมูลเป็นศูนย์ และพอยเตอร์ชี้ที่เซลล์แรกเสมอ (ที่ดัชนีของเซลล์เท่ากับศูนย์) โปรแกรมจะดำเนินตามคำสั่งในซอร์สโค้ดไปทีละคำสั่งจนกระทั่งสิ้นสุดที่อักษรตัวสุดท้าย การแสดงผลบนจอภาพและการรับข้อมูลเข้าจากคีย์บอร์ดเป็นตัวอักษรจะอ้างถึงค่าตามรหัสแอสกี (หรือรหัสอักขระตามที่คอมพิวเตอร์ใช้)

 ตัวอย่าง 
โปรแกรมต่อไปนี้จะพิมพ์คำว่า Hello World! และขึ้นบรรทัดใหม่บนจอภาพ
 ++++++++++
[>+++++++>++++++++++>+++>+<<<<-] วนรอบค่าต่างๆ ที่มีประโยชน์เก็บไว้ในอาร์เรย์
>++.                             พิมพ์ 'H'
>+.                              พิมพ์ 'e'
+++++++.                         พิมพ์ 'l'
.                                พิมพ์ 'l'
+++.                             พิมพ์ 'o'
>++.                             พิมพ์ ' '
<<+++++++++++++++.               พิมพ์ 'W'
>.                               พิมพ์ 'o'
+++.                             พิมพ์ 'r'
------.                          พิมพ์ 'l'
--------.                        พิมพ์ 'd'
>+.                              พิมพ์ '!'
>.                               ขึ้นบรรทัดใหม่ (พิมพ์อักขระ newline)

ซอร์สโค้ดข้างต้นมีการตัดขึ้นบรรทัดใหม่เพื่อให้สามารถอ่านได้ง่าย ซึ่งภาษาเบรนฟักจะทำงานเฉพาะโค้ด <>+-.,[] เท่านั้น อักษรอื่นๆ จะถูกข้ามไป จึงสามารถตัดบรรทัดหรือใส่หมายเหตุได้โดยไม่ต้องมีเครื่องหมายกำกับ สำหรับซอร์สโค้ดล้วนของโปรแกรมดังกล่าวสามารถเขียนได้ดังนี้
 ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.

การทำงานจะเริ่มจากบรรทัดแรก ซึ่งเพิ่มค่าเซลล์ที่ 0 ให้เป็น 10 โดยการเพิ่มค่าทีละหนึ่งเป็นจำนวน 10 ครั้ง การวนรอบในบรรทัดที่สองเป็นการกำหนดค่าต่างๆ ไว้ในอาร์เรย์ดังนี้คือ เซลล์ที่ 1 เท่ากับ 70 (ใกล้กับ 72 ซึ่งเป็นรหัสแอสกีของ 'H'), เซลล์ที่ 2 เท่ากับ 100 (ใกล้กับ 101 ของ 'e'), เซลล์ที่ 3 เท่ากับ 30 (ใกล้กับ 32 ซึ่งเป็นรหัสของช่องว่าง), และเซลล์ที่ 4 เท่ากับ 10 (อักขระ newline) การวนรอบดังกล่าวจะทำงานแทนการคูณค่า 10 ในเซลล์ที่ 0 เข้ากับ 7, 10, 3, และ 1 ตามลำดับ และบันทึกผลคูณไว้ต่างเซลล์กัน หลังจากการวนรอบสิ้นสุดแล้ว บรรทัดที่สามคือการเลื่อนพอยเตอร์ไปยังเซลล์ที่ 1 แล้วเพิ่มค่าขึ้นอีกสองจนได้ 72 จากนั้นจึงพิมพ์อักขระ 'H' ออกมา บรรทัดถัดไปเป็นการย้ายพอยเตอร์ไปยังเซลล์ที่ 2 แล้วบวกหนึ่งจนได้ 101 ซึ่งเป็นอักขระ 'e' แล้วแสดงผลบนหน้าจอ บรรทัดต่อๆ ไปก็มีการย้ายพอยเตอร์และมีการเพิ่มค่าหรือลดค่าไปตามคำสั่งคล้ายกันนี้ กระทั่งพิมพ์ Hello World! ออกมาครบทุกตัวอักษร (รวมทั้งการขึ้นบรรทัดใหม่)