คำนี้ดูเหมือนจะถูกนำไปใช้ในหลายบริบท สิ่งที่ดีที่สุดที่ฉันคิดได้คือมันหมายถึงตัวแปรที่ไม่สามารถเปลี่ยนแปลงได้ นั่นไม่ใช่ค่าคงที่ / รอบชิงชนะเลิศ (คุณคือ Java!) มีไว้เพื่ออะไร?
คำนี้ดูเหมือนจะถูกนำไปใช้ในหลายบริบท สิ่งที่ดีที่สุดที่ฉันคิดได้คือมันหมายถึงตัวแปรที่ไม่สามารถเปลี่ยนแปลงได้ นั่นไม่ใช่ค่าคงที่ / รอบชิงชนะเลิศ (คุณคือ Java!) มีไว้เพื่ออะไร?
คำตอบ:
ค่าคงที่เป็น "มโนทัศน์" มากกว่าตัวแปร โดยทั่วไปเป็นคุณสมบัติของสถานะโปรแกรมที่เป็นจริงเสมอ ฟังก์ชันหรือเมธอดที่ทำให้มั่นใจได้ว่าการระงับคงที่ถูกกล่าวว่ารักษาค่าคงที่
ตัวอย่างเช่นโครงสร้างการค้นหาแบบไบนารีอาจมีค่าคงที่สำหรับทุกโหนดคีย์ของลูกทางซ้ายของโหนดจะน้อยกว่าคีย์ของโหนดเอง ฟังก์ชันแทรกที่เขียนอย่างถูกต้องสำหรับทรีนี้จะคงค่าคงที่นั้นไว้
อย่างที่คุณบอกนั่นไม่ใช่ประเภทของสิ่งที่คุณสามารถเก็บไว้ในตัวแปร แต่เป็นคำสั่งเกี่ยวกับโปรแกรมมากกว่า ด้วยการหาประเภทของค่าคงที่ที่โปรแกรมของคุณควรคงไว้จากนั้นตรวจสอบโค้ดของคุณเพื่อให้แน่ใจว่ามันคงค่าคงที่เหล่านั้นไว้คุณจะสามารถหลีกเลี่ยงข้อผิดพลาดทางตรรกะในโค้ดของคุณได้
เป็นเงื่อนไขที่คุณรู้ว่าเป็นจริงในสถานที่หนึ่ง ๆ ในตรรกะของคุณและสามารถตรวจสอบได้เมื่อทำการดีบักเพื่อหาสิ่งที่ผิดพลาด
ฉันมักจะดูพวกเขามากกว่าในแง่ของอัลกอริทึมหรือโครงสร้าง
ตัวอย่างเช่นคุณอาจมีค่าคงที่ของลูปที่สามารถยืนยันได้ - เป็นจริงเสมอที่จุดเริ่มต้นหรือจุดสิ้นสุดของการวนซ้ำแต่ละครั้ง นั่นคือถ้าลูปของคุณควรจะประมวลผลกลุ่มของวัตถุจากกองหนึ่งไปยังอีกกองหนึ่งคุณสามารถพูดได้ว่า | stack1 | + | stack2 | = c ที่ด้านบนหรือด้านล่างของวง
หากการตรวจสอบค่าคงที่ล้มเหลวแสดงว่ามีบางอย่างผิดปกติ ในตัวอย่างนี้อาจหมายความว่าคุณลืมดันองค์ประกอบที่ประมวลผลไปยังสแต็กสุดท้ายเป็นต้น
ความมหัศจรรย์ของวิกิพีเดีย: Invariant (วิทยาการคอมพิวเตอร์)
ในวิทยาการคอมพิวเตอร์เพรดิเคตที่ถ้าเป็นจริงจะยังคงเป็นจริงตลอดลำดับการดำเนินการที่เฉพาะเจาะจงเรียกว่า (an) ไม่แปรผันกับลำดับนั้น
ตามที่บรรทัดนี้ระบุ:
ในวิทยาการคอมพิวเตอร์เพรดิเคตที่ถ้าเป็นจริงจะยังคงเป็นจริงตลอดลำดับการดำเนินการที่เฉพาะเจาะจงเรียกว่า (an) ไม่แปรผันกับลำดับนั้น
เพื่อให้เข้าใจได้ดีขึ้นหวังว่าตัวอย่างนี้ใน C ++ จะช่วยได้
พิจารณาสถานการณ์ที่คุณต้องได้รับค่าบางค่าและรับจำนวนรวมของตัวแปรที่เรียกว่าเป็นcount
และเพิ่มในตัวแปรที่เรียกว่าsum
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
โค้ดด้านบนจะเป็นแบบนี้
int count=0;
double sum=0,x=0;
while (cin >> x) {
++count;
sum+=x;
}
โค้ดด้านบนทำอะไร?
1) อ่านอินพุตจากcin
และใส่เข้าไปx
2) หลังจากการอ่านสำเร็จหนึ่งครั้งการเพิ่มcount
และsum = sum + x
3) ทำซ้ำ 1-2 จนกระทั่งหยุดอ่าน (เช่น ctrl + D)
คงที่ต้องเป็น True เสมอ ในตอนแรกคุณเริ่มต้นรหัสของคุณด้วยสิ่งนี้
while(cin>>x){
}
ลูปนี้อ่านข้อมูลจากอินพุตมาตรฐานและเก็บใน x ดีและดี แต่ค่าคงที่กลายเป็นเท็จเพราะส่วนแรกของค่าคงที่ของเราไม่ได้ตาม (หรือเก็บไว้เป็นจริง)
// we have read count grades so far, and
! ง่าย จำนวนที่เพิ่มขึ้น
ดังนั้น++count;
จะทำดี !. ตอนนี้รหัสของเรากลายเป็นแบบนี้
while(cin>>x){
++count;
}
ถึงแม้ตอนนี้ค่าคงที่ของเรา(แนวคิดที่ต้องเป็นจริง) ก็เป็นเท็จเพราะตอนนี้เราไม่ตอบสนองส่วนที่สองของค่าคงที่ของเรา
// sum is the sum of the first count grades
แล้วจะทำยังไงดีล่ะ?
เพิ่มx
ไปsum
และเก็บไว้ในsum
( sum+=x
) และครั้งต่อไปที่
cin>>x
จะอ่านค่าใหม่เข้าไป x
ตอนนี้รหัสของเรากลายเป็นแบบนี้
while(cin>>x){
++count;
sum+=x;
}
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
รหัส:
while(cin>>x){
++count;
sum+=x;
}
อา!. ตอนนี้ค่าคงที่ของลูปเป็น True เสมอและโค้ดก็ใช้ได้
ตัวอย่างข้างต้นนำมาและแก้ไขจากหนังสือAccelerated C ++โดย Andrew-koening และ Barbara-E
สิ่งที่ไม่เปลี่ยนแปลงภายในบล็อกโค้ด
จากสิ่งที่เป็นอยู่ค่าคงที่ค่อนข้างมีประโยชน์ในการเขียนโค้ดที่สะอาดเนื่องจากการรู้ในแนวความคิดว่าค่าคงที่ควรมีอยู่ในโค้ดของคุณช่วยให้คุณตัดสินใจได้อย่างง่ายดายว่าจะจัดระเบียบโค้ดของคุณอย่างไรเพื่อให้บรรลุเป้าหมายเหล่านั้น ตามที่กล่าวไว้ ealier พวกมันยังมีประโยชน์ในการดีบั๊กเนื่องจากการตรวจสอบเพื่อดูว่าค่าคงที่ที่ได้รับการบำรุงรักษามักเป็นวิธีที่ดีในการดูว่าการจัดการใด ๆ ที่คุณพยายามดำเนินการนั้นทำในสิ่งที่คุณต้องการหรือไม่
โดยทั่วไปจะเป็นปริมาณที่ไม่เปลี่ยนแปลงภายใต้การดำเนินการทางคณิตศาสตร์บางอย่าง ตัวอย่างเป็นสเกลาร์ซึ่งไม่เปลี่ยนแปลงภายใต้การหมุน ตัวอย่างเช่นในการถ่ายภาพด้วยคลื่นสนามแม่เหล็กจะมีประโยชน์ในการกำหนดลักษณะคุณสมบัติของเนื้อเยื่อโดยค่าคงที่ของการหมุนเนื่องจากการประมาณค่าโดยปกติแล้วจะไม่ขึ้นอยู่กับการวางแนวของร่างกายในเครื่องสแกน
คำตอบนี้สำหรับเด็กอายุ 5 ขวบของฉัน อย่าคิดว่าค่าคงที่เป็นค่าคงที่หรือค่าตัวเลขคงที่ แต่ก็สามารถทำได้ อย่างไรก็ตามมันมีมากกว่านั้น
แต่ความไม่แปรเปลี่ยนเป็นสิ่งที่เหมือนกับความสัมพันธ์คงที่ระหว่างเอนทิตีที่แตกต่างกัน ตัวอย่างเช่นอายุของคุณจะน้อยกว่านั้นเสมอเมื่อเทียบกับพ่อแม่ผู้ให้กำเนิด ทั้งอายุของคุณและอายุของพ่อแม่ของคุณเปลี่ยนแปลงไปตามกาลเวลา แต่ความสัมพันธ์ที่ฉันกล่าวถึงข้างต้นนั้นไม่แน่นอน
ค่าคงที่ยังสามารถเป็นค่าคงที่เป็นตัวเลขได้ ตัวอย่างเช่นค่าของpi
คืออัตราส่วนที่ไม่แปรเปลี่ยนระหว่างเส้นรอบวงของวงกลมกับเส้นผ่านศูนย์กลาง pi
ไม่ว่าเล็กหรือใหญ่วงกลมคือไม่มีอัตราส่วนที่มักจะเป็น
ADT ไม่แปรเปลี่ยนระบุความสัมพันธ์ระหว่างฟิลด์ข้อมูล (ตัวแปรอินสแตนซ์) ที่ต้องเป็นจริงก่อนและหลังการดำเนินการของวิธีอินสแตนซ์ใด ๆ
มีตัวอย่างที่ดีของค่าคงที่และทำไมมันเป็นเรื่องสำคัญในหนังสือJava Concurrency ในการปฏิบัติ
แม้ว่า Java เป็นศูนย์กลางตัวอย่างจะอธิบายโค้ดบางอย่างที่รับผิดชอบในการคำนวณปัจจัยของจำนวนเต็มที่ระบุ โค้ดตัวอย่างพยายามแคชหมายเลขสุดท้ายที่ระบุและปัจจัยที่คำนวณเพื่อปรับปรุงประสิทธิภาพ ในสถานการณ์นี้มีค่าคงที่ที่ไม่ได้ถูกนำมาใช้ในโค้ดตัวอย่างซึ่งทำให้โค้ดมีความอ่อนไหวต่อสภาวะการแข่งขันในสถานการณ์ที่เกิดขึ้นพร้อมกัน
คำตอบทั้งหมดที่นี่ดีมาก แต่ฉันรู้สึกว่าฉันสามารถให้ความกระจ่างในเรื่องนี้ได้มากขึ้น:
ไม่แปรเปลี่ยนจากมุมมองของภาษาหมายถึงสิ่งที่ไม่มีวันเปลี่ยนแปลง แนวคิดนี้มาจากคณิตศาสตร์ แต่เป็นหนึ่งในเทคนิคการพิสูจน์ยอดนิยมเมื่อรวมกับการเหนี่ยวนำ
นี่คือวิธีการพิสูจน์หากคุณสามารถพบค่าคงที่ที่อยู่ในสถานะเริ่มต้นและค่าคงที่นี้ยังคงมีอยู่ไม่ว่าจะมีการเปลี่ยนแปลง [ทางกฎหมาย] ใด ๆ กับรัฐคุณก็สามารถพิสูจน์ได้ว่าหากบางรัฐไม่มีสิ่งนี้ ค่าคงที่ไม่สามารถเกิดขึ้นได้ไม่ว่าลำดับของการแปลงจะนำไปใช้กับสถานะเริ่มต้นอย่างไร
ตอนนี้วิธีคิดก่อนหน้านี้ (รวมกับการเหนี่ยวนำอีกครั้ง) ทำให้สามารถแสดงตรรกะของซอฟต์แวร์คอมพิวเตอร์ได้ สิ่งสำคัญอย่างยิ่งเมื่อการดำเนินการดำเนินไปในลูปซึ่งสามารถใช้ค่าคงที่เพื่อพิสูจน์ว่าลูปหนึ่งจะให้ผลลัพธ์ที่แน่นอนหรือจะไม่มีวันเปลี่ยนสถานะของโปรแกรมในลักษณะใดวิธีหนึ่ง
เมื่อค่าคงที่จะใช้ในการสรุปตรรกะวงเรียกว่าคงห่วง สามารถใช้ลูปภายนอกได้ แต่สำหรับลูปนั้นสำคัญมากเพราะคุณมักจะมีความเป็นไปได้มากมายหรือความเป็นไปได้ที่ไม่สิ้นสุด
สังเกตว่าฉันใช้คำว่า "เพรดิเคต" เป็นตรรกะของซอฟต์แวร์คอมพิวเตอร์และไม่ได้พิสูจน์ และนั่นเป็นเพราะในขณะที่ความไม่แปรเปลี่ยนทางคณิตศาสตร์สามารถใช้เป็นหลักฐานได้ แต่ก็ไม่สามารถพิสูจน์ได้ว่าซอฟต์แวร์คอมพิวเตอร์เมื่อเรียกใช้งานจะให้ผลตามที่คาดหวังเนื่องจากซอฟต์แวร์ถูกเรียกใช้งานบนนามธรรมจำนวนมากซึ่งไม่สามารถพิสูจน์ได้ ว่าพวกเขาจะได้รับสิ่งที่คาดหวัง (ลองนึกถึงสิ่งที่เป็นนามธรรมของฮาร์ดแวร์)
ในที่สุดในขณะที่ตรรกะของซอฟต์แวร์ในทางทฤษฎีและอย่างเข้มงวดมีความสำคัญสำหรับแอปพลิเคชันที่มีความสำคัญสูงเช่นการแพทย์และการทหาร ยังคงสามารถใช้ Invariant เพื่อช่วยโปรแกรมเมอร์ทั่วไปเมื่อทำการดีบัก สามารถใช้เพื่อทราบว่าในตำแหน่งใดตำแหน่งหนึ่งโปรแกรมล้มเหลวเนื่องจากล้มเหลวในการรักษาค่าคงที่บางอย่าง - พวกเราหลายคนใช้มันต่อไปโดยไม่ได้คิดถึงมัน