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

برأيك هل يعمل بشكل صحيح؟

بدأه محمد عودة في 31 ديسمبر 2011 · 11 رد · 786 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

أخوانى فى المنتدى الكود التالى كود سي يعمل بشكل ممتاز ؟ برأيك هل يوجد به خطأ؟ واذا كان يوجد ما تفسيرك؟

#include <stdio.h>

int *pPointer ;
void SomeFunction()
{
    int nNumber;
    nNumber = 25;

    // make pPointer point to nNumber:

    pPointer = &nNumber;
}

void main()
{
    SomeFunction(); // make pPointer point to something


    // why does this fail?

    printf("Value of *pPointer: %d\n", *pPointer);
}

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

#2

السلام عليكم

لا يوجد أي خطأ

التفسير هو أن المؤشر pPointer* صرح به شامل (global)

اي أن المتغير الذي يصرح به خارج جسم أي دالة أو كلاس يمكن استخدامه في أي مكان من البرنامج

ليس ضروريا تمرير المتغير الشامل كبرامتر لإستخدامه داخل الدوال

المتغير الشامل ملك لجميع دوال البرنامج

مثال:

#include <stdio.h>

int number = 15 ;/*متغير شامل*/
void SomeFunction()
{
	int nNumber;
	nNumber = 22;

	// make pPointer point to nNumber:

	number = nNumber;
}

void main()
{
	SomeFunction(); // make pPointer point to something


	// why does this fail?

	printf("Value of number: %d\n", number);
}
#3

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

  1. الكود السابق .. تم تنفيذه دون أخطاء ... على DevCpp .. بصراحة لا أعرف لماذا ؟
    Value of *pPointer: 25

  2. جربوا هذا الكود ..
    #include <stdio.h>
    
    int *pPointer ;
    void SomeFunction()
    {
    	int nNumber;
    	nNumber = 25;
    
    	// make pPointer point to nNumber:
    
    	pPointer = &nNumber;
    }
    void go()
    {
     	int x = 10;
    }
    
    int  main()
    {
    	SomeFunction(); // make pPointer point to something
    	go();
    
    
    	// why does this fail?
    
    	printf("Value of *pPointer: %d\n", *pPointer);
    	scanf("dsds");
    	return 0;
    }

    ربما ستكون النتيجة مفاجأة للبعض ..

    Value of *pPointer: 10

  3. ربما لأن المترجم لا يقوم بمسح الذاكرة المخصصة لآخر استدعاء .. بل يتركها حتى يتم استدعاء جديد يقوم بكتابتة فوق الاستدعاء القديم (شي اسمه frame stack ربما) .. و ذلك أكيد يحسن اداء البرنامج .. و الله اعلم ..

تم تعديل هذه المشاركة بواسطة houssam11350_11350 في 31 ديسمبر 2011 في 02:52

1

لا إله إلا الله ... محمد رسول الله

لو كانت مشاركتي مفيدة و تريد تشجيعي على المزيد من العطاء , فضلا قم بتقييم المشاركة

المعرًف القديم : houssam11350_11350

من مواضيعي : ArabGenCode : مولد كود و إجراءات مخزنة و واجهات لجداول سيكوال سيرفر

#4
اقتباس
اي أن المتغير الذي يصرح به خارج جسم أي دالة أو كلاس يمكن استخدامه في أي مكان من البرنامج

أخى biginner2000 محاوﻻتك لتصحيح الكود ولكننا نريد معالجة الخطأ واسبابة فى المتغير المؤشر وليس تحويلة الى متغير عادى

اخى houssam11350_11350 محاولاتك جيدة على طريق تنقيح الكود.

مازال الكود محير وبة خطأ

حاولو معى لكى نصل الى نتيجة.

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

#5

لسلام عليكم

أنا لم أحاول تصحيح الكود لأنه لا يوجد أي خطأ في الكود الأول ، سوى أن المؤشر pPointer* صرح به شامل أي (global)

و المؤشر أو المتغير الذي يصرح به خارج جسم أي دالة أو كلاس يمكن استخدامه في أي مكان من البرنامج و

ليس ضروريا تمرير المتغير الشامل كبرامتر لإستخدامه داخل الدوال لأنه ملك لجميع دوال البرنامج

#6

السلام عليكم ورحمة الله وبركاته.

كود الاخ محمد ابو زايد كنت متوقعه ان النتيجة راح تكون 25 ولما نفذته فعلاً طلعت 25 استخدم ( Turbo C )

اقتباس

1.الكود السابق .. تم تنفيذه دون أخطاء ... على DevCpp .. بصراحة لا أعرف لماذا ؟

أخ حسام ,, ليش ايش كنت متوقع ؟!

اقتباس

ربما ستكون النتيجة مفاجأة للبعض ..

:wacko: معك حق .

طيب شوفوا هذه التجربة (نسخة من تجربة الاخ حسام (+1) بتصرف :happy: )

