کلی تحقیق

  جاوا-4 اصل و نسب جاوا

جاوا به زبان C++ ( نتیجه مستقیم زبان C ) وابسته است . بسیاری از خصلتهای
جاوا بطور مستقیم از این دو زبان گرفته شده است . دستور زبان جاوا منتج از
دستور زبان C است . بسیاری از جنبه های oop زبان جاوا از C++ بعاریت گرفته شده
است . در حقیقت بسیاری از خصلتهای زبان جاوا از این دو زبان مشتق شده یا با
آنها مرتبط است . علاوه بر این ، تولید جاوا بطور عمیقی متاثر از روال پالایش و
تطبیقی است که طی سه دهه گذشته برای زبانهای برنامه نویسی موجود پیش آمده است .
بهمین دلایل بهتر است سیر مراحل و نیروهایی که منجر به تولد جاوا شده را بررسی
نماییم . هرنوع ابتکار و فکر جدید در طراحی زبانها براساس نیاز به پشت سر نهادن
یک مشکل اصلی است که زبانهای قبلی از حل آن عاجز مانده اند . جاوا نیز بهمین
ترتیب متولد شد .

تولد زبان برنامه نویسی جدید : C
زبان C پس از تولد ، شوک بزرگی به دنیای کامپیوتر وارد کرد . این زبان بطور
اساسی شیوه های تفکر و دستیابی به برنامه نویسی کامپیوتر را دگرگون ساخت . تولد C
ناشی از نیاز به یک زبان ساخت یافته ، موثر و سطح بالا بعنوان جایگزینی برای
کدهای اسمبلی و پیاده سازی برنامه نویسی سیستم بود . هنگامیکه یک زبان برنامه
نویسی جدید متولد میشود ، مقایسه ها شروع خواهد شد . مقایسه ها براساس معیارهای
زیر انجام می گیرند :
ؤ راحتی کاربری در مقایسه با قدرتمندی زبان برنامه نویسی
ؤ ایمنی در مقایسه با سطح کارآیی
ؤ استحکام در مقایسه با توسعه پذیری
قبل از ظهور زبان C برنامه نویسان با زبانهایی کار می کردند که قدرت
بهینه سازی یک مجموعه خاص از خصایص را داشتند . بعنوان مثال هنگامیکه از فرترن
برای نوشتن برنامه های موثر در کاربردهای علمی استفاده می کنیم ، برنامه های
حاصله برای کدهای سیستم چندان مناسب نیست . زبان بیسیک با اینکه براحتی آموخته
می شود ، اما قدرت زیادی نداشته و عدم ساخت یافتگی آن در برنامه های بزرگ مشکل
آفرین خواهد شد . از زبان اسمبلی برای تولید برنامه های کاملا" موثر استفاده
می شود ، اما آموزش و کار با این زبان بسیار مشکل است . بعلاوه اشکال زدایی
کدهای اسمبلی بسیار طاقت فرساست .
مشکل اصلی دیگر این بود که زبانهای اولیه برنامه نویسی نظیر بیسیک ، کوبول
و فرترن براساس اصول ساخت یافته طراحی نشده بودند . این زبانها از Goto بعنوان
ابزارهای اولیه کنترل برنامه استفاده می کردند . در نتیجه ، برنامه های نوشته
شده با این زبانها تولید باصطلاح " کدهای اسپاگتی "(spaghetti code() می کردند
منظور مجموعه ای در هم تنیده از پرشها و شاخه های شرطی است که درک یک برنامه
طولانی را ناممکن می سازد . اگر چه زبانهایی نظیر پاسکال ، ساخت یافته هستند
اما فاقد کارایی لازم بوده و جنبه های ضروری برای کاربرد آنها در طیف وسیعی از
برنامه ها وجود ندارد . ( بخصوص ویرایش پاسکال استاندارد فاقد ابزارهای کافی
برای استفاده در سطح کدهای سیستم بود . )
تا قبل از ابداع زبان C ، زبان دیگری قدرت نداشت تا خصلتهای متضادی که در
زبانهای قبلی مشاهده میشد ، را یکجا گردآوری کند . نیاز به وجود یک چنین زبانی
شدیدا" احساس میشد. در اوایل دهه 1970 میلادی ، انقلاب رایانه ای در حال شکل گیری
بود و تقاضا برای انواع نرم افزارها فشار زیادی روی برنامه نویسان و تواناییهای
ایشان اعمال میکرد. درمراکز آموزشی تلاش مضاعفی برای ایجاد یک زبان برنامه نویسی
برتر انجام می گرفت . اما شاید از همه مهمتر تولید و عرضه انبوه سخت افزار
کامپیوتری بود که بعنوان یک نیروی ثانویه روی زبانهای برنامه نویسی عمل میکرد.
دیگر رایانه ها و اسرار درونی آنها پشت درهای بسته نگهداری نمی شد . برای اولین
بار بود که برنامه نویسان واقعا" دسترسی نامحدودی به اسرار ماشینهای خود پیدا
نمودند . این امر زمینه تجربیات آزادانه را بوجود آورد . همچنین برنامه نویسان
توانستند ابزارهای مورد نیازشان را ایجاد نمایند . با ظهور زبان C ، زمینه
جهشهای بزرگ در زبانهای برنامه نویسی مهیا شد .
زبان C نتیجه توسعه تحقیقاتی درباره یک زبان قدیمی تر بنام Bcpl بود . زبان C
اولین بار توسط Dennis Ritchie ابداع و روی ماشینهای DEC PDP-11 دارای سیستم
عامل یونیکس اجرا شد . زبان Bcpl توسط Martin Richards توسعه یافته بود . Bcpl
منجر به تولد زبان B شد که توسط Ken thompson ابداع شد و سرانجام به زبان C
منتهی شد . برای سالیان متمادی ، نسخه روایت استاندارد زبان C همانی بود که
روی سیستم عامل unix عرضه و توسط Briian Kernighanو Dennis Ritchieو در کتاب "The C programming Language"
توصیف شده بود . بعدا" در سال 1989 میلادی زبان C
مجددا" استاندارد شد وو استاندارد ANSI برای زبان C انتخاب شد .
بسیاری معتقدند که ایجاد زبان C راهگشای دوران جدیدی در زبانهای برنامه نویسی
بوده است . این زبان بطور موفقیت آمیزی تناقضهای موجود در زبان های برنامه نویسی
قبلی را مرتفع نمود . نتیجه فرآیند ایجاد زبان C ، یک زبان قدرتمند ، کارا و
ساخت یافته بود که براحتی قابل آموزش و فراگیری بود . این زبان یک ویژگی غیر
محسوس اما مهم داشت : زبان C ، زبان برنامه نویسان بود . قبل از ابداع زبان C
زبانهای برنامه نویسی یا جنبه های آموزشی داشته یا برای کارهای اداری طراحی
میشد . اما زبان C چیز دیگری بود . این زبان توسط برنامه نویسان واقعی و درگیر
با کارهای جدی ، طراحی و پیاده سازی شده و توسعه یافت . جنبه های مختلف این
زبان توسط افرادی که با خود زبان سر و کار داشته و برنامه نویسی می کردند مورد
بررسی ، آزمایش و تفکر و تفکر مجدد قرار گرفته بود . حاصل این فرآیند هم زبانی
بود که برنامه نویسان آن را دوست داشتند . در حقیقت زبان C بسرعت مورد توجه
برنامه نویسان قرار گرفت تا جایی که برنامه نویسان نسبت به C تعصب خاصی پیدا
نمودند . این زبان مقبولیت و محبوبیت زیادی در بین برنامه نویسان یافت . بطور
خلاصه زبان C توسط برنامه نویسان و برای برنامه نویسان طراحی شده است . بعدا"
می بینید که جاوا نیز این ویژگی را از اجداد خود بارث برده است .

نیاز به C++
طی دهه 1970 و اوایل دهه 80 میلادی زبان C نگین انگشتری برنامه نویسان بود و
هنوز هم در سطح وسیعی مورد استفده قرار می گیرد . از آنجاییکه C یک زبان موفق
و سودمند بوده ، ممکن است بپرسید چه نیازی به زبانهای جدیدتر وجود داشته است .
پاسخ شما یک کلمه یعنی پیچیدگی (Complexity) است . طی تاریخ کوتاه برنامه نویسی
پیچیدگی فزاینده برنامه ها نیاز برای شیوه های بهتر مدیریت پیچیدگی را بوجود
آورده است . C++ پاسخی است به این نیاز مدیریت پیچیدگی برنامه ها که زمینه اصلی
پیدایش C++ بوده است .
شیوه های برنامه نویسی از زمان اختراع رایانه تاکنون بطور قابل توجهی تغییر
نموده اند . بعنوان مثال ، هنگامیکه رایانه ها اختراع شدند ، برنامه نویسی با
استفاده از دستور العملهای باینری (Binary) ماشین انجام می گرفت .
مادامیکه برنامه ها شامل حدود چند دستور العمل بود ، این روش کارآیی داشت .
بموازات رشد برنامه ها زبان اسمبلی ابداع شد تا برنامه نویسان بتوانند برنامه های
بزرگتر و پیچیده تر را با استفاده از نشانه هایی که معرف دستورالعملهای ماشین
بودند ، بنویسند . اما پیشرفت و رشد برنامه ها همچنان ادامه یافت و زبانهای سطح
بالایی معرفی شدند که ابزارهای مناسب برای مدیریت پیچیدگی روزافزون برنامه ها را
در اختیار برنامه نویسان قرار می دادند .
اولین زبان مطرح در این زمینه فرترن بود . اگر چه فرترن اولین گام در این
مسیر بود، اما زبانی است که توسط آن برنامه های تمیز و سهل الادراک نوشته میشود.
در دهه 1960 میلادی برنامه نویسی ساخت یافته مطرح شد . با استفاده از زبانهای
ساخت یافته ، برای اولین بار امکان راحت نوشتن برنامه های بسیار پیچیده بوجود
آمد . اما حتی با وجود روشهای برنامه نویسی ساخت یافته ، هنگامیکه یک پروژه به
اندازه معینی می رسید ، پیچیدگی آن از توان مدیریت برنامه نویس خارج می شد . در
اوائل دهه 1980 میلادی بسیاری از پروژه های مدیریت برنامه نویسی از مرزهای
برنامه نویسی ساخت یافته گذشتند . برای حل این قبیل مشکلات ، یک روش نوین
برنامه نویسی ابداع شد . این روش را برنامه نویسی شی ئ گرا یا باختصار oop
می نامند . oop با جزئیات بیشتری بعدا" در همین کتاب بررسی خواهد شد ، اما
توصیف مختصر این روش عبارت است از : oop یک نوع روش شناسی برنامه نویسی است که
امکان سازماندهی برنامه های پیچیده از طریق بهره گیری از سه روش : وراثت ، کپسول
سازی و چند شکلی ، را ایجاد می کند .
در تحلیل نهایی ، اگر چه C بزرگترین و مهمترین زبان برنامه نویسی جهان است
اما محدودیتهایی در مدیریت پیچیدگی برنامه ها دارد . هنگامیکه یک برنامه از
محدوده 25000 تا 100000 خط از کدها تجاوز نماید، آنچنان پیچیده می شود که درک
آن بعنوان یک برنامه کلی ناممکن خواهد شد . C++ این محدودیت را از بین برده و
به برنامه نویس کمک می کند تا برنامه هایی از این بزرگتر را نیز درک و مدیریت
نماید . C++
در سال 1979 میلادی توسط Bjarne stoustrup هنگامیکه در آزمایشگاه بل در Marry Hill
ایالت New jersy مشغول کار بود ، ابداع شد . او در ابتدا این زبان
جدید را (C with classes) نامید . اما در سال 1983 میلادی نام این زبان جدید به C++
تغییر یافت . C++ تداوم زبان C بود که جنبه های oop نیز به آن اضافه می شد.
از آنجایی که زبان C++ براساس زبان C شکل گرفته ، در بر گیرنده کلیه جنبه ها
خسلتها (attributes) و مزایای زبان C می باشد . این عوامل دلایل قاطعی برای
موفقیت حتمی C++ بعنوان یک زبان برنامه نویسی هستند . ابداع C++ در حقیقت تلاشی
برای ایجاد یک زبان کاملا" جدید برنامه نویسی نبود. در حقیقت پروژه C++ منجر به
افزایش تواناییهای زبان موفق C شد .
چون C++ از ابتدای تولد تاکنون دارای روایتهای گوناگونی شده است ، در حال
حاضر در تلاش استاندارد نمودن این زبان هستند . ( اولین روایت پیشنهادی ANSI
برای استاندارد C++ در سال 1994 میلادی مطرح شد . ) روال استاندارد سازی این مچنان


  جاوا-3 integers ( اعداد صحیح )

جاوا چهار نوع عدد صحیح تعریف می کند : byte، short،، int،، long، . کلیه
این اعداد دارای علامات مثبت و منفی هستند . جاوا از اعداد صحیح غیر علامت دار و
فقط مثبت پشتیبانی نمی کند . بسیاری از زبانهای برنامه نویسی شامل Cو C++و هم
از اعداد صحیح علامت دار و هم از اعداد صحیح فاقد علامت پشتیبانی می کنند . اما
طراحان جاوا احساس می کردند که اعداد صحیح فاقد علامت غیر ضروری است . بویژه
آنها احساس کردند که مفهوم فاقد علامت (unsigned) بیشتر برای مشخص کردن رفتار
بیت بالاتر از حد مجاز (high-order bit) استفاده می شود که علامت یک int را
هنگامیکه بعنوان یک رقم عنوان می شود ، مشخص می کند . بعدا" خواهید دید که
جاوا مفهوم بیت بالاتر از حد مجاز (high-order bit) را بگونه ای متفاوت مدیریت
می کند ، یعنی با اضافه کردن یک عملگر ویژه حرکت به راست فاقد علامت unsigned)
(right shift . بدین ترتیب نیاز به یک نوع عدد صحیح فاقد علامت منتفی شده است .
پهنای (widit) یک نوع عدد صحیح را نباید با میزان حافظه ای که مصرف می کند
اشتباه گرفت ، بلکه نشانه رفتاری است که برای متغیرها و عبارات آن نوع تعریف
می شود . محیط حین اجرای جاوا از هر اندازه ای که نیاز داشته باشد ، استفاده
می کند ، البته تا آن اندازه ای که انواع براساس اعلام قبلی شما رفتار کنند . در
حقیقت ، حداقل یک پیاده سازی byte وجود دارد که ، short را بعنوان مقادیر 32
بیتی ذخیره می کند تا عملکرد را توسعه دهد. زیرا آنچه درحال حاضر مورد استفاده
قرار می گیرد ، اندازه کلمه (word size) اکثر کامپیوترهاست .
پهنا و دامنه این انواع اعداد صحیح همانطوریکه در جدول زیر مشاهده می کنید
طیف وسیعی دارند :
دامنه پهنا نام
long 64- 9/ 223/ 372/ 036/ 845/ 775/ 808 to 9/ 223/ 372
/036/ 854/ 775/ 807
int 32- 2/ 147/ 483/ 648 to 2/ 147/ 483/ 647
short 16- 32/ 768 to 32/ 767
byte 8- 128 to 127

اکنون نگاه دقیقتری به هر یک از انواع عدد صحیح خواهیم داشت .
byte

کوچکترین نوع عدد صحیح byte است . این یک نوع علامت دار 8 بیتی است که دامنه
آن از 128- تا 127 می باشد . متغیرهای نوع byte بویژه هنگامیکه با یک جریان
داده از یک شبکه یا یک فایل کار میکنید ، سودمند خواهند بود . همچنین هنگامیکه
با داده دودویی ( باینری ) خام مشغول کار هستید که ممکن است بطور مستقیم با
سایر انواع توکار جاوا سازگاری نداشته باشند ، بسیار سودمند هستند .
متغیرهای byte را با استفاده از واژه کلیدی byte اعلام می کنیم . بعنوان
مثال ، در زیر دو متغیر byte با اسامی bو cو را اعلام کرده ایم : + byte b/ c;

short

یک نوع 16 بیتی علامت داراست . دامنه آن از 768 32/- تا 767 32/ است . short
در اصل کم استفاده ترین نوع در جاوا می باشد ، چون طوری تعریف شده که بایت بالای
آن اول می آید ( آن را big-endian format میگویند ). این نوع برای کامپیوترهای 16
بیتی که بسرعت از رده خارج شده اند ، کاربری دارد .
در زیر مثالهایی از چگونگی اعلان متغیرهای short را مشاهده می کنید : + short s;
+ short t;

نکته : Endiannes توصیف کننده چگونگی ذخیره شدن انواع داده چند بایتی short int
و longو در حافظه است . اگر 2 بایت برای معرفی یک نوع short استفاده
شود ، آن بایتی که ابتدا قرار می گیرد ( مهمترین یا کم اهمیت ترین ? )
می گوید که یک ماشین big-endian است ، بدان معنی که مهمترین بایت اول
آمده و بعد از آن بایت کم اهمیت تر قرار دارد . ماشینهایی نظیر SPARC و power pc
از نوع big-endian و ماشینهای سری lntelx86نوع little-endianع
هستند .
int

رایجترین نوع عدد صحیح int است . این یک نوع 32 بیتی علامت دار است که دامنه
آن از 2/147/483/648- تا 2/147/483/647 گسترده است . علاوه بر کاربردهای دیگر
متغیرهای از نوع int برای کنترل حلقه ها و نمایه سازی آرایه ها مورد استفاده قرار
می گیرند . هر بار که یک عبارت عدد صحیح شامل byte، short،و intو و ارقام لفظی
(literal) داشته باشید، کل عبارت قبل از انجام محاسبات به int ارتقائ می یابد.
نوع int روان ترین و کاراترین نوع است و اکثر اوقات هنگامیکه میخواهید رقمی
را برای شمارش یا نمایه سازی آرایه ها یا انجام محاسبات عدد صحیح بوجود آورید
باید از آن استفاده نمایید . شاید بنظر آید که استفاده از انواع shortو byteو
سبب صرفه جویی در فضا شود ، اما هیچ تضمینی وجود ندارد که جاوا این انواع را
بطرق داخلی به int ارتقائ ندهد . همواره بیاد داشته باشید که نوع ، مشخص کننده
رفتار است نه اندازه . ( تنها استثنائ در این مورد، آرایه است که در آنجا byte
بصورت تضمینی برای هر عضو آرایه فقط یک بایت ، short دو بایت و int از چهار
بایت استفاده می کند . )
long

یک نوع 64 بیتی علامت دار است و برای مواردی مفید است که یک نوع int طول
کافی برای دربرگرفتن مقدار مورد نظر نداشته باشد. دامنه long کاملا" وسیع است .
این نوع ، برای کار با اعداد خیلی بزرگ مناسب است . بعنوان مثال ، در زیر
برنامه ای را مشاهده می کنید که مسافت طی شده توسط نور در تعداد مشخص روز را بر
حسب مایل محاسبه می کند .

+ // Compute distance light travels using long variables.
+ class Light {
+ public static void main(String args[] ){
+ int lightspeed;
+ long days;
+ long seconds;
+ long distance;
+
+ // approximate speed of light in miles per second
+ lightspeed = 86000;
+
+ days = 1000; // specify number of days here
+
+ seconds = days * 24 * 60 * 60; // convert to seconds
+
+ distance = lightspeed * seconds; // compute distance
+
+ System.out.print("In " + days);
+ System.out.print(" days light will travel about ");
+ System.out.println(distance + " miles .");
+ }
+ }

خروجی این برنامه بقرار زیر خواهد بود : ln 1000 days light will travel about 4730400000000 miles.



  ساختمان های بیتی

در زبان C برخلاف سایر زبانهای برنامه سازی ، به یک بیت خاص از یک بایت حافظه
می توان دسترسی پیدا کرد . این امر در زبان C به دلایل زیر مفید است : 1
اگر محدودیتی در میزان حافظه وجود داشته باشد، میتوان از یک بایت بعنوان
چند متغیر منطقی استفاده نمود . برای این منظور می توان هر بیت را بعنوان یک
متغیر منطقی در نظر گرفت که مقدار صفر به معنی ارزش " درستی " و مقدار یک به
معنی ارزش " نادرستی " و یا برعکس باشند . 2
در حین ارتباط کامپیوتر با دستگاه های خارجی ، بعضی از رابط ها می توانند
اطلاعات موجود در یک بایت را ( که هر بیت آن ممکن است تفسیر خاصی داشته باشد )
انتقال دهند . 3
بسیاری از زیربرنامه های سیستم ( که معمولا" از دید ما پنهان هستند ) نیاز
به دسترسی به بیت ها دارند .
اگر چه همه اعمال فوق توسط عملگرهای بیتی قابل انجامند ، ولی ساختمان های
بیتی ، روش مناسب تر و بهتری برای برآوردن این اهداف هستند . بطور کلی می توان
گفت که ساختمان بیتی ، مکانیزم ساختمانی جهت دسترسی به بیت های یک بایت از
حافظه است .
روش کلی تعریف ساختمان بیتی به صورت زیر است : {
نام ساختمان بیتی struct ;
طول فیلد >1نام فیلد >: <1نوع فیلد > <1 <;
طول فیلد >2نام فیلد >: <2نوع فیلد > <2 <.
.
.
;
طول فیلد >nنام فیلد >: اسامی متغیرهای بیتی }
نام ساختمان بیتی از قانون نامگذاری برای متغیرها تبعیت می کند . هر یک از
فیلدها در ساختمان بیتی می توانند از نوع int، unsigned، و یا signed باشد .
فیلدی که طول آن 1 باشد یاید از نوع unsigned انتخاب گردد . زیرا بیت با طول 1
نمیتواند شامل علامت هم باشد. طول فیلدها در ساختمان بیتی به بیت سنجیده میشود.
یعنی طول فیلد مشخص می کند که فیلد مورد نظر چند بیتی است .
بعنوان مثال ساختمان بیتی زیر را در نظر بگیرید :

struct device {
unsigned active :1 ;
unsigned ready :1 ;
unsigned xmt_error :1 ;
} dev_code ;

ساختمان 3 device فیلد که طول هر کدام یک پیت است را تعریف می کند و متغیر dev-code
از نوع ساختمان بیتی device تعریف شده است . متغیر dev-code بصورت آن
چه که در شکل (1) مشاهده می شود در حافظه قرار می گیرد .
یک بایت
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
شماره بایت
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ
< بالا استفاده ؤؤؤ<ؤؤؤ| | | | | |
dev-code/xxmt-error
ؤؤؤؤؤ | | dev-code/rready
ؤؤؤؤؤؤؤؤؤ | dev-code aactive
ؤؤؤؤؤؤؤؤؤؤؤؤؤ
شکل (1) . وضعیت متغیر dev-code

همانطور که در شکل (1) مشاهده می گردد برای دسترسی به اجرای متغیر ساختمان
بیتی از عملگر نقطه (.) استفاده می گردد . اگر اشاره گری به ساختمان بیتی اشاره
ؤؤ به اجزای این >نماید ، همانند ساختمان معمولی می توان با استفاده از عملگر
ساختمان دسترسی پیدا کرد .
یکی از موارد کاربرد ساختمان های بیتی ، درتجزیه و تحلیل اطلاعات اخذ شده از
یک دستگاه سخت افزاری است . بعنوان مثال ، پورت وضعیت یک تطبیق دهنده ارتباط
سری ، یک بایت وضعیت ، با ساختار زیر را برمی گرداند :
شماره بیت مفهوم بیت ( وقتی که 1 باشد )

change clear_to_send line 0
change in data_set_ready 1
trailing edge detected 2
change in recive line 3
clear_to_send 4
data_set_ready 5
telephone ringing 6
received signal 7

بایت وضعیت مربوط به تطبیق دهنده ارتباط سری را می توان با استفاده از
ساختمان بیتی تعریف کرد :

struct stalus_type {
unsigned delta_cts :1 ;
unsigned delta_dsr :1 ;
unsigned tr_edge :1 ;
unsigned delta_rec :1 ;
unsigned cts :1 ;
unsigned dsr :1 ;
unsigned ring :1 ;
unsigned rec_line :1 ;
} status;

برای استفاده از ساختار بیتی status کافی است که زیر برنامه ای نوشته شود تا
اطلاعات فرستاده شده را بخواند و سپس آن را تجزیه و تحلیل و بررسی نماید : status=get_port_status)(;

در دستور فوق ()get_port_status تابعی است که پورت وضعیت را خوانده و در
متغیر ساختمان بیتی status قرار می دهد .
بعضی از نکاتی که در مورد متغیرهای از نوع ساختمان بیتی باید در نظر داشت
عبارتند از : 1
نمی توان به آدرس آنها مراجعه کرد 2
نمی توانند بصورت آرایه تعریف شوند 3
به حد زیادی ، وابسته به ماشین هستند، بعنوان مثال ممکن است در یک ماشین
بیت ها از چپ به راست قابل دسترسی باشند و در ماشین دیگر از راست به چپ . 4
ترکیبی از ساختمان بیتی و ساختمان معمولی ، ممکن است :

struct emp {
struct addr address1 ;
float pay ;
unsigned lay-off :1 ;
unsigned hourly :1 ;
unsigned shifted :1 ;
} ;

در ساختمان emp ، فیلد address1 از نوع ساختمان address تعریف شده است که
این ساختمان می تواند بصورت زیر تعریف شود :

struct address {
char zip ;
char street [31] ;
char city [31] ;
} ;

نکته ای که در مورد ساختمان emp باید توجه داشت این است که از یک بایت برای
نگهداری 3 قلم اطلاعات ( اجزای lay-off، hourly،و shiftedو ) استفاده شده است .
اگر از ساختمان بیتی استفاده نمیشد حداقل به 3 بایت نیاز بود ( اگر این بایت ها
بصورت کاراکتری تعریف می شدند ) .

مثال : برنامه ای که چگونگی استفاده از ساختمان های بیتی را نشان می دهد .

struct date
{
unsigned int day: 5 ;
unsigned int month: 4 ;
unsigned int year: 7 ;
} ;
main)(
{
struct date dateofbirth / today ;
int age ;
char p1[40] / p2[40] ;
clrscr )(;
strcpy(p1/
"enter birth date( day month year:)");
strcpy(p2/
"enter today date(day month year: )");
askfordate(p1 / &dateofbirth );
askfordate(p1 / &today );
if( today.month > dateofbirth.month ||
( today.month == dateofbirth.month &&
today.day > dateofbirth.day))
age=today.year - dateofbirth.year ;
else
age=today.year - dateofbirth.year- 1;
printf(" the age is %d year."/age);
}
askfordate(char *prompt /
struct date *point)
{
unsigned int d/m /y ;
printf("%s"/prompt );
scanf("%d%d%d"/&d/&m/&y );
day ==d
;
ؤ>point month=m
;
ؤ>point year =y
;
ؤ>point }

نمونه ای از خروجی برنامه مثال بالا :

enter birth date(day month year:)12 12 50
enter t


  اشاره گرهای ساختمان

در زبان C تعریف اشاره گر از نوع ساختمان ، همانند تعریف سایر انواع اشاره گرها
امکان پذیر است . اشاره گر ساختمان به دو منظور استفاده می شود : 1
امکان فراخوانی به روش ارجاع در توابعی که دارای آرگومان از نوع ساختمان
هستند را فراهم می کند . 2
برای ایجاد لیست های پیوندی و سایر ساختمان داده هایی که با تخصیص حافظه
پویا سر و کار دارند بکار می رود .
وقتی که ساختمان ها از طریق فراخوانی به روش ارجاع به توابع منتقل می شوند
سرعت انجام عملیات بر روی آنها بیشتر می گردد. لذا در حین فراخوانی توابع بهتر
است بجای ساختمان ، آدرس آن را منتقل نمود. عملگر& برای مشخص کردن آدرس ساختمان
( همانند سایر متغیرها ) مورد استفاده قرار می گیرد .
تعریف اشاره گرهای ساختمان همانند تعریف متغیرهای ساختمان است . بااین تفاوت
که در جلوی اسم متغیر ، علامت * قرار می گیرد. بعنوان مثال ، ساختمان زیر را در
نظر بگیرید : struct bal {
float balance ;
char name[80] ;
} person ;
struct bal *p;

در مجموعه دستورات فوق ، person یک متغیر ساختمان وp یک اشاره گر به ساختمان
تعریف شده است . لذا دستور p= &person;

آدرس متغیر ساختمان person را در اشاره گر p قرار می دهد . برای دسترسی به
محتویات اجزای ساختمان از طریق اشاره گر، باید اشاره گر را در داخل پرانتز محصور
نمود . بعنوان مثال دستور ( *p.)balance

موجب دسترسی به عنصر balance از ساختمان person میشود. علت قرار دادن متغیر
اشاره گر ساختمان در پرانتز ، این است که تقدم عملگر نقطه (.) از عملگر * بالاتر
است .
بطور کلی برای دسترسی به اجزای ساختمانی که یک اشاره گر به آن اشاره می کند
به دو روش می توان عمل کرد : 1
ذکر نام اشاره گر در داخل پرانتز و سپس نام عنصر مورد نظر که با نقطه از
هم جدا می شوند ( مثل دسترسی به عنصر balance از ساختمان person توسط اشاره گر ( . p
2
ؤؤ که روش مناسب تری است . اگر بخواهیم با استفاده از > استفاده از عملگر
ؤؤ به عنصر >عملگر balance از ساختمان person دسترسی داشته باشیم باید به طریق
زیر عمل کنیم : balance
ؤؤ > p

مثال 1: برنامه ای که با استفاده از اشاره گرهای ساختمان ، یک timer را شبیه
سازی می کند .

struct tm
{
int hours ;
int minutes ;
int second ;
} ;
main)(
{
struct tm time ={0} ;
for( ;;)
{
update( &time );
display( &time );
}
}
update( struct tm *t)
{
( *t.)second ++ ;
if(( *t.)second == 60)
{
( *t.)second=0 ;
( *t.)minutes ++ ;
}
if(( *t.)minutes == 60)
{
( *t.)minutes=0 ;
( *t.)hours ++ ;
}
if(( *t.)hours==24)
( *t.)hours=0 ;
delay )( ;
}
display(struct tm *t)
{
gotoxy(70/2 );
printf(" %2d:"/(*t.)hours );
printf("%2d:"/(*t.)minutes );
printf("%2d"/(*t.)second );
}
delay)(
{
long int t ;
for( t=1 ; t < 128000 ; ++t );
}

همانطور که در مثال 1 مشاهده می شود برای دسترسی به اجزای ساختمان از عملگر *
ؤ ، تابع ()> استفاده شده است که جهت آشنایی با عملگر update را با این عملگر
بازنویسی می کنیم :

update( struct tm *t)
{
second ++
;
ؤ> t
(َsecond == 60ؤ> t) if {
;
َsecond=0ؤ> t minutes ++
;
ؤ> t }

(َminutes == 60ؤ> t) if {
;
َminutes=0ؤ> t ;
hours ++ؤ> t }

(َhours==24ؤ> t) if ;
َhours=0ؤ> t delay )( ;
}


مثال 2: برنامه ای که مشخصات مربوط به تعدادی از دانشجویان را خوانده و در
آرایه ای از ساختمان ها قرار می دهد . مشخصات دانشجو عبارتند از: 1 نام دانشجو 2
شماره دانشجویی 3 تعداد درس ترم جاری 4 نمره هر درس . این برنامه پس از
خواندن اطلاعات دانشجو معدل آنها را نیز محاسبه می کند و در آرایه قرار می دهد.
امکان حذف دانشجویی از آرایه ، مشاهده اطلاعات یک یا چند دانشجو ، پیدا کردن
دانشجویان مشروط ( معدل کمتر از 12 ) و دانشجویان ممتاز ( معدل بالاتر از 17 )
از جمله وظایف این برنامه است .
قبل از مشاهده لیست کامل برنامه ، نمودار سلسله مراتبی آن را رسم کرده ( شکل
الف ) و وظایف هر یک از توابع را تشریح می کنیم :


ؤؤؤؤؤؤؤؤؤؤؤؤؤؤ | main )(|

ؤؤؤؤؤؤؤؤؤؤؤؤؤؤ
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ
ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ |init_list)(||delete)(|| list)(||list1)(||list2)(||enter)(||menu_select)(|

ؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤؤ | | | |

ؤؤؤؤؤؤؤؤؤؤؤؤؤ| | ؤؤؤؤؤؤؤؤؤؤؤ |
()||find_free |ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ
ؤؤؤؤؤؤؤؤؤؤؤؤؤ| ||()| |print()|title |
|ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ | |
|
ؤؤؤؤؤؤؤؤؤؤؤ |
ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ |title)(| |print)(||
|
ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ |

ؤؤؤؤؤؤؤؤؤؤؤ
ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ |title)(| |print)(|

ؤؤؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤؤؤ

شکل الف . نمودار سلسله مراتبی برنامه مثال 2

وظیفه تابع ()main : تعریف بعضی از متغیرها و فراخوانی توابع دیگر مطابق
نمودار سلسله مراتبی شکل الف .
وظیفه تابع init-list : در ابتدای تابع main فراخوانی شده و با NULL کردن
اولین محل جزئ name ، آرایه را ارزش دهی می کند .
وظیفه تابع ()enter : ورود اطلاعات به آرایه .
وظیفه تابع ()delete : این تابع برای حذف رکوردهایی از آرایه مورد استفاده
قرار میگیرد. برای این منظور اولین محل جزئ name را برابر با NULL قرار میدهد.
وظیفه تابع ()list : بررسی آرایه ، جهت انتقال کامل اطلاعات آن به خروجی با
استفاده از دو تابع ()title و ()print .
وظیفه تابع ()list1 : بررسی آرایه ، جهت پیدا کردن دانشجویان مشروط و انتقال
اطلاعات این دانشجویان به خروجی ، توسط دو تابع ()title و ()print .
وظیفه تابع ()list2 : بررسی آرایه ، ئهت پیدا کردن دانشجویان ممتاز و انتقال
اطلاعات آنها به خروجی ، توسط دو تابع ()title و ()print .
وظیفه تابع ()menu-select : ظاهر نمودن منویی در صفحه نمایش جهت درخواست
انجام کار از برنامه .
وظیفه تابع ()find-free : پیدا کردن اولین محل خالی آرایه جهت قرار دادن
اطلاعات جدید در آن توسط تابع ()enter .
وظیفه تابع ()title : چاپ عنوان برای خروجی .
وظیفه تابع ()print : چاپ اطلاعات موجود در آرایه در صفحه نمایش .

#include "stdio.h"
#include "stdlib.h"
#define MAX 100
struct student {
char name[10] ;
float mead ;
int unit ;
int number ;
int stno;
} st_info[MAX] ;
float x ;
int r=0 ;
void init_list(void)/enter(void );
void delete(void)/list(void)/list1)(/list2)(;
int menu_select(void)/find_free(void );
float sumgrade ;
int sumunit ;
int unit1/t ;
main(void)
{
char choice ;
init_list )(;
for(;;){
choice=menu_select )(;
switch(choice)
{
case 1:
enter )(;
break ;
case 2:
delete )(;
break ;
case 3:
list )(;
break ;
case 4:
list1 )(;
break ;
case 5:
list2 )(;
break ;
case 6:
exit(0 );
}
}
}
void init_list(void)
{
register int n ;
for(t=0 ; t st_info[t].name[0]='' ;
}
menu_select(void)
{
char s[10] ;
int c ;
clrscr )(;
gotoxy(29/3 );
printf("1 )<< enter a name >>");
gotoxy(29/5 );
printf("2 )<< delete a name >>");
gotoxy(29/7 );
printf("3 )<< list the file >>");
gotoxy(29/9 );
printf("4 )<< list for probation >>");
gotoxy(29/11 );
printf("5 )<< list for exelent >>");
gotoxy(29/13 );
printf("6 )<< Quit >>");
do {
gotoxy(27/15 );
printf(" Please enter your " );
printf("choice(1-6 :)" );
gets(s );
c=atoi(s );
} while(c < 0 || c > 6 );
return( c );
}
void enter(void)
{
float grade ;
int slot /j ;
char s[80] ;
sumgrade=0 ;
sumunit=0 ;
slot=find_free )(;
if(slot==-1){
printf(" list full" );
return ;
}
gotoxy(5/17 );
printf("enter name:" );
gets(st_info[slot].name );

gotoxy(5/18 );
printf("enter stno:" );
scanf("%d"/&st_info[slot].stno );

gotoxy(5/19 );
printf("enter number:" );
scanf("%d"/&st_info[slot].number );
for(j=1;j<=st_info[slot].number;j++)
{
gotoxy(40/17 );
printf(" ");
gotoxy(40/17 );
printf("enter grade number %d:"/j);
scanf("%f"/&grade );
gotoxy(40/19 );
printf(" ");
gotoxy(40/19 );
printf("enter unit of grade %d:"/j);
scanf("%d"/&unit1 );
sumgrade+=grade*unit1 ;
sumunit+=unit1 ;
}
st_info[slot].mead=sumgrade/sumunit ;
st_info[slot].unit=sumunit ;
}
find free(void)
{
register int t ;
for(t=0;st_info[t].name[0] &&
t < MAX ; ++t);
if(t==MAX )return- 1 ;
return t ;
}
void delete(void)
{
int slot ;
gotoxy(28/19 );
printf("enter record #(0 - 99:)" );
scanf("%d"/&slot );
if(slot <= 0 && slot < MAX)
st_info[slot].name[0]='' ;
}
void list(void)
{
char ch ;
clrscr )(;
r=0 ;
title ;
for(t=0;t if(st_info[t].name[0])
print )(;
}
gotoxy(13/6+r );
printf("******************************");
printf("*******************************" );
gotoxy(27/7+r );
printf("press any key to continue " );
getch)(;
}
void list1(void)
{
char ch ;
r=0 ;
clrscr )(;
title )(;
for(t=0;t if(st_info[t].name[0] && st_info[t].mead<12)
print)(
}
gotoxy(13/6+r );
printf("******************************");
printf("*******************************" );
gotoxy(27/7+r );
printf("press any key to continue " );
getch)(;
}
void list2(void)
char ch ;
r=0 ;
clrscr )(;
title )(;
for(t=0;t if(st_info[t].name[0] && st_info[t].mead<17)
print)(
}
gotoxy(13/6+r );
printf("******************************");
printf("*******************************" );
gotoxy(27/7+r );
printf("press any key to continue " );
getch)(;
}
title)(
{
gotoxy(25/2 );
printf(" << information in list");
printf("are :>>");
gotoxy(13/3 );
printf("*************************");
printf("****************");
printf("********************");
gotoxy(10/4 );
printf(" name mead ");
printf(" unit " );
printf(" number ");
printf(" stno " );
gotoxy(10/5);
;
(" ؤؤؤؤؤؤؤ ؤؤؤؤؤؤؤ ")printf ;
(" ؤؤؤؤؤ ")printf ;
(" ؤؤؤؤ ؤؤؤؤؤ ")printf }
print)(
{
gotoxy(14/6+r );
printf("%s "/st_info[t].name );
gotoxy(26/6+r );
printf("%.2f "/st_info[t].mead );
gotoxy(40/6+r );
printf("%d "/st_info[t].unit );
gotoxy(54/6+r );
printf("%d "/st_info[t].number );
gotoxy(70/6+r );
printf("%u "/st_info[t].stno );
r++ ;
}

نمونه ای از خروجی برنامه مثال 2 : 1 )

<< enter a name >>
2 )<< delete a name >>
3 )<< list the file >>
4 )<< list for probation >>
5 )<< list for exelent >>
6 )<< Quit >>

