Pretty C เป็นภาษาสคริปต์ใหม่ที่เข้ากันได้กับ C Pretty C เพิ่มประสิทธิภาพโปรแกรมของคุณด้วยการพิมพ์แบบไดนามิก การวนซ้ำทั่วไป การติดตามทรัพยากร และรายละเอียดอื่นๆ และมันเข้ากันได้กับ C และไลบรารีทั้งหมดของมัน! แรงบันดาลใจจาก Lua, Python, JavaScript และ Lisp ต่อไปนี้คือวิธีที่การนำ head utility ไปใช้ใหม่อย่างไร้เดียงสาอาจดูเหมือนกับ Pretty C:
#include "pretty.h"
int main ( int argc , string argv [])
{
if ( argc above 1 )
with ( f , fclose , fopen ( argv [ 1 ], "r" ))
fortimes ( line , 10 )
with ( buf , free , vector ( 200 , char , 0 ))
when ( fgets ( buf , 200 , f ))
then print ( buf )
otherwise 0 ;
else
println ( "Please provide an input file" );
return EXIT_SUCCESS ;
}เป้าหมายของ Pretty C คือ:
#include -able จากไฟล์ C ใดก็ได้!) เพื่อเปลี่ยนโค้ดเบสใด ๆ ให้กลายเป็นโค้ดที่เป็นมิตรสำหรับผู้เริ่มต้นชำระเงินที่เก็บข้อมูล
git clone https://github.com/aartaka/pretty.c หรือเพียงแค่คัดลอกไฟล์ pretty.h เพราะ Pretty C เป็นไลบรารี่แบบส่วนหัวเท่านั้น คุณจึงสามารถทำได้
#include "pretty.h" จากไฟล์ใด ๆ ในไดเร็กทอรีที่คุณวาง pretty.h ไปที่ หรือจากไฟล์ใดๆ จริงๆ หากคุณระบุเส้นทางไปยัง Pretty C เป็นเส้นทางรวม ( -I )
นี่คือการเปลี่ยนแปลงที่สวยงามทั้งหมดที่ทำให้ C hip กลับมาอีกครั้ง
true , false และ booluint64_tand สำหรับ && และ or สำหรับ || - ประณีต! ทุกคนเป็นผู้กำหนดสิ่งเหล่านี้ ดังนั้นทำไมไม่จัดเตรียมไว้ล่ะ?
max และ min ของตัวเลขสองตัวlen สำหรับความยาวอาเรย์default สำหรับการระบุค่าทางเลือกlimit เพื่อให้แน่ใจว่าช่วงค่าที่เหมาะสมbetween เพื่อตรวจสอบว่าตัวเลขอยู่ในช่วงหรือไม่divisible เพื่อตรวจสอบว่าตัวเลขแบบโมดูโลหารด้วยตัวเลขอื่นหรือไม่ ประเภทนามแฝง:
string == char*byte == charbytes == char*any == void*ucharushort .uintulong ส่วนใหญ่สร้างแบบจำลองตาม Lua และ Lisp:
eq เนื่องจาก iso646.h มีเพียง not_eq เท่านั้นis หมายถึง == เช่นกันbitnot และ bitxor สำหรับการดำเนินการที่เคยถูกเรียกไม่สอดคล้องกัน ( compl และ xor ตามลำดับ) ใน iso646.hsuccess และ fail / failure สำหรับรูปแบบ success == 0 .below above upto และ downtoeven , odd , positive , negative , zero และ empty เป็นเพรดิเคตสำหรับตัวเลข/ข้อมูลnil สำหรับ NULLuntil ถูกปฏิเสธ whileelif เป็น else ififnt for if(!...) และ elifnt (คุณเดาได้)repeat จาก Lua เป็นนามแฝงสำหรับ dodone~/~finish และ pass เป็นนามแฝงสำหรับ break และ continue ตามลำดับalways , forever , loop และ indefinitely เพื่อให้คุณสามารถสร้างลูปไม่สิ้นสุด (เหตุการณ์? เซิร์ฟเวอร์?) always println ( "After all this time?" );never comment เพื่อแสดงความคิดเห็นในโค้ดด้วยคำหลักเพียงคำเดียว ในขณะที่ยังคงอนุญาตให้คอมไพเลอร์วิเคราะห์/ปรับให้เหมาะสม (คล้ายกับแบบฟอร์ม comment Clojure): never println ( "This never runs, but never gets outdated, because compiler will shout at you if it does." );ใช่คุณสามารถทำได้
var t = time ( 0 );
let lt = localtime ( & t );
local at = asctime ( lt );
println ( at );กับพริตตี้ซี
print สิ่งที่คุณป้อน println จะเพิ่มบรรทัดใหม่หลังจากนั้น
println ( 3.1 );
print ( "Hello world!n" );เปรียบเทียบทุกสิ่ง!
equal ( "NA" , line ); // true
equal ( 0.3 , 0.2 + 0.1 ); // true ternaries นั้นน่ากลัว ดังนั้นการเพิ่มข้อความธรรมดาลงไปก็ไม่เสียหาย if มีการดำเนินการ else แต่มีทางเลือกทางภาษาที่เหมาะสมซึ่งมีลักษณะค่อนข้างคล้าย Python / Lisp:
return when some_condition
then do_something ()
other do_something_else ();มันเป็นไตรภาคด้านล่าง:
when ขยายเป็นสตริงว่างและมีไว้เพื่อให้อ่านง่ายเท่านั้นunless จะขยายให้ not เป็นเวอร์ชันเชิงลบของ whenthen ขยายเป็น ? -other / otherwise จะขยายเป็น : . นอกจากนี้ยังมี only เมื่อส่วนคำสั่ง otherwise ไม่จำเป็น:
return when done ()
then 42 only ; และ otherwhen สำหรับเงื่อนไขต่อไป
return when c is 'A'
then 'a'
otherwhen c is 'B'
then 'b' only ;for มาโคร มาโครเหล่านี้เป็นนามแฝงสำหรับรูปแบบลูป for รูปแบบ โดยแต่ละรายการจะแยกการใช้ for loop ที่พบบ่อยบางส่วนออกไป
foreach (var, type, length, ...) อันนี้เดินอาร์เรย์หรือขอบเขตหน่วยความจำที่เตรียมใช้งานกับนิพจน์ vararg ทุกครั้งที่มันวนซ้ำ var จะถูกตั้งค่าให้เป็นตัวชี้ไปยังองค์ประกอบอาร์เรย์ที่เกี่ยวข้อง ใช่ ตัวชี้—เพื่อให้คุณสามารถแก้ไของค์ประกอบในตำแหน่งนั้นได้หากต้องการ
foreach ( i , int , 10 , vector ( 10 , int , 1 , 2 , 3 , 3 , 4 , 5 ))
println ( * i ); แสดงการใช้ vector ด้วย
forthese (var, type, ...) วนซ้ำ varargs ที่ให้มา โดยผูกแต่ละรายการเหล่านี้กับ type -d var วงด้านบนสามารถแปลเป็น:
forthese ( i , int , 1 , 2 , 3 , 3 , 4 , 5 )
println ( i );fortimes (var, times)กรณีที่เกิดขึ้นบ่อยครั้งจาก 0 ไปเป็นจำนวนบวกบางจำนวน ช่วยคุณประหยัดเวลาได้มากทีเดียว
for ( int i = 0 ; i < 28 ; i ++ )
println ( i + 1 );เปลี่ยนมันให้เป็นเรื่องง่าย
fortimes ( i , 28 )
println ( i + 1 );
println ( "28 stab wounds, you didn't want to leave him a chance, huh?" );forrange (var, init, target) วนซ้ำช่วงตัวเลขตั้งแต่ init ถึง target ไพธอนเนสก์. นี่คือลูปการแปลงเซลเซียสเป็นฟาเรนไฮต์ด้วย forrange :
forrange ( c , -10 , 20 )
printf ( "Celsius %i = Fahrenheit %fn" , c , ( 32 + ( c * 1.8 ))); โปรดทราบว่า init และ target เป็นจำนวนเต็มตามอำเภอใจ ทั้งแบบลงนามและไม่ได้ลงนาม และ init อาจมากกว่า target ซึ่งในกรณีนี้ขั้นตอนการวนซ้ำจะลดตัวแปรลง
forrangeby (var, type, init, target, by) วนซ้ำ type -d var จาก iter ไปยัง target by ขั้นทุกครั้ง ไพธอนเนสก์.
forrangeby ( x , double , 1.0 , 10.0 , 0.5 )
println ( x );สิ่งเหล่านี้ช่วยให้สามารถจัดสรรรูปแบบทั่วไปได้อย่างรวดเร็วและสกปรก ส่วนใหญ่สร้างโมเดลหลังจาก C++
new (type, ...) โอเปอเรเตอร์ new C++ นั้นดี ดังนั้นมันจะไม่เจ็บถ้ามีอะไรที่คล้ายกันใน C ใช่ไหม ไม่ต้องถามอีกต่อไป:
struct ListNode {
int val ;
struct ListNode * next ;
};
struct ListNode * node = new ( struct ListNode , 2 , new ( struct ListNode , 1 , nil ));หรือถ้าคุณชอบ คุณสามารถเพิ่มไวยากรณ์เพิ่มเติมที่ด้านบนได้:
#define cons ( val , ...) new(struct ListNode, val, __VA_ARGS__)
cons ( 2 , cons ( 1 , nil ));vector (length, type, ...) ซี++อีกแล้ว std::vector เป็นโครงสร้างข้อมูลที่มีประโยชน์และหลากหลายซึ่งง่ายต่อการให้เหตุผล แม้ว่ามาโครนี้จะไม่ได้มีคุณสมบัติจากระยะไกลเหมือนกับภาษา C++ แต่ก็ทำให้รูปแบบ “จัดสรรอาร์เรย์ขององค์ประกอบจำนวนมากนั้นและเนื้อหาเหล่านี้” บ่อยครั้งง่ายขึ้น:
double * vec = vector ( 10 , double , 1 , 2 , 3 , 4 , 5 );delete (...) ในกรณีที่คุณไม่ชอบการใช้ทรัพยากร free และต้องการชื่อ C ++ ที่น่าดึงดูดกว่า
อย่างอื่นก็ free เหมือนกัน
สิ่งเหล่านี้จะสร้างการเชื่อมโยงภายในเครื่องใหม่ ตรวจสอบให้แน่ใจว่าการคำนวณถูกเลื่อนออกไป หรือดำเนินการกับบล็อกที่ตามมา
lambda (ret, name, ...) (GCC, Clang หรือ C++)ฟังก์ชั่นที่ซ้อนกัน/lambdas/closures ตอนนี้อยู่ใน C!
int * arr = vector ( 10 , int , 23423 , 23423 , 234 , 5233 , 6 , 4 , 34 , 643 , 3 , 9 );
lambda ( int , cmp , int * a , int * b ) {
return * a - * b ;
};
qsort ( arr , 10 , sizeof ( int ), cmp );
// arr becomes {3, 4, 6, 9, 34, 234, 643, 5233, 23423, 23423}with (var, close, ...) วิธีนี้ช่วยให้แน่ใจว่าคุณจะไม่มีวันใช้งานฟรีอีกต่อไป เนื่องจากคุณจัดเตรียมขั้นตอนการปลดปล่อย ( close ) ไว้ล่วงหน้า มีประโยชน์อย่างยิ่งสำหรับอ็อบเจ็กต์และตัวกำหนดไฟล์ที่จัดสรรแบบไดนามิก
with ( file , fclose , fopen ( "hello.txt" , "w" ))
fprintf ( file , "Hello world!n" ); ข้อเสียประการหนึ่งคือ var ที่ถูกผูกไว้นั้นเป็น void * ดังนั้นคุณอาจต้องบังคับมันให้ตรงกับประเภทของคุณก่อนใช้งาน
defer (...) ออฟโหลดโค้ดที่จะดำเนินการหลังจากบล็อกต่อไปนี้ ไม่ใช่จุดสิ้นสุดของฟังก์ชันเหมือนใน Go เพราะนั่นคือ เป็นไปไม่ได้ ใช้งานยากใน C ถึงกระนั้น Pretty C defer ก็มีประโยชน์เพียงพอ
try catchการจัดการข้อผิดพลาดแฟนซี ขณะนี้อยู่ในตัวอย่าง C. Refactored จากการอ้างอิง errno:
try log ( 0.0 );
catch ( NOERR )
println ( "No error." );
catch ( EDOM , ERANGE )
println ( "Math error!" ); Pretty C ยังให้บริการ NOERR และ NOERROR เพื่อความสะดวกในการสลับเคสข้อผิดพลาด
make indent ก่อนที่จะคอมมิต ซึ่งควรจัดการรายละเอียดสไตล์ส่วนใหญ่