اینجا هستید : safarionline.ir / books / pumr / ch02

فصل ۲ - The Concept of Data: Simple Data Types

ASCII = American Standard Code for International Interchange.
ANSI = American National Standard Institute.
ISO = International Organization for Standardization.

Data کلمه‌ای کلی است که هر چیزی که کامپیوتر روی آن عمل می‌کند را توصیف می‌کند. در سطح سخت‌افزار و کدِ زبانِ ماشین همه‌ی data ها به وسیله‌ی یک توالی از ارقام دودویی یا باینری ارایه می‌شوند. زبان‌های سطح بالا با استفاده از انتزاع و تجرید و ایجاد مفهوم «نوع داده» یا data type جزئیات این نمایش پیچیده و سطح پایین باینری را پنهان می‌کنند.

یک نوع داده مجموعه‌ی مقادیری که یک متغیر می‌تواند نگهداری کند و عملیاتی که ممکن است روی این متغیر انجام شود را تعریف می‌کند. هر متغیری که در برنامه ظاهر بشود فقط و فقط یک «نوع» خواهد داشت. اگرچه data type ها در پاسکال می‌توانند تا اندازه‌ی زیادی پیچیده شوند، سرانجام همه‌ی آن‌ها باید از انواع ساده و بدون ساختار ساخته شوند.

در فصل‌های ۶ تا ۱۰ خواهید دید که پاسکال امکاناتی برای ساخت مجموعه‌هایی از data type ها به شکل انواع ساختاریافته و اشاره‌گر فراهم کرده است.

دو نوع داده‌ای ساده یا simple data type در پاسکال عبارتند از:

  1. نوع داده‌ی ترتیبی یا ordinal که خودش به دو قسم تقسیم می‌شود:

    1. تعریف شده توسط برنامه‌نویس:

      1. enumerated data type یا نوع داده‌ی شمارشی

        یک نوع شمارشی با مجموعه‌ی مقادیر متمایزش شناخته می‌شود که روی آن یک «ترتیب خطی» تعریف می‌شود. مقادیر با identifier هایی که در موقع تعریف type مشخص شده‌اند نشان داده می‌شوند.

      2. subrange data type

        نوع داده‌ای subrange از یک نوع ordinal که قبلا تعریف شده است یک مقدار minimum و یک مقدار maximum را می‌گیرد و نوع داده‌ای جدیدی تعریف می‌شود. بدیهی است که این نوع داده‌ای جدید هم ordinal است.

    2. انواع داده‌ی ترتیبی از پیش تعریف شده که توسط identifier های زیر نشان داده می‌شوند:

      1. Boolean
      2. Integer
      3. Char
  2. نوع داده‌ی اعشاری که توسط type identifier از پیش تعریف‌شده‌ی Real در دسترس است.

یک نوع داده‌ی ordinal یا ترتیبی یک مجموعه از مقادیر مرتب شده و محدود را توصیف می‌کند. این مقادیر به اعداد ترتیبی 0، 1، 2 و ... نگاشت می‌شوند بجز در مورد اعداد ترتیبیِ Integer که به خودشان نگاشت می‌شوند. هر نوع داده‌ی ترتیبی یک مقدار minimum و یک مقدار maximum دارد. بجز در مورد مقدار minimum هر مقدار از یک نوع داده‌ی ordinal یک مقدار predecessor یا قبلی دارد و بجز در مورد مقدار maximum، هر مقدار از یک نوع داده‌ی ترتیبی یک مقدار successor یا بعدی دارد.

سه تابع از پیش تعریف شده‌ی succ(X) و pred(X) و ord(X) آرگومانی از هر نوع داده‌ی ordinal می‌پذیرند. تابع ord(X) مقدار ordinal-number آرگومان X را برمی‌گرداند. Succ مقدار بعدی و Pred مقدار قبلی را برمی‌گرداند.

❗ در پاسکالِ ویرث تابع Ord بر روی یک آرگومان از نوع ترتیبی sub range، مکان آن مقدار در آن subrange را برمی‌گرداند ولی Free Pascal مکان مقدار ترتیبی نوع پایه را برمی‌گرداند. ⬅ این مثال را ببینید

