English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
في هذا الدرس، سنتعلم كيفية استخدام عميلات العمليات المرتبطة بالحروف في C++ من خلال أمثلة.
في C++، تنفذ عميلات العمليات المرتبطة بالحروف عمليات على بيانات الصفاء على مستوى الحروف. هذه العمليات تشمل الفحص، الإعداد أو تنقل الحروف الفعلية.
a & b; a | b;
هذه قائمة بستة من عميلات العمليات المرتبطة بالحروف الموجودة في C++.
عميل | الاسم | وصف | مثال |
---|---|---|---|
& | العميل AND المرتبط بالحروف | إذا كانت الحرف موجودة في كلا المعاملين، فإن عميل AND الثنائي ينسخ حرفًا واحدًا إلى الناتج. | (A & B) سيكون 12، أي 0000 1100 |
| | عمليات OR | إذا كانت الحرف موجودة في أي من المعاملين، فإن عميل OR الثنائي ينسخ حرفًا واحدًا إلى الناتج. | (A | B) سيكون 61، أي 0011 1101 |
^ | العميل XOR المرتبط بالحروف | إذا كانت الحرف موجودة في أحد المعاملين لكنها ليست موجودة في كلا المعاملين، فإن عميل XOR الثنائي ينسخ حرفًا واحدًا إلى الناتج. | (A ^ B) سيكون 49، أي 0011 0001 |
~ | مكتبات الموقع | عميل التعويض الثنائي هو عميل ثنائي يملك تأثير "تدوير" للحروف، أي أن 0 يصبح 1 و 1 يصبح 0. | (~A) سيكون -61، أي 1100 0011، هي شكل التعويض الثنائي للعدد الموجب. |
<< | تنقل الحروف | عميل تنقل الحروف الثنائية. يتم تحريك قيمة المعامل الأيسر إلى اليسار بمقدار عدد الحروف المحدد من المعامل الأيمن. | A << 2 سيكون 240، أي 1111 0000 |
>> | تنقل الحروف | عميل تنقل الحروف الثنائية. يتم تحريك قيمة المعامل الأيسر إلى اليمين بمقدار عدد الحروف المحدد من المعامل الأيمن. | A >> 2 سيكون 15، أي 0000 1111 |
هذه العمليات ضرورية لأن وحدة العمليات الأرقامية والأولية (ALU) في معالج الحاسوب تنفذ عمليات الحساب على مستوى الحروف.
ملاحظة:يمكن استخدام عميلات العمليات المرتبطة بالحروف فقط مع أنواع البيانات char و int.
يعود عميل AND المرتبط بالحروف فقط إذا كانت كلا المعاملين هما 1. في هذه الحالة، سيكون الناتج 0.
هذا المثال يوضح كيفية عمل عمليات AND المرتبطة بالحروف. افترض أن a و b هما معاملان يمكن أن يأخذوا فقط قيمتين ثنائيتين وهي 1 و 0.
a | b | a & b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
a & bالاحتياط: على
الجدول يُدعى "جدول الصحة" للعمليات AND الرقمية.
12 = 00001100 (binary) 25 = 00011001 (binary) // عمليات AND الرقمية بين 12 و 25 00001100 & 00011001 _________ 00001000 = 8 (decimal)
#include <iostream> using namespace std; int main() { // إعلان المتغيرات int a = 12, b = 25; cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "a & b = " << (a & b) << endl; return 0; }
نتائج الخروج
a = 12 b = 25 a & b = 8
في المثال السابق، تم إعلان متغيرين a و b. انتبه إلى هذا السطر،
cout << "a & b = " << (a & b) << endl;
في هذا المثال، نقوم بتنفيذ عمليات AND الرقمية بين المتغيرات a و b.
إذا كان لدينا على الأقل عمود 1، فإن عمليات OR (|) تعيد 1. وإلا تعيد 0.
الجدول التالي يوضح كيفية عمل عمليات OR الرقمية. افترضaوالbللذكاءات التي يمكن أن تأخذ فقط قيم ثنائية (أي1 أو 0) منالمعملون.
a | b | a | b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
دعونا نرى العددين12وال25عمليات OR الرقمية:
12 = 00001100 (binary) 25 = 00011001 (binary) // عمليات OR الرقمية بين 12 و 25 00001100 | 00011001 _________ 00011101 = 29 (decimal)
#include <iostream> int main() { int a = 12, b = 25; cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "a | b = " << (a | b) << endl; return 0; }
نتائج الخروج
a = 12 b = 25 a | b = 29
فيعمليات ORباستخدام a = 12 و b = 25 نحصل على 29.
عندما يكون أحد المشتملات 1، يعيد عمود التباين الرقمي ^ قيمة 1. ولكن إذا كانت كلا المشتملتين 0 أو كلاهما 1، فإن النتيجة هي 0.
الجدول التالي يوضح كيفية عمل عمليات OR الرقمية. افترضaوالbللذكاءات التي يمكن أن تأخذ فقط قيم ثنائية (أي1 أو 0) منالمعملون.
a | b | a ^ b |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
دعونا نرى حساب التباين الرقمي للعددين 12 و 25:
12 = 00001100 (binary) 25 = 00011001 (binary) // عمليات التباين الرقمي بين 12 و 25 00001100 ^ 00011001 _________ 00010101 = 21 (decimal)
#include <iostream> int main() { int a = 12, b = 25; cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "a ^ b = " << (a ^ b) << endl; return 0; }
نتائج الخروج
a = 12 b = 25 a ^ b = 21
a = 12 و b = 25 حساب التباين الرقمي يعطي 21.
عمود مكتبات هو عمود عملي (يعمل على عمود واحد فقط). وتمثل بـ ~، تقوم بتعديل الأرقام الثنائية من 1 إلى 0، و0 إلى 1.
على الرغم من ذلك، يجب الانتباه إلى أن مكتبات أي عدد صحيح N تساوي - (N + 1). على سبيل المثال
مثلاً عددًا صحيحًا35. وفقًا للقواعد،35مكتبات الموقع يجب أن تكون-(35 +1) = -36. الآن، لنرى إذا كنا نحصل على الإجابة الصحيحة.
35 = 00100011 (أكواد) // استخدام عمود مكتبات ~ 00100011 __________ 11011100
في المثال السابق، نستنتج00100011(35)مكتبات الموقع له11011100. هنا، إذا قمنا بتحويل النتيجة إلى ثنائي، نحصل على220.
لكن يجب الانتباه إلى أننا لا نستطيع تحويل النتيجة مباشرة إلى ثنائي، للحصول على المخرج المطلوب. لأن نتيجة الأكواد الثنائية11011100ويساوي-36.
لفهم هذا، نحتاج أولاً إلى حساب-36الخروج الثنائي. نستخدم مكتبات 2 لحساب أكواد الأعداد السالبية.
في حسابات الأكواد الثنائية، يقوم مكتبات 1 بتعديل 0 إلى 1، و1 إلى 0. بالإضافة إلى ذلك، إذا أضفنا 1 إلى نتيجة مكتبات 1، نحصل على مكتبات الأكواد 2 للرقم الأصلي.
مثلاً:
36 = 00100100 (أكواد) مكتبات 1 = 11011011 مكتبات الـ2: 11011011 + 1 _________ 11011100
في هذا، يمكننا رؤية مكتبات 36 في الموقعين (أي -36) هي 11011100. هذا العدد يساوي مكتبات 35.
لذلك، يمكننا القول أن مكتبات 35 هي -36.
#include <iostream> int main() { int num1 = 35; int num2 = -150; cout << "~(" << num1 << ") = " << (~num1) << endl; cout << "~(" << num2 << ") = " << (~num2) << endl; return 0; }
نتائج الخروج
~(35) = -36 ~(-150) = 149
في المثال السابق، قمنا بإنشاء متغيرين زوجيين اسمهما num1 و num2، وقمنا بتعيينهما بـ 35 و -150 على التوالي.
ثم نستخدم كود (~num1) و (~num2) لحساب مكتباتها، ونعرضها على الشاشة.
35的按位补码 = - (35 + 1) = -36 即 ~35 = -36 -150的按位补码 = - (-150 + 1) = - (-149) = 149 بالتالي ~(-150) = 149
وهذا هو الناتج الذي نحصل عليه في الخروج.
في برمجة C++ هناك عمليتان من عمليات التحويل:
عمليات التحويل يمين >>
عمليات التحويل يسار <<
عمليات التحويل يمين
عند تحريك أي عدد إلى اليمين،أدنى الرقم الفعالسيتم التخلص منه، بينماأعلى الرقم الفعالبصفر.
من خلال الرسم البياني أعلاه يمكننا ملاحظة أن لدينا رقمًا من 4 أرقام. عند تنفيذ تحويل يمين واحد، يتم تحريك كل رقمة واحدة إلى اليمين.
نتيجة لذلك، يتم التخلص من أحدث الرقم الموجود في أقصى اليمين، بينما يبقى الموضع الأيسر فارغًا. يتم استبدال هذا الموضع الفارغ0بديلاً عن (Bit Replacement).
عمليات تحويل يسار
من خلال الرسم البياني أعلاه يمكننا ملاحظة أن لدينا رقمًا من 4 أرقام. عند تنفيذ تحويل يسار واحد، يتم تحريك كل رقمة واحدة إلى اليسار.
نتيجة لذلك، يتم التخلص من أحدث الرقم الموجود في أيسر الموضع، بينما يبقى الموضع الأيسر فارغًا. يتم استبدال هذا الموضع الفارغ0بديلاً عن (Bit Replacement).
#include <iostream> int main() { //إعلان متغيرين كاملين int num = 212, i; //عمليات تحويل إلى اليمين cout << "تحويل إلى اليمين:" << endl; //استخدام دالة for لتحويل num من الموضع 0 إلى الموضع 3 for (i = 0; i < 4; i++) { cout << "212 >> " << i << " = " << (212 >> i) << endl; } //عمليات تحويل إلى اليسار cout << "\nتحويل إلى اليسار:" << endl; //استخدام دالة for لتحويل num من الموضع 0 إلى الموضع 3 for (i = 0; i < 4; i++) { cout << "212 << " << i << " = " << (212 << i) << endl; } return 0; }
نتائج الخروج
تحويل إلى اليمين: 212 >> 0 = 212 212 >> 1 = 106 212 >> 2 = 53 212 >> 3 = 26 تحويل إلى اليسار: 212 << 0 = 212 212 << 1 = 424 212 << 2 = 848 212 << 3 = 1696
من مخرجات البرنامج أعلاه، يمكننا استنتاج أن لكل عددN،نتيجة عمليات التحويل إلى اليمين هي دائمًا:
N >> 0 = N N >> 1 = (N >> 0) / 2 N >> 2 = (N >> 1) / 2 N >> 3 = (N >> 2) / 2
وغيرها.
على نفس الطريقة، النتيجة للتحويل إلى اليسار هي:
N << 0 = N N << 1 = (N << 0) * 2 N << 2 = (N << 1) * 2 N << 3 = (N << 2) * 2
وغيرها.
لذلك، يمكننا إيجاد نتيجة،
N >> m = [ N >> (m-1) ] / 2 N << m = [ N << (m-1) ] * 2