القيم مصنَّفة النوع (Literals) هي عبارات تدل على ثابت تشير صياغته المحرفية إلى نوعه وقيمته، فمثلًا 42
هي قيمة مصنَّفة النوع بينما x
ليست كذلك لأنك تحتاج إلى أن تنظر إلى تصريحها (declaration) لتعرف نوعها وتطالع الأسطر السابقة من الشيفرة لتعرف قيمتها. غير أن C++11 أتاحت للمستخدم إضافة قيم مصنَّفة النوع (User-Defined Literals)، وتُستخدم كاختصار لاستدعاءات الدوال.
سنستَعرض في هذا الدرس بعض القيم مصنَّفة النوع في C++، بدءًا بالقيمة this
، ثم نستعرض بقية القيم في الأقسام التالية.
الكلمة المفتاحية this
تشير الكلمة المفتاحية this
داخل دالة تابعة (member function) إلى نسخة من الصنف التي استدعيّت الدالة عليها، ولا يمكن استخدامها -أي this
- في دالة تابعة ساكنة (static member function).
struct S { int x; S & operator = (const S & other) { x = other.x; // تعيد مرجعًا إلى الكائن الذي أسندَت إليه return *this; } };
يعتمد نوع this
على خاصية التأهيل الخاص بالتابع -سواء التأهيل المتطاير volatile أو الثابت constant- (بالإنجليزية اختصارًا: cv-qualification). فمثلًا، إن كان التابع X::f
ثابتًا (const
)، فإنّ نوع this
داخل f
سيكون مؤشرًا ثابتًا إلى X
(أي const X*
)، لذلك لا يمكن استخدام this
لتعديل الحقول غير الساكنة (non-static data members) من داخل دالة const
تابعة. وبالمثل، يكتسب this
التأهيل المتطاير (volatile qualification) من الدالة التي يظهر فيها. الإصدار ≥ C++11
يمكن أيضًا استخدام this
في المُهيِّئ المعقوص (brace-or-equal-initializer) للحقول غير الساكنة.
struct S; struct T { T(const S * s); // ... }; struct S { // ... T t { this }; };
this
عبارة عن قيمة يمينيّة (rvalue)، أي أنّها تعبير لا يمكن أن يكون إلا في الطرف الأيمن من أيّ عملية إسناد (assignment)، لذلك لا يمكن إسناد قيمة لها.
الأعداد الصحيحة قيمةً ونوعًا (Integer literal)
تأخذ صياغة العدد الصحيح أحد الأشكال التالية:
- نوع عشري (decimal-literal): وهو عدد مؤلف من رقم عشري يخالف الصفر (1، 2، 3، 4، 5، 6، 7، 8، 9)، متبوعًا برقم عشريّ واحد أو أكثر (0، 1، 2، 3، 4، 5، 6، 7، 8، 9)، مثلًا:
int d = 42;
- نوع ثماني (octal-literal): وهو عدد يبدأ بالرقم صفر (0) متبوعًا برقم ثُمانيّ (octal) واحد أو أكثر (0، 1، 2، 3، 4، 5، 6، 7)، مثلًا:
int o = 052;
- نوع ست عشري (hex-literal): وهو تسلسل الأحرف 0x أو 0X متبوعًا برقم واحد أو أكثر من الأرقام الست عشرية (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C, d, D, e, E, f, F)، مثلًا:
int x = 0x2a; int X = 0X2A;
- نوع ثنائي (binary-literal): (منذ C ++ 14) هو تسلسل الأحرف 0b أو 0B متبوعًا برقم ثنائي واحد أو أكثر (0، 1)، مثلا:
int b = 0b101010;
-
الأعداد الصحيحة الملحوقة غير المؤشّرة (unsigned-suffix)، قد تحتوي على أحد أو كلا الأمرين التاليين -قد يظهرا بدون ترتيب محدد في حالة وجودهما معًا:
- الأعداد الملحوقة غير المُؤشرة (unsigned-suffix): هي أعداد ملحوقة بالحرف u أو U، مثلا:
unsigned int u_1 = 42u;
- الأعداد الملحوقة الطويلة (long-suffix): هي أعداد ملحوقة بالحرف l أو L، أو الأعداد الملحوقة الطويلة المزدوجة (long-long-suffix)، وهي أعداد ملحوقة بالحرفين ll أو الحرفين LL (منذ C++11)
تأخذ المتغيرات التالية نفس القيمة:
unsigned long long l1 = 18446744073709550592ull; // C++11 unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14 unsigned long long l3 = 1844'6744'0737'0955'0592uLL; // C++14 unsigned long long l4 = 184467'440737'0'95505'92LLU; // C++14
ملاحظات
الأحرف الموجودة في الأعداد الصحيحة غير حساسة للحالة (case-insensitive): فتمثل الصيغتان 0xDeAdBaBeU و 0XdeadBABEu نفس العدد (الاستثناء الوحيد هو الأعداد الملحوقة الطويلة المزدوجة، والتي يمكن أن تكون إما ll أو LL، ولكن ليس lL أو Ll).
لا توجد صياغة لأعداد سالبة، فمثلًا تطبق تعابير مثل -1
عامل السالب الأحادي (unary minus operator) على القيمة المُمثّلة بالقيمة مصنفَّة النوع (Literal)، والتي قد تتضمن تحويلات ضمنية للنوع (implicit type conversions).
في إصدارات C السابقة للإصدار C99 (ولكن ليس في C++)، يُسمح للقيم العشرية غير الملحوقة (unsuffixed decimal) من غير النوع long int
أن تكون من النوع unsigned long int
(عدد صحيح طويل عديم الإشارة).
تتصرف جميع الثوابت الصحيحة المؤشَّرة (signed integer constants) عند استخدامها في التعبيرات الشرطية -مثل #if
أو #elif
- كما لو كانت من النوع std::intmax_t
، فيما تتصرف الثوابت الصحيحة غير المؤشرة كما لو كانت من النوع std::uintmax_t
.
القيم المنطقية
الكلمة المفتاحية true
true
هي كلمة مفتاحية تمثّل إحدى القيمتين المنطقيّتين المُمكنَتين للنوع bool
.
bool ok = true; if (!f()) { ok = false; goto end; }
الكلمة المفتاحية false
false
هي كلمة مفتاحية تمثل إحدى القيمتين المنطقيّتين المُمكنتين للنوع bool
.
bool ok = true; if (!f()) { ok = false; goto end; }
الكلمة المفتاحية nullptr
الإصدار ≥ C++ 11
nullptr
هي كلمة مفتاحية تمثل مؤشرًا ثابتًا فارغًا (null pointer constant)، ويمكن تحويلها إلى أيّ نوع من المؤشرات (Pointers) أو المؤشرات إلى الأعضاء (pointer-to-member)، وتعيد مؤشرًا فارغًا يشير إلى النوع الناتج.
Widget* p = new Widget(); delete p; p = nullptr; // تفريغ المؤشر بعد الحذف
لاحظ أنّ nullptr
ليست مؤشرًا بحد ذاتها، وإنّما هي نوع أساسي معروف باسم std::nullptr_t
.
void f(int * p); template < class T > void g(T * p); void h(std::nullptr_t p); int main() { f(nullptr); // ok g(nullptr); // error h(nullptr); // ok }
هذا الدرس جزء من سلسلة دروس عن C++.
ترجمة -وبتصرّف- للفصل Chapter 2: Literals من كتاب C++ Notes for Professionals
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.