المؤشرات والوظائف في C ++
-
21-09-2019 - |
سؤال
من محاضرات ملاحظات الدورة في الجامعة ، على "الاتصال على أساس القيمة":
void fun(int *ip) { *ip =100; }
دعا من قبل
int n=2; int *np; np = &n; fun(np);
من شأنه أن يغير قيمة n إلى 100.
عندما نقول "int *ip" ، ماذا نعني بالضبط؟ مؤشر من النوع عدد صحيح؟ إذا كان الأمر كذلك ، عندما نسمي المتعة () مع NP كوسيطة لها ، ألا ينبغي أن يكون هناك خطأ لأن NP لديه عنوان N ، وهو ليس عددًا صحيحًا؟
وبعد ذلك ، نقوم بتغيير قيمة IP إلى 100 ، لذلك لا يعني هذا أن N لديها الآن القيمة الموجودة في "فتحة الذاكرة" مع العنوان 100؟ أنا متأكد من أنني أفتقد شيئًا. قون
المحلول
مؤشر من النوع عدد صحيح؟
لا ، مؤشر ل عدد صحيح.
عندما نسمي المتعة () مع NP كوسيطة لها ، ألا ينبغي أن يكون هناك خطأ لأن NP لديه عنوان N ، وهو ليس عددًا صحيحًا؟
n
هو عدد صحيح لذلك لا توجد مشكلة. &n
, np
و ip
جميعها لها نفس النوع في الكود الخاص بك: int*
.
وبعد ذلك ، نغير قيمة IP إلى 100
لا ... نغير قيمة *ip
, ، وليس من ip
. وهذا هو ، نحن نغير القيمة التي ip
نقاط ل (والتي تسمى أحيانًا نقطة).
نصائح أخرى
نعم ، عندما تستخدم int *
كنوع معلمة من fun
أنت تقول إنه يقبل مؤشرًا إلى int. حيث np
هو مؤشر لتمريره إلى fun
على ما يرام.
np
و ip
تشير إلى عنوان n
, ، لذلك عند تعيين قيمة مثل *ip = 42
, ، سيقوم بتعيين قيمة 42 إلى موقع الذاكرة ip
يشير إلى - وهو n
.
ما لديك في رمز العينة يسمى تمر بواسطة المؤشر. وظيفتك لها معلمة من النوع مؤشر إلى عدد صحيح. لذا فإن القيمة التي تم تمريرها إلى الوظيفة هي العنوان من المتغير n
. تعين الوظيفة 100
إلى المتغير (أي موقع الذاكرة) وأشار إلى بواسطة معلمة المؤشر ip
. النجم *
هل مشغل dereference في C/C ++.
في المرح () ، أنت لا تقوم بتغيير قيمة IP إلى 100 ، فأنت تقوم بتغيير موقع الذاكرة الذي أشار إليه IP.
type*
المستخدمة كنوع تعني "مؤشر لهذا النوع"
الاستخدام الشائع هو int *var
, ، لكني أحب أن أكتبها int* var
لأن ذلك يجعله تمييزًا أفضل من الإخلاء في المؤشر ، أي *ptr
.
لذا int* a
يعني ، A مؤشر لكائن من النوع int ، *a
يعني الكائن الذي أشار إليه و &a
يعني عنوان الكائن أ.
افكر في np
اعتبارا من النوع int*
. ضع في اعتبارك أنه لهذا الغرض من النجمة و int
قم معًا بتجميع نوع "المؤشر إلى int" ، ولا يمكن فصلهما.
ip
هو مؤشر ، مع ip*
يمكنك الوصول إلى "فتحة الذاكرة" التي تشير إليها. np
هو أيضا مؤشر. استخدام &n
يمكنك تعيين عنوان فتحة الذاكرة n
ل np
. لذلك عند الاتصال fun()
, ، داخل fun()
فتحة الذاكرة الوحيدة التي يتم الوصول إليها هي واحدة من n
وبالتالي إلى n
تم تعيين 100.
بعض الالتباس ممكن هنا لأن كلا من N و NP Store أرقام - ومع ذلك ، عند التجميع ، سيستخدم التحويل البرمجي الأرقام بشكل مختلف ؛ هذا هو ، بينما
n++;
و
np++;
كلاهما في الواقع العمليات الحسابية ، التجميع المولد مختلف. من المهم أن نتذكر أنه في نهاية المطاف ، جميع البيانات في الكمبيوتر هي أرقام. تصبح مختلفة الأنواع من البيانات فقط لأننا نعاملهم بشكل مختلف.
على وجه التحديد فيما يتعلق بمثالك ،
*np = 100;
عليك أن تتذكر أن ال *
يعني dereference, ، وهذه العملية تحدث قبل المهمة. قد يكون أكثر وضوحا مع أقواس لا لزوم لها:
(* (np) ) = 100;
أو في سياق مختلف:
int n = *np;
الآن ، يجب أن أقول ، إنه يسخن قلبي عندما تقول ،
نحن نغير قيمة IP إلى 100 ، فلا يعني هذا أن N لديه الآن القيمة الموجودة في "فتحة الذاكرة" مع العنوان 100؟ كما يكذب ما أعتبره فهمًا مهمًا. ومع ذلك ، أعتقد أنني على صواب عندما أقول ، يجب أن تخرج عن طريقك للقيام بهذا النوع من الأشياء للمؤشرات:
static_cast<int>(np) = 100;
هذا من شأنه أن يفعل ما وصفته ، لأنه يخبر الكمبيوتر بمعالجة الرقم الذي هو NP كنوع مختلف من الأرقام ؛ بنفس الطريقة static_cast<char*>(np)
سوف يعامل الرقم NP يشير إليه كشخصية ، بدلاً من أن تكون عددًا صحيحًا.