ahmed.o.mohamed

[C] المتغيرات و المؤثرات

1 مشاركة في هذا الموضوع

فهرس الأسئلة:

  1. المتغيرات (Variables) :
    • ماهو النوع char و ماهي المساحة التي يمثلها ؟
    • ماهي المساحة التي يمثلها int ؟
    • أحيانا, ألاحظ أن حجم int مساوي لــ short أو long أو long long !, لماذا ؟
    • ماذا عن اختلاف حجم int بالنسبة للبيئة التي يعمل عليها البرنامج ؟
    • ما الحل ؟
    • و ما هي الـ Length Modifier ؟
    • إذا, توجد أربعة أنواع للأرقام الصحيحة ؟
    • هل تحدد اللغة أحجام البيانات ؟
    • إذا, اللغة لا تهتم بالمساحة التي يستهلكها int ؟
    • كلمة أخيرة عن أحجام البيانات ؟
    • ماذا تعني الكلمة signed ؟
    • المترجم الخاص بي لا يعرف النوع long long, لماذا ؟
    • هل تدعم لغة C المتغيرات المنطقية ؟
    • ما فائدة المؤثر sizeof ؟
    • هل يمكننا معرفة الحجم الكامل المستعمل للبرنامج عن طريق sizeof ؟
    • ما هو النوع size_t ؟
    • ماهو النوع wchar_t ؟
    • كيف أنشئ اسما مستعارا للأنواع الموجودة في اللغة ؟
    • ماذا تعني الكلمة const ؟
    • ماهي الرموز المُستخدمة مع الأنواع الصحيحة ؟
    • متى أستخدم if-else و متى أستخدم switch ؟
    • ماذا يحدث للمتغيرات الغير مهيئة (uninitialized variable) ؟

[*]المؤثرات (Operators) :

  • مالفرق بين المؤثر = و المؤثر == ؟
  • ماهو المؤثر الثلاثي (ternary operator) ؟
  • هل يمكن استخدام المؤثر الثلاثي في حالة وجود أكثر من statement ؟
  • كيف نحسب باقي القسمة ؟
  • مالفرق بين الزيادة القبلية و الزيادة البعدية ؟
  • كيف يعمل المؤثر AND (&&) ؟
  • كيف يعمل المؤثر OR (||) ؟
  • كيف يعمل المؤثر AND_BIT (&) ؟
  • كيف يعمل المؤثر OR_BIT (|) ؟
  • كيف يعمل المؤثر NOT_BIT (~) ؟
  • كيف يعمل المؤثر XOR (^) ؟
  • كيف تعمل مؤثرات الإزاحة ؟
  • ماهو ترتيب أولوية المؤثرات ؟

1. المتغيرات (Variables) :

ماهو النوع char و ماهي المساحة التي يمثلها ؟

نوع البيانات char وعلى المستوى المنخفض هو أصغر جزء يمكن حجزه في الذاكرة لتخزين أي عدد صحيح ضمن ترتيب تسلسلي معين وهو ما يُعرف بـ range. حتى وإن كان المتغير من نوع char يُعامل على أنه حرف أو رمز مطبوع أو غير مطبوع على الشاشة فإنه ذو أصول عريقة تنحدر من سلالة نوع البيانات للأعداد الصحيحة وهو int.

حسب التعريف فإن SizeOfChar تساوي 1 مما يعني أن النوع char يأخذ من الذاكرة مساحة قدرها 1 بايت, البايت الواحد يُساوي على الأقل 8 بت و الحجم الحقيقي لــ char بالبت مُخزن في الماكرو CHAR_BIT الموجود في المكتبة limits.h, انظر المثال:

#include<stdio.h>
#include<limits.h>
int main(){
short const SIZE_CHAR = CHAR_BIT;
printf("Size of char = %d bits", CHAR_BIT);
return 0;
}

ماهي المساحة التي يمثلها int ؟

المساحة التي يمثلها int في الذاكرة تتناسب مع الحاسب الذي تعمل عليه, فإذا كنت تعمل على نظام 16 بت (مثل الدوس) فستكون مساحة int تساوي 2 بايت و إذا كنت تعمل على نظام 32 بت (مثل ويندوز 2000) فستجد أن مساحة int هي 4 بايت أما إذا كنت تعمل على نظام 64 بت (مثل ويندوز 7-x64) فستجد أن مساحة int تساوي 8 بايت.