#include <stdio.h> 

int *pPointer;
void SomeFunction()
{
	int nNumber;
	nNumber = 25;

	// make pPointer point to nNumber:

	pPointer = &nNumber;
}
void go()
{
	int x=10;
	//printf("pPointer address=%u \nx address=%u\n",pPointer,&x);
	x=5;
} 

int  main() 
{ 
        clrscr();
        SomeFunction(); // make pPointer point to something 
	go();

        // why does this fail? 

        printf("Value of *pPointer: %d\n", *pPointer); 
        scanf("dsds"); 
        return 0; 
}

النتيجة :

Value of *pPointer: 0

فعِّلوا هذا السطر :

printf("pPointer address=%u \nx address=%u\n",pPointer,&x);

النتيجة :

Value of *pPointer: 5

:blink:

:mellow: من وجة نظري المتواضعة اعتقد انه المخرجات تختلف من Compiler لاخر .

((إِنَّ اللَّهَ وَمَلائِكَتَهُ يُصَلُّونَ عَلَى النَّبِيِّ يَا أَيُّهَا الَّذِينَ آمَنُوا صَلُّوا عَلَيْهِ وَسَلِّمُوا تَسْلِيمًا))

#7

أخى حسام

اقتباس
void go()

{

int x = 10;

}

المشكلة فى دالة go نفس فى المشكلة فى دالة SomeFunction.

أم اﻻخت روز محمد

اقتباس
Value of *pPointer: 5

فالـــ 5 هى قيمة x. وليست قيمة *pPointer .

وهذة هى المشكلة الرئيسية لما ﻻ يعطينا *pPointer القيمة الصحية؟

اقتباس
:mellow: من وجة نظري المتواضعة اعتقد انه المخرجات تختلف من Compiler لاخر .

أم المخرجات فى ثابتة فى جميع المترجمات دائما بالنسبة لهذا الكود. لو أكتشفنا أين تكمن المشكلة؟

أرجو من اﻻعضاء اعادة النظر فى فى المشكلة. حتى نحاول الوصول الى حل ان شاء الله

تم تعديل هذه المشاركة بواسطة محمد ابوزايد في 31 ديسمبر 2011 في 20:02

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

#8

عزيزي, ما لديك هو undefined behavior لأنك تقوم بعمل dereferencing لمؤشر يشير لمتغير automatic قد انتهت حياته بعد الخروج من الدالة. ابحث عن موضوع الـ dangling pointers و ستفهم المشكلة,

تحياتي...

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 31 ديسمبر 2011 في 20:33

1
#9
Khaled.Alshaya كتب:

عزيزي, ما لديك هو undefined behavior لأنك تقوم بعمل dereferencing لمؤشر يشير لمتغير automatic قد انتهت حياته بعد الخروج من الدالة.

هذه هي.... صحيح أن المؤشر "غالبا" سيظهر 25. لكن هذا غير مضمون، أي أن الكود المكتوب لا يضمن ذلك، كل ما سيظهره المؤشر هو آخر قيمة لا زالت موجودة في العنوان الذي يشير إليه، ماذا لو تمت الكتابة على العنوان "الذي أصبح غير محجوز"؟؟

يعني أنت كتبت كود قائم على كونك "محظوظ أو غير محظوظ" في بقاء القيمة 25. وليس المبرمج الحق بفاعلها smile.gif.

تم تعديل هذه المشاركة بواسطة A.S Hack في 31 ديسمبر 2011 في 22:03

" إن الله كتب الإحسان على كل شيء"

::

الإرادة ... تحقق السيادة.

#10

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

  1. اقتباس
    أخ حسام ,, ليش ايش كنت متوقع ؟!
    كنت متوقع أن يعطي خطأ .. لكن المؤشر يشير إلى عنوان متحول تم إنشاؤه داخل function و حسب معلوماتي يتم مسح كامل الــ local variables التي يتم تعريفها في function بعد انتهاء تنفيذ هذا الـ sub function .. و بالتالي المفروض ان المؤشر سيشير إلى عنوان غير موجود .. إو على الأقل قيمته صفر ..
  2. الكود الأول .. لم يعطي على devCpp مع المترجم g++ النتيجة التي ذكرتها (صفر) .. بل أعطى خمسة ..
  3. الكود الذي طلبت منا تفعيله ..
    printf("pPointer address=%u \nx address=%u\n",pPointer,&x);

    يطبع النتيجة

    pPointer address=2280644 x address=2280644

    أي أن المؤشر يشير إلى عنوان x علما اننا جعلناه يشير إلى nNumber أي تم حجز المتحول x في نفس المكان الذي تم حجز فيه المتحول nNumber ...

  4. مشكورين الإخوة على الردود ... إذا المشكلة هي أنه لدينا Dangling_pointer ...و هو مؤشر يشير إلى مكان ما .. و تم حذف و تغيير هذا المكان دون تصحيح قيمة المؤشر ..

