‏הצגת רשומות עם תוויות C#. הצג את כל הרשומות
‏הצגת רשומות עם תוויות C#. הצג את כל הרשומות

יום שישי, 15 בנובמבר 2019

הסבר מתומצת על Casting בשפות מונחות עצמים

נסביר על התכונות הבסיסיות של Casting. כל הדוגמאות יהיו בג'אווה, אבל העקרונות נכונים בעוד הרבה שפות טיפוסיות (Statically Typed Languages) מונחות עצמים.


 Casting

נניח שיש לנו מחלקה משם Animal ויורשת ממנה מחלקה בשם Bird.

מצביע מסוג Animal יכול להצביע על Animal כמובן, אבל הוא יכול להצביע גם על היורשים, ולכן גם על Bird.

    Animal myAnimal1 = new Animal();
    Animal myAnimal2 = new Bird();

פעולה זו נקראת Upcasting, והיא הבסיס לפולימרפיזם.



לאחר ההמרה myAnimal2 לא יכול לקרוא לפונקציות של Bird, מאחר והחיה הזו שכחה שהיא הייתה פעם ציפור. אמנם היא עודנה ציפור וניתן להזכיר לה זאת על ידי Downcasting.


מהו Downcasting?
ההפך של Upcasting. הצבעה על אובייקט עם מצביע ממחלקה שיורשת ממחלקת האובייקט.
Downcasting לעולם יבוא רק לאחר שנעשה Upcasting.

    Bird myBird = (Bird) myAnimal2;

אחרי Downcasting ניתן לקרוא לפונקציות של Bird.

    myBird.fly();