أحيانا, ألاحظ أن حجم int مساوي لـ short أو long أو long long !, لماذا ؟

عندما تستخدم int فإن المترجم سيعتبره short أو long أو long long و ذلك حسب إعدادات المترجم الافتراضية.

ماذا عن اختلاف حجم int بالنسبة للبيئة التي يعمل عليها البرنامج ؟

إذا عمل برنامجك على نظام تشغيل 16 بت و أنت تستخدم int فسيكون مساحته 2 بايت و هذا قد يجعل برنامجك يفشل في تطبيق ما يريد !,فهو يتوقع أن حجم int هو 4 بايت و قد ظهر أن مساحته هي 2 بايت !

ما الحل ؟

الحل هنا يكمن في استخدام طريقه تسمح لك بتحديد المساحة التي يستهلكها int مـن الذاكرة أو بمعنى أدق مدى الأرقام الذي يمكن تمثيله بـ int و ذلك سواء كنت تعمـل على نظام تشغيل 16بت أو 32 بت أو 64 بت أو غيرهم حيث ستكون المساحة التي يستخدمها برنامجك واحدة في كل الأحوال. هذه الطريقة تتم باستخدام ما يسمى بـ Length Modifier أو "محددات المساحة" إن صح التعبير !.

و ما هي الـ Length Modifier ؟

الـ Length Modifier هي كلمات محجوزة مسبقا, باستخدامها مع int تجعل مدى الأرقام الذي يمكن تمثيله به ثابت و لا يتغير من نظام تشغيل لآخر أو بمعنى أدق من Architecture لأخرى و بذلك تكون وصلت إلى ما تريد. الـ Length Modifier هى :

signed short
signed long
signed long long
unsigned short
unsigned long
unsigned long long

إذا, توجد أربعة أنواع للأرقام الصحيحة ؟

لم أقل هذا, قلتُ أنه يوجد نوع بيانات واحد للأرقام الصحيحة و هو int و يمكننا تغيير المدى الخاص به عن طريق الـ Length Modifier لنحصل على أنواع جديدة مشتقة منه و هي short و long و long long كأن نكتب:

short int//short int = short
long int// long int = long
long long int// long long int = long long

هل تحدد اللغة أحجام البيانات ؟

اللغة لا تحدد حجم البيانات لأنواع البيانات و لكنها تحدد القيمة العظمى و الصغرى للأنواع الرقمية و نظرا لأن القيمة العظمى و الصغرى لهم تستهلك مساحات بقدر 2 و 4 و 8 بايت فقد تم التعارف على أن أحجام البيانات لهم هي بالمساحات السابق ذكرها و يمكنك مراجعة الملف limits.h (خاص بلغةc) و الفئةnumeric_limits (خاصة بلغة cpp) حتى تتعرف بشكل أكبر على هذه الأنواع.

إذا, اللغة لا تهتم بالمساحة التي يستهلكها int ؟

صحيح, اللغة لا تهتم بالمساحة التي يستهلكها int من الذاكرة و إنما تهتم بمدى الأرقام الذي يمكن تمثيله داخل هذا النوع و ذلك لأنه باختلاف العتاد تختلف المعايير المتعلقة بحجز الذاكرة و تحديد المساحات لذا و حتى تصبح اللغة مستقلة عن العتاد لابد من تحديد أسس معينه يتم العمل بها و هي في هذه الحالة مدى الأرقام و ليس المساحة المستهلكة من الذاكرة.

كلمة أخيرة عن أحجام البيانات ؟

إذا قمت بالنظر داخل الملف limits.h أو الفئه numeric_limits ستجد أنه يعطيك المدى المسموح به من الأرقام لنوع معين و هو ما تشترطه اللغة, أما المساحة التي يحجزها من الذاكرة لتمثيل ذلك المدى فهي تعود للمترجم و يمكن أن تختلف من أحدهم لآخر.

ماذا تعني الكلمة signed ؟