لا إله إلا الله ... محمد رسول الله

لو كانت مشاركتي مفيدة و تريد تشجيعي على المزيد من العطاء , فضلا قم بتقييم المشاركة

المعرًف القديم : houssam11350_11350

من مواضيعي : ArabGenCode : مولد كود و إجراءات مخزنة و واجهات لجداول سيكوال سيرفر

#11
اقتباس
عزيزي, ما لديك هو undefined behavior لأنك تقوم بعمل dereferencing لمؤشر يشير لمتغير automatic قد انتهت حياته بعد الخروج من الدالة. ابحث عن موضوع الـ dangling pointers و ستفهم المشكلة,

ما شاء الله أخى خالد لقد وصلت الى ما اريد.

اخونا خالد يقصد ان المتغيرات المحلية داخل الدالة تحذف بمجرد انتها عمل الدالة . أى عندما تنتهى الدالة SomeFunction() من العمل فأن المتغيرnNumber لن يعد موجودا. وان العنوان الذى كان يأخذة فى الذاكرة لم يعد يخص برنامجنا الحالى . وان أى محاولة وصول لة تعتبر محاولة خطأ ﻻننا ببساطة ﻻنعلم ماذا يوجد بهذا العنوان من بيانات . واذا حصلنا على بيانات فأنها بينات تخص برامج اخرى او قيمة غير مفهومة undefined.

فالتالى عندما نحاول طباعة قيمة nNumber بأستخدام *pPointer فأننا نحاول الوصول الى موقع فى الذاكرة ﻻيخص برنامجنا.

السؤال اﻵن هو كيف نصل الى هذا المكان فى الذكرة بصورة آمنه فى الدالة somefuction() .

او ماهى الطريقة الصحية لحجز الذاكرة فى الدالة SomeFunction(). بحيث يستطيع المؤشر pPointer الوصول اليها بأمان على الرغم من انتهاء عمل الدالة SomeFunction().

اﻻ وهى استخدام new من سي++ . وبالتالى فأن البرنامج سوف يعمل بدون مشاكل كما يلى:

#include<iostream>
#include <stdio.h>
#include<cstdlib>
using namespace std;

int *pPointer;

void SomeFunction()
{
    // make pPointer point to a new integer

    pPointer = new int;
    *pPointer = 25;
}

int main()
{
    SomeFunction(); // make pPointer point to something

    printf("Value of *pPointer: %d\n", *pPointer);

    std::cin.get();
    return 0;
}

تذكر أن : الذاكرة المحجوزة بأستخدام المعامل new يتم تحريرها(اى حذفها) باستخدام delete .

حقيقا لقد صادفنى هذا الكود اثناء تصفحى بعض المقاﻻت عن المؤشرات والتى اثارت انتباهى ﻻنها من الوهلة اﻻولى تبدو عادية. ولكنها خادعة.

وعمقت لى مفهوم المتغيرات المحلية

واحبتت ان اشاركم المنفعة علمنا واياك الله

تحياتى العطرة والله الموفق.

تم تعديل هذه المشاركة بواسطة محمد ابوزايد في 31 ديسمبر 2011 في 22:38

1

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

#12

السلام عليكم ورحمة الله وبركاته.

بدايةً شكراً لكم جميعاً :) .

اقتباس

فالـــ 5 هى قيمة x. وليست قيمة *pPointer .

وهذة هى المشكلة الرئيسية لما ﻻ يعطينا *pPointer القيمة الصحية؟

لهذا السبب كنت مستغربة!!

اقتباس

2.الكود الأول .. لم يعطي على devCpp مع المترجم g++ النتيجة التي ذكرتها (صفر) .. بل أعطى خمسة ..

3.الكود الذي طلبت منا تفعيله ..

printf("pPointer address=%u \nx address=%u\n",pPointer,&x);

يطبع النتيجة

pPointer address=2280644 x address=2280644

ما قصدته أنني عندما كنت اطبق الكود بدون تفعيل سطر الطباعة كان يعطي النتيجة 0 , لكن عندما افعّل هذا السطر يطبع 5 !!

اقتباس

حقيقا لقد صادفنى هذا الكود اثناء تصفحى بعض المقاﻻت عن المؤشرات والتى اثارت انتباهى ﻻنها من الوهلة اﻻولى تبدو عادية. ولكنها خادعة.

وعمقت لى مفهوم المتغيرات المحلية

واحبتت ان اشاركم المنفعة علمنا واياك الله

تحياتى العطرة والله الموفق.

+1

جزاك الله خير :) .

تمنياتي لكم بالتوفيق.

((إِنَّ اللَّهَ وَمَلائِكَتَهُ يُصَلُّونَ عَلَى النَّبِيِّ يَا أَيُّهَا الَّذِينَ آمَنُوا صَلُّوا عَلَيْهِ وَسَلِّمُوا تَسْلِيمًا))

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

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…