• بتحكم في الـ Flow بتاع الـ Program
  • من غيرها هو بيبقا Sequential خام بمعنى انه بينفذ سطر ورا سطر
  • انما الأدوات دي بتخليه يعمل Branching بمعنى انه ممكن يروح ينفذ حاجة على جنب ينفذ حاجة مثلًا ويرجع يكمل البرنامج بعدها

Selection Statements (Conditions)

If Else

Default If Else

if (condition1)
{
  // block of code to be executed if condition1 is True
} 
else if (condition2) 
{
  // block of code to be executed if the condition1 is false and condition2 is True
} 
else
{
  // block of code to be executed if the condition1 is false and condition2 is False
}

example:

int time = 22;
if (time < 10) 
{
  Console.WriteLine("Good morning.");
} 
else if (time < 20) 
{
  Console.WriteLine("Good day.");
} 
else 
{
  Console.WriteLine("Good evening.");
}
// Outputs "Good evening."

Short Hand If .. Else (Ternary Operator)

  • بستخدمها عشان أحط قيمة في variable على حسب شرط معين
  • بتحتاجها دايمًا لما تيجي تعمل Select من Database
variable = (condition) ? expressionTrue :  expressionFalse;
 
variable = (condition) ? expressionTrue: (Else if Condition)? expressionTrue: expressionFalse;

example:

int time = 20;
if (time < 18) 
{
  Console.WriteLine("Good day.");
} 
else 
{
  Console.WriteLine("Good evening.");
}
 
//******************************//
 
int time = 20;
string result = (time < 18) ? "Good day." : "Good evening.";
Console.WriteLine(result);

Switch

  • بتختار حاجة من ال blocks الكتير اللي عندك وبتنفذها لو الشرط اتحقق
  • ال break هنا mandatory ولازم تبقا موجودة
  • لو الحالة محتاجة Switch فاستخدمها من غير تفكير لأن هي أحسن في الـ Performance لأنها بتستخدم الـ Hashing

example 1

int day = 4;
switch (day) 
{
  case 1:
    Console.WriteLine("Monday");
    break;
  case 2:
    Console.WriteLine("Tuesday");
    break;
  case 3:
    Console.WriteLine("Wednesday");
    break;
  default:
	Console.WriteLine("def");
	break;
}
// Outputs "Thursday" (day 4)

example 2: With when

double degree = double.Parse(Console.ReadLine());
 
switch (degree)
{
    case double d when (d >= 0 && d <= 50):
        Console.WriteLine("F");
        break;
    case double d when (d >= 51 && d <= 65):
        Console.WriteLine("D");
        break;
    case double d when (d >= 66 && d <= 75):
        Console.WriteLine("C");
        break;
    case double d when (d >= 76 && d <= 85):
        Console.WriteLine("B");
        break;
    case double d when (d >= 86 && d <= 100):
        Console.WriteLine("A");
        break;
    default:
        Console.WriteLine("Null");
        break;
}

example 3: Same body

  • لو ال body بتاع اتنين case هيبقا واحد فممكن مكررش وأعملهم group
int x = 2;
switch (x)
{
	case 1:
	case 3:
		Console.WriteLine("Odd");
		break;
	case 2:
	case 4:
		Console.WriteLine("Even");
		break;
	default:
		Console.WriteLine("Out of Range");
}

Fall-through

  • انه بكل بساطة ممكن أخد ال body من أول case ومن التاني ومن التالت وهكذا
  • وفي الطريقة دي بستخدم معاها ال goto
int Value = 3000;
 
switch (Value)
{
	case 3000:
		Console.WriteLine("Option 03");
		Console.WriteLine("Option 02");
		Console.WriteLine("Option 01");
		break;
	case 2000:
		Console.WriteLine("Option 02");
		Console.WriteLine("Option 01");
		break;
 
	case 1000:
		Console.WriteLine("Option 01");
		break;
	default:
		Console.WriteLine("NA");
		break;
}
 
switch (Value)
{
	case 3000:
		Console.WriteLine("Option 03");
		//Console.WriteLine("Option 02");
		//Console.WriteLine("Option 01");
		goto case 2000;
	//break;
	case 2000:
		Console.WriteLine("Option 02");
		//Console.WriteLine("Option 01");
		goto case 1000;
	//break;
	case 1000:
		Console.WriteLine("Option 01");
		break;
	default:
		Console.WriteLine("NA");
		break;
}

انك تستخدم ال goto عموما مش أحسن حاجة ودي الحالة الوحيدة اللي ممكن تستخدمها فيها وحتى استخدامها على مسئوليتك

Switch vs If Else

  • لو فيه checks كتير استخدمها ومتستخدمش If Else لان ال If Else بتاخد Time Complexity = O(N) انما ال Switch بتاخد O(1) لأنها بتستخدم Hash table فبالنسبالها كلمة case عبارة عن label او يفطة وهي بتعمل jump عليها
  • اقدر استخدمها برضو مع ال strings بس في الحالة دي انسى كل الكلام اللي فوق بتاع الفرق بينها وبين ال If Else لأنها هتاخد نفس ال time complexity ودا بسبب انها مش بتستخدم ال jump table اللي قولنا عليه
  • لما بستخدم string أكنه بيحول ال code ل If Else
  • فلو عدد ال options صغير شوية مش هتفرق تستخدم ايه انما لو عدد ال cases أكبر شوية فاستخدم ال switch لانه في الحالة دي بيستخدم ال Hash table

