Trigraph چیست ؟
سه نگاره ( Trigraph ) به سه نویسه پشت سرهم گفته می شود که برای نمایش تنها یک آوا استفاده می شوند. برای مثال ، سه نگاره حروف sch در زبان آلمانی که معادل ش در فارسی یا sh در انگلیسی است. حال این مورد در برنامه نویسی به چه صورت است ؟
به توالی قرارگیری دو کارکتر خاص در برنامه نویسی دیگراف ( Digraph ) و سه کارکتر ( Trigraph ) می گویند. برای مثال به رشته کارکتر های زیر توجه کنید :
Digraph
عبارت | معادل |
---|---|
<: | [ |
:> | ] |
<% | { |
%> | } |
%: | # |
Trigraph
عبارت | معادل |
---|---|
??= | # |
??/ | \ |
??' | ^ |
??( | [ |
??) | ] |
??! | | |
??< | { |
??> | } |
??- | ~ |
به این کارکتر ها دونگاره یا Digraph گفته می شود که هر کدام معادل کارکتری خاص می باشند.
تاریخچه
مجموعه کاراکتر های اصلی زبان برنامه نویسی C زیر مجموعه ای از کاراکتر های ASCII است و شامل 9 کارکتر بوده که در خارج از مجموعه ی ISO 646 قرار دارند ( جدول بالا ). این امر هنگام رمزنگاری ( encode ) ها و نوشتن سورس کد وقتی هیچکدام از این 9 کارکتر پشتیبانی نمی شود مشکلاتی را به وجود می آورد.
پس از آن بود که کمیته ANSI زبان برنامه نویسی C نگاره های چندگانه ( دیگراف / تریگراف ) را به عنوان روشی برای وارد کردن کد منبع با هر صفحه کلیدی که از هر نسخه مجموعه کاراکتر ISO 646 پشتیبانی می کنند ، اختراع کرد.
برای مثال فرض کنید در مجموعه استاندارد کارکتر ها ، کارکتری مانند A وجود ندارد. پس به هنگام نوشتن کد های برنامه و کامپایل کردن آن به مشکل بر میخوریم. حال مجموعه کارکتری مانند BC اختراع شد تا در زمان کامپایل همان عبارت اصلی یعنی A قرار بگیرد.
پیاده سازی
تریگراف ها معمولا خارج محیط کامپایلر معنایی ندارند ، چون همانند کارکتر های معمولی به حساب می آیند. بعضی از کامپایل ها گزینه ای جهت فعال کردن شناسایی و کامپایل عبارات تریگراف نیز دارند که کاربر بسته به سورس کد می تواند آن را فعال کند. برنامه ی Borland حتی کار را ساده تر کرده و برنامه ی جدایی را با نام TRIGRAPH.EXE توسعه داده است که به هنگام نیاز جهت کامپایل عبارات تریگراف فراخوانی شود.
مشکلات
یکی از اولین دفعاتی که این عبارات مشکلاتی را به وجود آورد در همان زبان C بود که تا الان نیز همچنان به عنوان یک باگ بزرگ از آن یاد می شود. برای درک بهتر این موضوع ابتدا قطعه کد زیر را در هر کامپایلر زبان C اجرا کنید. در صورتی که روی سیستم خود کامپایلر مناسب ندارید می توانید از نسخه های آنلاین استفاده کنید ( مانند CodeChef{:target="_blank"} ) :
#include <stdio.h>
int main()
{
int a = 0;
// What will be the value of a????/
a++;
printf("%d", a);
return 0;
}
چه انتظاری از خروجی این قطعه کد دارید ؟ مقدار متغییر a باید چه باشد ؟ قطعا باید پس از دستور ++a
مقدار این متغییر 1 شود. حال پس از اجرا می بینید که هنوز مقدار 0 پیشفرض می باشد.
دلیل آن خط قبلی است که کامنت شده است. این خط مانع اجرا شدن خط بعدی خودش می شود. استفاده از تریگراف ها در انتهای این خط باعث چنین اتفاقی می شود. خطی که مشاهده می کنید به هنگام کامپایل تبدیل به چنین خطی خواهد شد :
// What will be the value of a??\
و در نهایت قطعه کد شما تبدیل به چنین چیزی خواهد شد :
int a = 0;
// What will be the value of a??a++;
پس از تبدیل تریگراف /??
این عبارت به یک کارکتر \
تبدیل خواهد شد ( طبق جدول ) و باعث می شود که کارکتر خط جدید یا همان n\
که باعث می شود به خط بعدی بروید را از بین می برد. در نتیجه خط بعدی کد که همان ++a
می باشد با آن ادغام می شود.
// What will be the value of a??a++;
حال همه چیز روشن شد. متغییر a هیچوقت مقدار جدیدی به خود نگرفته و همچنان 0 خواهد ماند.
در حال حاضر اکثر کامپایل ها به هنگام شناسایی تریگراف ها در کد ، به شما خطایی داده و از آن ها صرف نظر می کند مگر اینکه خودتان به کامپایلر بگویید تریگراف را اجرا کند.