Please enter your choice(1-6:)1

enter name:ali enter grade number 1:19
enter stno:123 enter unit of grade 1:2
enter number:2 enter grade number 2:18
enter unit of grade 2:3

1 )<< enter a name >>
2 )<< delete a name >>
3 )<< list the file >>
4 )<< list for probation >>
5 )<< list for exelent >>
6 )<< Quit >>

Please enter your choice(1-6:)2

enter name:reza enter grade number 1:12
enter stno:321 enter unit of grade 1:3
enter number:3 enter grade number 2:11
enter unit of grade 2:2
enter grade number 3:10
enter unit of grade 3:4

1 )<< enter a name >>
2 )<< delete a name >>
3 )<< list the file >>
4 )<< list for probation >>
5 )<< list for exelent >>
6 )<< Quit >>

Please enter your choice(1-6:)3

<< information in list are :>>
***************************************
name mead unit number stno
----- ------ ---- ---- ------
ali 18:00 5 2 123
reza 10:00 9 3 321
***************************************
press any key to continue

1 )<< enter a name >>
2 )<< delete a name >>
3 )<< list the file >>
4 )<< list for probation >>
5 )<< list for exelent >>
6 )<< Quit >>

Please enter your choice(1-6:)5

<< information in list are :>>
***************************************
name mead unit number stno
----- ------ ---- ---- ------
ali 18:00 5 2 123
***************************************
press any key to continue

1 )<< enter a name >>
2 )<< delete a name >>
3 )<< list the file >>
4 )<< list for probation >>
5 )<< list for exelent >>
6 )<< Quit >>

Please enter your choice(1-6:)4

<< information in list are :>>
***************************************
reza 10:00 9 3 321
***************************************
press any key to continue

1 )<< enter a name >>
2 )<< delete a name >>
3 )<< list the file >>
4 )<< list for probation >>
5 )<< list for exelent >>
6 )<< Quit

نظرات 0 + ارسال نظر
برای نمایش آواتار خود در این وبلاگ در سایت Gravatar.com ثبت نام کنید. (راهنما)
ایمیل شما بعد از ثبت نمایش داده نخواهد شد