الكلمة signed هي إحدى الكلمات المحجوزة مسبقا و تنتمي إلى عائلة محددات الأسماء أو ما يعـرف بـ Length Modifier , هذه الكلمة تُستخدم مع الأنواع الصحيحة فقط و تعني أن المتغير المستخدم معها سيحتوي عـلى إشارة (ربما تكون موجبة أو سالبة). الكلمة signed تُمثل الحالة الافتراضية للمتغيرات (لأن المتغيرات بالأصل يمكنها تخزين أعداد موجبة أو سالبة).

أما unsigned تعني أن المتغير سيحوي قيم موجبة فقط.

المترجم الخاص بي لا يعرف النوع long long, لماذا ؟

لأن هذا النوع لم يتم تضمينه إلا في المعيار C99, ربما تستخدم مترجم لا يدعم هذا المعيار أو ربما قمتَ بإعداد المترجم الخاص بك على المعيار C90.

هل تدعم لغة C المتغيرات المنطقية ؟

قبل مقياس C99 لم تكن توجد متغيرات من النوع المنطقي bool ولكن من السهل جدا إنشاء هذا النوع من المتغيرات إذا كان المترجم لا يقدم تلك الخدمة :

#define BOOL int
#define TRUE 1
#define FALSE 0

أو :

typedef enum {
FALSE, TRUE
} BOOL;

في لغة C كل قيمة معدومة (0, 0.0, ...) تعني false بينما تعني كل قيمة غير معدومة (-4, 9.06, ...) القيمة true. المقياس C99 أدخل النوع _BOOL الموجود في الملف الرأسي stdbool.h بالإضافة إلى الماكرو :

__bool_true_false_are_defined

الذي يسمح بمعرفة ما إذا كانت المتغيرات المنطقية معتمدة أصلا أم لا.

يمكننا أيضا استخدام الأنواع الأصلية من أجل تعريف نوع جديد في حالة عدم توفر النوع bool:

#ifndef __bool_true_false_are_defined
# define bool int
# define true 1
# define false 0
# define __bool_true_false_are_defined
#endif

ما فائدة المؤثر sizeof ؟

هذا المؤثر يسمح بمعرفة أحجام البيانات و تكون النتيجة بالبايت bytes, انظر المثال:

#include<stdio.h>
int main(){
int SizeOfArray[800];
printf("Char = %d Byte(s)\n",sizeof(char));
printf("Bool = %d Byte(s)\n",sizeof(bool));
printf("Short = %d Byte(s)\n",sizeof(short));
printf("Int = %d Byte(s)\n",sizeof(int));
printf("Long = %d Byte(s)\n",sizeof(long));
printf("Long long = %d Byte(s)\n",sizeof(long long));
printf("Float = %d Byte(s)\n",sizeof(float));
printf("Double = %d Byte(s)\n",sizeof(double));
printf("Long double = %d Byte(s)\n",sizeof(long double));
printf("SizeOfArray = %d Byte(s)\n",sizeof(SizeOfArray));
return 0;
}

هل يمكننا معرفة الحجم الكامل المستعمل للبرنامج عن طريق sizeof ؟

لا يمكن لأن حجم البرنامج النهائي يمكن أن يدخل فيه مكتبات أخرى بالإضافة الى هيكلة الملف الناتج نفسه ليعمل على Environment محددة وهو شيء خارج عن مهام الـCompiler.

ما هو النوع size_t ؟

هذا النوع يُمثل القيمة المــُعادة من طرف المؤثر sizeof وهو مُعرف في الملف الرأسي stddef.h, البعض يعتبره مُكافئا لـ unsigned long.

ماهو النوع wchar_t ؟

يُستخدم هذا النوع عادة عند التعامل مع الكلمات العربية, يأخذ من الذاكرة مساحة قدرها 2 بايت و الترميز المستخدم يعود للمترجم و في الأغلب يكون إما Universal Character Set الخاص بــ ISO أو UTF-16 الخاص بــ Unicode على عكس char الذي يدعم ترميز الـ ASCII فقط أو بعض الــ encoding المشابهة لها.

يوجد تشابه كبير بين الدوال التي تُستخدم مع char و الأخرى التي تُستخدم مع wchar_t, مثل wprintf بدلا من printf و wcscpy بدلا من strcpy و iswaplha بدلا من isaplha, يمكنك تضمين wchar.h أو wctype.h حسب الدوال التي ستستخدمها, انظر المثال:

