الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[ تمت الإجابة ]طلب شرح لـلمكدّس والقوالب

بدأه _Is_ في 25 ديسمبر 2012 · 8 رد · 1,122 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ..

كيف الحال ؟

لو سمحتو اريد شرح عن templates friends !!

و ماهي ال stack التي تستخدم ف ال templates ..

اريد شرح وافي وكافي لهذه .. ف بعد كم يوم عندي امتحان فاينل ولم اتقنهم لحد الان ..

وجزاكم الله خير ..

#2
اقتباس
اريد شرح وافي وكافي لهذه .. ف بعد كم يوم عندي امتحان فاينل ولم اتقنهم لحد الان ..

فى هذه الحالة توجد جملة تناسب حالك و هي: اللى ذاكر ذاكر

مدونتي: C++ Tips and Tricks

#3

^

اوك اخي ب ذاكر ولكن كيف اذاكر وانا لم افهم له ؟

#4

ارجوكم اريد شرح لهذا الكود ..

template <class T> 
class Stack {
private: 
	int size ; // number of elements on Stack. int top ; 
	T* stackPtr ; 

public: 
	Stack(int = 10) ; 
	~Stack() { delete [] stackPtr ; } 
	int push(const T&); int pop(T&) ; 
	int isEmpty()const {return top == -1 ; } int isFull() const {return top == size-1;} 
} ; 
//constructor with the default size 10 
	template <class T> 
	Stack<T>::Stack(int s) { 
	size = (s > 0 && s < 1000) ? s : 10 ; 
	top = -1 ; 
	stackPtr = new T[size] ; } 

// push an element onto the Stack 
	template <class T> 
	int Stack<T>::push(const T& item) { 
		if (!isFull()) { 
			stackPtr[++top] = item ; 
			return 1 ;  
		} 
		return 0 ;
	}

