سؤال

النظر في التعليمات البرمجية التالية:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    string myAry[] = 
    {
        "Mary",
        "had", 
        "a",
        "Little",
        "Lamb"
    };
    const size_t numStrs = sizeof(myStr)/sizeof(myAry[0]);

    vector<string> myVec(&myAry[0], &myAry[numStrs]);

    copy( myVec.begin(), myVec.end(), ostream_iterator<string>(cout, " "));

    return 0;
}

من الاهتمام هنا هو &myAry[numStrs]: Numstrs يساوي 5، لذلك &myAry[numStrs] يشير إلى شيء غير موجود؛ ال السادس عنصر في الصفيف. هناك مثال آخر على هذا في الرمز أعلاه: myVec.end(), ، والذي يشير إلى نهاية واحدة من المتجه myVec. وبعد إنها قانونية مثالية لأخذ عنوان هذا العنصر غير موجود. نحن نعرف حجم string, ، لذلك نحن نعرف أين عنوان العنصر السادس من مجموعة أسلوب C من stringيجب أن يشير إلى. طالما أننا نقيم هذا المؤشر فقط وليس إلغاؤه أبدا، نحن بخير. يمكننا حتى قارنها بمؤشرات أخرى للمساواة. يقوم الأمراض المنقولة جنسيا بذلك طوال الوقت في الخوارزميات التي تعمل على مجموعة من المحفزين. ال end() نقاط المحرك الماضي في النهاية، والحلقات حافظ على حلقات أثناء العداد != end().

حتى الآن النظر في هذا:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    string myStr = "Mary";
    string* myPtr = &myStr;
    vector<string> myVec2(myPtr, &myPtr[1]);

    copy( myVec2.begin(), myVec2.end(), ostream_iterator<string>(cout, " "));   

    return 0;
}

هل هذا الرمز قانوني ومحدد جيدا؟ إنها قانونية ومحددة جيدا لاتخاذ عنوان عنصر صفيف الماضي، كما هو الحال في &myAry[numStrs], ، لذلك يجب أن يكون قانونيا ومحددا جيدا للتظاهر بذلك myPtr هو أيضا صفيف؟

هل كانت مفيدة؟

المحلول

إنه قانونية وليس UB أن يكون لديك مؤشر "ماضي واحد نهاية" صفيف، ويمكن علاج أي كائن واحد كما لو كان في مجموعة من الطول 1؛ ومع ذلك، تحتاج إلى استخدام ptr + 1 بدلا من ذلك بسبب التقنية &ptr[1] dereferencing ثم أخذ العنوان. هذا ينطبق أيضا على &array[size] تصبح array + size.

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

نصائح أخرى

يقول معيار C ++ في 5.6 / 4 "المشغلين المضافات":

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

يقول C99 Standard 6.5.6 / 7 أساسا نفس الشيء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top