#include <stdio.h>
#include <wchar.h>
int main()
{
wchar_t ws[256];
wcscpy(ws, L"Hello");
wcscat(ws, L", world !");
wprintf(L"%s\n", ws);
return 0;
}

كيف أنشئ اسما مستعارا للأنواع الموجودة في اللغة ؟

يتم ذلك باستخدام الكلمة المحجوزة مُسبقا typedef حيث تُستعمل هذه الكلمة لإعطاء أنواع المتغيرات أسماء مستعارة, و طريقة استخدامها تكون بكتابة الكلمة ثم نوع البيانات متبوعا بالاسم المستعار هكذا:

Typedef DataType AliaseName

أمثلة:

typedef int VECTEUR[3];
typedef void * POINTEUR;
typedef struct { int value; } INTVALUE;
VECTEUR u, v; /* int u[3], int v[3]; */
POINTEUR p1, p2; /* void * p1, * p2; */
INTVALUE n; /* struct { int value; } n; */

ماذا تعني الكلمة const ؟

تُستخدم هذه الكلمة للإعلان عن الثوابت حيث يجب إسناد قيمة ابتدائية للثابت و لا يمكن تغيير تلك القيمة فيما بعد.

ماهي الرموز المُستخدمة مع الأنواع الصحيحة ؟

  • الرموز التالية %d,%i,%o,%x تُمثل القيم التي من النوع int أو unsigned int فقط و إذا أردنا استخدامها مع الأعداد الصحيحة المضاعفة فإننا نستخدم الرموز التالية %ld,%li,%lo,%lx
  • إذا أردنا إظهار عدد صحيح قصير موجب unsigned short فإننا نستخدم الرمز %hu و نستخدم الرمز %lu مع unsigned long أما إذا أردنا إظهار عدد صحيح مضاعف ضخم موجب فإننا نستخدم الرمز %llu. (راجع السؤال التاسع من الفصل الرابع لمعرفة المزيد).

متى أستخدم if-else و متى أستخدم switch ؟

يُنصح باستخدام الجمل الشرطية if,else عند التعامل مع الأعداد الحقيقة أو الجمل. من عيوب switch أنها لا تدعم الأعداد الحقيقة و الجمل ! فهي لا تتعامل إلا مع الأعداد الصحيحة و الحروف ,بالنسبة للحروف فهي تتعامل مع الشفرة المقابلة للحرف في جدول ASCII.

ماذا يحدث للمتغيرات الغير مهيئة (uninitialized variable) ؟

المتغيرات الغير مهيئة هي المتغيرات التى تم التصريح عنها و لكن لم يتم ادخال قيمة لها , يقوم المترجم بإعطائك التحذير unreferenced local variable و فى حالة نسخ الـ debug من البرنامج يتم حجز مساحة لها داخل الـ stack و لكن يترك مكانها كما هو بالقيمه التى يحتوى عليها و تسمى القيمه التى يحتوى عليها فى هذا الوقت بــ junk اى قيم غير صحيحة.

2. المؤثرات (Operators) :

مالفرق بين المؤثر = و المؤثر == ؟

المؤثر = هو معامل الإسناد, حيث يقوم بإسناد القيمة الموجودة على يمينه إلى المتغير الموجود في اليسار, أما المؤثر == فيُستعمل للمقارنة حيث يُعيد true إذا تساوى الطرفان و false في العكس.

ماهو المؤثر الثلاثي (ternary operator) ؟

المؤثر الثلاثي هو تعبير يستخدم عادة في الشروط البسيطة و شكله العام كالتالي:

Condition ? doThis : doThis ;

إذا كان الشرط محقق فسيتم تنفيذ الأمر الموجود قبل الرمز : و إلا فسيتم تنفيذ الأمر الموجود بعده و هذا يعني أن تركيبة المؤثر الثلاثي تكافئ:

if(Condition == true)
do this;
else
do this;

يمكن أيضا استخدام المؤثر الثلاثي في الشروط المتداخلة :

if(x > y){
if(x > z) return x;
else return z;
}else{
if(y > z) return y;
else return z;
}

هكذا:

( x > y )?( (x > z)? x : z ) :( y > z )? y : z;