למה Downcasting צריך לכתוב בפירוש ואילו Upcasting לא?
כשיורדים יכולה להיווצר שגיאת זמן ריצה, ולכן ג'אווה בודקת שהמתכנת בטוח לגבי ההחלטה לרדת.
(בשפות ללא הצהרות טיפוסים נגלה את השגיאה רק בשימוש בתכונות הבן שאינן קיימות, ואילו בג'אווה נגלה את זה כבר ברגע ההמרה)

כשעולים לא יכולה להיווצר שגיאת זמן ריצה ולכן אין טעם לציין זאת. (הסיבה היחידה לציין Upcasting היא קצת שיפור של קריאות הקוד, וג'אווה החליטו לוותר על זה)


נדגים:

public class Engineer {
    public void doEngineering() {
        System.out.println("I do some engineering");
    }
}

public class SmartEngineer extends Engineer {
    @Override
    public void doEngineering() {
        System.out.println("I do some engineering (but I am smart!)");
    }
    public void doSmartEngineering() {
        System.out.println("I do some smart engineering");
    }
}

public static void main(String[] args) {
    String userInput = "normal";
        
    Engineer engineer = null;
        
    if (userInput.equals("normal")) {
        engineer = new Engineer();
    }
    else {
        engineer = new SmartEngineer();
    }

    // We can do:
    engineer.doEngineering();

    // We can't do (compilation error):
    // engineer.doSmartEngineering();


    // We can do it but it's risky (If userInput is "normal" we get ClassCastException):

    ((SmartEngineer) engineer).doSmartEngineering();
}


מקווה שהכל ברור.



יום שני, 18 ביוני 2018

יצירת קובץ EXE עם כל הספריות dll הדרושות (#C)

קבצי dll ב-Visual Studio

לפעמים אנחנו צריכים לעשות שימוש בספריות חיצוניות בפרויקט שלנו (לדוגמה DotNetZip.dll לעבודה עם קבצי זיפ).
ספריות אלו נותנות לנו כלים נוחים לשימוש, מבלי שנצטרך לממש אותם בעצמנו.

- כל הספריות בפרויקט שלנו שמורות תחת References.
- רק אחרי שנוסיף את הספרייה לפרויקט נוכל לקרוא לה על ידי using.




הוספת ספרייה לפרויקט:
דרך 1: להוריד את ה-dll ולהוסיף אותו ידנית.
דרך 2: אם מדובר בספרייה מוכרת, יתכן שניתן בעזרת NuGet להגיע אליה ישירות באמצעות חיפוש אונליין בויזואל סטודיו.
אפשר להגיע אל NuGet כך: TOOLS->Library Package Manager->Manage NuGet Packages for Solution.
או כפי שמתואר כאן.










יצירת קובץ EXE שמכיל את כל הספריות שעשינו בהן שימוש:

יום שני, 5 במרץ 2018

Enum ב-#C

Enum

בעבר למדנו על Enum בשפת C, היום נלמד עליו ב-#C.
Enum מאפשר לנו ליצג במילים דברים שהיינו יכולים ליצג במספרים, למען קריאות התוכנית למתכנת.

- ניתן ליצור Enum בתוך ומחוץ למחלקות ולמבנים. (מבנים = structs).
- פנייה לקבוע של אינם מסויים היא באמצעות שם האינם.
- אם מדובר באינם ציבורי ממחלקה אחרת, ניתן לפנות אליו רק בצירוף שם המחלקה.
- לכל מילה יש ערך מספרי. בברירת המחדל למילה הראשונה יש את הערך 0 ולכל מילה אחריה יש ערך גדול ב-1.
- לא ניתן להוסיף קבועים לEnum במהלך התוכנית.








דוגמאות:


Enum בתוך מחלקה, והמרה מקבוע אל int:
    class Program
    {
        // יצירת אינם ציבורי בתוך מחלקה
        public enum Season { WINTER, SPRING, SUMMER, FALL } 
 
        static void Main(string[] args)
        {
            // לתת למשתנה את הערך המספרי של קבוע מסוים בתוך האינם
            // int שימו לב שבשפת סי שארפ נדרשת המרה ל  
            int x = (int)Season.WINTER;
            int y = (int)Season.SUMMER;
 
            Console.WriteLine("WINTER = {0}", x); // ידפיס 0
            Console.WriteLine("SUMMER = {0}", y); // ידפיס 2
        }
    }



יום שני, 19 בפברואר 2018

פרסום קוד: מציאת כל הפתרונות האפשריים של כדור מחומשים (#C)

מציאת כל הפתרונות האפשריים שיש לכדור המחומשים

הכל התחיל מכדור מחומשים יפה ושלם.
מדובר היה במשחק, לפרק את הכדור ולהרכיב אותו בחזרה, איזה כיף.
אך אבוי! אחרי שפורק הכדור איש לא הצליח להרכיב אותו בהצלחה.

עברו שנים, ונזכרתי שאני מתכנת...





תמונה של הכדור מפורק:




יום שלישי, 6 בפברואר 2018

בגרות לבתי ספר על־יסודיים - מדעי המחשב (#C ו-Java)


בגרות במדעי המחשב


להורדת המבחנים והפתרונות של שנים 2016-2017: כאן.







שאלון 899381
המבחנים הם מאתר משרד החינוך.

יום חמישי, 25 בינואר 2018

ייצוג "תור" ב-#C

ייצוג פשוט של "תור" (עליו למדנו במבנה נתונים) בשפת #C.

הקוד פשוט מאוד להבנה:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace LearnQueue
{
    // תור = הראשון שנכנס הוא הראשון שיוצא
 
 

יום רביעי, 24 בינואר 2018

רשימה ג'נרית ב-#C

מימוש רשימה ג'נרית ב-#C

בדומה לרשימה המקושרת הפשוטה עליה למדנו, גם רשימה ג'נרית כבר קיימת כחלק מהשפה ואנחנו לא צריכים לממש אותה.
בכל זאת, למטרות לימוד נדגים מימוש אפשרי.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication103
{
    class Node<T> // "המחלקה "צומת
    {
        private T info;
        private Node<T> next;
 
        public Node(T info)
        {
            this.info = info;
            this.next = null;
        }
 
        public Node(T info, Node<T> next)
        {
            this.info = info;
            this.next = next;
        }
 

תכנות ג'נרי ב-#C

Generic

פונקציות ג'נריות מאפשרות לנו לכתוב פעם אחת קוד שמתאים למספר סוגים של משתנים.
הקוד מקבל כפרמטר את סוג המשתנים ומגיב בהתאם.



דוגמא - פונקציה ג'נרית להדפסת מערך פשוטה:
(אפשר לתת לסוג המשתנים כל שם, כאן נשתמש ב-"E".)
    class Program
    {
        // פונקציה ג'נרית להדפסה של איברי מערך מכל סוג מספרי
        static void PrintArray<E>(E[] inputArray)
        {
            foreach (E element in inputArray)
                Console.Write(element + ", ");
            Console.WriteLine("\n");
        }
 
 
        static void Main(string[] args)
        {
            // double ו int יצירת מערך של 
            int[] intArray = { 1, 2, 3, 4, 5, 6 };
            double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };
 
            // int הדפסת מערך
            PrintArray<int>(intArray); // 1, 2, 3, 4, 5, 6, :ידפיס
 
            // double הדפסת מערך
            PrintArray<double>(doubleArray); // 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, :ידפיס
        }
    }

יום שישי, 5 בינואר 2018

רשימות מקושרות ב-#C

זוכרים מהי רשימה מקושרת?
היום נלמד על רשימות מקושרות ב-#C.



רשימות מקושרות | Linked List
לפני שנלמד על רשימות מקושרות חשוב להבין שבשפת #C אין מצביעים. למה?
משום שבשפת #C כמעט כל דבר הוא מצביע! עד כדי כך שכבר אין צורך לסמן את זה באופן מיוחד.

הוכחה 1:
        static void Main(string[] args)
        {
            int[] arr1 = new int[5];
            int[] arr2 = new int[5];
            arr2 = arr1;
            arr2[0] = 19;
            Console.WriteLine(arr1[0]); // arr2 ידפיס 19, למרות שביצענו את השינויים על
        }




יום חמישי, 14 בדצמבר 2017

יום שני, 4 בדצמבר 2017

מספר פרמטרים משתנה - C#) params)

params
כמו בהרבה שפות, ב-#C קיימת אפשרות שפונקציה תקבל מספר משתנה של פרמטרים.
בשפת C ראינו את זה הרבה בפונקציות ()printf וְ ()scanf שמדפיסות או מקבלות מספר משתנים ככל העולה על רוחנו.




תחביר:
 שם_הפונקציה   ערך_מוחזר(params טייפ_הפרמטרים[] name){.....}

כל הפרמטרים נכנסים לפונקציה במערך. ה"Length" של המערך שווה למספר הפרמטרים שהוזנו.




דוגמה 1:
    class Program
    {
        public static int Sum(params int[] numbers)
        {
            int sum = 0;
            for (int i = 0; i < numbers.Length; i++)
            {
                sum += numbers[i];
            }
            return sum;
        }
        static void Main(string[] args)
        {
            Console.WriteLine(Sum());  // ידפיס 0
            Console.WriteLine(Sum(3, 5));  // ידפיס 8
            Console.WriteLine(Sum(3, 5, 10));  // ידפיס 18
        } 
    }

יום רביעי, 29 בנובמבר 2017

צבעים בחלון הפקודה #C

צבעים #C

נוכל לשנות את צבע הטקסט בחלון הפקודה.


1.
צריך להוסיף בראש התוכנית: using System.
לרוב, ה-System כבר כתובה אוטומטית בראש הקוד ע"י הוויזואל סטודיו.

שימו לב: ב-#C על ידי ה-using אנחנו לא מייבאים "ספריות", אלא "ניימספייסים" (namespace). מעתה נקרא להם בשמם.





2.
כדי לשנות את צבע הטקסט:
; צבע = Console.ForegroundColor

אחרי הפקודה כל הטקסט יהיה בצבע שבחרתם.
(כדי לציין את הצבע משתמשים ב enum הצבעים: "ConsoleColor".)

        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Hello");
        }

יום שלישי, 28 בנובמבר 2017

ה-ref וה-C#) out)

בדומה ל"משתנה המיוחס" ב ++C, גם ב-#C פונקציה יכולה להשפיע על הארגומנטים שהיא מקבלת.
כדי להשפיע על ארגומנט נוסיף לו את המילה השמורה "ref" או "out" בראש הפונקציה ובשליחה לפונקציה.



ref

עם ref נשלח משתנה שכבר עבר אתחול. כל השינויים שהוא יעבור ישפיעו על המשתנה המקורי.

דוגמה:
החלפת ערכים בין שני משתנים
    class Program
    {
        static void Swap(ref int x, ref int y)
        {
            int tmp = x;
            x = y;
            y = tmp;
        }
        static void Main(string[] args)
        {
            int a = 5, b = 10;
            Swap(ref a, ref b);
 
            // :הדפסה
            Console.WriteLine("a: " + a); // a: 10
            Console.WriteLine("b: " + b); // b: 5
        }
    }

יום רביעי, 22 בנובמבר 2017

שימושים של המחלקה Math ב-#C

פונקציות שימושיות במחלקה Math:


1
Math.Abs(מספר)
מחזיר את הערך המוחלט של המספר
            double n = Math.Abs(-8.9);
            Console.WriteLine(n);  // ידפיס: 8.9


2
Math.Pow(מספר1, מספר2)
מחזיר את מספר2 בחזקת מספר1
            double n = Math.Pow(10, 2);
            Console.WriteLine(n);  // ידפיס: 100


3
Math.Sqrt(מספר)
מחזיר את השורש הריבועי של המספר
            double n = Math.Sqrt(25);
            Console.WriteLine(n);  // ידפיס: 5

יום שבת, 18 בנובמבר 2017

פונקציה נחמדה שכתבתי לקליטה בטוחה של מספר שלם מהמשתמש

הפונקציה כתובה כאן ב-#C, אבל תוכלו להמיר אותה עם קצת מחשבה לכל שפה.
אגב, בחלק מהתוכניות בבלוג כבר עשינו בה שימוש.

קליטה בטוחה של מספר int מהמשתמש:

תיאור: פונקציות לקליטת מספר שלם אחד או יותר מהמשתמש באופן בטוח.
במקרה שהמשתמש הזין קלט לא תקין, (כגון: אותיות, מינוס במקום לא נכון, יותר או פחות מספרים מהנחוץ, לא הכניס שום קלט, מספרים ארוכים מדי, מספרים שחורגים מערכי המינימום והמקסימום וכו'), הוא יתבקש להזין מחדש את הקלט עד לקבלת קלט תקין.

הערה: הפונקציה Get_Save_int_Number_From_User נכתבה במקור עבור שפת C, כנראה תמצאו בה דברים שאפשר לקצר באמצעות #C.
בניגוד אליה, הפונקציה Get_Save_int_Numbers_From_User נכתבה ישירות עבור #C.






יום רביעי, 15 בנובמבר 2017

מספרים ומערכים רנדומלים (#C)

למדנו על מספרים רנדומליים בשפת C וב ++C. היום נלמד עליהם ב-#C תוך הרחבה של הנושא.

מספרים אקראיים:


כדי ליצור מספר אקראי ניצור אובייקט מהמחלקה Random:
Random r = new Random();

נוכל להשתמש בו כדי לקבל מספר רנדומלי חדש.
כך: הפונקציה ()Next מחזירה מספר רנדומלי חדש (לא תחזיר מינוס)
r.Next();


נוכל לשלוח לפונקציה Next טווח מספרים.
כך למשל על-מנת להגריל מספר שלם בין 1 ל- 7 (כולל 1 אך לא כולל 7):
r.Next(1,7);
לדוגמה:
            Random r = new Random();
            Console.WriteLine(r.Next(1,9)); // ידפיס מספר רנדומלי בין 1 ל-8 כולל 



יום שני, 6 בנובמבר 2017

שפת #C - מחרוזות

אנחנו כבר יודעים איך לעבוד עם מחרוזות בשפת C ובשפת ++C.
היום נלמד על מחרוזות ב-#C:

String

עד היום השתמשנו במערך של משתנים מטייפ char לעבודה עם מחרוזות.
ב#C, (בדומה לJava), קיים טייפ מיוחד בשם "String" שנועד במיוחד לאחסון מחרוזות.

הגדרה:
String str;

אתחול בהגדרה:
String str = "Hello!";

הדפסה:
Console.WriteLine(str);

קליטה:
כאן אין צורך בפונקציית ההמרה "()Parse", משום שהפונקציה ()ReadLine כבר מחזירה String.
str = Console.ReadLine();


NULL מסיים:
ל-String אין NULL מסיים. במקומו נוכל להשתמש במאפיין Length שמייצג את אורך המחרוזת.
str.Length

יום חמישי, 2 בנובמבר 2017

מערכים והלולאה C#) foreach)

Arrays


בשפת #C מערכים מתנהגים קצת שונה מבשפת C.

- לקביעת גודל של מערך אפשר להשתמש במשתנה.
- מערך הוא אובייקט (כמו הכל ב #C), יש לו שדה שמייצג את מספר איבריו: Length.


הגדרת מערך של int:
int[] Array;
מערך זה עדיין לא מאותחל. כרגע Array הוא רק "שם של מערך". בדומה לשפת C - שם של מערך הוא מצביע.
(בשפת #C לא משתמשים במצביעים, לכן לא נקפיד לקרוא לו בשם "מצביע". זכרו שהוא מתנהג כמו מצביע.)


כדי להתחיל להשתמש בו לאחסון מידע נצטרך לבצע לו איתחול:
Array = new int[5];
כעת Array הוא מערך מאותחל בגודל 5 איברים.
כשמערך מאותחל כל איבריו מקבלים את הערך 0.



ניתן לבצע את כל זה בשורה אחת:
int[] Array = new int[5];

תחילת עבודה עם #C

מה שונה ב #C ?


#C היא שפה מתקדמת יותר עם לא מעט יכולות נוספות. בכל זאת לתוכניות שדורשות ביצועי מערכת מהירים במיוחד הרבה יעדיפו שימוש ב ++C.

כדי לפתוח בוויזואל סטודיו פרויקט ב #C צריך לבחור במיוחד:
Visual C#  ->  Console Application

אחרי זה יופיע לנו הקוד הבא:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication25
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}