c++ - القيم الماضي مؤشر صالح إلى سلسلة C- نمط




arrays pointers (3)

C ++ يسمح لك لجعل المؤشر إلى ca[0] خلال الماضي الماضي ca[4] ، شاملة. يمكنك ديريفيرانس (أي تطبيق المشغل * ) إلى مؤشرات فقط إلى ca[0] خلال ca[4] ، على الرغم من؛ المؤشر الذي يشير إلى الماضي الماضي ca[4] هو خارج الحدود. ما يحدث في أقرب وقت كنت ديريفيرانس المؤشر هو سلوك غير معروف . البرنامج قد تنتج أي بيانات، أو حتى الحادث.

ما يحدث في الواقع هو أبسط: المؤشر هو مجرد عنوان في الذاكرة، لذلك ديريفيرانسينغ أنه لا يزال لتقديم أرقام لبرنامجك. عند نقطة ما، يحتوي العنوان على بايت صفر. هذا هو عندما يتوقف البرنامج الخاص بك.

يتم تخصيص صفيف في الذاكرة التلقائية. معظم المجمعين استخدام وحدة المعالجة المركزية المكدس لذلك. محتوى بايت 5..20 من المرجح جدا يتضمن cp count ، لأن المجمعين تميل إلى وضع المتغيرات المحلية معا. هناك على الأرجح بعض الحشو في بين، لأن مؤشر و int تتم محاذاة عادة في عناوين القسمة من قبل 4. بطبيعة الحال، لا يمكنك الاعتماد على أي من ذلك يحدث، لأن المبرمجين الآخرين سوف تفعل ذلك بشكل مختلف.

أنا حاليا في طريقي من خلال "C ++ التمهيدي". في واحدة من الأسئلة ممارسة يسأل:

ماذا يفعل البرنامج التالي؟

const char ca[] = { 'h', 'e', 'l', 'l', 'o' };

const char *cp = ca;

while (*cp)
{
    cout << *cp << endl;

    cp++;
}

أنا سعيد جدا أن أفهم * كب سيتم الاستمرار في أن يكون صحيحا الماضي الحرف الأخير من كا [] صفيف لأنه لا يوجد حرف فارغة كآخر عنصر في الصفيف.

بل هو أكثر لفضولتي الخاصة لما يجعل حلقة في حين تصبح كاذبة. يبدو أن تظهر دائما 19 حرفا على جهاز الكمبيوتر الخاص بي. 0-4 هي سلسلة مرحبا، 5-11 هي دائما نفس، و 12-19 تغيير مع كل تنفيذ.

#include <iostream>

using namespace std;

int main( )
{
    const char ca[ ] = { 'h', 'e', 'l', 'l', 'o'/*, '\0'*/ };

    const char *cp = ca;

    int count = 0;

    while ( *cp )
    {
        // {counter} {object-pointed-to} {number-equivalent}
        cout << count << "\t" << *cp << "\t" << (int)*cp << endl;

        count++;
        cp++;
    }

    return 0;
}

السؤال: ما الذي يجعل الحلقة في حين تصبح غير صالحة؟ لماذا 5-11 دائما نفس الحرف؟


الشيء المهم الذي يجب معرفته هو أنك تعاني من Undefined behavior معروف. لذلك مهما كنت ترى الآن، يمكن أن تكون مختلفة عند استخدام مترجم مختلف أو خيارات مترجم مختلفة.

السبب الأكثر شرحا لقيم 'ثابت' على 5-11 هو أنك تقرأ جزءا من المكدس، الذي يحدث فقط أن يكون لها نفس القيمة في كل مرة.


للمبتدئين:

يقوم هذا: بتخزين مجموعة من الأحرف (سلسلة قابلة للتعديل) بما في ذلك \0 نول تيرميناتور:

const char ca[] = "hello";

لا يتضمن هذا المحرر الناقص. فإنه يقوم بتهيئة الصفيف من القائمة الأولية

const char ca[] = { 'h', 'e', 'l', 'l', 'o' };

يعمل بنفس الطريقة التي سوف تفعل:

const int ib[] = {2, 5, 7, 9};

يجعل من المنطقي هنا، يتسبب في برنامج التحويل البرمجي يجب عدم إضافة المزيد من الاشياء إلى صفيف الخاص بك.

const char ca[] = { 'h', 'e', 'l', 'l', 'o' };
const char *cp = ca;
while (*cp){
    cout << *cp << endl;
    cp++;
}

حسنا، لديك سلوك غير معروف في التعليمات البرمجية الخاصة بك لأنك ديريفيرانس الماضي صفيف الخاص بك لأنه لا يوجد \0 نول نهاية في صفيف الخاص بك.

ما الذي يؤدي إلى أن تصبح الحلقة غير صالحة؟

لذلك ما يحدث بعد طباعة الحرف الأخير في صفيف الخاص بك هو أن البرنامج الخاص بك يحتفظ القراءة والطباعة من وندفيند (غير معروف) موقع الذاكرة حتى وصلت إلى نقطة حيث تم العثور على 0 وخرج الحلقة.

لماذا 5-11 دائما نفس الحرف؟

أما لماذا نظروا إلى نفسه: رتبت المتغيرات كومة نوع من خطيا كما يرغب المترجم. الذاكرة مبطن أيضا . مرة أخرى، يتم إعادة استخدام الذاكرة ، وبالتالي تقرأ من عنوان الاشياء، التي ليس لديك أي عمل قانوني مع.

الحاشية السفلية: قد يقوم البرنامج باستدعاء وظائف أخرى قبل int main() . (انها ليست عملك، ما يدعو). تقوم هذه الدالات بتهيئة المتغيرات الثابتة التي تتضمن أشياء مثل std::cout





char