سؤال

ال ج المعيار (5.1.2.2.1 بدء تشغيل البرنامج) يقول:

يتم تسمية الوظيفة المسماة عند بدء تشغيل البرنامج الرئيسي. [...]
يجب أن يكون DE NED بنوع عائد INT ومع عدم وجود معلمات:
int main(void) { /* ... */ }

أو مع اثنين من المعلمات [...] :
int main(int argc, char *argv[]) { /* ... */ }

ويقول في وقت لاحق:

يجب أن تكون قيمة Argc غير نوطة.

  • لماذا لا ينبغي ذلك argc يتم تعريفها على أنها unsigned int, argc معنى من المفترض أن "عدد الحواف"؟
  • ينبغي argc أن تستخدم كمؤشر ل argv?

لذلك بدأت أتساءل عما إذا كان معيار C يقول شيئا عن نوع مؤشر الصفيف. هل وقعت؟

6.5.2.1 صفيف الاشتراك:

يجب أن يكون لأحد التعبيرات نوعا "مؤشر نوع الكائن''، يجب أن يكون التعبير الآخر عدد صحيحوالنتيجة لديها نوع "يكتب’’.

لا يقول أي شيء عن انقطاعه (أو لم أجده). من الشائع أن نرى رموز باستخدام فهارس صفيف السلبيات (array[-1]) ولكن أليس سلوك غير محدد؟

  • يجب أن تكون مؤشرات الصفيف غير موقعة؟
هل كانت مفيدة؟

المحلول

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

نصائح أخرى

1) حول الصفحة الرئيسية () ARGC: IMHO تواصل المعيار تقاليد قديمة جدا (أكثر من 30 عاما!)، والآن ... ببساطة بعد فوات الأوان لتغيير الأشياء (ملاحظة: على معظم الأنظمة لا مترجم، ولا رابط ، ولا وحدة المعالجة المركزية ستشكو إذا تم تعريف "ARGC" "غير موقعة"، لكنك خارج المعيار!)

2) على غالبية التطبيقات Argv [Argc] قانونية وتقييم إلى NULL. في الواقع، هناك طريقة بديلة للعثور على نهاية قائمة الوساطة هي التكرار على Argv من 0 إنهاء عندما يكون Argv [i] NULL.

3) Array / المؤشر الحسابي بالأرقام السلبية قانونية بقدر ما ينتمي نطاق العنوان من (PN) إلى P نفس كائن الذاكرة. أي يمكنك الحصول عليها

char array[100];
char *p;

p = &array[50];
p += -30; /* Now p points to array[20]. */

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

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

if (argc > -1)

(ال -1 يتم ترقيته إلى unsigned int, ، لذلك يتم تحويل قيمتها إلى UINT_MAX, ، وهو أكثر بالتأكيد أكبر من argc).

1) Argc عدد حجة، ولكن أن تكون صادقا جدا، كيف يمكنك إعدام الوسيطة قبل اسم البرنامج الذي argv[0]. وبعد تخيل برنامج يسمى foo, ، لا يمكنك أن تقول ببساطة args1 foo args2 لأن هذا لا معنى له، على الرغم من argc كونه نوع موقع من int, ، أي أي شيء مثل argv[-1] والتي سوف تحصل لك 'args1' ...

2) السبب archc ليس حقا فهرس إلى ناقل الحجة (وبالتالي "argv') كمؤدي وقت التشغيل اسم البرنامج القابل للتنفيذ في إزاحة Zero'th، أي argv[0] وبالتالي argc سوف تكون خارج 1.

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

char v [100]؛ char * p = & v [0]؛ يمكنك القيام بذلك: ص [55] = 'A'؛ وهو نفسه * (ص + 55) = 'A'؛ يمكنك حتى القيام بذلك: P = & V [55]؛ P [-10] = 'B' / * هذا سيوضح "B" في إزاحة 45! * / ما هو نفسه * (P - 10) = 'B'؛

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

4) في بيئات NIX *، سيكون لدى البعض معلمة ثالثة مزودة إلى Main char **endvp, ، مرة أخرى نادرا ما يستخدم هذا في Microsoft World of DOS / Windows. بعض تطبيقات وقت التشغيل NIX، لأسباب ما قبل التاريخية، يمكنك تمرير متغيرات البيئة عبر وقت التشغيل.

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