سؤال

آسف إذا كان هذا هو سؤال noob :(.

قطعة من كود C.

int array[5];
int cnt;

for(cnt = 0; cnt <= 10; cnt+=1)
{
      array[cnt] = cnt;
}

يجب إعطاء خطأ، أليس كذلك؟ رقم! يعمل بشكل جيد! ولكن لماذا هذا؟ يبدو أنه - في الخط الأول - يتم تعريف مجموعة أكثر من الحجم المزدوج (11). يمكنك حتى الوصول إلى صفيف [5 إلى 10] في وقت لاحق. وهذا يربكني. توقف عن العمل عند تحديد الصفيف [4 أو أقل] ...

شكرا مقدما.

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

المحلول

قد يحدث ذلك للعمل مع برنامج التحويل البرمجي الخاص بك والكمبيوتر الخاص بك، لكن يجب أن لا تعتمد عليه.

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

على عكس لغات أعلى مستوى أعلى مثل Java و C #، يثق بك ولا تؤدي الشيكات الصريحة على حدود المصفوفات. من المفترض أن تكون مسؤولا وعدم السرعة خارج حدود الصفيف.

نصائح أخرى

هذا فقط "يعمل" إذا كان تعريفك "Works" مرادفا ب "لم يحطمت بعد".

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

"ولكن لماذا هذا؟"

لأن هذا هو الطريق C هو.

لم يتم التحقق من حدود الصفيف في وقت التشغيل.

هذا هو "قانون C"

أود فقط أن أشير إلى أن كل هذا غير محدد بالفعل. مثالك "يعمل" في هذا المثال المحدد لأن كلا المتغيرين موجودون على المكدس. هذا هو عنوان CNT هو أقل بقليل من نهاية الصفيف. عند الوصول إلى CNT CNT == 5 صفيف العبارة [CNT] = CNT؛ لا يكتب في الذاكرة المخصصة للمصفيف ولكن بعد ذلك فقط، حيث يضع عنوان CNT. إنه مجرد حظ أنه لا يغير عدادك. عند CNT> 5 لا توجد ذاكرة لسلة القمامة وسوف تكتب فقط في "كومة الفراغ" (لا أعرف الكلمة الصحيحة).

مثال آخر لتوضيح هذا:

int main(int ac,char **av)
{
    int a[5];
    int cnt;
    int cnt2=3;

    for(cnt=0;cnt<7;cnt++) {
        a[cnt]=cnt;
        printf("%d %d %d\n", a[cnt], cnt, cnt2);
    }
}

انتاج:

0 0 3
1 1 3
2 2 3
3 3 3
4 4 3
5 5 5
6 6 5

آخر اثنين من الكتابة من الحلقة الكتابة فوق بيانات المكدس بعد [] وقد تسفر عن أخطاء مربكة للغاية. في هذه الحالة يتم القمامة CNT2.

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

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

عادة عند إعلان صفائف في C، من الأفضل استخدام نوع من الثابت أو #Define لتمييز حجم الصفيف:

#define MAX_ELEMENTS 10
int array[MAX_ELEMENTS];
int cnt;
for(cnt = 0; cnt < MAX_ELEMENTS; cnt+=1) {
   array[cnt] = cnt;
}

إذا ذهبت إلى Max_Elements في مهمة الصفيف، فقد يتم الكتابة فوق قيمة CNT. قد تقوم بالكتابة فوق بعض المتغيرات الأخرى. كل هذا يتوقف على المحول البرمجي وبنية التعليمات البرمجية. لاحظ أيضا استخدام <تسجيل الدخول في حلقة. مقصات C تستند إلى 0 بحيث يتعين عليك التحقق من استخدام أقل غير وليست أقل من عدم توفرها.

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

بمجرد تشغيل نهاية الصفيف، فإنك تقوم بالكتابة فوق الذاكرة التي لا يتوقعها البرنامج وتخصيص الكومة. قد تستمر البرنامج في الركض، ولكن سيكون غير مستقر للغاية!

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

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