عملگرهای رابطه‌ای = ، <> ، < ، <= ، > و >= بر روی تمام انواع داده‌ای ordinal قابل اعمال هستند مشروط به این که هر دو عملوند یا operand از همان نوع داده‌ای باشند. نتیجه‌ی مقایسه بر مبنای ordinal-number عملگرهای داده شده به دست می‌آید.

  ⬅ مثال از تعریف enumeration type و subrange type و مقایسه روی آن‌ها

در این جا به بررسی چهار نوع داده‌ای ساده‌یِ از پیش تعریف شده در پاسکال می‌پردازیم:

  1. نوع داده‌ای Boolean

    1. یک مقدار Boolean یکی از دو مقدار درستی یا نادرستی است که توسط identifier های از پیش تعریف شده‌یِ true و false نشان داده می‌شوند.

    2. عملگر‌های منطقی and و or و not وقتی روی عملوندهای Boolean استفاده شوند یک مقدار Boolean یا منطقی برمی‌گردانند.

    3. زبان پاسکال به گونه‌ای طراحی شده که True > False است. (بررسی این موضوع). از این رو تعریف 16 boolean operations یا ۱۶ تابع بولی با استفاده از عملگرهای منطقی و رابطه‌ای بالا ممکن است. #Think

      نام گیت مدار منطقی پیاده‌سازی
      exclusive or xor P <> Q
      equivalence xnor P = Q
      implication P <= Q
    4. هر کدام از عملگرهای رابطه‌ای = ، > ، < ، <= ، > ، >= و in یک مقدار Boolean برمی‌گردانند.

    5. توابع Boolean از پیش تعریف شده، یعنی توابعی که یک مقدار Boolean برمی‌گردانند، عبارتند از: Odd(I) و Eoln(F) و Eof(F).

  2. نوع داده‌ای Integer

    1. یک مقدار از نوع داده‌ای Integer، عنصری است از زیر مجموعه‌ی اعداد صحیح نامنفی (whole number). عملگرهای محاسباتی زیر اگر بر روی دو عملوند Integer به کار روند یک Integer برمی‌گردانند.

      عملگر توضیحات
      * ضرب
      + جمع
      تفریق
      div divide and truncate (i.e., value is not rounded)
      mod Reminder = A - (A div B) * B;
      IF Reminder < 0 THEN
          Reminder = Reminder + B;
    2. MaxInt یک identifier ثابت از پیش تعریف شده مربوط به پیاده‌سازی است که حداکثر عدد مجاز برای تمام عملیات‌های Integer را مشخص می‌کند. اگر A و B به اعداد Integer تفسیر شوند آنگاه عملیات A op B زمانی تضمین می‌شود که درست پیاده‌سازی گردد که:

      Abs(A op B) <= MaxInt
      Abs(A) <= MaxInt
      Abs(B) <= MaxInt
      

      مثال برای دیدن یک نتیجه‌ی غیر منتظره و اشتباه

    3. چهار تابعی که به عنوان نتیجه Integer برمی‌گردانند عبارتند از:

      تابع توضیحات
      Abs(I) قدر مطلق عدد Integer داده شده
      Sqr(I) مجذور عدد Integer داده شده با فرض
      I <= MaxInt div I
      Trunc(R) R از نوع Real است. نتیجه‌ی تابع قسمت کامل عدد است.
      قسمت اعشاری دور ریخته می‌شود.
      Trunc(3.7) = 3 و Trunc(-3.7) = -3
      Round(R) R از نوع Real است. نتیجه‌رند شده‌ی عدد R به صورت Integer است.


      IF R >= 0 THEN
          Result := Trunc(R + 0.5)
      ELSE
          Result := Trunc(R - 0.5);

    4. اگر I یک مقدار Integer باشد آنگاه:

      Succ(I);        { yields the "next" Integer (I + 1) }
      Pred(I);        { yields the preceding Integer (I - 1) }
      
  3. نوع داده‌ای Char

    یک مقدار از نوع Char عنصری از یک مجموعه‌ی محدود و مرتب شده از کاراکترها است. هر سیستم کامپیوتری یک چنین مجموعه‌ای را به منظور برقراری ارتباط تعریف می‌کند و سپس این کاراکترها در دسترس تجهیزات ورودی و خروجی قرار می‌گیرند. متاسفانه یک مجموعه کاراکتر استاندارد وجود ندارد و بنابراین عنصرها و ترتیب آن‌ها به شدت وابسته به تعاریف پیاده‌سازی یا implementation defined هستند.


    🔴 پیوست G صفحه‌ی ۲۴۷

    ASCII یا «کد استاندارد آمریکایی برای تبادل اطلاعات» گونه‌ی آمریکایی مجموعه کاراکتر استاندارد و به رسمیت شناخته شده‌ای است که ISO (به طور دقیقتر ISO-646) نام دارد. (در واقع ISO-646 از روی ASCII تنظیم شد و ASCII به عنوان نسخه‌ی آمریکایی آن پذیرفته شد.)

    ASCII، ۱۲۸ کاراکتر را کد می‌کند. در «کد کاراکتری ISO» برای ۱۲ کاراکتر می‌تواند نسخه‌ی ملی آن کاراکترها قرار داشته باشد (مثلا نماد پول $). از میان این ۱۲۸ کاراکتر ۹۵ کاراکتر با یک نماد گرافیکی نوشته می‌شوند و ۳۳ کاراکتر برای device control استفاده می‌شوند.

    کاراکتر کنترلی backspace برای پاک کردن متن طراحی نشده بود؛ کاربرد آن این بود که هد چاپ را یک خانه به عقب ببرد تا کاراکتر بعدی روی کاراکتر قبلی چاپ شود و بتوان حروفِ دارای اعراب و علائم را تولید کرد.

    در تصویر بالا کد ۷ بیتی یک کاراکتر از جمع اعداد آن سطر و ستون به دست می‌آید. برای مثال کد حرف G برابر با 7 + 64 = 71.


    کاراکتری که در داخل یک single quote ، ' ، محصور شده باشد نشان دهنده‌ی مقداری از نوع Char است. برای نوشتن خود کاراکتر single quotes آن را با یک single quotes دیگر escape کنید یعنی آن را دو بار بنویسید. با وجود این ممکن است بعضی مقادیر کاراکتری «نمایش» ثابتی نداشته باشند. (یعنی هر کاراکتری از میان این ۱۲۸ کاراکتر را نمی‌توان مستقیما میان single quotes نوشت و در صفحه نمایش داد.)

    در زیر چند مقدار از نوع Char را می‌بینید:

    '*'     'G'     '3'     ''''    'X'
    

    فارغ از پیاده‌سازی در سطوح پایین سیستم، فرض‌های حداقلی زیر را برای نوع داده‌ی Char در نظر می‌گیریم:

    1. ارقام decimal یعنی کاراکتر '0' تا '9' به صورت عددی مرتب شده و یکی بعد از دیگری قرار گرفته‌اند. یعنی Succ('5') = '6'
    2. حروف بزرگ 'A' تا 'Z' ممکن است وجود داشته باشند؛ اگر این گونه باشد، از نظر الفبایی مرتب شده هستند ولی لزوما پشت سر هم قرار ندارند. (‍'A' < 'B')
    3. حروف کوچک 'a' تا 'z' ممکن است وجود داشته باشند؛ اگر این گونه باشد، از نظر الفبایی مرتب شده هستند ولی لزوما پشت سر هم قرار ندارند. ('a' < 'b')

    توابع از پیش تعریف شده‌ی Ord(C) و Chr(I) نگاشت بین کاراکتر و ordinal-number آن در مجموعه‌ی کاراکترها و برعکس را انجام می‌دهند. به این توابع، transfer functions می‌گویند. به سرعت می‌توانید مورد زیر را تست کنید و ببینید که توابع Ord(C) و Chr(I) کار یکدیگر را بر عکس می‌کنند.

    Chr(Ord(C)) = C
    Ord(Chr(I)) = I
    

    مثال

    ترتیب کاراکترها در یک مجموعه‌ی کاراکتری به صورت زیر تعریف می‌شود:

    C1 < C2     iff (if and only if)     Ord(C1) < Ord(C2)
    

    💡 iff یعنی if and only if یا به عبارت دیگر «اگر و تنها اگر»، و این چیزی است که در ریاضی آن را با علامت ⟺ نشان می‌دهیم. مثلا A⟺B یعنی اگر A درست باشد آنگاه B هم درست است و اگر B درست باشد آنگاه A هم درست است. به این رابطه، رابطه‌ی دوشرطی گفته می‌شود.

    همین تعریف بالا می‌تواند به تمام عملگرهای رابطه‌ای زیر بسط یابد: = ، <> ، < ، <= ، > و >= . اگر R یکی از این operator ها باشد، آنگاه:

    C1 R C2     iff     Ord(C1) R Ord(C2)
    

    اگر آرگومان توابع از پیش تعریف شده‌ی Pred و Succ از نوع Char باشد، این توابع می‌توانند به صورت زیر تعریف شوند:

    Pred(C) = Chr(Ord(C)-1)
    Succ(C) = Chr(Ord(C)+1)
    

    ❗ predecessor و successor یک کاراکتر وابسته به مجموعه کاراکترهای تعریف شده در سطح پایین سیستم است. این مقادیر فقط زمانی برگردانده می‌شوند که عنصر قبلی یا بعدی وجود داشته باشند.

  4. نوع داده‌ای Real

    یک مقدار از نوع داده‌ای Real، عنصری از زیر مجموعه‌ی اعداد اعشاری تعریف شده در زمان پیاده‌سازی سیستم است. تمام اعمالی که روی مقادیر نوع Real انجام می‌شود تقریبی هستند و دقت آن‌ها به وسیله‌ی ماشینی که استفاده می‌کنید تعریف می‌شود. Real تنها نوع داده‌ی ساده‌ای است که ordinal یا ترتیبی نیست. مقادیر Real هیچ ordinal-number ای و همچنین مقدار successor یا predecessor ای ندارند.

    در مورد عملگرها یا operator های * ، / ، + و - مادامی که حداقل یکی از عملوندها از نوع Real باشد، نتیجه یک مقدار Real خواهد بود. در عملگر / حتی اگر دو عملوند Integer باشند، نتیجه از نوع Real است. ⬅ مثال

    توابع از پیش تعریف شده‌ی زیر اگر آرگومانی از نوع Real بگیرند، مقداری از نوع Real برمی‌گردانند. قبلا دیدید که همین دو تابع اگر آرگومانشان از نوع Integer می‌بود مقداری از نوع Integer برمی‌گرداندند.

    تابع توضیحات
    Abs(R) قدر مطلق مقدار R
    Sqr(R) مجذور عدد R به شرطی که نتیجه از محدوده‌ی اعداد Real تجاوز نکند.

    توابع از پیش تعریف شده‌ی زیر چه در صورتی که آرگومانی از نوع Integer بگیرند و چه در صورتی که آرگومانی از نوع Real بگیرند مقداری از نوع Real برمی‌گردانند:

    تابع توضیحات
    Sin(X) سینوس عدد X، X از نوع رادیان
    Cos(X) کسینوس عدد X، X از نوع رادیان
    Arctan(X) arc tangant in radians of X
    Ln(X) لگاریتم طبیعی (پایه‌ی e) عدد X و X > 0
    Exp(X) exponential function (e raised to the X)
    Sqrt(X) ریشه‌ی عدد X و X >= 0

    ❗ اگرچه Real در مجموعه‌ی انواع داده‌ای ساده گنجانده شده است، همیشه نمی‌تواند در همان context ای که سایر انواع داده‌ای ساده (انواع ordinal) به کار می‌روند، به کار برود. به طور ویژه توابع Pred و Succ نمی‌توانند آرگومانی از نوع Real بگیرند. مقادیر نوع Real نمی‌توانند به عنوان اندیس آرایه به کار بروند؛ و نه در کنترل حلقه‌ی FOR و نه در تعریف نوع پایه‌ی یک مجموعه یا set. علاوه بر این مقادیر Real نمی توانند در نوع داده‌ای subrange استفاده شوند و نه در برچسب‌گذاری case ها.

© کلیه‌ی حقوق برای safarionline.ir محفوظ است.