// pop an element off the Stack 
	template <class T> 
	int Stack<T>::pop(T& popValue) { 
		if (!isEmpty()) { 
			popValue = stackPtr[top--] ; 			return 1 ; //pop successful } 	
		return 0 ; // pop unsuccessful 
	}
int main(){
	Stack<float> fs(5);	
	float f = 1.1 ; 

	cout << "Pushing elements onto fs" << endl ; 
	while (fs.push(f)) cout << f << ' ' ; f += 1.1 ; 
	cout << "\nStack Full.\n" << "Popping elements from fs\n"; 

	while (fs.pop(f)) cout << f << ' ' ; 
	cout << “\nStack Empty\n"; 
return 0;}
#5
اقتباس
ارجوكم اريد شرح لهذا الكود ..

اخي استخدم مربع بحث جوجل المخصص بتزييل الصفحة،

لم استخدمه يوما وخذلني..

استخدم كلمات بحث كـــ قوالب سي++ ، القوالب فى c++ ، درس القوالب فى برمجة، C++ templates .... الخ.

الله يوفقك ...

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#6

هل لديك مفهوم ال stack اولا ؟

ال stack مثل كومة الأطباق فتضع طبق ثم طبق ثم طبق وآخر طبق تضعه هو أول ماتبدأ في غسله LAST IN FIRST OUT

عملية الوضع تسمى push

عملية الغسل (اخراج الطبق) تسمى pop

هل تفرق أطباق صيني أو اطباق خشبية في الآلية ؟ الجواب ﻷ

إذا فبدلا من أن يكون لديك عدة صفوف intStack او floatStack او doubleStack وفرت C++ لك مايسمى ال templates كصورة أعلى للتعميم

(map share people)

فضلا لاتقم بمراسلتي من أجل أسئلة لها أقسامها في المنتدى حتى تعم الفائدة على الجميع وللحصول على إجابات أفضل من أعضاء أكثر خبرة.
Weblog
@bitbucket
@xmonader

#7
template <class T> class Stack

template كلمة محجوزة مسبقا وتعني قالب و T تعني نوع يتم تحديده لاحقاً و Stack هو اسم الفئة الجديدة.

الفئة Stack عبارة عن مُحاكاة للمكدس باستخدام المصفوفات, لكن نوع المصفوفة يُحدده المستخدم (و هذا ما يُميز القوالب عن غيرها)

الفئة Stack تحتوي على 3 متغيرات :

  • size : يُمثل حجم المكدس.
  • top : يحمل رقم أول خانات المكدس.
  • stackPtr : مؤشر لــ T حيث يُمثل المكدس و يتم تخزين العناصر بداخله.

هذا السطر : (يُمثل توقيع دالة البناء)

Stack(int = 10)

و يعني أن القيمة الافتراضية لحجم المكدس هي 10.

هذه الفقرة تُمثل دالة الهدم :

~Stack() {
        delete [] stackPtr;
    }

حيث تقوم هذه الدالة بتحرير ذاكرة الفئة Stack.

بالنسبة لجسم دالة البناء فهو كالتالي :

template <class T>
Stack<T>::Stack(int s) {
    size = (s > 0 && s < 1000) ? s : 10;
    top = -1;
    stackPtr = new T[size];
}

الدالة تستقبل عدد صحيح, إذا كان أكبر من الصفر و أقل من ألف سيتم أخذ قيمته و إلا فسيأخذ القيمة الافتراضية له و هي 10.

تم إسناد القيمة -1 للمتغير top كقيمة ابتدائية بالإضافة إلى الإعلان عن مصفوفة من نوع T عدد عناصرها يُساوي size.

بالنسبة للدالة push فتستقبل مؤشر ثابت لمتغير من نوع T, إذا كان المكدس لم يمتلأ بعد نقوم بإدراج القيمة الجديدة في قمة المكدس ثم نجعل top يحمل رقم الخانة الموالية. و نُعيد 1 كإشارة على نجاح عملية الإدراج.

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

الدالة pop معاكسة تماما للدالة push حيث تقوم بحذف عنصر من بداية المكدس.

إذا كان المكدس لم يمتلأ بعد, نقوم بالرجوع خطوة إلى الخلف و نُسند قيمة الخانة الحالية للمكدس إلى الوسيط المُستقبل ثم نعيد 1.

في الحالة المعاكسة نُعيد الصفر.

في الدالة main قمنا بتحديد نوع القالب على أنه float و فمنا بالإعلان عن مكدس يحوي 5 عناصر.

ما دامت fs.push(f) تختلف عن الصفر فهذا يعني أن المكدس لم يمتلأ بعد و بالتالي نستمر في إدراج العناصر بداخله.

عند امتلاء المكدس سيتم الخروج من while.

و نفس الفكرة تحدث في الــ while الثانية (عند إفراغ المكدس سيتم الخروج من الحلقة)

اقتباس
فى هذه الحالة توجد جملة تناسب حالك و هي: اللى ذاكر ذاكر

+1

@Is

في المرات القادمة, عليك فهم دروسك بفترة كافية قبل الامتحان حتى لا تقع في نفس الخطأ مرة أخرى.

ملاحظة : تم تعديل عنوان الموضوع ليتناسب مع محتواه.

أرجو لك التوفيق.

1
#8

أختي المكدس والقوالب لاعلاقة مباشرة بينهما. لكن لو كتبت تطبيق للمكدس كهذا (لايقوم بشيء فقط للتوضيح):

#include <iostream>

using namespace std;

class MYStack {
private:
	int elem;
public:
	MYStack(unsigned int init_size) {
    	// ...
	}

	void push( int value ) {
    	// ...
    	this->elem = value;
	}

	int pop(void) {
    	// ...
    	return this->elem;
	}
};

int main(int argc, char **argv)
{
	MYStack mystack(10);

	mystack.push(1);
	mystack.push(2);

	return 0;
}

الكود السابق محدود فلايمكنه من التعامل الا مع int. وربما تضطرين لكتابة class خاص لكل نوع من البيانات أو إستخدام طرق معقدة.

لإعادة إستخدام الـclass نستخدم القوالب، فقط نكتب قالب واحد ويمكننا إستخدام أي نوع بيانات معه:

#include <iostream>

using namespace std;

template <class Type> class MYStack {
private:
	Type elem;
public:
	MYStack(unsigned int init_size) {
    	// ...
	}

	void push(Type value ) {
    	// ...
    	this->elem = value;
	}

	Type pop(void) {
    	// ...
    	return this->elem;
	}
};

struct XYPoint {
	unsigned int x;
	unsigned int y;
};

int main(int argc, char **argv)
{
	XYPoint p1;
	XYPoint p2;

	p1.x = 0;
	p1.y = 100;

	p2.x = 200;
	p2.y = 400;

	MYStack<int> mystack_int(10);   	// كائن لمكدس من النوع int
	MYStack<double> mystack_double(10); // كائن آخر لمكدس من النوع double
	MYStack<XYPoint> mystack_struct(10); // كائن آخر لمكدس من النوع XYPoints

	mystack_int.push(1);
	mystack_int.push(2);

	mystack_double.push(13.1);
	mystack_double.push(44.1);

	mystack_struct.push(p1);
	mystack_struct.push(p2);

	// ...

	return 0;
}

إستخدمنا ثلاث أنواع من البيانات مع نفس الـclass وهذا لم يمكن تحقيقة بدون القوالب.

#9

بالنسبة للـ template friends، من هنــا

و الله ولي التوفيق

مدونتي: C++ Tips and Tricks

مواضيع مشابهة