الفرق من ناحية الأداء:

  1. if-else:

    • يتم تقييم الشروط بشكل تسلسلي. إذا كان لديك سلسلة طويلة من الشروط، فقد يكون الأداء أبطأ لأن كل شرط يتم تقييمه حتى يتم العثور على الشرط الصحيح.
    • الأداء يعتمد على عدد الشروط وكيفية ترتيبها.
  2. switch:

    • يمكن أن يكون أسرع من if-else في بعض الحالات، خاصة إذا كان هناك عدد كبير من الحالات (cases) التي يتم التحقق منها.
    • في بعض اللغات، يتم تنفيذ switch باستخدام جداول القفز (jump tables) أو هياكل بيانات أخرى مثل الأشجار الثنائية، مما يجعل الوصول إلى الحالة الصحيحة أسرع.

البنية الداخلية (Data Structure):

  • if-else:

    • لا يعتمد على بنية بيانات محددة. يتم تنفيذ الشروط بشكل تسلسلي، وعادة ما يتم ترجمتها إلى سلسلة من التعليمات الشرطية في الكود المترجم.
  • switch:

    • في بعض اللغات، يتم تنفيذ switch باستخدام (jump tables) عندما تكون الحالات متتالية وقريبة من بعضها. هذا يسمح بالوصول المباشر إلى الحالة الصحيحة بدلاً من التحقق من كل حالة على حدة. اللي بيتم من خلال الـ Hashing
    • إذا كانت الحالات غير متتالية أو معقدة، قد يتم تنفيذ switch باستخدام سلسلة من التعليمات الشرطية مثل if-else.

ملاحظات إضافية:

  • اختيار استخدام switch أو if-else يعتمد على الحالة الخاصة بالكود الذي تكتبه. إذا كان لديك عدد قليل من الشروط، قد لا يكون هناك فرق كبير في الأداء.
  • في بعض اللغات، switch يدعم فقط أنواع بيانات معينة (مثل الأعداد الصحيحة أو الأحرف)، بينما if-else يمكن استخدامه مع أي نوع من الشروط.

Iteration Statements (Loops)

Loops is a control structure that repeats a group of steps in a program. We should have:

  1. initial value
  2. condition
  3. counter (+ , -)

For

// for (initial value; condition; counter)
for (int i = 0; i < 5; i++)
{
	Console.WriteLine(i);
}

Nested Loops

اننا نحط loop جوا loop

// Outer loop
for (int i = 1; i <= 2; ++i) 
{
  Console.WriteLine("Outer: " + i);  // Executes 2 times
 
  // Inner loop
  for (int j = 1; j <= 3; j++) 
  {
    Console.WriteLine(" Inner: " + j); // Executes 6 times (2 * 3)
  }
}

Foreach

We use it a lot with Cs Arrays or any collection

string[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
foreach (string i in cars) 
{
  Console.WriteLine(i);
}

While

طول ما الشرط true اللي جواها هيتنفذ

int i = 0;
while (i < 5) 
{
  Console.WriteLine(i);
  i++;
}
// 0 1 2 3 4

Do not forget to increase the variable used in the condition, otherwise the loop will never end!

Do/While

زي while بالظبط بس هو هينفذ الأول وبعدين يعمل check على الشرط

int i = 0;
do 
{
  Console.WriteLine(i);
  i++;
}
while (i < 5);
// 0 1 2 3 4

Nested Loops

الـ Nested loops في تعني وجود (loop) داخل loop أخرى. تُستخدم هذه التقنية عندما تحتاج إلى تكرار مجموعة من العمليات داخل مجموعة أخرى من العمليات. يمكن أن تكون هذه الحلقات من أي نوع: for, while, أو do-while.

مثال بسيط على Nested loops باستخدام for:

for (int i = 0; i < 3; i++) // Outer Loop
{
    for (int j = 0; j < 2; j++) // Inner Loop
    {
        Console.WriteLine($"i: {i}, j: {j}");
    }
}

في هذا المثال، الحلقة الخارجية (for) تتكرر 3 مرات، وفي كل مرة تتكرر فيها، تقوم بتشغيل الحلقة الداخلية (for) التي تتكرر بدورها مرتين. النتيجة هي أن الحلقة الداخلية تُنفذ 6 مرات في المجموع (3 مرات للحلقة الخارجية × 2 مرات للحلقة الداخلية).

استخدامات شائعة للـ Nested loops:

  1. التعامل مع المصفوفات متعددة الأبعاد: مثل المصفوفات الثنائية الأبعاد (2D arrays)، حيث تحتاج إلى حلقة للتنقل عبر الصفوف وأخرى للتنقل عبر الأعمدة.

  2. تنفيذ عمليات معقدة: مثل العمليات الحسابية أو المنطقية التي تتطلب تكرارًا متعدد المستويات.

  3. معالجة البيانات: مثل قراءة البيانات من جداول أو ملفات تحتوي على هيكلية معقدة.

ملاحظات:

  • الأداء: يمكن أن تؤدي الحلقات المتداخلة إلى زيادة كبيرة في عدد العمليات، مما قد يؤثر على الأداء إذا لم يتم استخدامها بحذر، خاصة إذا كانت الحلقات تحتوي على عدد كبير من التكرارات.

  • التعقيد: من المهم الحفاظ على وضوح الكود عند استخدام الحلقات المتداخلة لتجنب التعقيد الزائد الذي قد يصعب فهمه أو صيانته.

  • الخروج من الحلقات: يمكنك استخدام break للخروج من الحلقة الحالية أو continue لتخطي التكرار الحالي والانتقال إلى التكرار التالي.