هل يمكن استخدام المؤثر الثلاثي في حالة وجود أكثر من statement, هكذا :

#include <stdio.h>
int main()
{
int x = 0;
if(x != 0){
x++;
printf("%d",x);
}else{
x--;
printf("%d",x);
}
return 0;
}

نعم, يمكن إستخدام الـ ternary operator في حالة وجود أكثر من statement داخل كل block عن طريق استخدام الـ sequence operator (المعامل comma) كالتالي:

#include <stdio.h>
int main()
{
int x = 0;
x != 0 ? x++, printf("%d",x) : x--, printf("%d",x);
return 0;
}

كيف نحسب باقي القسمة ؟

توجد 5 طرق لحساب باقي القسمة:

#include<iostream>
#include<cstdlib>
using namespace std;

int main() {
int a, b;
cout << "a = ";
cin >> a;
cout << "b = ";
cin >> b;

/********* Debut *******/

/******** Methode 1 : *********/
cout << a << " % " << b << " = " << a % b << endl;

/******** Methode 2 : *********/
int c;
c = a / b;
c *= b;
cout << a << " % " << b << " = " << a - c << endl;

/******** Methode 3 : *********/
c = 0;
while (c + b < a)
c += b;
cout << a << " % " << b << " = " << a - c << endl;

/******** Methode 4 : *********/
c = a;
for (; c > b;)
c -= b;
cout << a << " % " << b << " = " << c << endl;

/******** Methode 5 : *********/
div_t divresult;
divresult = div(a, b);
cout << a << " % " << b << " = " << divresult.rem << endl;

/********* Fin *******/
return 0;
}

مالفرق بين الزيادة القبلية (++i ) و الزيادة البعدية (i++) ؟

يختلفان من ناحية الأسبقية, فالزيادة القبلية تُنفذ قبل تنفيذ جميع الأوامر المرافقة لها أما الزيادة البعدية فيتم تنفيذها بعد تنفيذ جميع الأوامر المرافقة لها.

كيف يعمل المؤثر AND (&&) ؟

المؤثر && يعتبر حرف العطف "و" في لغة البشر, فلو قلت لك: "ذهبت للبيت أنا و أخي"

ثم أخبرتك أن أخي لم يذهب !, حينئذ ستكون الجملة غير صحيحة و كذلك لو قلت لك أن أخي ذهب لكنني لم أذهب, أولم نذهب نحن الإثنان معا ! ففي الأحوال السابقة تكون الجملة غير صحيحة.تكون الجملة صحيحة في حالة واحدة ووحيدة و هي أن نذهب أنا و أخي معا إلى البيت.

مما سبق نجد أن هذا المؤثر يعمل على ربط علاقتين منطقيتين و تكون نتيجة العبارة الجديدة صحيحة إذا كانت العبارتان صحيحتان في نفس الوقت أما في باقي الحالات فالنتيجة خاطئة والجدول التالي يوضح ما سبق:

post-219439-051423800 1343757657_thumb.p

كيف يعمل المؤثر OR (||) ؟

المؤثر "||" يعتبر "أو" في لغة البشر, لو قلت لك "سأجلس للبرمجة أو تصفح الانترنت"

فلو جلست للبرمجة فقط فكلامي صحيح, أو جلست لتصفح الانترنت فقط فكلامي صحيح أيضا, ولو جلست و فعلت الاثنتين معا لكان كلامي صحيحا أيضا !!

تكون هذه الجملة خاطئة في حالة وحيدة, هي عندما لا أجلس للبرمجة و لا أتصفح الانترنت.

مما سبق نجد أن هذا المؤثر يعمل على ربط علاقتين منطقيتين و تكون نتيجة العبارة الجديدة خاطئة إذا كانت العبارتان خاطئتان في نفس الوقت أما في باقي الحالات فالنتيجة صحيحة و الجدول التالي يوضح ما سبق:

post-219439-005085100 1343757678_thumb.p

كيف يعمل المؤثر AND_BIT (&) ؟

هذا المؤثر يقارن كل بت من العدد الأول مع البت المقابل له من العدد الثاني و هذه طريقة عمله:

/*
Bitwise :And Operator
True = 1
False = 0
*/
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0

مثال:

/*
Bitwise :And Operator
True = 1
False = 0
*/
23 & 11 = 3
00010111 // 23 decimal = 00010111 Binary
&
00001011// 11 decimal = 00001011 Binary
------------
=
00000011// 3 decimal = 00000011 Binary

كيف يعمل المؤثر OR_BIT (|) ؟

هذا المؤثر يقارن أيضا بين البتات المتقابلة لعددين و يعطي عدد جديد بناء على القاعدة التالية:

/*
Bitwise :Or Operator
True = 1
False = 0
*/
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0

مثال:

/*
Bitwise :Or Operator
True = 1
False = 0
*/
23 | 11 = 31
00010111 // 23 decimal = 00010111 Binary
&
00001011// 11 decimal = 00001011 Binary
------------
=
00011111// 31 decimal = 00000011 Binary

كيف يعمل المؤثر NOT_BIT (~) ؟

هذا المؤثر يسمى"المتمم", كل ما يقوم به هو عكس قيمة الـ Bit فلو كان 0 و طبقنا عليه المؤثر فسيصبح 1 و العكس صحيح:

/*
Bitwise :NOT Operator
True = 1
False = 0
*/
~0 =1
~1= 0

هذا المؤثر يأخذ قيمة واحدة فقط ليعطينا المتمم لها:

/*
Bitwise :NOT Operator
True = 1
False = 0
*/
~(255) = 0
~(11111111) = 00000000

كيف يعمل المؤثر XOR (^) ؟

يسمى هذا المؤثر Exclusive OR, حيث يعيد True فقط إذا كان المدخلان مختلفين, و يعيد False إذا كانا متشابهان:

/*
Bitwise :XOR Operator
True = 1
False = 0
*/
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0

و كمثال على ذلك:

/*
Bitwise :XOR Operator
True = 1
False = 0
*/
15 ^ 8 = 7
00001111 // 15 decimal = 00001111 Binary
^
00001000 // 8 decimal = 00001000 Binary
------------
=
00000111 // 7 decimal = 00000111 Binary

و يُستعمل هذا المؤثر بكثرة في تشفير النصوص.

كيف تعمل مؤثرات الإزاحة ؟

  • >> تقوم بإزاحة بتات المتغير إلى اليسار بمقدار معين من الخانات
  • << تقوم بإزاحة بتات المتغير إلى اليمين بمقدار معين من الخانات
  • <<= تقوم بإزاحة بتات المتغير إلى اليسار بمقدار معين من الخانات و يتم إسناد الناتج إلى نفس المتغير
  • >>= تقوم بإزاحة بتات المتغير إلى اليمين بمقدار معين من الخانات و يتم إسناد الناتج إلى نفس المتغير

/*
Bitwise : Shifting Operator
Right shift
*/
10010010 >> 5 = 00000100
//10010 this part is taken out because of the boundries of the byte.
//146 decimal = 10010010 Binary
//4 decimal = 00000100 Binary

لاحظ أن العدد المكون من خمس خانات على يمين العدد الناتج عن الإزاحة يمثل الجزء الضائع لأنه خرج عن حدود الـ Byte و بالتالي لم يعد موجودا أصلا, أما الخمس خانات الجديدة على اليسار فهي أصفار دائما, أي أن هناك جزء ضائع و أصفار مكتوبة لتعبئة الفراغ المتولد من الإزاحة. هذا ما تفعله الإزاحة إلى اليمين أو إلى اليسار بشكل كامل.

مثال آخر:

unsigned char c1, c2, c3, c4;
c1 = 5; /* 00000101 */
c2 = 4; /* 00000100 */
c3 = c1 << 2; /* 00000101(c1) -> 00010100(c3) */
c4 = c2 >> 2; /* 00000100(c2) -> 00000001(c4) */
c1 <<= 2; /* 00000101(c1) -> 00010100(c1) */
c2 >>= 2; /* 00000100(c2) -> 00000001(c2) */

ماهو ترتيب أولوية المؤثرات ؟

الجدول التالي يُرتب جميع المؤثرات الموجودة في C++ (بما في ذلك تلك الموجودة في C), حسب أولويتها :

post-219439-008122000 1347398631_thumb.p

تم تعديل بواسطه أحمد الشنقيطي
إضافة أسئلة جديدة.
4

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .