1 00:00:00,000 --> 00:00:03,486 [MUSIC PLAYING] 2 00:00:03,486 --> 00:00:50,300 3 00:00:50,300 --> 00:00:54,350 ديفيد ج. مالان: حسنًا، هذه هي دورة CS50 وهذه هي المحاضرة الرابعة. 4 00:00:54,350 --> 00:00:56,510 إذن نحن هنا في قاعة محاضرات لويل الجميلة 5 00:00:56,510 --> 00:00:57,830 وسنستخدم Sanders اليوم. 6 00:00:57,830 --> 00:00:59,788 وانضم إلينا بعض الأصدقاء الذين 7 00:00:59,788 --> 00:01:02,610 سيأتون ويظهرون في غضون لحظات. 8 00:01:02,610 --> 00:01:06,140 ولكن قبل ذلك، تذكّروا آخر مرة ألقينا فيها نظرة على CS50 IDE. 9 00:01:06,140 --> 00:01:08,990 كانت تلك عبارة عن بيئة برمجية جديدة قائمة على الويب تشبه في جوهرها 10 00:01:08,990 --> 00:01:12,470 CS50 Sandbox وCS50 Lab، ولكن أضيفت إليها بعض الميزات. 11 00:01:12,470 --> 00:01:16,640 على سبيل المثال، ما هي الميزات التي أضافتها إليك-- 12 00:01:16,640 --> 00:01:17,620 لقدراتك؟ 13 00:01:17,620 --> 00:01:18,120 نعم؟ 14 00:01:18,120 --> 00:01:19,040 الجمهور: مصحح الأخطاء. 15 00:01:19,040 --> 00:01:19,530 ديفيد ج. مالان: ماذا؟ 16 00:01:19,530 --> 00:01:20,210 الجمهور: مصحح الأخطاء. 17 00:01:20,210 --> 00:01:20,880 ديفيد ج. مالان: مصحح الأخطاء. 18 00:01:20,880 --> 00:01:23,120 إذن debug50، الذي يفتح تلك اللوحة الجانبية التي 19 00:01:23,120 --> 00:01:26,250 تتيح لك المضي خلال تعليماتك البرمجية، خطوة بخطوة، ورؤية المتغيرات. 20 00:01:26,250 --> 00:01:26,750 نعم؟ 21 00:01:26,750 --> 00:01:27,670 الجمهور: Check50. 22 00:01:27,670 --> 00:01:28,270 ديفيد ج. مالان: معذرة، قل ذلك مجددًا؟ 23 00:01:28,270 --> 00:01:28,860 الجمهور: Check50. 24 00:01:28,860 --> 00:01:31,700 ديفيد ج. مالان: Check50 كذلك، وهي أداة محددة من CS50 25 00:01:31,700 --> 00:01:33,410 تتيح لك التحقق من صحة تعليماتك البرمجية 26 00:01:33,410 --> 00:01:36,410 تشبه إلى حد كبير ما سيقوم به زملاء التدريس أثناء تقديم الملاحظات بشأنها. 27 00:01:36,410 --> 00:01:38,609 تشغيل سلسلة من الاختبارات التي تشبه إلى حد كبير 28 00:01:38,609 --> 00:01:40,400 الاختبارات نفسها التي سيشجعكم الكثير من الواجبات المنزلية 29 00:01:40,400 --> 00:01:42,410 على تشغيلها يدويًا، 30 00:01:42,410 --> 00:01:43,970 لكنها تعمل فقط على تشغيل العملية تلقائيًا. 31 00:01:43,970 --> 00:01:44,719 وأي شيء آخر؟ 32 00:01:44,719 --> 00:01:51,020 الجمهور: [INAUDIBLE] 33 00:01:51,020 --> 00:01:52,520 ديفيد ج. مالان: إذن هذا صحيح أيضًا. 34 00:01:52,520 --> 00:01:55,530 توجد وظيفة مخفية إلى حد ما والتي لا نستخدمها في هذا الفصل الدراسي، 35 00:01:55,530 --> 00:01:56,400 لكن نعم بالفعل. 36 00:01:56,400 --> 00:01:58,650 إذا كنت تبحث عن قطعة لغز صغيرة، فيمكنك 37 00:01:58,650 --> 00:02:02,430 بالفعل تحويل تعليمة C البرمجية الخاصة بك إلى سكراتش مثل قطع اللغز 38 00:02:02,430 --> 00:02:06,257 ذهابًا وإيابًا، وذهابًا وإيابًا، بفضل كريم وبعض أفراد الفريق. 39 00:02:06,257 --> 00:02:08,340 لذلك هذا هناك، ولكن الآن، ربما من الأفضل 40 00:02:08,340 --> 00:02:09,929 التعود على النص أيضًا. 41 00:02:09,929 --> 00:02:11,970 إذن يوجد لدينا بعض الأدوات الأخرى التي قمنا 42 00:02:11,970 --> 00:02:15,780 باستخدامها طوال وقت الدورة بجانب check50 وdebug50. 43 00:02:15,780 --> 00:02:20,040 لقد استخدمنا بالطبع printf ومتى يكون printf مفيدًا؟ 44 00:02:20,040 --> 00:02:24,030 على سبيل المثال عندما ترغب في استخدامه بعدما تجاوزنا مرحلة طباعة شيء ما فقط 45 00:02:24,030 --> 00:02:25,710 لأن مجموعة المشاكل تخبرك بذلك. 46 00:02:25,710 --> 00:02:25,890 أجل؟ 47 00:02:25,890 --> 00:02:27,480 الجمهور: للعثور على مكان وجود الخطأ. 48 00:02:27,480 --> 00:02:29,605 ديفيد ج. مالان: نعم، إذن للعثور على مكان وجود الخطأ. 49 00:02:29,605 --> 00:02:32,982 إذا كنت فقط ترغب نوعًا ما في طباعة متغيرات، أو قيمة أو نص 50 00:02:32,982 --> 00:02:35,190 إذن تعرف ما يحدث ولا تريد بالضرورة 51 00:02:35,190 --> 00:02:37,000 نشر debug50، يمكنك القيام بذلك. 52 00:02:37,000 --> 00:02:37,500 متى أيضًا؟ 53 00:02:37,500 --> 00:02:41,372 الجمهور: إذا كانت لديك صيغة طويلة لشيء ما [INAUDIBLE] 54 00:02:41,372 --> 00:02:43,266 وتريد أن ترى [INAUDIBLE]. 55 00:02:43,266 --> 00:02:44,140 ديفيد مالان: جيد. 56 00:02:44,140 --> 00:02:44,639 نعم. 57 00:02:44,639 --> 00:02:48,492 الجمهور: كيفية التشغيل-- مثل التنقل من خلال debug50 خمسين مرة. 58 00:02:48,492 --> 00:02:49,450 ديفيد ج. مالان: بالفعل. 59 00:02:49,450 --> 00:02:51,616 حسنًا، في الحياة الواقعية-- إذن قد ترغب في استخدام printf 60 00:02:51,616 --> 00:02:55,190 عندما يكون لديك تكرار حلقي متداخل، وترغب في وضع printf داخل التكرار الحلقي 61 00:02:55,190 --> 00:02:57,010 حتى ترى متى يبدأ المفعول. 62 00:02:57,010 --> 00:02:59,200 بالطبع، يمكنك استخدام debug50، ولكن 63 00:02:59,200 --> 00:03:02,544 قد ينتهي الأمر بتشغيلك debug50 أو النقر فوق التالي، التالي، التالي، التالي، التالي، التالي، 64 00:03:02,544 --> 00:03:04,460 التالي لمرات عديدة الأمر يصبح مملاً بعض الشيء. 65 00:03:04,460 --> 00:03:08,020 ولكن ضَع في اعتبارك، أنه يمكنك وضع نقطة توقف أعمق في تعليماتك البرمجية 66 00:03:08,020 --> 00:03:10,832 أيضًا ومن المحتمل إزالة نقطة توقف لوقت سابق كذلك. 67 00:03:10,832 --> 00:03:13,540 وبصراحة، طوال الوقت، سواء كان في لغة C أو لغات أخرى، 68 00:03:13,540 --> 00:03:18,400 هل أجد نفسي أحيانًا أستخدم printf فقط لكتابة printf هنا 69 00:03:18,400 --> 00:03:22,581 فقط حتى يمكنني حرفيًا رؤية ما إذا وصلت تعليمتي البرمجية إلى نقطة معينة هنا 70 00:03:22,581 --> 00:03:23,830 لرؤية ما إذا تمت طباعة شيء ما. 71 00:03:23,830 --> 00:03:25,210 لكن مصحح الأخطاء الذي ستعثر عليه من الآن 72 00:03:25,210 --> 00:03:28,060 فصاعدًا أكثر قدرةً، ومتنوع الاستعمالات للغاية. 73 00:03:28,060 --> 00:03:31,280 إذن إذا لم تعتد بالفعل على استخدام debug50 بكل 74 00:03:31,280 --> 00:03:34,720 الطرق فابدأ باستخدم نقاط التوقف تلك للتنقل فعليًا خلال تعليمتك البرمجية 75 00:03:34,720 --> 00:03:36,456 حيث تهتم برؤية ما يجري. 76 00:03:36,456 --> 00:03:39,580 إذن style50، بالطبع، يتحقق من أسلوب تعليمتك البرمجية مثلما قد يقوم 77 00:03:39,580 --> 00:03:41,970 بذلك زملاء التدريس، ويظهر لك باللون الأحمر أو الأخضر 78 00:03:41,970 --> 00:03:44,439 ما هي المساحات التي قد ترغب في حذفها، ما هي المساحات التي قد 79 00:03:44,439 --> 00:03:45,980 ترغب في إضافتها فقط لتزيين الأمور. 80 00:03:45,980 --> 00:03:47,688 حتى تكون أكثر قابلية للقراءة لك وللآخرين. 81 00:03:47,688 --> 00:03:49,120 ثم ماذا عن help50؟ 82 00:03:49,120 --> 00:03:52,540 متى يجب عليك الوصول بديهيًا إلى help50؟ 83 00:03:52,540 --> 00:03:55,245 الجمهور: عندما لا تفهم رسالة الخطأ. 84 00:03:55,245 --> 00:03:56,245 ديفيد ج. مالان: بالضبط. 85 00:03:56,245 --> 00:03:58,020 نعم، عندما لا تفهم رسالة الخطأ. 86 00:03:58,020 --> 00:03:59,050 إذن أنت تقوم بتحويل شيء ما برمجيًا. 87 00:03:59,050 --> 00:03:59,890 أنت تشغل أمرًا. 88 00:03:59,890 --> 00:04:02,650 إنه لا يعمل تمامًا بالفعل وتشاهد رسالة خطأ مشفرة. 89 00:04:02,650 --> 00:04:05,358 في النهاية، ستحصل على الذاكرة العضلية ونوع التعرض 90 00:04:05,358 --> 00:04:07,270 لمجرد المعرفة، أوه، تذكرتُ ماذا يعني ذلك. 91 00:04:07,270 --> 00:04:10,300 ولكن حتى ذلك الحين، قم بتشغيل help50 في بداية ذلك الأمر نفسه، 92 00:04:10,300 --> 00:04:13,210 وستقوم بمحاولة كشف خطئك 93 00:04:13,210 --> 00:04:17,260 وتوفير ملاحظات من زميل تدريس على كيفية العمل بالفعل حول هذا الأمر. 94 00:04:17,260 --> 00:04:22,120 سترى اثنتين على موقع الدورة التدريبية على الويب عبارة عن نشرة رائعة معدّة 95 00:04:22,120 --> 00:04:24,670 من قِبل إميلي هونغ، واحدة من زملائنا في التدريس، 96 00:04:24,670 --> 00:04:26,920 التي تقدِّم فيها جميع هذه الأدوات، وبضع أدوات أخرى، 97 00:04:26,920 --> 00:04:29,597 وتجعلك تتعود على التفكير في الأمور. 98 00:04:29,597 --> 00:04:30,680 إنه مخطط انسيابي نوعًا ما. 99 00:04:30,680 --> 00:04:32,650 إذا كانت لديّ هذه المشكلة، سأقوم بذلك أو أي شيء آخر 100 00:04:32,650 --> 00:04:34,640 إذا كانت لديّ هذه المشكلة سأقوم بالشيء الآخر. 101 00:04:34,640 --> 00:04:36,440 للتأكد من ذلك أيضًا. 102 00:04:36,440 --> 00:04:39,854 لكن اليوم، دعونا نقدم الأداة الأخيرة بالفعل، وبالتأكيد للغة C، 103 00:04:39,854 --> 00:04:41,770 من أدوات سطر الأوامر الخاصة بنا التي ستساعدك 104 00:04:41,770 --> 00:04:44,350 في تعقب المشاكل في تعليمتك البرمجية. 105 00:04:44,350 --> 00:04:47,390 في الأسبوع الماضي، تذكّروا أننا تحدثنا عن الذاكرة كثيرًا. 106 00:04:47,390 --> 00:04:49,540 تحدثنا عن malloc، وعن تخصيص الذاكرة، 107 00:04:49,540 --> 00:04:51,610 وتحدثنا عن تحرير مساحة الذاكرة وما شابه ذلك. 108 00:04:51,610 --> 00:04:53,650 ولكن تبين، أنه يمكنك خلق الكثير من الضرر 109 00:04:53,650 --> 00:04:55,220 عندما تبدأ بالعبث في الذاكرة. 110 00:04:55,220 --> 00:04:58,840 في الحقيقة، ربما الآن، تقريبًا الجميع-- خطأ التجزئة؟ 111 00:04:58,840 --> 00:04:59,590 [LAUGHTER] 112 00:04:59,590 --> 00:05:02,500 نعم، إذن هذا مجرد خطأ واحد من الأخطاء التي ربما تواجهها، 113 00:05:02,500 --> 00:05:06,070 وبصراحة، قد يكون لديك أخطاء في تعليمتك البرمجية من الآن 114 00:05:06,070 --> 00:05:08,674 فصاعدًا وهي تحتوي على أخطاء ولكنك لا تدرك وجودها حتى 115 00:05:08,674 --> 00:05:10,090 لأنك محظوظ فقط. 116 00:05:10,090 --> 00:05:13,187 ولن يتعطل البرنامج أو يتوقف تمامًا، 117 00:05:13,187 --> 00:05:14,270 لكن يمكن أن يحدث هذا. 118 00:05:14,270 --> 00:05:17,890 ولذا Valgrind هو برنامج سطر أوامر ومن المحتمل 119 00:05:17,890 --> 00:05:19,700 أن يبدو على أنه الأداة الأكثر رعبًا من بين الأدوات التي استخدمناها، 120 00:05:19,700 --> 00:05:21,610 ولكن يمكنك أيضًا استخدامها مع help50، وهي 121 00:05:21,610 --> 00:05:24,799 تحاول فقط العثور على ما يسمى بتسريبات الذاكرة في برنامجك. 122 00:05:24,799 --> 00:05:26,590 تذكّروا أننا في الأسبوع الماضي قدّمنا ​​malloc، 123 00:05:26,590 --> 00:05:28,580 ويتيح لك malloc تخصيص الذاكرة. 124 00:05:28,580 --> 00:05:32,830 ولكن إذا لم تحرر تلك الذاكرة، من خلال تسمية الدالة الفارغة حرفيًا، 125 00:05:32,830 --> 00:05:35,990 فستطلب باستمرار من نظام التشغيل لديك، MacOS، Linux، 126 00:05:35,990 --> 00:05:37,812 Windows، أيًا كان، هل يمكنني الحصول على المزيد من الذاكرة؟ 127 00:05:37,812 --> 00:05:38,770 هل يمكنني الحصول على المزيد من الذاكرة؟ 128 00:05:38,770 --> 00:05:39,728 هل يمكنني الحصول على المزيد من الذاكرة؟ 129 00:05:39,728 --> 00:05:42,760 وإذا لم تسترجعها، حرفيًا، أبدًا من خلال طلب التحرير فقد يصبح جهاز الكمبيوتر 130 00:05:42,760 --> 00:05:45,570 الخاص بك بطيئًا أو يتوقف عن العمل أو يتعطل. 131 00:05:45,570 --> 00:05:49,000 وبصراحة، إذا سبق وحدث ذلك على جهاز Mac أو PC لديك، فمن المحتمل جدًا 132 00:05:49,000 --> 00:05:50,920 أن هذا ما فعله بعض البشر عن طريق الخطأ. 133 00:05:50,920 --> 00:05:53,110 يقوم هو أو هي فقط بتخصيص المزيد والمزيد من الذاكرة 134 00:05:53,110 --> 00:05:56,060 ولكن لم يتم تحرير تلك الذاكرة بالفعل. 135 00:05:56,060 --> 00:05:59,950 إذن Valgrind يمكنه مساعدتك في العثور على تلك الأخطاء قبل أن تقوم أنت أو المستخدمون لديك بذلك. 136 00:05:59,950 --> 00:06:04,630 إذن دعونا نقوم بمثال سريع، دعوني أنتقل إلى CS50 IDE، ودعوني أمضي قدمًا 137 00:06:04,630 --> 00:06:07,180 وأقوم بإعداد برنامج جديد هنا. 138 00:06:07,180 --> 00:06:10,360 سنسميه memory.c لأننا سنرى لاحقًا اليوم كيف 139 00:06:10,360 --> 00:06:12,274 يمكنني تعقب تسربات الذاكرة تلك. 140 00:06:12,274 --> 00:06:15,190 ولكن الآن، لنبدأ بشيء مبسط أكثر، وربما قمتم بتنفيذه 141 00:06:15,190 --> 00:06:18,569 جميعكم حتى الآن، وهو لمس الذاكرة عن طريق الخطأ 142 00:06:18,569 --> 00:06:21,860 والتي كان يجب عليكم عدم، تغييرها، أو قراءتها ودعونا نرى ما الذي قد يعنيه هذا. 143 00:06:21,860 --> 00:06:25,330 إذن دعونا نقوم بما اعتدنا فعله في الأعلى هنا. 144 00:06:25,330 --> 00:06:28,675 Include standard IO "تضمين إدخال/إخراج قياسي". 145 00:06:28,675 --> 00:06:30,050 حسنًا، دعونا ألا نقوم بذلك الآن. 146 00:06:30,050 --> 00:06:31,091 دعونا فقط نقوم بهذا أولاً. 147 00:06:31,091 --> 00:06:34,240 دعونا نقوم بكتابة int، main(void)، فقط لكي نبدأ برنامجًا بسيطًا 148 00:06:34,240 --> 00:06:38,440 وهنا دعوني أمضي قدمًا وأستدعي فقط دالة باسم f. 149 00:06:38,440 --> 00:06:40,450 ولا أهتم في الحقيقة بماهية اسمها اليوم. 150 00:06:40,450 --> 00:06:43,780 أنا أريد فقط استدعاء دالة f، ومن ثم فهذا كل شيء. 151 00:06:43,780 --> 00:06:47,620 الآن هذه الدالة f، دعوني أمضي قدمًا وأعّرفها على النحو التالي، (void f(void. 152 00:06:47,620 --> 00:06:50,034 لن تفعل الكثير مطلقًا. 153 00:06:50,034 --> 00:06:53,200 لكن دعونا نفترض، فقط من أجل المناقشة، هذا هو هدف f في الحياة 154 00:06:53,200 --> 00:06:55,780 هو تخصيص الذاكرة فقط لأي غرض مفيد، 155 00:06:55,780 --> 00:06:58,480 ولكن الآن إنها للإثبات فقط. 156 00:06:58,480 --> 00:07:01,830 إذن ما هي الدالة التي يمكنك تخصيص الذاكرة باستخدامها؟ 157 00:07:01,830 --> 00:07:02,710 الجمهور: Malloc. 158 00:07:02,710 --> 00:07:03,668 ديفيد ج. مالان: Malloc. 159 00:07:03,668 --> 00:07:06,490 إذن افترضوا أنني أريد مساحة malloc من أجل، لا أدري، 160 00:07:06,490 --> 00:07:08,439 شيء بسيط مثل عدد صحيح واحد فقط. 161 00:07:08,439 --> 00:07:10,480 نحن نقوم بهذا فقط لأغراض التوضيح، 162 00:07:10,480 --> 00:07:13,420 أو في الواقع دعونا نقوم بالمزيد، 10 أعداد صحيحة، 10 أعداد صحيحة. 163 00:07:13,420 --> 00:07:17,800 يمكنني، بالطبع، القيام-- حسنًا، أعطني 10، لكن كم وحدة بايت أريدها؟ 164 00:07:17,800 --> 00:07:19,810 كم وحدة بايت أحتاجها لـ 10 أعداد صحيحة؟ 165 00:07:19,810 --> 00:07:20,800 الجمهور: sizeof(int). 166 00:07:20,800 --> 00:07:23,540 ديفيد ج. مالان: أجل، إذن يمكنني كتابة sizeof(int) 167 00:07:23,540 --> 00:07:28,072 وعلى الأرجح فكم سيكون حجم العدد الصحيح؟ 168 00:07:28,072 --> 00:07:28,729 الجمهور: أربعة. 169 00:07:28,729 --> 00:07:30,020 ديفيد ج. مالان: أربعة، ربما. 170 00:07:30,020 --> 00:07:32,750 في العديد من الأنظمة اليوم، يبلغ 4 وحدات بايت فقط أو 32 بايت، 171 00:07:32,750 --> 00:07:36,200 ولكنك لا تريد تعليمات برمجية ثابتة حتى لا يستخدم كمبيوتر شخص آخر 172 00:07:36,200 --> 00:07:37,170 هذه القيم نفسها. 173 00:07:37,170 --> 00:07:38,280 إذن حجم عدد صحيح. 174 00:07:38,280 --> 00:07:39,980 إذن 10 أضعاف حجم العدد الصحيح. 175 00:07:39,980 --> 00:07:42,270 يعيد Malloc أي نوع من البيانات؟ 176 00:07:42,270 --> 00:07:45,254 ما الذي يُعيده هذا إليّ؟ 177 00:07:45,254 --> 00:07:46,742 الجمهور: [INAUDIBLE] 178 00:07:46,742 --> 00:07:49,000 ديفيد ج. مالان: أجل، يعيد عنوانًا أو مؤشرًا. 179 00:07:49,000 --> 00:07:53,600 بالتحديد، العنوان، 100، 900، أيًا كان، من جزء الذاكرة 180 00:07:53,600 --> 00:07:55,200 الذي تم تخصصيه لك للتو. 181 00:07:55,200 --> 00:07:58,400 إذن إذا رغبت في الاحتفاظ بهذا هنا، سأحتاج إلى إعلان مؤشر. 182 00:07:58,400 --> 00:08:01,070 دعونا نسميه x اليوم والذي يخزِّن ذلك العنوان. 183 00:08:01,070 --> 00:08:04,430 يمكن أن نسميه x، y، z، أيًا كان، لكنه ليس العدد الصحيح الذي تتم إعادته. 184 00:08:04,430 --> 00:08:05,720 وإنما عنوان العدد الصحيح. 185 00:08:05,720 --> 00:08:07,970 وتذكّروا، ما الذي يعنيه مُشغل النجمة الآن. 186 00:08:07,970 --> 00:08:10,010 عنوان بعض أنواع البيانات. 187 00:08:10,010 --> 00:08:11,270 إنه مجرد رقم. 188 00:08:11,270 --> 00:08:14,330 حسنًا، الآن إذا كنت-- 189 00:08:14,330 --> 00:08:15,680 دعونا أولاً، نمحو هذا. 190 00:08:15,680 --> 00:08:20,090 يتضح أنك تستخدم malloc، أحتاج إلى استخدام stdlib.h. 191 00:08:20,090 --> 00:08:22,670 الذي شاهدناه الأسبوع الماضي، وإن كان لفترة وجيزة، وبعد ذلك بالطبع 192 00:08:22,670 --> 00:08:26,390 إذا كنت سأستدعي f، فما الذي يتعين عليّ القيام به لإصلاح هذه التعليمة البرمجية؟ 193 00:08:26,390 --> 00:08:27,830 الجمهور: أنت بحاجة إلى إعلان. 194 00:08:27,830 --> 00:08:29,954 ديفيد ج. مالان: اجل، أحتاج إلى إعلانه هنا، 195 00:08:29,954 --> 00:08:32,149 أو يمكنني فقط تحريك تنفيذ f إلى الأعلى. 196 00:08:32,149 --> 00:08:34,690 إذن أعتقد ان الأمر نجح، رغم أن هذا البرنامج في الوقت الحالي 197 00:08:34,690 --> 00:08:35,580 أحمق للغاية. 198 00:08:35,580 --> 00:08:38,510 إنه لا يقوم بأي شيء مفيد، ولكنه سيخصص الذاكرة. 199 00:08:38,510 --> 00:08:41,010 وسأفعل شيئًا باستخدامه على النحو التالي. 200 00:08:41,010 --> 00:08:45,359 إذا كنت أرغب في تغيير القيمة الأولى في جزء الذاكرة هذا، 201 00:08:45,359 --> 00:08:46,400 حسنًا كيف يمكنني القيام بذلك؟ 202 00:08:46,400 --> 00:08:51,020 حسنًا، لقد طلبت من الكمبيوتر 10 أعداد صحيحة أو بالأحرى مساحة 203 00:08:51,020 --> 00:08:52,367 لـ 10 أعداد صحيحة. 204 00:08:52,367 --> 00:08:54,200 الشيء المثير للاهتمام حول malloc هو أنه عندما 205 00:08:54,200 --> 00:08:58,566 يعيد جزءًا من الذاكرة إليك إنه متجاور، على التوالي. 206 00:08:58,566 --> 00:09:00,440 وعندما تسمعون متجاور أو على التوالي، 207 00:09:00,440 --> 00:09:03,710 فما هو نوع بنية البيانات التي تتبادر في ذهنكم؟ 208 00:09:03,710 --> 00:09:04,569 الجمهور: مصفوفة. 209 00:09:04,569 --> 00:09:05,610 ديفيد ج. مالان: مصفوفة. 210 00:09:05,610 --> 00:09:09,290 إذن يتضح أنه يمكننا التعامل مع هذا الجزء العشوائي فقط من الذاكرة 211 00:09:09,290 --> 00:09:10,440 كأنه مصفوفة. 212 00:09:10,440 --> 00:09:14,300 لذلك إذا أردنا الانتقال إلى الموقع الأول في تلك المصفوفة من الذاكرة، 213 00:09:14,300 --> 00:09:18,200 يمكنني فقط القيام بذلك وأضع رقمًا لنقل 50. 214 00:09:18,200 --> 00:09:21,680 أو إذا أردت الانتقال إلى الموقع التالي، يمكنني القيام بذلك. 215 00:09:21,680 --> 00:09:24,410 أو إذا أردت الانتقال إلى الموقع التالي، يمكنني القيام بذلك. 216 00:09:24,410 --> 00:09:27,200 أو إذا كنت أردت الانتقال إلى الموقع الأخير، فقد أقوم بذلك، 217 00:09:27,200 --> 00:09:32,064 ولكن هل هذا جيد أم سيئ؟ 218 00:09:32,064 --> 00:09:32,950 الجمهور: سيئ. 219 00:09:32,950 --> 00:09:33,952 ديفيد ج. مالان: لماذا سيئ؟ 220 00:09:33,952 --> 00:09:35,560 الجمهور: إنه-- خارج الحدود 221 00:09:35,560 --> 00:09:36,860 ديفيد ج. مالان: أجل، إنه إذن خارج الحدود. 222 00:09:36,860 --> 00:09:37,360 أليس كذلك؟ 223 00:09:37,360 --> 00:09:39,950 هذا هو نوع أخطاء أسلوب الأسبوع الأول عندما تعلق الأمر بالتكرارات الحلقية. 224 00:09:39,950 --> 00:09:42,360 تذكرون، مع التكرار حلقي أو أثناء تكرارات حلقية، قد تذهب بعيدًا للغاية، 225 00:09:42,360 --> 00:09:43,260 وهذا جيد. 226 00:09:43,260 --> 00:09:45,500 ولكن الآن سنرى بالفعل أن لدينا أداة 227 00:09:45,500 --> 00:09:47,040 يمكن أن تساعدنا في ملاحظة هذه الأشياء. 228 00:09:47,040 --> 00:09:50,780 إذن آمل، فقط بشكل مرئي، أنه من الواضح أن الذي يحدث هنا 229 00:09:50,780 --> 00:09:54,800 هو فقط-- على السطر 12، لديّ متغير x 230 00:09:54,800 --> 00:09:56,870 الذي يخزِّن العنوان لهذا الجزء من الذاكرة. 231 00:09:56,870 --> 00:10:00,890 ثم على السطر 13، أحاول فقط الوصول إلى موقع 10 232 00:10:00,890 --> 00:10:02,180 وأقوم بتعيين القيمة 50 هناك. 233 00:10:02,180 --> 00:10:04,460 ولكن كما تلاحظون، لا يوجد موقع 10. 234 00:10:04,460 --> 00:10:08,750 توجد مواقع 0، 1، 2، 3، بنفس النسق خلال 9، بالطبع. 235 00:10:08,750 --> 00:10:10,800 إذن كيف يمكننا اكتشاف هذا باستخدام برنامج؟ 236 00:10:10,800 --> 00:10:13,466 حسنًا، دعوني أمضي قدمًا وأوسع النافذة الطرفية قليلاً 237 00:10:13,466 --> 00:10:17,560 هنا، وأحفظ ملفي، ودعوني أمضي قدمًا وأحول make memory برمجيًا. 238 00:10:17,560 --> 00:10:18,650 حسنًا، كل شيء على ما يرام. 239 00:10:18,650 --> 00:10:20,690 تم تحويلها برمجيًا بدون أي رسائل أخطاء، والآن 240 00:10:20,690 --> 00:10:24,237 دعوني أمضي قدمًا وأشغل الذاكرة، enter. 241 00:10:24,237 --> 00:10:25,820 حسنًا، إذن هذا يعمل بشكل جيد للغاية. 242 00:10:25,820 --> 00:10:29,014 دعونا في الواقع نكون أكثر وضوحًا هنا فقط لتدبر الأمور جيدًا. 243 00:10:29,014 --> 00:10:30,680 دعوني أمضي قدمًا وأطبع شيئًا ما. 244 00:10:30,680 --> 00:10:36,290 إذن printf، %i لعدد صحيح، ودعونا نجعله أكثر وضوحًا. 245 00:10:36,290 --> 00:10:42,140 قمتَ بإدخال %i ومن ثم فاصلة x قوس 10. 246 00:10:42,140 --> 00:10:46,405 وما الذي يتعين عليّ القيام به لتضمينك باستخدام printf؟ 247 00:10:46,405 --> 00:10:47,320 الجمهور: stdio.h. 248 00:10:47,320 --> 00:10:48,611 ديفيد ج. مالان: نعم، إذن stdio. 249 00:10:48,611 --> 00:10:51,940 إذن دعونا فقط بسرعة نضيف هذا، stdio.h، حفظ. 250 00:10:51,940 --> 00:10:55,000 حسناً، دعوني أعيد تحويل هذا برمجيًا، make memory، enter. 251 00:10:55,000 --> 00:10:59,410 والآن دعوني أمضي قدمًا وأكتب ./memory. 252 00:10:59,410 --> 00:11:00,610 ها؟ 253 00:11:00,610 --> 00:11:02,469 يبدو أنه البرنامج الصحيح. 254 00:11:02,469 --> 00:11:05,260 ومع ذلك، لبضعة أسابيع الآن كنا نزعم أن امم-مم، 255 00:11:05,260 --> 00:11:06,490 لا تفعل ذلك. 256 00:11:06,490 --> 00:11:09,100 ولا تتجاوز حدود مصفوفتك. 257 00:11:09,100 --> 00:11:10,352 إذن كيف يمكننا تسوية هذا الأمر؟ 258 00:11:10,352 --> 00:11:13,060 يبدو وكأنها تعليمة برمجية خاطئة أو على الأقل لقد أخبرناكم أنها تعليمة برمجية خاطئة، 259 00:11:13,060 --> 00:11:13,935 ومع ذلك نجح الأمر. 260 00:11:13,935 --> 00:11:16,301 261 00:11:16,301 --> 00:11:16,800 أجل؟ 262 00:11:16,800 --> 00:11:19,273 الجمهور: [INAUDIBLE] 263 00:11:19,273 --> 00:11:21,272 ديفيد ج. مالان: هذه وسيلة جيدة لوضعها. 264 00:11:21,272 --> 00:11:23,076 الجمهور: ما زالت متشابهة للغاية. 265 00:11:23,076 --> 00:11:23,980 نحن نريد ذلك. 266 00:11:23,980 --> 00:11:24,771 ديفيد ج. مالان: حسنًا. 267 00:11:24,771 --> 00:11:27,120 الجمهور: إذن يمكننا من الناحية النظرية-- 268 00:11:27,120 --> 00:11:29,902 لقد أنشأت برنامجًا للتو. 269 00:11:29,902 --> 00:11:32,360 ديفيد ج. مالان: نعم، وأعتقد إذا سمعتك بشكل صحيح، 270 00:11:32,360 --> 00:11:35,066 أنك قلتِ أن لغة C لا تقوم بالتنبيه إذا ذهبت بعيدًا أكثر مما ينبغي؟ 271 00:11:35,066 --> 00:11:35,690 الجمهور: نعم. 272 00:11:35,690 --> 00:11:36,070 ديفيد ج. مالان: أجل، حسنًا. 273 00:11:36,070 --> 00:11:37,528 هذه طريقة جيدة لوضعها. 274 00:11:37,528 --> 00:11:39,640 على سبيل المثال، يمكنك أن تكون محظوظًا في لغة C. ويمكنك 275 00:11:39,640 --> 00:11:43,707 القيام بشيء ما خطأ من الناحية الموضوعية، التعليمية، وتقريبًا الفنية، 276 00:11:43,707 --> 00:11:45,290 لكن الكمبيوتر لن يتعطل. 277 00:11:45,290 --> 00:11:46,790 لن يتوقف فقط لأنك محظوظ. 278 00:11:46,790 --> 00:11:48,970 لأنه في كثير من الأحيان، لأسباب تتعلق بالأداء، عندما 279 00:11:48,970 --> 00:11:51,220 تخصص مساحة لـ 10 أعداد الصحيحة، فستقوم 280 00:11:51,220 --> 00:11:53,110 في الواقع باسترجاع جزء من الذاكرة مجددًا 281 00:11:53,110 --> 00:11:54,651 وهو أكبر مما تحتاج إليه قليلاً. 282 00:11:54,651 --> 00:11:58,172 ليس من الآمن فقط أن تفترض أنه أكبر مما تحتاج إليه، 283 00:11:58,172 --> 00:11:59,380 ولكن قد يحالفك الحظ فقط. 284 00:11:59,380 --> 00:12:02,421 وقد ينتهي الأمر بوجود المزيد من الذاكرة لديك والتي يمكنك الحصول عليها من الناحية الفنية 285 00:12:02,421 --> 00:12:05,780 باللمس أو الوصول أو التغيير، ولن يلاحظ الكمبيوتر ذلك. 286 00:12:05,780 --> 00:12:08,114 ولكن هذا ليس آمنًا لأنه على جهاز Mac أو كمبيوتر شخص آخر، 287 00:12:08,114 --> 00:12:11,238 قد يكون جهاز الكمبيوتر الخاص بهم يعمل فقط بشكل مختلف قليلاً عن جهازك، 288 00:12:11,238 --> 00:12:13,780 وفجأة، سيعبث هذا الخطأ بها وليس بجهازك. 289 00:12:13,780 --> 00:12:16,990 وهذه هي الأخطاء الأصعب والأكثر إزعاجًا لتعقبها كما قد 290 00:12:16,990 --> 00:12:17,800 تعرّض البعض منكم إلى ذلك. 291 00:12:17,800 --> 00:12:18,299 أليس كذلك؟ 292 00:12:18,299 --> 00:12:21,200 وهي تعمل على جهاز الكمبيوتر الخاص بك وليس عند الأصدقاء أو العكس بالعكس. 293 00:12:21,200 --> 00:12:23,320 هذه هي أنواع التفسيرات لذلك. 294 00:12:23,320 --> 00:12:26,890 إذن يمكن أن يساعدنا Valgrind في تعقب هذه الأخطاء الأكثر دقة. 295 00:12:26,890 --> 00:12:28,670 يبدو أن البرنامج يعمل. 296 00:12:28,670 --> 00:12:30,426 Check50 أو الأدوات المشابهة لها قد تفترض 297 00:12:30,426 --> 00:12:32,800 أنه يعمل لأنها تطبع الشيء الصحيح، 298 00:12:32,800 --> 00:12:36,010 ولكن دعونا نلقي نظرة على ما يفكر فيه هذا البرنامج Valgrind. 299 00:12:36,010 --> 00:12:38,740 دعوني أزيد حجم النافذة الطرفية هنا، 300 00:12:38,740 --> 00:12:41,980 وأمضي قدمًا وأكتب في Valgrind ./memory. 301 00:12:41,980 --> 00:12:47,240 إذن اسم البرنامج نفسه ./memory لكنني بدأته بوضع اسم Valgrind. 302 00:12:47,240 --> 00:12:47,740 حسنًا؟ 303 00:12:47,740 --> 00:12:50,020 لسوء الحظ، Valgrind قبيح تمامًا بالفعل، 304 00:12:50,020 --> 00:12:52,490 ويطبع مجموعة كاملة من الأشياء هنا. 305 00:12:52,490 --> 00:12:53,500 إذن دعونا نلقي نظرة. 306 00:12:53,500 --> 00:12:56,330 في الأعلى، سترون جميع هذه الأرقام على اليسار، 307 00:12:56,330 --> 00:12:58,150 وهذه مجرد صورة جمالية مؤسفة. 308 00:12:58,150 --> 00:13:00,450 لكننا نرى بعض المعلومات المفيدة. 309 00:13:00,450 --> 00:13:03,580 قراءة غير صالحة للحجم 4 ثم إنها تحتوي على هذه 310 00:13:03,580 --> 00:13:05,080 الأرقام والأحرف التي تبدو مشفرة. 311 00:13:05,080 --> 00:13:07,990 ما هي هذه؟ 312 00:13:07,990 --> 00:13:09,634 إنها مجرد عناوين والسداسيّ العشريّ. 313 00:13:09,634 --> 00:13:11,800 لا يهم حقًا ما هي، ولكن Valgrind 314 00:13:11,800 --> 00:13:15,670 يمكنه أن يخبرنا أين هي الذاكرة التي تتصرف على نحو مريب. 315 00:13:15,670 --> 00:13:18,370 يمكنكم بعد ذلك رؤية ما بجانب ذلك، حيث يشير Valgrind إلى 316 00:13:18,370 --> 00:13:21,760 دالة f على السطر 15 من memory. c. 317 00:13:21,760 --> 00:13:24,327 لذا قد يكون ذلك مفيدًا، ومن ثم main على السطر 8 318 00:13:24,327 --> 00:13:26,160 لأن هذه هي الدالة التي تم استدعاؤها. 319 00:13:26,160 --> 00:13:29,590 إذن Valgrind في الواقع جيد إلى حد ما كونه يعرض لنا جميع الدوال 320 00:13:29,590 --> 00:13:33,160 التي قمت باستدعائها من الأسفل، والتي تشبه المكدس من الأسبوع الماضي كثيرًا. 321 00:13:33,160 --> 00:13:37,420 وهكذا فإن شيئًا ما يحدث على نحو خاطىء في السطر 15، وإذا عدنا إلى ذلك، 322 00:13:37,420 --> 00:13:39,750 دعونا نرى أن السطر 15 كان-- 323 00:13:39,750 --> 00:13:41,240 حسنًا، مؤكد بما فيه الكفاية. 324 00:13:41,240 --> 00:13:43,660 أنا أحاول في الواقع الوصول إلى موقع الذاكرة ذلك 325 00:13:43,660 --> 00:13:46,040 وبصراحة قمت بذلك على السطر 14 أيضًا. 326 00:13:46,040 --> 00:13:49,540 لذا آمل أن إصلاح أحدهما أو كليهما سيعالج تلك المشكلة. 327 00:13:49,540 --> 00:13:54,460 ولاحظوا هنا، فهذا صراحةً يصبح الآن غامرًا نوعًا ما بسرعة. 328 00:13:54,460 --> 00:13:58,384 ثم، أوه، فُقِدت بالتأكيد 40 وحدة بايت في كتلة واحدة في السجل المفقود. 329 00:13:58,384 --> 00:14:00,550 أعني، هذه هي المشكلة في Valgrind، بصراحة. 330 00:14:00,550 --> 00:14:03,820 فقد تمت كتابته منذ بضع سنوات، وليس مناسبًا للمستخدمين على وجه الخصوص، 331 00:14:03,820 --> 00:14:05,980 ولكن من الجيد أن لدينا أداة لمعالجة هذا. 332 00:14:05,980 --> 00:14:09,610 دعوني أمضي قدمًا وأعيد تشغيل Valgrind باستخدام help50، 333 00:14:09,610 --> 00:14:13,150 enter، ونرى إذا لم نتمكن من مجرد المساعدة في هذا. 334 00:14:13,150 --> 00:14:16,990 حسنًا، إذن ما تزال الكمية نفسها من المُدخل الأبيض والأسود ولكن في الأسفل هنا الآن 335 00:14:16,990 --> 00:14:21,700 يقوم help50 بالملاحظة، أوه، يمكنني مساعدتك بشأن الكتابة غير الصحيحة للحجم 4. 336 00:14:21,700 --> 00:14:23,880 إذن ما تزال في الموقع نفسه، ولكن هذه المرة-- 337 00:14:23,880 --> 00:14:26,950 أو بالأحرى الملف نفسه، memory.c ولكن في السطر 14. 338 00:14:26,950 --> 00:14:30,550 ونقترح، يبدو أنك تحاول تعديل 4 وحدات بايت من ذاكرة 339 00:14:30,550 --> 00:14:32,029 لا تخصك، علامة استفهام. 340 00:14:32,029 --> 00:14:34,570 هل جربتم تخزين شيء يفوق مساحة المصفوفة؟ 341 00:14:34,570 --> 00:14:37,590 ألقوا نظرة عن قرب على السطر 14 من memory.c. 342 00:14:37,590 --> 00:14:40,930 إذن آمل أن، على الرغم من أن مخرج Valgrind سري خيالي، 343 00:14:40,930 --> 00:14:43,870 فسيشير على الأقل المخرج الأصفر لك نحو، آه، السطر 14. 344 00:14:43,870 --> 00:14:48,282 أقوم بالفعل بلمس 4 وحدات بايت، عدد صحيح، ولا يجب فعل هذا. 345 00:14:48,282 --> 00:14:49,740 إذن دعونا نمضي قدمًا ونصلح هذا. 346 00:14:49,740 --> 00:14:53,050 إذا انتقلت إلى برنامجي، ولن أقوم بذلك. 347 00:14:53,050 --> 00:14:57,250 دعونا نغيره إلى الموقع 9، والموقع 9 هنا وحفظ. 348 00:14:57,250 --> 00:15:02,680 ثم دعوني أمضي قدمًا وأعيد تشغيل Valgrind دون استخدام help50. 349 00:15:02,680 --> 00:15:05,270 حسنًا، يحدث التقدم باستثناء-- 350 00:15:05,270 --> 00:15:05,770 عذرًا. 351 00:15:05,770 --> 00:15:07,160 كلا، لا يوجد تقدم. 352 00:15:07,160 --> 00:15:08,590 لقد تخطيتُ الخطوة. 353 00:15:08,590 --> 00:15:10,840 نعم، لم أُعِد تحويله برمجيًا. 354 00:15:10,840 --> 00:15:12,590 ينتابني شيء من الحيرة لماذا رأيت الشيء نفسه. 355 00:15:12,590 --> 00:15:18,730 إذن دعونا الآن نعيد تشغيل Valgrind وهنا يبدو أنه أفضل. 356 00:15:18,730 --> 00:15:20,830 لذلك لا أرى رسالة الخطأ نفسها 357 00:15:20,830 --> 00:15:25,810 في الأعلى كما فعلنا من قبل، ولكن لاحظوا هنا، توجد 40 وحدة بايت في كتلة واحدة. 358 00:15:25,810 --> 00:15:29,140 حسنًا، لقد كانت تلك هي القاعدة السيئة في البرنامج، لكنها بالتأكيد 359 00:15:29,140 --> 00:15:30,545 فُقِدت خلال فقدان السجل 1 من 1. 360 00:15:30,545 --> 00:15:32,170 إذن ما زلت لا أفهم ذلك تمامًا. 361 00:15:32,170 --> 00:15:33,100 ليس أمرًا صعبًا. 362 00:15:33,100 --> 00:15:36,580 دعونا نمضي قدمًا ونشغل help50 ونرى ما الخطأ الثاني من الخطأين 363 00:15:36,580 --> 00:15:38,020 الذي يبدو أنه هنا. 364 00:15:38,020 --> 00:15:40,590 إذن يقوم بتظليل تلك السطور هنا. 365 00:15:40,590 --> 00:15:43,960 بالتأكيد تم فقدان 40 وحدة بايت وكتلة واحدة، ويبدو أن برنامجك 366 00:15:43,960 --> 00:15:45,550 قام بتسريب 40 وحدة بايت من الذاكرة. 367 00:15:45,550 --> 00:15:48,250 هل نسيت الذاكرة المُحررة التي قمت بتخصيصها باستخدام malloc؟ 368 00:15:48,250 --> 00:15:51,580 ألقوا نظرة عن قرب على السطر 13 من memory.c. 369 00:15:51,580 --> 00:15:54,970 إذن في هذه الحالة، السطر 13 لديه بالفعل استدعاء إلى malloc. 370 00:15:54,970 --> 00:15:57,916 إذن كيف يمكن إصلاح هذه المشكلة؟ 371 00:15:57,916 --> 00:15:58,659 الجمهور: تحرير. 372 00:15:58,659 --> 00:16:00,700 ديفيد ج. مالان: حسب help50 أم ببديهتك الخاصة؟ 373 00:16:00,700 --> 00:16:02,715 ما الذي يتعين عليّ إضافته إلى هذا البرنامج؟ 374 00:16:02,715 --> 00:16:03,340 الجمهور: تحرير. 375 00:16:03,340 --> 00:16:03,570 الجمهور: تحرير. 376 00:16:03,570 --> 00:16:05,028 نعم، تحرير، وإلى أين يؤدي ذلك؟ 377 00:16:05,028 --> 00:16:07,640 378 00:16:07,640 --> 00:16:08,420 هنا بالضبط. 379 00:16:08,420 --> 00:16:11,690 إذن يمكننا تحرير الذاكرة. 380 00:16:11,690 --> 00:16:13,186 لماذا سيكون هذا سيئًا؟ 381 00:16:13,186 --> 00:16:17,040 الجمهور: [INAUDIBLE] 382 00:16:17,040 --> 00:16:18,040 ديفيد ج. مالان: بالضبط. 383 00:16:18,040 --> 00:16:20,260 نحن نحرر الذاكرة، كقولنا لنظام التشغيل، 384 00:16:20,260 --> 00:16:21,520 لا أحتاج ذلك بعد الآن. 385 00:16:21,520 --> 00:16:24,190 ومع ذلك، بعد سطرين فيما بعد سنستخدمه مرارًا وتكرارًا. 386 00:16:24,190 --> 00:16:24,940 سيئ جدًا. 387 00:16:24,940 --> 00:16:27,342 لم نفعل هذا الخطأ الأسبوع الماضي، ولكن يجب أن تحرروا فقط 388 00:16:27,342 --> 00:16:29,050 الذاكرة عندما تصبحون، حرفيًا، 389 00:16:29,050 --> 00:16:31,870 مستعدين لتحريرها وإعادتها مجددًا، والذي يجب أن يكون على الأرجح 390 00:16:31,870 --> 00:16:33,170 في نهاية البرنامج. 391 00:16:33,170 --> 00:16:36,580 إذن دعوني أمضي قدمًا وأعيد حفظ هذا، فتح، أعلى النافذة الطرفية، 392 00:16:36,580 --> 00:16:40,690 وأعيد تحويلها برمجيًا هذه المرة، والآن، دعوني أشغل Valgrind للمرة الأخيرة 393 00:16:40,690 --> 00:16:42,190 دون استخدام help50. 394 00:16:42,190 --> 00:16:47,070 وما يزال الأمر أكثر إطنابًا قليلاً، ولكنه بدون أخطاء، بدون سياقات. 395 00:16:47,070 --> 00:16:48,070 هذا يبدو جيدًا للغاية. 396 00:16:48,070 --> 00:16:52,599 وعلاوة على ذلك، فإنه أيضا يقول بوضوح، أنه تم تحرير جميع كتل الكومة. 397 00:16:52,599 --> 00:16:54,640 وتذكّروا أن الكومة، هي ذلك الجزء من الذاكرة 398 00:16:54,640 --> 00:16:58,300 الذي رسمناه بشكل مرئي هنا، حيثما يأخذ malloc الذاكرة منه. 399 00:16:58,300 --> 00:16:59,590 إذن، انتهينا. 400 00:16:59,590 --> 00:17:02,620 إذن هذه نوعًا من هي طريقة التفكير التي 401 00:17:02,620 --> 00:17:05,788 يجب وجودها عندما تتناول بها صحة تعليمتك البرمجية. 402 00:17:05,788 --> 00:17:08,829 على سبيل المثال، هي طريقة من طرق تشغيل نماذج مدخلات، أو تشغيل البرنامج كما فعلتُ. 403 00:17:08,829 --> 00:17:09,524 بدا كل شيء جيدًا. 404 00:17:09,524 --> 00:17:12,190 إنها طريقة من طرق تشغيل أدوات مثل check50، الذي كتبناه نحن البشر. 405 00:17:12,190 --> 00:17:15,148 ولكننا أيضًا عُرضة للخطأ، بالتأكيد، وقد لا نفكر في أي شيء. 406 00:17:15,148 --> 00:17:18,099 ولحسن الحظ، قام البشر الأذكياء بإنشاء الأدوات، التي تبدو من الوهلة الأولى، 407 00:17:18,099 --> 00:17:19,349 صعبة نوعًا ما لاستخدامها. 408 00:17:19,349 --> 00:17:21,849 مثل debug50، كما هو Valgrind الآن. 409 00:17:21,849 --> 00:17:24,910 ولكنها في نهاية المطاف تساعدك في جعل تعليمتك البرمجية صحيحة بنسبة 100٪ 410 00:17:24,910 --> 00:17:28,240 دون أن تضطر إلى أن تعاني بصريًا لمجرد التحديق في الشاشة. 411 00:17:28,240 --> 00:17:30,394 ونرى هذا كثيرًا في الساعات المكتبية، بصراحة. 412 00:17:30,394 --> 00:17:33,310 العديد من الطلاب، مع احترامهم، يستنتجون نوعًا ما من خلال، التحديق 413 00:17:33,310 --> 00:17:35,809 في الشاشة، فقط لمحاولة فهم ما الذي يحدث بشكل خاطىء، 414 00:17:35,809 --> 00:17:38,950 لكنهم لا يأخذون أي مدخل إضافي بخلاف الأحرف 415 00:17:38,950 --> 00:17:39,550 على الشاشة. 416 00:17:39,550 --> 00:17:43,360 لديك الكثير من الأدوات التي يمكن أن تمنحك الكثير والكثير من التلميحات على طول الطريق. 417 00:17:43,360 --> 00:17:46,510 لذلك اكتسب تلك الغرائز. 418 00:17:46,510 --> 00:17:48,340 أي أسئلة أخرى حول هذا؟ 419 00:17:48,340 --> 00:17:48,925 أجل؟ 420 00:17:48,925 --> 00:17:53,755 الحضور: سيدي، إذا كان لديك دالة main أخذت الوسيطات. 421 00:17:53,755 --> 00:17:57,254 هل ستقوم بتشغيل Valgrind باستخدام تلك الوسيطات أيضًا؟ 422 00:17:57,254 --> 00:17:58,420 ديفيد ج. مالان: نعم، بالفعل. 423 00:17:58,420 --> 00:18:02,080 إذن يعمل Valgrind تمامًا مثل debug50، تمامًا مثل help50. 424 00:18:02,080 --> 00:18:05,050 إذا كانت لديك وسيطات سطر أوامر، فقط قم بتشغيلها كالمعتاد، 425 00:18:05,050 --> 00:18:08,920 ولكن ابدأ الأمر الخاص بك باستخدام Valgrind، أو حتى باستخدام help50 Valgrind، 426 00:18:08,920 --> 00:18:10,090 لمساعدة واحدة باستخدام الأخرى. 427 00:18:10,090 --> 00:18:10,870 سؤال جيد. 428 00:18:10,870 --> 00:18:11,990 أي أفكار أخرى؟ 429 00:18:11,990 --> 00:18:12,490 نعم؟ 430 00:18:12,490 --> 00:18:14,406 الجمهور: إلى أين تنتقل البيانات [INAUDIBLE]؟ 431 00:18:14,406 --> 00:18:18,580 432 00:18:18,580 --> 00:18:19,830 ديفيد ج. مالان: سؤال جيد. 433 00:18:19,830 --> 00:18:21,830 إذن في نهاية اليوم، فكّروا في الشيء 434 00:18:21,830 --> 00:18:24,470 الموجود داخل جهاز الكمبيوتر، والذي يعتبر شيئًا ما كهذا تمامًا. 435 00:18:24,470 --> 00:18:26,510 لذا من الناحية المادية، من الواضح أنه ما زال هناك. 436 00:18:26,510 --> 00:18:29,420 إنها يتم التعامل معها فقط بواسطة نظام التشغيل-- 437 00:18:29,420 --> 00:18:32,840 Mac، نظام التشغيل، Windows، Linux، أيًا كان، يشبه تجمعًا في الذاكرة. 438 00:18:32,840 --> 00:18:36,420 نحن نستمر في رسمها كشبكة بحيث تبدو نوعًا ما كهذا. 439 00:18:36,420 --> 00:18:40,370 لذا مهمة أنظمة التشغيل هي فقط تعقب أي من هذه المربعات 440 00:18:40,370 --> 00:18:42,329 قيد الاستخدام، وذلك بفضل malloc. 441 00:18:42,329 --> 00:18:43,370 والذي تم تحريره. 442 00:18:43,370 --> 00:18:44,820 وهكذا يمكنك التفكير في الأمر على أن لديها علامات 443 00:18:44,820 --> 00:18:47,540 تحقق بجانبها لتقول إن، هذا قيد الاستخدام، هذا قيد الاستخدام، 444 00:18:47,540 --> 00:18:48,930 هؤلاء الآخرين ليسوا قيد الاستخدام. 445 00:18:48,930 --> 00:18:53,047 إذن عادوا فقط إلى ما يسمى بالقائمة الحرة في ذلك التجمع من الذاكرة. 446 00:18:53,047 --> 00:18:53,630 سؤال جيد. 447 00:18:53,630 --> 00:18:56,255 إذا كنت تأخذ دورة المستوى الأعلى حول أنظمة التشغيل في الواقع، 448 00:18:56,255 --> 00:19:00,630 أو CS61 أو 161 في جامعة هارفارد، فستبني بنفسك هذه الأشياء 449 00:19:00,630 --> 00:19:01,130 بالفعل. 450 00:19:01,130 --> 00:19:03,411 وتقوم بتنفيذ أدوات على سبيل المثال، malloc، بنفسك. 451 00:19:03,411 --> 00:19:03,910 أجل؟ 452 00:19:03,910 --> 00:19:07,160 الجمهور: إذن لماذا يجب أن نخصص ذاكرة في هذه الحالة، وما الذي يحدث 453 00:19:07,160 --> 00:19:07,661 [INAUDIBLE]؟ 454 00:19:07,661 --> 00:19:08,910 ديفيد ج. مالان: سؤال جيد. 455 00:19:08,910 --> 00:19:10,980 لماذا يجب أن نخصص ذاكرة في هذه الحالة؟ 456 00:19:10,980 --> 00:19:11,840 لم نفعل. 457 00:19:11,840 --> 00:19:14,810 كان هذا ببساطة، كما ذكرت، لأغراض التوضيح. 458 00:19:14,810 --> 00:19:16,910 إذا كانت لدينا بعض البرامج التي أردنا فيها 459 00:19:16,910 --> 00:19:20,860 تخصيص قدر من الذاكرة، لذا هذه هي الكيفية التي قد نقوم بها. 460 00:19:20,860 --> 00:19:24,320 ومع ذلك، أفضل طريقة للقيام بكل هذا، 461 00:19:24,320 --> 00:19:29,604 كانت بقول، مرحبًا، جهاز الكمبيوتر، أعطني 10 أعداد صحيحة هكذا، 462 00:19:29,604 --> 00:19:31,520 ولا داعي للقلق على إدارة الذاكرة. 463 00:19:31,520 --> 00:19:35,330 وهذه هي النقطة التي بدأنا منها في الأسبوع الأول، فقط باستخدام المصفوفات على المكدس، 464 00:19:35,330 --> 00:19:36,320 إذا جاز التعبير. 465 00:19:36,320 --> 00:19:37,560 ولم نستخدم malloc مطلقًا. 466 00:19:37,560 --> 00:19:40,670 إذن الفكرة فقط أنه، بمجرد أن تبدأ في استخدام malloc، ودالة free، 467 00:19:40,670 --> 00:19:43,760 والذاكرة بشكل عام، سيقع على عاتقك المزيد من المسؤوليات 468 00:19:43,760 --> 00:19:46,870 أكثر مما فعلنا في الأسبوع الأول. 469 00:19:46,870 --> 00:19:47,560 سؤال جيد. 470 00:19:47,560 --> 00:19:49,300 أي أسئلة أخرى؟ 471 00:19:49,300 --> 00:19:49,810 حسنًا. 472 00:19:49,810 --> 00:19:53,090 إذن، تبين أن، هناك أداة أخرى، بكل جدية. 473 00:19:53,090 --> 00:19:55,090 ها هي ذا. 474 00:19:55,090 --> 00:20:01,420 [? GDB50. ?] إذن debug50 هو إشارة إلى أداة شائعة جدًا، تسمى، GDB50، 475 00:20:01,420 --> 00:20:02,720 مصحح الأخطاء [؟ Gnu؟]. 476 00:20:02,720 --> 00:20:05,230 إنها الأداة الأقدم التي لن تستخدمها في سطر الأوامر، 477 00:20:05,230 --> 00:20:07,510 ولكنها تجعل debug50 تعمل. 478 00:20:07,510 --> 00:20:08,720 اتضح أنه، يوجد شيء. 479 00:20:08,720 --> 00:20:10,720 وهناك بالفعل مقال ويكيبيديا فعلي 480 00:20:10,720 --> 00:20:14,320 ربما قد فتحته في البريد الإلكتروني الخاص بي ليلة أمس، يطلق عليه تصحيح أخطاء البطة المطاطية. 481 00:20:14,320 --> 00:20:18,140 وبصراحة، لا يتعين عليك القيام بكل شيء، بشكل مفرط، كما فعلنا هنا، 482 00:20:18,140 --> 00:20:20,800 لكن الغرض من هذه التقنية، من برنامج تصحيح أخطاء البطة المطاطية، 483 00:20:20,800 --> 00:20:24,275 هو الحفاظ، حرفيًا، على البطة المطاطية على الرف لديك، أو على مكتبك. 484 00:20:24,275 --> 00:20:27,400 وعندما تواجه خطأ وليس لديك زميل تدريس، 485 00:20:27,400 --> 00:20:31,210 أو رفيق سكن حصل على دورة CS50، أو صديق فني آخر يمكنه مساعدتك في الانتقال 486 00:20:31,210 --> 00:20:34,450 خلال تعليمتك البرمجية، حرفيًا، فابدأ الانتقال خلال تعليمتك البرمجية 487 00:20:34,450 --> 00:20:39,410 حرفيًا، متحدثًا إلى البطة قائلاً، حسنًا، على السطر 2، أنا أعلن main، 488 00:20:39,410 --> 00:20:42,310 وعلى السطر 3، أقوم بتخصيص مساحة لمصفوفة. 489 00:20:42,310 --> 00:20:44,920 ثم، على السطر 4، أستدعي - آه! 490 00:20:44,920 --> 00:20:46,254 هذا ما أفعله بشكل خاطىء. 491 00:20:46,254 --> 00:20:49,420 إذن إذا كان أي منكم قد تعرّض لذلك، سواء في ساعات العمل، 492 00:20:49,420 --> 00:20:51,704 أو بمفردك، حيث تتحدث داخل عقلك، 493 00:20:51,704 --> 00:20:53,870 أو كنت تتحدث من خلال تعليمتك البرمجية إلى شخص آخر. 494 00:20:53,870 --> 00:20:55,661 وهنا، لا يتعين عليها الرد. 495 00:20:55,661 --> 00:21:01,150 أنت فقط تستمع إلى نفسك وأنت تقول الشيء الخاطئ، أو تتعرّض لذلك. 496 00:21:01,150 --> 00:21:05,110 يمكنك تقريب ذلك من خلال الاحتفاظ بواحدة من صغار البط تلك على مكتبك، 497 00:21:05,110 --> 00:21:06,310 والإبقاء على تلك المحادثة. 498 00:21:06,310 --> 00:21:09,310 ولا يبدو هذا جنونيًا كما هو في الواقع. 499 00:21:09,310 --> 00:21:12,040 إنه عبارة عن عملية تحدّث فقط خلال تعليمتك البرمجية بشكل منطقي، 500 00:21:12,040 --> 00:21:15,430 خطوة خطوة، وبطريقة لا يمكنك بالضرورة القيام بها داخل عقلك. 501 00:21:15,430 --> 00:21:16,570 على الأقل لا يمكنني. 502 00:21:16,570 --> 00:21:18,370 عندما تسمع نفسك وأنت تقول شيئًا خاطئًا، 503 00:21:18,370 --> 00:21:20,920 أو لا يمكنك اتباعها بشكل منطقي، وفجأة، يمكنك 504 00:21:20,920 --> 00:21:22,689 الحصول على ذلك في الواقع. 505 00:21:22,689 --> 00:21:25,480 إذن في نهاية اليوم، بكل الوسائل، خذ أيًا من صغار البط هذه. 506 00:21:25,480 --> 00:21:28,210 حيث استغرق ذلك وقتًا طويلاً من [? كولتن ?] لوضعها اليوم. 507 00:21:28,210 --> 00:21:31,810 وسيكون لدينا المزيد في ساعات العمل في الأسابيع المقبلة، إذا كنتم ترغبون في ذلك. 508 00:21:31,810 --> 00:21:35,680 إذن قد يتذكر البعض منكم تلك البطة من منزل [؟ كورير؟] 509 00:21:35,680 --> 00:21:38,840 العام الماضي أيضًا، والتي كانت ابنة عم لخاصته أيضًا. 510 00:21:38,840 --> 00:21:39,340 حسنًا. 511 00:21:39,340 --> 00:21:41,372 إذن هذا برنامج تصحيح أخطاء البطة المطاطية. 512 00:21:41,372 --> 00:21:44,080 الآن، الأسبوع الماضي، تذكرون أننا بدأنا في إخراج عجلات التدريب. 513 00:21:44,080 --> 00:21:46,132 التي كنا سنستخدمها لبضعة أسابيع، المكتبة CS50. 514 00:21:46,132 --> 00:21:47,590 ويبدو هذا من الماضي الآن. 515 00:21:47,590 --> 00:21:50,050 كانت هذه مجرد تقنية، أداة، عبرها 516 00:21:50,050 --> 00:21:53,200 يمكننا أن نحصل على مدخل المستخدم بطريقة أفضل، مما لو بدأنا بالفعل 517 00:21:53,200 --> 00:21:55,000 بالتعامل مع الذاكرة في وقت مبكر. 518 00:21:55,000 --> 00:21:58,180 وكشفنا الأسبوع الماضي أن "سلسة"، اقتباس، إنهاء الاقتباس، 519 00:21:58,180 --> 00:22:00,410 عبارة عن ماذا، أسفل الغطاء في لغة C؟ 520 00:22:00,410 --> 00:22:02,930 521 00:22:02,930 --> 00:22:04,390 قلها مجددًا. 522 00:22:04,390 --> 00:22:05,500 مصفوفة من الأحرف. 523 00:22:05,500 --> 00:22:10,780 وبصورة أكثر تحديدًا، إنها S-T-R-I-N-G مرادفة لأي نوع 524 00:22:10,780 --> 00:22:12,530 من البيانات بالفعل؟ 525 00:22:12,530 --> 00:22:14,170 char نجمة، كما أطلقنا عليها. 526 00:22:14,170 --> 00:22:16,960 إذن char نجمة هي مجرد طريقة يصف بها علماء الكمبيوتر 527 00:22:16,960 --> 00:22:19,420 مؤشرًا إلى حرف، 528 00:22:19,420 --> 00:22:21,790 أو بالأحرى عنوان حرف، وهي 529 00:22:21,790 --> 00:22:26,290 تعادل قول مصفوفة الذاكرة، أو تسلسل الذاكرة بشكل وظيفي. 530 00:22:26,290 --> 00:22:29,720 ولكنها طريقة فنية أكثر، وأكثر دقة لوصفها. 531 00:22:29,720 --> 00:22:33,460 ونعلم أن لدينا الآن char نجمة أسفل الغطاء، حسنًا، 532 00:22:33,460 --> 00:22:34,844 من أين يأتي كل هذا؟ 533 00:22:34,844 --> 00:22:36,760 حسنًا، في الحقيقة، يتم ربطه مباشرة بتلك الذاكرة. 534 00:22:36,760 --> 00:22:40,090 نستمر في الإشارة إلى أن شيئًا مثل هذا داخل جهاز الكمبيوتر الخاص بك. 535 00:22:40,090 --> 00:22:43,540 ويمكننا التفكير في الذاكرة باعتبارها مجرد أجزاء من الذاكرة، 536 00:22:43,540 --> 00:22:45,640 جميع وحدات البايت بها مرقمة. 537 00:22:45,640 --> 00:22:49,600 من 0 إلى 2 جيجابايت، أو 2 مليار، أيًا كانت القيمة. 538 00:22:49,600 --> 00:22:52,780 ولكن بالطبع الأسبوع الماضي، أشرنا إلى أنك تفكر في هذه الذاكرة 539 00:22:52,780 --> 00:22:56,709 ليس كجهاز في حد ذاتها، ولكن كمجموعة الذاكرة تلك التي 540 00:22:56,709 --> 00:22:58,000 تنقسم إلى مناطق مختلفة. 541 00:22:58,000 --> 00:23:00,770 الجزء العلوي من ذاكرة الكمبيوتر الخاص بك، إذا جاز التعبير، 542 00:23:00,770 --> 00:23:02,450 هو ما نطلق عليه جزء النص. 543 00:23:02,450 --> 00:23:05,560 وماذا يحدث في جزء النص من ذاكرة جهاز الكمبيوتر 544 00:23:05,560 --> 00:23:08,160 عندما تقوم بتشغيل برنامج؟ 545 00:23:08,160 --> 00:23:12,930 يبدو النص كاختيار ضعيف للكلمات، بصراحة، ولكن ما هو؟ 546 00:23:12,930 --> 00:23:13,556 قلها مجددًا. 547 00:23:13,556 --> 00:23:14,850 الجمهور: رؤوس الملفات؟ 548 00:23:14,850 --> 00:23:16,990 ديفيد ج. مالان: ليست رؤوس الملفات، في هذه الحالة. 549 00:23:16,990 --> 00:23:19,850 هذا في سياق تشغيل برنامج، وليس بالضرورة حفظ ملف. 550 00:23:19,850 --> 00:23:20,240 نعم؟ 551 00:23:20,240 --> 00:23:21,410 الجمهور: حرفية السلسلة. 552 00:23:21,410 --> 00:23:23,210 ديفيد ج. مالان: ليست حرفية السلسلة هنا، 553 00:23:23,210 --> 00:23:25,300 لكنها قريبة، بالفعل، في الذاكرة. 554 00:23:25,300 --> 00:23:26,180 الجمهور: الدوال. 555 00:23:26,180 --> 00:23:27,800 ديفيد ج. مالان: الدوال، اقتربنا. 556 00:23:27,800 --> 00:23:28,520 نعم. 557 00:23:28,520 --> 00:23:31,400 أين يوجد جزء النص من ذاكرة جهاز الكمبيوتر، 558 00:23:31,400 --> 00:23:33,950 عندما تنقر بشكل مزدوج فوق برنامج ليتم تشغيله، 559 00:23:33,950 --> 00:23:37,700 أو في Linux، عندما تكتب نقطة خط مائل شيئًا ما، ليتم تشغيله. 560 00:23:37,700 --> 00:23:41,360 حيث توجد أصفار وواحدات برنامجك الفعلي، التعليمة البرمجية الآلية، 561 00:23:41,360 --> 00:23:44,660 التي تحدثنا عنها في الأسبوع صفر، يتم تحميلها فقط في ذاكرة الوصول العشوائي. 562 00:23:44,660 --> 00:23:48,150 لذلك تذكرون أنه من الأسبوع الماضي، كما تعلمون، أي شيء مادي في هذا العالم-- 563 00:23:48,150 --> 00:23:51,170 محركات الأقراص الصلبة، محركات الأقراص ذات الحالة الصلبة، بطيء. 564 00:23:51,170 --> 00:23:55,100 لذا تلك الأجهزة بطيئة، ولكن ذاكرة الوصول العشوائي، والأشياء التي واصلنا سحبها على الشاشة، 565 00:23:55,100 --> 00:23:56,090 سريعة نسبيًا. 566 00:23:56,090 --> 00:23:57,770 إذا كانت فقط لا تحتوي على أجزاء متحركة. 567 00:23:57,770 --> 00:23:58,862 إنها إلكترونية تمامًا. 568 00:23:58,862 --> 00:24:01,070 إذن عند النقر المزدوج فوق برنامج على جهاز Mac أو الكمبيوتر الشخصي لديك، 569 00:24:01,070 --> 00:24:03,290 أو كتابة نقطة خط مائل شيء في Linux، الذي 570 00:24:03,290 --> 00:24:05,930 يتم تحميله من جهاز بطيء، محرك الأقراص الصلبة لديك، 571 00:24:05,930 --> 00:24:09,710 حيث يتم تخزين البيانات لمدة طويلة، في ذاكرة الوصول العشوائي أو الذاكرة، 572 00:24:09,710 --> 00:24:14,070 حيث يمكنها أن تعمل بسرعة أكبر بكثير وبصورة ممتعة من حيث الأداء. 573 00:24:14,070 --> 00:24:16,710 إذن، ماذا يعني هذا في الواقع لنا؟ 574 00:24:16,710 --> 00:24:18,050 حسنًا، لقد انتقلت إلى مكان ما. 575 00:24:18,050 --> 00:24:20,180 لقد قررنا، نحن البشر، فقط، منذ سنوات أنها 576 00:24:20,180 --> 00:24:22,760 ستنتقل إلى أعلى، إذا جاز التعبير، هذا الجزء من الذاكرة. 577 00:24:22,760 --> 00:24:25,910 وتوجد في الأسفل على الرغم من ذلك، المناطق الأكثر ديناميكية من الذاكرة-- 578 00:24:25,910 --> 00:24:27,530 المكدس والكومة. 579 00:24:27,530 --> 00:24:31,040 وقلنا هذا منذ لحظات، وفي الأسبوع الماضي كذلك، ما الذي يجري في الكومة؟ 580 00:24:31,040 --> 00:24:33,445 أو مَن يستخدم الكومة؟ 581 00:24:33,445 --> 00:24:34,720 الجمهور: الذاكرة الديناميكية. 582 00:24:34,720 --> 00:24:36,011 ديفيد ج. مالان: الذاكرة الديناميكية. 583 00:24:36,011 --> 00:24:38,740 أي وقت تستدعي malloc، فأنت تطلب من نظام التشغيل 584 00:24:38,740 --> 00:24:40,330 ذاكرة مما يطلق عليه الكومة. 585 00:24:40,330 --> 00:24:43,596 في أي وقت تستدعي دالة free، فأنت تقوم بإرجاعها مجددًا من الناحية النظرية. 586 00:24:43,596 --> 00:24:45,220 على سبيل المثال، هي لا تنتقل في الواقع إلى أي مكان. 587 00:24:45,220 --> 00:24:49,720 أنت تقوم فقط بتمييزها كمتاحة للمتغيرات والدوال الأخرى ليتم استخدامها. 588 00:24:49,720 --> 00:24:53,127 في الوقت نفسه، فيمَ يتم استخدام المكدس؟ 589 00:24:53,127 --> 00:24:54,210 الجمهور: المتغيرات المحلية. 590 00:24:54,210 --> 00:24:56,760 ديفيد ج. مالان: المتغيرات المحلية وأي من الدوال الخاصة بك. 591 00:24:56,760 --> 00:24:59,820 إذن main، تأخذ عادة شريحة من الذاكرة في الأسفل. 592 00:24:59,820 --> 00:25:03,240 إذا استدعت main دالة أخرى، فستحصل على شريحة من الذاكرة أعلى ذلك. 593 00:25:03,240 --> 00:25:06,260 إذا كانت هذه الدالة تستدعي واحدة أخرى، فستحصل على شريحة من الذاكرة أعلى ذلك. 594 00:25:06,260 --> 00:25:08,670 حتى يكون لكل منها مناطق مختلفة خاصة بها من الذاكرة. 595 00:25:08,670 --> 00:25:11,580 ولكن بالطبع، السهمان، يشيران إلى بعضهما البعض، 596 00:25:11,580 --> 00:25:13,740 لا يبدو هذا تصميمًا جيدًا. 597 00:25:13,740 --> 00:25:16,090 ولكن في الواقع، يمكن أن تحدث أشياء سيئة. 598 00:25:16,090 --> 00:25:20,460 يمكنك تخصيص الكثير من تلك الذاكرة، وفجأة، يتجاوز المكدس الكومة. 599 00:25:20,460 --> 00:25:22,530 أو تتجاوز الكومة المكدس. 600 00:25:22,530 --> 00:25:25,497 وهكذا تم إنشاء مواقع ويب مثل Stack Overflow، وما شابه ذلك. 601 00:25:25,497 --> 00:25:26,580 لكن ذلك واقع تمامًا. 602 00:25:26,580 --> 00:25:28,910 إذا كانت لديك كمية محدودة من الذاكرة، في مرحلة ما، 603 00:25:28,910 --> 00:25:30,180 سيتعطل شيء ما. 604 00:25:30,180 --> 00:25:32,824 أو سيتعين على الكمبيوتر قول، امم-امم، لا يوجد المزيد من الذاكرة. 605 00:25:32,824 --> 00:25:35,490 سيتعين عليك إنهاء بعض البرامج، أو إغلاق بعض الملفات، 606 00:25:35,490 --> 00:25:36,316 أو أي شيء. 607 00:25:36,316 --> 00:25:38,940 لذا كان هذا فقط لقول أن هذه هي الكيفية التي يتم وضع الذاكرة بها. 608 00:25:38,940 --> 00:25:42,330 وبدأنا في استكشاف هذا عن طريق بعض البرامج. 609 00:25:42,330 --> 00:25:44,520 هذا البرنامج الموجود هنا-- إنه داكن قليلاً هنا. 610 00:25:44,520 --> 00:25:46,940 وهذا الموجود هنا، كان دالة swap. 611 00:25:46,940 --> 00:25:48,000 الآن إنه داكن أكثر. 612 00:25:48,000 --> 00:25:54,480 كانت دالة swap في الواقع هي التي تبدّل بين القيمتين، A وB. 613 00:25:54,480 --> 00:25:57,120 لكنها في الواقع لم تعمل بالطريقة التي قصدناها. 614 00:25:57,120 --> 00:25:59,610 ما الذي تم تقسيمه في دالة swap تلك الأسبوع الماضي؟ 615 00:25:59,610 --> 00:26:02,390 616 00:26:02,390 --> 00:26:04,280 على سبيل المثال، أنا متأكد من أنها نجحت. 617 00:26:04,280 --> 00:26:08,030 وعندما صعدت متطوعتنا الشجاعة وبادلت عصير البرتقال والحليب، 618 00:26:08,030 --> 00:26:08,850 نجح الأمر. 619 00:26:08,850 --> 00:26:14,400 إذن، كان المنطق صحيحًا، ولكن البرنامج نفسه لم ينجح. 620 00:26:14,400 --> 00:26:14,970 لماذا؟ 621 00:26:14,970 --> 00:26:17,220 الجمهورر: لقد تغيرت قيم نُسخ المتغيرات. 622 00:26:17,220 --> 00:26:17,660 ديفيد ج. مالان: بالضبط. 623 00:26:17,660 --> 00:26:20,120 غيرت القيم في نُسخ المتغير. 624 00:26:20,120 --> 00:26:22,910 إذن تذكرون، أنه عندما كانت main الدالة 625 00:26:22,910 --> 00:26:26,900 التي استدعيناها، وكانت لديها قيمتان، x وy، كان ذلك الجزء من الذاكرة هنا. 626 00:26:26,900 --> 00:26:28,160 كان هذا الجزء من الذاكرة هنا. 627 00:26:28,160 --> 00:26:29,930 وكان به مثل الرقمين 1 و2. 628 00:26:29,930 --> 00:26:33,080 ولكن عندما استدعى دالة swap، التي حصلت على جزء الذاكرة الخاصة بها. 629 00:26:33,080 --> 00:26:35,930 لذا كانت main في الأسفل، وكانت دالة swap أعلى ذلك. 630 00:26:35,930 --> 00:26:38,480 ولديها أجزاء الذاكرة الخاصة بها والتي يطلق عليها، a وb، والتي 631 00:26:38,480 --> 00:26:40,430 حصلت، في البداية على القيمتين 1 و2. 632 00:26:40,430 --> 00:26:42,230 تمت مبادلة 1 و2 بالفعل بنجاح، 633 00:26:42,230 --> 00:26:44,930 ولكن هذا لم يؤثر على x وy. 634 00:26:44,930 --> 00:26:45,797 لذا قمنا بإصلاح ذلك. 635 00:26:45,797 --> 00:26:47,880 مع الإصدار الأحدث من هذا البرنامج، بالطبع، 636 00:26:47,880 --> 00:26:50,960 بدا مشفرًا أكثر للوهلة الأولى، ولكن في اللغة الإنجليزية، 637 00:26:50,960 --> 00:26:53,780 هل يمكن أن يصف شخص ما تحديدًا ما يحدث 638 00:26:53,780 --> 00:26:56,460 في هذا المثال الذي كان صحيحًا بدرجة أكبر؟ 639 00:26:56,460 --> 00:26:58,500 على سبيل المثال، ما الذي يفعله هذا البرنامج سطرًا بسطر؟ 640 00:26:58,500 --> 00:26:59,000 نعم؟ 641 00:26:59,000 --> 00:27:01,208 الجمهور: بدلاً من تمرير نُسخ المتغيرات، 642 00:27:01,208 --> 00:27:03,100 تقوم بتمرير المؤشرات إلى عناوينها. 643 00:27:03,100 --> 00:27:04,100 ديفيد ج. مالان: بالضبط. 644 00:27:04,100 --> 00:27:06,975 بدلاً من تمرير قيم المتغيرات، وبالتالي نسخها، 645 00:27:06,975 --> 00:27:09,420 إنها تقوم بتمرير عناوين تلك المتغيرات. 646 00:27:09,420 --> 00:27:13,110 لذا هذا يبدو مثل قول، لا يهمني من الناحية الفنية مكانها في الذاكرة، 647 00:27:13,110 --> 00:27:15,660 ولكن أحتاج إلى أن أعرف أنها في مكان ما في الذاكرة. 648 00:27:15,660 --> 00:27:18,300 لذا بدلاً من تمرير x في الرقم 1، 649 00:27:18,300 --> 00:27:20,600 لنفترض أن x في الموقع 100-- 650 00:27:20,600 --> 00:27:21,961 دعوني أنتقل إلى مثال. 651 00:27:21,961 --> 00:27:24,210 إنه في الواقع الرقم 100 الذي سنضعه هناك. 652 00:27:24,210 --> 00:27:27,460 وإذا كان y فى الموقع على سبيل المثال، 104، حسنًا، فإن 653 00:27:27,460 --> 00:27:31,220 104 هو الرقم الذي سنضعه هناك، وهو ليس القيمة التي نريد تبديلها، 654 00:27:31,220 --> 00:27:34,370 لكن هذه بمثابة خريطة صغيرة أو تتبع للآثار إذا صح التعبير، 655 00:27:34,370 --> 00:27:36,550 التي تقودنا إلى الموقع الصحيح. 656 00:27:36,550 --> 00:27:39,380 حتى عندما ننفذ تلك التعليمات البرمجية، التي نبدلها فى النهاية 657 00:27:39,380 --> 00:27:43,410 في السطور الثلاثة تلك، وهي هذا وهذا، وجميعها على طول الطريق، 658 00:27:43,410 --> 00:27:45,740 تذكرون، أننا نستخدم متغيرًا مؤقتًا هناك 659 00:27:45,740 --> 00:27:48,050 يمكننا الاستغناء عنه بعد ذلك. 660 00:27:48,050 --> 00:27:50,090 لذا هذا ما تتيحه لنا المؤشرات للقيام به. 661 00:27:50,090 --> 00:27:54,110 و هذا ما يتيح لنا تغيير القيم بالفعل على ما يسمى بالمكدس، 662 00:27:54,110 --> 00:27:58,890 حتى باستدعاء دالة أخرى. 663 00:27:58,890 --> 00:27:59,390 حسنًا. 664 00:27:59,390 --> 00:28:05,540 أي أسئلة لاحقًا، بشأن مكان توقفنا في المرة السابقة عند حديثنا عن المكدس والمبادلة؟ 665 00:28:05,540 --> 00:28:07,270 لا؟ 666 00:28:07,270 --> 00:28:07,770 حسنًا. 667 00:28:07,770 --> 00:28:11,940 إذن تذكرون أننا قدمنا بينكي أيضًا الذي فقد رأسه عند نقطة معينة، 668 00:28:11,940 --> 00:28:13,140 لكن لماذا؟ 669 00:28:13,140 --> 00:28:16,552 ما الخطأ المروع الذي حدث، وانحرف بصورة مروعة في هذا المشهد من فيلم الأسبوع الماضي 670 00:28:16,552 --> 00:28:17,135 من ستانفورد؟ 671 00:28:17,135 --> 00:28:20,297 672 00:28:20,297 --> 00:28:22,130 كان بينكي يقوم بكل شيء على نحو صحيح، أليس كذلك؟ 673 00:28:22,130 --> 00:28:23,140 مثل، تحريك القيم. 674 00:28:23,140 --> 00:28:24,700 كان 42 ناجحًا. 675 00:28:24,700 --> 00:28:25,619 ومن ثم، أجل؟ 676 00:28:25,619 --> 00:28:27,618 الجمهور: حاول القيام بالإسناد المؤشري لشيء 677 00:28:27,618 --> 00:28:31,500 لم يكن يشير إلى أي عنوان حقيقي. 678 00:28:31,500 --> 00:28:32,500 ديفيد ج. مالان: بالضبط. 679 00:28:32,500 --> 00:28:36,400 حاول القيام بالإسناد المؤشري لمؤشر، لعنوان، لم يكن يشير بالفعل 680 00:28:36,400 --> 00:28:37,630 إلى عنوان صالح. 681 00:28:37,630 --> 00:28:41,560 تذكرون أن هذا كان هو السطر الموجود في التعليمة البرمجية المطلوبة والذي كان سيئًا وغير موفق. 682 00:28:41,560 --> 00:28:45,310 نجمة y، تعني، انتقل إلى العنوان في y، وقم بشيء ما له. 683 00:28:45,310 --> 00:28:47,380 قم بتعيينه ليصبح معادلاً للرقم 13. 684 00:28:47,380 --> 00:28:50,680 ولكن كانت المشكلة، في التعليمة البرمجية، التي تحدثنا عنها الأسبوع الماضي 685 00:28:50,680 --> 00:28:54,550 أن كل ما فعلناه في البداية كان قول مرحبًا، جهاز الكمبيوتر أعطني مؤشرًا لعدد صحيح، 686 00:28:54,550 --> 00:28:55,810 وأطلق عليه x. 687 00:28:55,810 --> 00:28:58,070 قم بنفس الأمر، وأطلق عليه y. 688 00:28:58,070 --> 00:29:02,320 خصّص مساحة وضَع x فيها. 689 00:29:02,320 --> 00:29:04,450 لكننا لم نقم بالأمر نفسه لـ y. 690 00:29:04,450 --> 00:29:08,860 إذن في حين تضمن x، الأسبوع الماضي، عنوان جزء حقيقى من الذاكرة، 691 00:29:08,860 --> 00:29:12,640 بفضل malloc، ما الذي يتضمنه y في تلك المرحلة من القصة؟ 692 00:29:12,640 --> 00:29:13,670 السطر الأصفر هناك. 693 00:29:13,670 --> 00:29:16,290 694 00:29:16,290 --> 00:29:17,276 ما الذي يتضمنه y؟ 695 00:29:17,276 --> 00:29:17,775 أي قيمة؟ 696 00:29:17,775 --> 00:29:21,886 697 00:29:21,886 --> 00:29:22,850 الجمهور: فارغ. 698 00:29:22,850 --> 00:29:23,730 ديفيد ج. مالان: فارغ. 699 00:29:23,730 --> 00:29:24,711 ربما. 700 00:29:24,711 --> 00:29:25,210 ربما. 701 00:29:25,210 --> 00:29:28,509 لكنه ليس واضحًا لعدم الإشارة إلى فارغ في البرنامج. 702 00:29:28,509 --> 00:29:29,300 قد نكون محظوظين. 703 00:29:29,300 --> 00:29:30,640 فارغ هو فقط 0. 704 00:29:30,640 --> 00:29:33,760 وأحيانًا نرى أن 0 هو القيم الافتراضية في برنامج. 705 00:29:33,760 --> 00:29:34,560 إذن ربما. 706 00:29:34,560 --> 00:29:37,941 لكن أنا أقول، ربما، وأنا أحاول إعطاء إجابة قاطعة عن السبب. 707 00:29:37,941 --> 00:29:39,435 الجمهور: [INAUDIBLE]. 708 00:29:39,435 --> 00:29:40,310 ديفيد ج. مالان: حسنًا. 709 00:29:40,310 --> 00:29:42,700 و لم تقم بتخصيصه-- حسنًا، تخصيص، ليست الكلمة الصحيحة تمامًا. 710 00:29:42,700 --> 00:29:44,658 هذا يقترح أنك قمت بتخصيص الذاكرة الفعلية. 711 00:29:44,658 --> 00:29:45,790 إنها قيمة ضئيلة. 712 00:29:45,790 --> 00:29:46,810 يوجد شيء ما هناك. 713 00:29:46,810 --> 00:29:47,020 أليس كذلك؟ 714 00:29:47,020 --> 00:29:48,687 تم تشغيل جهاز Mac الخاص بي لبضع ساعات. 715 00:29:48,687 --> 00:29:51,603 ومن المحتمل أن تعمل أجهزة Mac، وأجهزة الكمبيوتر الشخصي، والهواتف الخاصة بكم، طوال اليوم. 716 00:29:51,603 --> 00:29:52,990 أو بالتأكيد عندما يكون الغطاء مفتوحًا. 717 00:29:52,990 --> 00:29:55,930 وهكذا، يتم استخدام الذاكرة وإلغاء استخدامها، واستخدامها. 718 00:29:55,930 --> 00:29:57,530 على سبيل المثال، تحدث أشياء كثيرة. 719 00:29:57,530 --> 00:30:00,567 إذن لم تتم تعبئة جهاز الكمبيوتر الخاص بك بجميع الأصفار والواحدات. 720 00:30:00,567 --> 00:30:02,650 إذا نظرت إليها في بعض المراحل العشوائية في اليوم، 721 00:30:02,650 --> 00:30:05,290 إنها ممتلئة بمجموعات ومجموعات من الأصفار والواحدات 722 00:30:05,290 --> 00:30:07,840 من البرامج السابقة التي خرجت منها منذ فترة طويلة. 723 00:30:07,840 --> 00:30:09,889 النوافذ الموجودة لديك فى الخلفية وما شابه ذلك. 724 00:30:09,889 --> 00:30:11,680 إذن، اختصارًا لها، عندما تقوم بتشغيل 725 00:30:11,680 --> 00:30:15,271 برنامج للمرة الأولى، ويتم تشغيله الآن لبعض الوقت، 726 00:30:15,271 --> 00:30:16,270 سيصبح فوضويًا. 727 00:30:16,270 --> 00:30:18,978 سيكون بهذا المستطيل الكبير من الذاكرة هنا بعض الواحدات 728 00:30:18,978 --> 00:30:21,350 وبعض الأصفار هنا والعكس. 729 00:30:21,350 --> 00:30:26,300 لذلك هي قيم ضئيلة، لأن وحدات البايت هذه بها بعض القيم. 730 00:30:26,300 --> 00:30:28,400 أنت لا تعرف بالضرورة ماهيتها. 731 00:30:28,400 --> 00:30:31,630 إذن النقطة هي، لا يجب أن تقوم بالإسناد المؤشري أبدًا لمؤشر 732 00:30:31,630 --> 00:30:33,940 لم تقم بتعيينه بنفسك. 733 00:30:33,940 --> 00:30:35,080 قد يتعطل. 734 00:30:35,080 --> 00:30:36,010 وقد لا يتعطل. 735 00:30:36,010 --> 00:30:38,830 يمكن أن يساعدك Valgrind في إيجاد تلك الأشياء ولكن يتم ذلك أحيانًا. 736 00:30:38,830 --> 00:30:41,800 لكنها ليست عملية آمنة فقط. 737 00:30:41,800 --> 00:30:43,949 وأخيرًا، كان آخر شيء قدمناه الأسبوع الماضي، 738 00:30:43,949 --> 00:30:46,990 والذي سيكون ركيزة للمشاكل التي سنقوم بحلها هذا الأسبوع، 739 00:30:46,990 --> 00:30:47,880 هو struct. 740 00:30:47,880 --> 00:30:52,540 إذن struct نوعًا ما رائع، حيث يمكنك تصميم بنيات بياناتك 741 00:30:52,540 --> 00:30:53,410 المخصصة. 742 00:30:53,410 --> 00:30:55,630 تبدو لغة C محدودة للغاية خارج الصندوق، إذا جاز التعبير. 743 00:30:55,630 --> 00:30:59,500 لديك فقط chars وpools، وfloats، وints، وdoubles، 744 00:30:59,500 --> 00:31:00,730 وlongs، وstr-- 745 00:31:00,730 --> 00:31:02,439 حسنًا، ليس لدينا سلاسل، في حد ذاتها. 746 00:31:02,439 --> 00:31:05,479 لذا فهي لا تأتي بميزات كثيرة بالفعل، كالكثير من اللغات. 747 00:31:05,479 --> 00:31:07,720 مثل Python، والتي سنراها في غضون بضعة أسابيع. 748 00:31:07,720 --> 00:31:09,970 إذن باستخدام struct في لغة C، لديك القدرة على 749 00:31:09,970 --> 00:31:11,680 حل بعض المشاكل الخاصة بك. 750 00:31:11,680 --> 00:31:15,460 على سبيل المثال، باستخدام struct، يمكننا بالفعل 751 00:31:15,460 --> 00:31:19,110 البدء في تنفيذ الميزات الخاصة بنا. 752 00:31:19,110 --> 00:31:20,260 أو أنواع البيانات الخاصة بنا. 753 00:31:20,260 --> 00:31:22,010 على سبيل المثال، دعوني أنتقل إلى الأعلى هنا. 754 00:31:22,010 --> 00:31:25,510 ودعوني أمضي قدمًا وأقوم بإنشاء ملف يسمى مثلاً، 755 00:31:25,510 --> 00:31:28,540 student، أو بالأحرى struct نقطة h. 756 00:31:28,540 --> 00:31:30,430 إذن تذكرون أن نقطة h هو ملف رأس. 757 00:31:30,430 --> 00:31:33,200 حتى الآن، كنتم تستخدمون ملفات الرأس التي قام أشخاص آخرون بإنشائها. 758 00:31:33,200 --> 00:31:36,850 مثل، CS50 نقطة h، وstandard IO نقطة h، وstandard [? lid ?] نقطة h، 759 00:31:36,850 --> 00:31:38,080 لكن يمكنكم إنشاء واحد لكم. 760 00:31:38,080 --> 00:31:41,380 ملفات الرأس هي مجرد ملفات تحتوي عادةً على تعليمات برمجية 761 00:31:41,380 --> 00:31:43,450 ترغب في مشاركتها عبر برامج متعددة. 762 00:31:43,450 --> 00:31:45,169 وسنرى المزيد من ذلك في الوقت المناسب. 763 00:31:45,169 --> 00:31:46,960 لذا دعوني أمضي قدمًا وأقوم فقط بحفظ هذا الملف. 764 00:31:46,960 --> 00:31:50,890 ولنفترض أنني أريد تمثيل طالب في الذاكرة. 765 00:31:50,890 --> 00:31:54,880 فإن الطالب بالطبع، من المحتمل أن يكون لديه ماذا؟ 766 00:31:54,880 --> 00:31:59,640 على سبيل المثال، ماذا عن سلسلة لاسمه، 767 00:31:59,640 --> 00:32:02,650 سلسلة لسكنه-- ولكن السلسلة منذ أسبوعين تقريبًا. 768 00:32:02,650 --> 00:32:04,630 دعونا نسمي هذا char نجمة. 769 00:32:04,630 --> 00:32:07,720 ودعونا نطلق عليه اسم، char نجمة. 770 00:32:07,720 --> 00:32:11,150 لذا قد ترغب في الربط هكذا، قطع بيانات متعددة مع الطلاب. 771 00:32:11,150 --> 00:32:11,650 أليس كذلك؟ 772 00:32:11,650 --> 00:32:13,280 ولا ترغب في أن يكون لديك متغيرات متعددة، في حد ذاتها. 773 00:32:13,280 --> 00:32:14,830 سيكون من الجيد تغليف هذه معًا. 774 00:32:14,830 --> 00:32:16,900 وتذكروا أننا في نهاية الأسبوع الماضي قد 775 00:32:16,900 --> 00:32:20,680 شاهدنا هذه الميزة حيث يمكنكم تحديد النوع الخاص بكم، 776 00:32:20,680 --> 00:32:23,920 باستخدام typedef، والذي يمثل بنية بنفسها. 777 00:32:23,920 --> 00:32:25,340 ويمكنكم إطلاق اسم عليه. 778 00:32:25,340 --> 00:32:29,060 لذا باختصار، وببساطة بتنفيذ سطور التعليمة البرمجية هذه، 779 00:32:29,060 --> 00:32:31,060 قمتم بإنشاء نوع البيانات المخصصة الخاصة بكم للتو. 780 00:32:31,060 --> 00:32:32,410 والتي تسمى student الآن. 781 00:32:32,410 --> 00:32:36,340 ويجب أن يكون لدى كل طالب في العالم، حسب هذه التعليمة البرمجية، اسم 782 00:32:36,340 --> 00:32:38,090 وسكن مرتبطان به. 783 00:32:38,090 --> 00:32:39,170 الآن، لماذا يعدّ هذا مفيدًا؟ 784 00:32:39,170 --> 00:32:42,250 حسنًا البرنامج، الذي نظرنا إليه في نهاية المرة السابقة ظهر 785 00:32:42,250 --> 00:32:43,830 شيئًا صغيرًا كهذا. 786 00:32:43,830 --> 00:32:48,730 Instruct0 نقطة c، كان لدينا ما يلي، 787 00:32:48,730 --> 00:32:52,016 أنا أولاً قمت بتخصيص مقدار من المساحة للطالب. 788 00:32:52,016 --> 00:32:54,640 سألتُ المستخدم ما هو التسجيل في الصف أو ما هو غير ذلك؟ 789 00:32:54,640 --> 00:32:56,020 ويعطينا هذا عددًا صحيحًا. 790 00:32:56,020 --> 00:33:01,910 ومن ثم، قمنا بتخصيص مصفوفة من النوع student، تسمى students، جمع. 791 00:33:01,910 --> 00:33:04,600 كان هذا بديلاً، تذكرون، للقيام بشيء ما 792 00:33:04,600 --> 00:33:10,270 كهذا، string names enrollment، وstring dorms enrollment. 793 00:33:10,270 --> 00:33:11,200 أيهما سينجح. 794 00:33:11,200 --> 00:33:13,283 يمكن أن تكون لديك مصفوفتان منفصلتان، ويجب عليك فقط 795 00:33:13,283 --> 00:33:17,170 أن تتذكر الاسم صفر أو المسكن صفر هو نفس الشخص. 796 00:33:17,170 --> 00:33:19,490 ولكن لماذا تقوم بذلك إذا كان بإمكانك الاحتفاظ بالأشياء معًا. 797 00:33:19,490 --> 00:33:21,610 إذن باستخدام structs، تمكننّا من القيام بذلك. 798 00:33:21,610 --> 00:33:27,250 أعطني العديد من بنيات الطلاب، وأطلق على المصفوفة كاملة اسم students. 799 00:33:27,250 --> 00:33:34,460 والصيغة الجديدة الوحيدة التي نقدمها لتحقيق هذا الهدف، كانت أي مُشغل؟ 800 00:33:34,460 --> 00:33:35,356 الجمهور: النقطة. 801 00:33:35,356 --> 00:33:36,356 ديفيد ج. مالان: النقطة. 802 00:33:36,356 --> 00:33:36,856 أجل. 803 00:33:36,856 --> 00:33:40,090 لذا في الماضي، تذكرون أننا منذ أسبوعين تقريبًا، قدمنا ​​المصفوفات. 804 00:33:40,090 --> 00:33:42,280 وتتيح لك المصفوفات القيام بتدوين الأقواس المربعة. 805 00:33:42,280 --> 00:33:45,490 لذا هذا لا يختلف عمّا حدث في الأسبوعين الماضيين. 806 00:33:45,490 --> 00:33:49,450 لكن إذا لم تخزِّن مصفوفتك الأعداد الصحيحة أو الأحرف أو القيم الكسرية فقط، 807 00:33:49,450 --> 00:33:53,080 أو أيًا كان، فإنها تخزِّن بالفعل بنية، مثل student، 808 00:33:53,080 --> 00:33:57,400 يمكنك الحصول على اسم ذلك الطالب حرفيًا بقول نقطة name فقط. 809 00:33:57,400 --> 00:33:59,999 ويمكنك الحصول على مسكنه من خلال القيام بكتابة نقطة dorm. 810 00:33:59,999 --> 00:34:01,540 ومن ثم أي شيء آخر على نفس الحال. 811 00:34:01,540 --> 00:34:03,190 وهذا ما يسمى، التغليف. 812 00:34:03,190 --> 00:34:05,690 وهو يعتبر نوعًا ما كمبدأ أساسي في البرمجة 813 00:34:05,690 --> 00:34:08,949 وفيه، إذا كان لديك كيان ما في العالم الحقيقي، مثل طالب، 814 00:34:08,949 --> 00:34:11,800 وتريد تمثيل طلاب باستخدام التعليمة البرمجية، أجل، 815 00:34:11,800 --> 00:34:16,659 فيمكن أن تكون لديك مجموعة من المصفوفات التي أطلق عليها جميعًا أسماء، مساكن، عناوين بريد إلكتروني، أرقام 816 00:34:16,659 --> 00:34:18,159 هواتف، لكن يصبح هذا فوضويًا تمامًا. 817 00:34:18,159 --> 00:34:22,150 يمكنك بدلاً من ذلك تغليف كل تلك المعلومات ذات الصلة حول طالب 818 00:34:22,150 --> 00:34:27,310 في بنية بيانات واحدة بحيث يكون لديك الآن، حسب الأسبوع صفر، تجريد. 819 00:34:27,310 --> 00:34:30,050 على سبيل المثال، الطالب هو تعبير تجريدي. 820 00:34:30,050 --> 00:34:34,150 وإذا ما كسرنا هذا التجريد، فما هو الطالب في الواقع؟ 821 00:34:34,150 --> 00:34:37,830 ليس في العالم الحقيقي، لكن في عالم التعليمات البرمجية الخاص بنا هنا؟ 822 00:34:37,830 --> 00:34:39,010 الطالب هو تعبير تجريدي. 823 00:34:39,010 --> 00:34:41,909 إنها كلمة مفيدة، يمكن لنا جميعًا تقريبًا التوافق على أنها تعني شيئًا ما، 824 00:34:41,909 --> 00:34:45,810 لكن من الناحية الفنية، ماذا يعني هذا بوضوح؟ 825 00:34:45,810 --> 00:34:48,989 الطالب هو في الواقع اسم في مسكن، وهو في الواقع نوعًا ما 826 00:34:48,989 --> 00:34:52,409 صغير بالنسبة للجميع في هذه الغرفة، ولكننا قمنا باستخلاصه في التعليمة البرمجية 827 00:34:52,409 --> 00:34:53,999 لتلك القيمتين فقط. 828 00:34:53,999 --> 00:34:55,290 لذا لدينا هنا تغليف. 829 00:34:55,290 --> 00:34:57,656 تقوم تقريبًا بتغليف قيم متعددة معًا. 830 00:34:57,656 --> 00:35:00,030 وتقوم بالتجريد ليكون لديك فقط مصطلح أكثر فائدة، 831 00:35:00,030 --> 00:35:02,790 لأنه لا أحد سيرغب في التحدّث في مصطلحات سطور التعليمة البرمجية 832 00:35:02,790 --> 00:35:04,200 لوصف أي شيء. 833 00:35:04,200 --> 00:35:05,590 لذا، نفس الموضوع كما حدث في الماضي. 834 00:35:05,590 --> 00:35:10,020 لذا، لدينا الآن القدرة على التوصل إلى بنيات البيانات المخصصة الخاصة بنا 835 00:35:10,020 --> 00:35:10,710 كما تبدو. 836 00:35:10,710 --> 00:35:13,330 يمكننا تخزين أي شيء نريده داخلها. 837 00:35:13,330 --> 00:35:16,860 لذا دعونا نرى الآن كيف قمنا بتصميم 838 00:35:16,860 --> 00:35:19,360 بعض الأشياء بشكل رديء في الأسابيع القليلة الماضية. 839 00:35:19,360 --> 00:35:22,830 لذا يتضح أن معظم التعليمات البرمجية، التي آمل 840 00:35:22,830 --> 00:35:25,210 أننا كتبناها في الأسابيع الأخيرة بطريقة صحيحة، 841 00:35:25,210 --> 00:35:28,954 لكننا لم نصمم بالضرورة حلولاً بطريقة أفضل. 842 00:35:28,954 --> 00:35:30,870 تذكرون أنه عندما يكون لدينا هذا الجزء من الذاكرة، 843 00:35:30,870 --> 00:35:34,150 فإننا تعاملنا تمامًا معه في الغالب، كمصفوفة. 844 00:35:34,150 --> 00:35:35,700 لذا جزء من الذاكرة متجاور فقط. 845 00:35:35,700 --> 00:35:39,450 وبفضل هذا النموذج العقلي البسيط جدًا، نحصل على السلاسل، 846 00:35:39,450 --> 00:35:42,210 نحصل على مصفوفات الطلاب الآن. 847 00:35:42,210 --> 00:35:45,960 ولكن المصفوفات ليست بالضرورة بنية البيانات الأفضل في العالم. 848 00:35:45,960 --> 00:35:49,800 على سبيل المثال، ما هو الجانب السلبي لمصفوفة إذا واجهتها حتى الآن. 849 00:35:49,800 --> 00:35:52,430 850 00:35:52,430 --> 00:35:54,770 في لغة C، ما هو الجانب السلبي للمصفوفة؟ 851 00:35:54,770 --> 00:35:55,760 أجل؟ 852 00:35:55,760 --> 00:35:58,230 الجمهور: [INAUDIBLE]. 853 00:35:58,230 --> 00:35:59,480 ديفيد ج. مالان: هل يمكن أم لا يمكن؟ 854 00:35:59,480 --> 00:36:00,010 الجمهور: لا يمكن. 855 00:36:00,010 --> 00:36:00,680 ديفيد ج. مالان: لا يمكنك. 856 00:36:00,680 --> 00:36:01,440 هذا صحيح. 857 00:36:01,440 --> 00:36:05,690 إذن في لغة C، لا يمكنك خلط أنواع البيانات داخل مصفوفة. 858 00:36:05,690 --> 00:36:09,907 يجب أن تكون جميعها أعداد صحيحة، يجب أن تكون جميعها أحرفًا، يجب أن تكون جميعها طلابًا. 859 00:36:09,907 --> 00:36:11,990 إنها كذبة بيضاء لأنه من الناحية الفنية، يمكنك 860 00:36:11,990 --> 00:36:15,320 الحصول على شيء ما يسمى void star، ويمكنك بالفعل الربط-- لكن أجل. 861 00:36:15,320 --> 00:36:18,161 على الرغم من أن ذلك صحيح، وعلى وجه التحديد-- لا يمكن خلط أنواع البيانات. 862 00:36:18,161 --> 00:36:20,660 بصراحة، حتى على الرغم أن بعض اللغات الأخرى تتيح لك القيام بذلك، 863 00:36:20,660 --> 00:36:22,580 فهي ليست بالضرورة أفضل قرار تصميم. 864 00:36:22,580 --> 00:36:23,540 لكن بالتأكيد، إنها حد. 865 00:36:23,540 --> 00:36:24,190 أفكار أخرى. 866 00:36:24,190 --> 00:36:24,734 أجل؟ 867 00:36:24,734 --> 00:36:26,110 الجمهور: لا يمكن تغيير الحجم. 868 00:36:26,110 --> 00:36:27,734 ديفيد ج. مالان: لا يمكن تغيير الحجم. 869 00:36:27,734 --> 00:36:28,760 دعونا نركز على هذا. 870 00:36:28,760 --> 00:36:32,240 لأن هذا نوع من الحد بشكل أكبر مما يبدو. 871 00:36:32,240 --> 00:36:37,010 لذا إذا كنت تريد مصفوفة من أجل، لنقل، قيمتين، فما الذي ستقوم به؟ 872 00:36:37,010 --> 00:36:41,744 حسنًا، يمكنك القيام بشيء مثل int، x، قوس، 2، فاصلة منقوطة. 873 00:36:41,744 --> 00:36:44,660 وما الذي سيعطيه لك ذلك بالفعل داخل ذاكرة جهاز الكمبيوتر الخاص بك؟ 874 00:36:44,660 --> 00:36:47,600 سيعطيك جزءًا ما سنقوم برسمه كمستطيل. 875 00:36:47,600 --> 00:36:48,850 هذا هو الموقع 0. 876 00:36:48,850 --> 00:36:49,900 هذا هو الموقع 1. 877 00:36:49,900 --> 00:36:52,400 لنفترض أنك، أوه، بعد بضع دقائق، غيرتَ رأيك. 878 00:36:52,400 --> 00:36:54,215 أوه، لقد أخذتُ للتو-- 879 00:36:54,215 --> 00:36:56,480 أريد الكتابة في قيمة ثالثة، أو أريد 880 00:36:56,480 --> 00:36:58,430 إضافة طالب آخر إلى المصفوفة. 881 00:36:58,430 --> 00:37:00,230 أين ستضع هذا؟ 882 00:37:00,230 --> 00:37:01,550 حسنًا، لن تفعل. 883 00:37:01,550 --> 00:37:04,490 إذا كنت ترغب في إضافة قيمة ثالثة إلى مصفوفة من الحجم 2، 884 00:37:04,490 --> 00:37:06,900 فما هو خيارك الوحيد في لغة C؟ 885 00:37:06,900 --> 00:37:08,380 الجمهور: إنشاء مصفوفة جديدة. 886 00:37:08,380 --> 00:37:09,280 ديفيد ج. مالان: ستقوم بإنشاء مصفوفة جديدة. 887 00:37:09,280 --> 00:37:09,940 هكذا حرفيًا. 888 00:37:09,940 --> 00:37:13,150 وإذا كانت المصفوفة تحتوي على رقم مثل 42، 889 00:37:13,150 --> 00:37:17,260 وهذه تحتوي على الرقم 13، فإن الطريقة الوحيدة لإضافة رقم ثالث هو تخصيص 890 00:37:17,260 --> 00:37:23,780 مصفوفة ثانية، ونسخ القيم إلى نفس الموقعين، 42، 13، وبعد ذلك، 891 00:37:23,780 --> 00:37:25,390 سنقوم بإضافة قيمة أخرى، 50. 892 00:37:25,390 --> 00:37:28,150 ومن ثم، حتى لا تستخدم ما يزيد عن ضعفي المساحة 893 00:37:28,150 --> 00:37:31,630 بشكل دائم تقريبًا، الآن تستطيع التحرر بطريقة ما تقريبًا، 894 00:37:31,630 --> 00:37:33,830 أو التوقف عن استخدام هذا الجزء من الذاكرة. 895 00:37:33,830 --> 00:37:34,480 لذا هذا جيد. 896 00:37:34,480 --> 00:37:35,857 إنه فقط تصحيح لما قمنا به. 897 00:37:35,857 --> 00:37:37,690 ولكن ما هي مدة تشغيل هذه العملية؟ 898 00:37:37,690 --> 00:37:40,362 899 00:37:40,362 --> 00:37:43,570 تذكرون أننا منذ أسبوعين، بدأنا في التحدث عن الكفاءة والتصميم. 900 00:37:43,570 --> 00:37:47,750 ما هي مدة التشغيل لتغيير حجم مصفوفة. 901 00:37:47,750 --> 00:37:48,542 الجمهور: طويل للغاية. 902 00:37:48,542 --> 00:37:49,624 ديفيد ج. مالان: كررها مرة أخرى. 903 00:37:49,624 --> 00:37:50,860 الجمهور: قلتُ، طويل للغاية. 904 00:37:50,860 --> 00:37:51,901 ديفيد ج. مالان: طويل للغاية. 905 00:37:51,901 --> 00:37:53,137 جيد. 906 00:37:53,137 --> 00:37:54,220 لكن دعونا نكون أكثر دقة. 907 00:37:54,220 --> 00:38:01,945 حرف o الكبير في-- حرف o الكبير فيمَ؟ 908 00:38:01,945 --> 00:38:02,829 الجمهور: N. 909 00:38:02,829 --> 00:38:03,995 ديفيد ج. مالان: N. ما هو n؟ 910 00:38:03,995 --> 00:38:05,150 الجمهور: [INAUDIBLE]. 911 00:38:05,150 --> 00:38:05,500 ديفيد ج. مالان: حسنًا. 912 00:38:05,500 --> 00:38:05,770 صحيح. 913 00:38:05,770 --> 00:38:06,853 لكن ما الذي يمثله n؟ 914 00:38:06,853 --> 00:38:08,375 الجمهور: [INAUDIBLE]. 915 00:38:08,375 --> 00:38:09,250 ديفيد ج. مالان: أجل. 916 00:38:09,250 --> 00:38:10,680 لذا فأنتم في الواقع لم يعُد هناك داعٍ لعدم معرفتكم بذلك. 917 00:38:10,680 --> 00:38:11,804 إنها مجرد إجابة عامة. 918 00:38:11,804 --> 00:38:14,700 في هذه الحالة، فأيًا كان طول المصفوفة، أطلقوا عليها n. 919 00:38:14,700 --> 00:38:18,340 إنها خطوات متعددة لتغيير حجمها إلى هذا زائد 1. 920 00:38:18,340 --> 00:38:20,142 من الناحية الفنية هي رمز o الكبير، على n، زائد 1. 921 00:38:20,142 --> 00:38:22,600 لكن تذكروا أننا في مناقشتنا، "تدوين رمز o الكبير"، أننا فقط 922 00:38:22,600 --> 00:38:26,890 تجاهلنا المصطلحات الأصغر-- زائد الواحدات، المقسومة على الاثنينات، زائد n. 923 00:38:26,890 --> 00:38:30,400 نحن نركز فقط على المصطلح الأقوى في التعبير، وهو 924 00:38:30,400 --> 00:38:31,540 تحديدًا n هنا. 925 00:38:31,540 --> 00:38:35,140 إذن أجل، إذا كانت لديك مصفوفة بحجم 2، وقمت بتغيير حجمها 926 00:38:35,140 --> 00:38:38,710 إلى مصفوفة بحجم 3 أو في الواقع، n زائد 1، فهذا 927 00:38:38,710 --> 00:38:40,210 سيستغرق مني n من الخطوات. 928 00:38:40,210 --> 00:38:41,710 من الناحية الفنية n زائد 1 من الخطوات. 929 00:38:41,710 --> 00:38:42,820 لكن n من الخطوات. 930 00:38:42,820 --> 00:38:44,260 وهذا ما يشير إليه حرف o الكبير من n. 931 00:38:44,260 --> 00:38:45,320 لذا هي عملية خطية. 932 00:38:45,320 --> 00:38:48,560 ممكنة جدًا ولكنها ليست بالضرورة أسرع 933 00:38:48,560 --> 00:38:51,970 شيء لأنه كان عليه حرفيًا أن يحرك كل تلك القيم التافهة. 934 00:38:51,970 --> 00:38:56,110 إذن ما الذي سيكون أفضل من هذا؟ 935 00:38:56,110 --> 00:38:59,950 وإذا قمت بالبرمجة من قبل، فقد يكون لديك الحدس الصحيح بالفعل. 936 00:38:59,950 --> 00:39:01,210 كيف يمكننا حل هذه المشكلة؟ 937 00:39:01,210 --> 00:39:04,598 938 00:39:04,598 --> 00:39:05,098 أجل؟ 939 00:39:05,098 --> 00:39:07,540 الجمهور: هل يمكنك تخصيص المزيد من الذاكرة في نهاية المصفوفة؟ 940 00:39:07,540 --> 00:39:10,165 ديفيد ج. مالان: إعادة تخصيص المزيد من الذاكرة في نهاية المصفوفة. 941 00:39:10,165 --> 00:39:15,300 إذن من الواضح أن لغة c تحتوي على دالة تسمى، realloc. 942 00:39:15,300 --> 00:39:19,480 تمامًا، إذا لم تتم تسميتها بشكل واضح وهي تعيد تخصيص الذاكرة. 943 00:39:19,480 --> 00:39:23,200 وإذا قمت باجتيازها، فإن عنوان جزء الذاكرة الذي قمتَ بتخصيصه، 944 00:39:23,200 --> 00:39:26,020 وسيلاحظ نظام التشغيل، أوه، نعم أنك كنت محظوظًا. 945 00:39:26,020 --> 00:39:28,460 لدي المزيد من الذاكرة في نهاية هذه المصفوفة، 946 00:39:28,460 --> 00:39:32,050 ستقوم بعد ذلك بتخصيص ذاكرة الوصول العشوائي الإضافية تلك لك، وتتيح لك استخدامها. 947 00:39:32,050 --> 00:39:34,830 أو في أسوأ حالة، إذا لم يتوفر أي شيء في نهاية 948 00:39:34,830 --> 00:39:36,580 المصفوفة الموجودة في الذاكرة، لأنه يتم 949 00:39:36,580 --> 00:39:38,890 استخدامها بواسطة شيء ما آخر في برنامجك. 950 00:39:38,890 --> 00:39:39,760 هذا جيد. 951 00:39:39,760 --> 00:39:44,920 ستتولى Realloc مسؤولية إنشاء مصفوفة أخرى في مكان ما 952 00:39:44,920 --> 00:39:48,010 في الذاكرة، ونسخ جميع بياناتك تلك فيها، 953 00:39:48,010 --> 00:39:51,190 وإرجاع عنوان الجزء الجديد من الذاكرة هذا. 954 00:39:51,190 --> 00:39:53,031 لسوء الحظ، هذا لا يزال خطيًا. 955 00:39:53,031 --> 00:39:53,530 أجل؟ 956 00:39:53,530 --> 00:39:55,282 الجمهور: هل يتم كل هذا في الكومة؟ 957 00:39:55,282 --> 00:39:55,720 أو-- 958 00:39:55,720 --> 00:39:57,845 ديفيد ج. مالان: يتم كل هذا في الكومة. 959 00:39:57,845 --> 00:40:00,760 Malloc، وrealloc، وfree، جميعها تعمل على الكومة. 960 00:40:00,760 --> 00:40:01,630 أجل. 961 00:40:01,630 --> 00:40:04,750 إذن هذا حل، لكنه لا لا يعبر بالفعل عن الكفاءة. 962 00:40:04,750 --> 00:40:05,250 أجل؟ 963 00:40:05,250 --> 00:40:06,360 الجمهور: هل يمكنك استخدام قائمة مترابطة؟ 964 00:40:06,360 --> 00:40:07,235 ديفيد ج. مالان: أجل. 965 00:40:07,235 --> 00:40:09,730 ما هي القائمة المترابطة؟ 966 00:40:09,730 --> 00:40:10,367 امضِ قدمًا. 967 00:40:10,367 --> 00:40:13,450 الجمهور: عندما يكون لديك عنصر يشير إلى عناصر مختلفة. 968 00:40:13,450 --> 00:40:14,241 ديفيد ج. مالان: حسنًا. 969 00:40:14,241 --> 00:40:15,391 تشير إلى عناصر أخرى. 970 00:40:15,391 --> 00:40:15,890 أجل. 971 00:40:15,890 --> 00:40:18,100 لذا دعوني أتحدث عن المشكلة الأساسية هنا. 972 00:40:18,100 --> 00:40:23,530 المشكلة الأساسية هي أشبه بأن تضع نفسك في موقف حرج، 973 00:40:23,530 --> 00:40:25,060 لذا إذا جاز التعبير، كما يقول المثل الشائع. 974 00:40:25,060 --> 00:40:29,260 باستخدام مصفوفة، فأنت تقرر مسبقًا ما هو حجم بنية البيانات 975 00:40:29,260 --> 00:40:30,666 وتلتزم به. 976 00:40:30,666 --> 00:40:32,290 حسنًا، ماذا لو فعلت العكس فقط. 977 00:40:32,290 --> 00:40:33,490 لا تفعل ذلك. 978 00:40:33,490 --> 00:40:39,130 إذا كنت ترغب في ذلك من البداية، فخصّص مساحة لقيمة واحدة فقط، لنقل عدد صحيح واحد، 979 00:40:39,130 --> 00:40:41,230 فقط اطلب من الكمبيوتر القيام بذلك. 980 00:40:41,230 --> 00:40:44,890 أعطني مساحة لعدد صحيح واحد وسأضع رقمي 42 هنا. 981 00:40:44,890 --> 00:40:48,660 وبعد ذلك، إذا وفقط إذا، كنت ترغب في عدد صحيح ثانٍ، 982 00:40:48,660 --> 00:40:50,890 فاطلب من الكمبيوتر عددًا صحيحًا ثانيًا. 983 00:40:50,890 --> 00:40:54,490 وهكذا فإن الكمبيوتر، كما هو الحال من خلال malloc، أو أي شيء، سيعطيك واحدًا آخر 984 00:40:54,490 --> 00:40:55,510 على سبيل المثال، الرقم 13. 985 00:40:55,510 --> 00:40:58,900 وإذا كنت ترغب في الحصول على ثالث، فاطلب نفس الطلب من نظام التشغيل. 986 00:40:58,900 --> 00:41:02,470 في كل مرة فقط يعيد فيها جزءًا واحدًا من الذاكرة. 987 00:41:02,470 --> 00:41:05,560 لكن يوجد مفهوم أساسي هنا. 988 00:41:05,560 --> 00:41:06,850 هناك دائمًا عملية مقايضة. 989 00:41:06,850 --> 00:41:08,200 إذن أجل، هذا ممكن. 990 00:41:08,200 --> 00:41:10,150 يمكنك استدعاء malloc ثلاث مرات. 991 00:41:10,150 --> 00:41:13,690 في كل مرة تطلب جزءًا من الذاكرة بحجم 1، بدلاً من الحجم 3، 992 00:41:13,690 --> 00:41:15,160 على سبيل المثال. 993 00:41:15,160 --> 00:41:16,450 لكن ما هو المقابل الذي ستقدمه؟ 994 00:41:16,450 --> 00:41:18,460 أو ما هي المشكلة التي ما زلنا بحاجة إلى حلها؟ 995 00:41:18,460 --> 00:41:19,147 أجل؟ 996 00:41:19,147 --> 00:41:20,580 الجمهور: لا يتم تخزينها بجانب بعضها البعض. 997 00:41:20,580 --> 00:41:20,780 ديفيد ج. مالان: أجل. 998 00:41:20,780 --> 00:41:22,613 لا يتم تخزينها بجانب بعضها البعض. 999 00:41:22,613 --> 00:41:26,440 على الرغم من ذلك، يمكنني التفكير في هذا كالعنصر الأول، والثاني، 1000 00:41:26,440 --> 00:41:31,960 والثالث، فليس لديك في هذه القصة، الوصول العشوائي إلى العناصر. 1001 00:41:31,960 --> 00:41:35,710 والوصول العشوائي، وهذا ما يشار إليه، بذاكرة الوصول العشوائي، أو RAM، 1002 00:41:35,710 --> 00:41:38,290 يعني هذا فقط بشكل حسابي، على سبيل المثال، أنه يمكنك 1003 00:41:38,290 --> 00:41:43,190 الانتقال، بشكل حسابي، إلى الموقع 0، الموقع 1، الموقع 2، بشكل عشوائي، أو في وقت 1004 00:41:43,190 --> 00:41:43,690 ثابت. 1005 00:41:43,690 --> 00:41:44,831 فقط بشكل مباشر. 1006 00:41:44,831 --> 00:41:47,830 لأنهم إذا عادوا جميعًا على التوالي إلى الوراء، فإن كل ما عليك القيام به هو، 1007 00:41:47,830 --> 00:41:51,730 إضافة 1، أو إضافة 4، أو أي شيء إلى العنوان، وأنت هناك. 1008 00:41:51,730 --> 00:41:55,570 لكن المشكلة هي، أنك إذا قمت باستدعاء malloc مرارًا 1009 00:41:55,570 --> 00:41:58,450 وتكرارًا، فلا يوجد ضمان بأن هذه الأشياء 1010 00:41:58,450 --> 00:42:00,890 ستكون قريبة من بعضها البعض. 1011 00:42:00,890 --> 00:42:03,550 قد تنتهي هذه الأجزاء الثانية من الذاكرة-- 1012 00:42:03,550 --> 00:42:06,880 إذا كان هذا جزءًا كبيرًا من الذاكرة التي تحدثنا عنها، 1013 00:42:06,880 --> 00:42:09,550 حيث الأكوام بالأعلى هنا، والمكدسات بالأسفل هنا-- 1014 00:42:09,550 --> 00:42:11,690 فقد ينتهي 42 هنا. 1015 00:42:11,690 --> 00:42:14,350 الجزء التالي من الذاكرة، 50، قد ينتهي هنا. 1016 00:42:14,350 --> 00:42:16,600 الجزء الثالث قد ينتهي هنا. 1017 00:42:16,600 --> 00:42:19,600 لذا لا يمكنك الانتقال من الموقع 0، إلى 1، إلى 2، 1018 00:42:19,600 --> 00:42:25,730 لأنه يجب عليك أن تتذكر بطريقة ما أين يوجد الموقع 0، و1، و2. 1019 00:42:25,730 --> 00:42:27,287 إذن كيف يمكننا حل هذا؟ 1020 00:42:27,287 --> 00:42:30,370 حتى لو لم تقم بالبرمجة من قبل، على سبيل المثال، ما هو الحل هنا؟ 1021 00:42:30,370 --> 00:42:33,274 1022 00:42:33,274 --> 00:42:35,659 الجمهور: بطريقة ما تخزين [INAUDIBLE]. 1023 00:42:35,659 --> 00:42:36,450 ديفيد ج. مالان: حسنًا. 1024 00:42:36,450 --> 00:42:38,772 التخزين بطريقة ما لعناوين-- 1025 00:42:38,772 --> 00:42:40,500 الجمهور: من [INAUDIBLE] 1026 00:42:40,500 --> 00:42:40,890 ديفيد ج. مالان: حسنًا. 1027 00:42:40,890 --> 00:42:44,056 لذلك دعونا نفترض، من أجل المناقشة، أن هذا الجزء من الذاكرة 1028 00:42:44,056 --> 00:42:45,420 ينتهى في الموقع 100. 1029 00:42:45,420 --> 00:42:48,180 هذا الجزء ينتهى في 150 تقريبًا. 1030 00:42:48,180 --> 00:42:51,360 هذا الجزء ينتهى في 475. 1031 00:42:51,360 --> 00:42:53,610 مهما كانت تلك القيم. 1032 00:42:53,610 --> 00:42:56,680 يبدو أنني بطريقة أو بأخرى أحتاج إلى تذكر القيم الثلاث-- 1033 00:42:56,680 --> 00:43:00,030 100، و150، و475. 1034 00:43:00,030 --> 00:43:01,620 لذا أين يمكنني تخزين ذلك؟ 1035 00:43:01,620 --> 00:43:05,070 حسنًا، من الواضح أنه، يمكنني أن أكون ماهرًا قليلاً ولكن طماعًا قليلاً. 1036 00:43:05,070 --> 00:43:08,040 أستطيع أن أقول لـ malloc، تعرف ماذا، في كل مرة أقوم باستدعائك فيها، لا تعطيني 1037 00:43:08,040 --> 00:43:11,580 فقط مساحة لعدد صحيح، أعطني مساحة لعدد صحيح 1038 00:43:11,580 --> 00:43:15,520 بالإضافة إلى عنوان عدد صحيح آخر. 1039 00:43:15,520 --> 00:43:19,350 لذا إذا رأيت ما يشبه حبات الفشار المصطفة معًا في سلسلة، 1040 00:43:19,350 --> 00:43:24,360 أو أي نوع من سياج ربط السلسلة حيث يرتبط أحد الروابط بالآخر. 1041 00:43:24,360 --> 00:43:29,130 فيمكننا إنشاء معادل لـ-- عفوًا ليس هذا. 1042 00:43:29,130 --> 00:43:33,900 يمكننا إنشاء معادل لنوع الصورة هذا، 1043 00:43:33,900 --> 00:43:38,010 حيث كل هذه المربعات أو العُقد، سنبدأ بتسميتها، نوعًا من روابط 1044 00:43:38,010 --> 00:43:39,270 مرتبطة بيانيًا ببعضها البعض. 1045 00:43:39,270 --> 00:43:41,790 حسنًا، لقد رأينا هذه الروابط، أو هذه المؤشرات، 1046 00:43:41,790 --> 00:43:44,490 حرفيًا الأسهم التي تشير إلى انتهاء التنفيذ في التعليمات البرمجية. 1047 00:43:44,490 --> 00:43:46,740 فالسهم أو المؤشر هو مجرد عنوان. 1048 00:43:46,740 --> 00:43:47,640 لذلك أتعلمون؟ 1049 00:43:47,640 --> 00:43:53,310 لا يجب أن نطلب من malloc مجرد مساحة كافية فقط للرقم 42، 1050 00:43:53,310 --> 00:43:57,990 بدلاً من ذلك، يجب أن نطلب المزيد من الذاكرة في كل هذه المربعات، 1051 00:43:57,990 --> 00:44:00,510 لجعلها مستطيلات بشكل تصويري الآن. 1052 00:44:00,510 --> 00:44:04,320 لذا الآن، أجل، لدينا هذه الأسهم من الناحية النظرية 1053 00:44:04,320 --> 00:44:06,460 والتي تشير من موقع واحد لآخر. 1054 00:44:06,460 --> 00:44:10,602 ولكن ما هي القيم التي أريد في الواقع وضعها في هذه المربعات الإضافية الجديدة؟ 1055 00:44:10,602 --> 00:44:12,570 الجمهور: عناوين القيم التالية. 1056 00:44:12,570 --> 00:44:13,800 ديفيد ج. مالان: عناوين القيم التالية. 1057 00:44:13,800 --> 00:44:15,258 لذا فهي تشبه فتات الخبز. 1058 00:44:15,258 --> 00:44:18,390 إذن في هذا المربع هنا، المرتبط بالقيمة الأولى، 1059 00:44:18,390 --> 00:44:22,950 يجب أن يكون عنوان قيمتي الثانية، 475. 1060 00:44:22,950 --> 00:44:26,370 المرتبط مع القيمة الثانية هنا، لكل سهم-- 1061 00:44:26,370 --> 00:44:28,920 ودعوني أرسم السهم من المكان الصحيح. 1062 00:44:28,920 --> 00:44:33,150 --من السهم، يجب أن يكون العنوان 150، لأنه الأخير. 1063 00:44:33,150 --> 00:44:37,090 ومن ثم، من هذا المربع الإضافي، ما الذي يجب أن أضعه هناك؟ 1064 00:44:37,090 --> 00:44:37,590 أجل؟ 1065 00:44:37,590 --> 00:44:38,880 الجمهور: خط مائل 0 أو شيء ما؟ 1066 00:44:38,880 --> 00:44:39,755 ديفيد ج. مالان: أجل. 1067 00:44:39,755 --> 00:44:43,050 لذا من المحتمل، أن معادل خط مائل 0، وهو في عالم استدعاء المؤشر، 1068 00:44:43,050 --> 00:44:44,460 فارغ. 1069 00:44:44,460 --> 00:44:47,820 لذا هو مجرد قيمة خاصة تعني أن هذا هو كل شيء، هذه هي نهاية السطر. 1070 00:44:47,820 --> 00:44:51,320 ما زال يتيح لنا ذلك مجالاً لإضافة قيمة رابعة والإشارة إليها، 1071 00:44:51,320 --> 00:44:56,020 ولكنه في الوقت الحالي، يعني لنا بوضوح شديد أنه لا يوجد شيء في الواقع هناك. 1072 00:44:56,020 --> 00:44:58,210 إذن ما الذي قمنا بفعله تحديدًا؟ 1073 00:44:58,210 --> 00:45:03,210 لقد قمنا بإنشاء قائمة القيم 50، أوه عذرًا 42، 50، 13، 1074 00:45:03,210 --> 00:45:04,549 لكننا قمنا بربطها سويًا. 1075 00:45:04,549 --> 00:45:06,090 أولاً، بشكل تصويري، باستخدام الأسهم فقط. 1076 00:45:06,090 --> 00:45:08,280 مثلما قد يقوم به أي شخص باستخدام قطعة من الطباشير. 1077 00:45:08,280 --> 00:45:10,530 لكن بشكل فني في التعليمة البرمجية، يمكنني القيام بذلك 1078 00:45:10,530 --> 00:45:14,380 من خلال تخزين العناوين فقط في كل من هذه الأماكن. 1079 00:45:14,380 --> 00:45:19,260 فقط لنكون واضحين بعد ذلك، ما الذي قد يترجمه هذا بالفعل في التعليمة البرمجية؟ 1080 00:45:19,260 --> 00:45:22,020 حسنًا، ماذا لو اقترحت هذا. 1081 00:45:22,020 --> 00:45:28,320 في التعليمة البرمجية، قد يمكننا القيام بشيء ما مثل هذا. 1082 00:45:28,320 --> 00:45:29,831 إذا كنا نريد تخزين عدد صحيح. 1083 00:45:29,831 --> 00:45:32,580 فسنحتاج بالطبع إلى تخزين على سبيل المثال العدد الصحيح n، الذي سنقوم بتسميته. 1084 00:45:32,580 --> 00:45:35,790 سيقوم n بتمثيل 42، أو 50، أو 13. 1085 00:45:35,790 --> 00:45:37,585 لكن إذا رغبنا في إنشاء بنية بيانات، 1086 00:45:37,585 --> 00:45:39,960 فقد نرغب في البدء بإعطاء بنية البيانات هذه اسمًا. 1087 00:45:39,960 --> 00:45:44,250 لقد قمتُ بتسميتها، منذ لحظة، عُقدة، والتي هي عبارة عن مصطلح في علوم الكمبيوتر لعقدة في 1088 00:45:44,250 --> 00:45:45,430 قائمة مرتبطة، إذا جاز التعبير. 1089 00:45:45,430 --> 00:45:46,410 وتبدو مثل هذا. 1090 00:45:46,410 --> 00:45:48,780 لذا تشير typedef إلى، أعطني النوع الخاص بي. 1091 00:45:48,780 --> 00:45:51,120 تشير Struct إلى، اجعله بنية، مثلما كان الطالب. 1092 00:45:51,120 --> 00:45:53,620 ثم، العُقدة، والتي ستكون اسمًا لهذا الشيء. 1093 00:45:53,620 --> 00:45:57,720 وسأشرح بعد قليل لماذا لدي كلمة عُقدة مرتين هذه المرة. 1094 00:45:57,720 --> 00:46:01,870 لكنني تركت مساحة على اللوحة لسطر واحد آخر فقط. 1095 00:46:01,870 --> 00:46:06,120 بالإضافة إلى int، التي يُطلق عليه n، أو أيًا كان، 1096 00:46:06,120 --> 00:46:09,450 أنا بحاجة إلى تمثيله بطريقة ما في التعليمة البرمجية، الذاكرة الإضافية 1097 00:46:09,450 --> 00:46:11,890 التي أريد من malloc أن يعطيني إياها من أجل العنوان. 1098 00:46:11,890 --> 00:46:14,910 أولاً وقبل كل شيء، هذه عناوين أي أنواع من البيانات؟ 1099 00:46:14,910 --> 00:46:16,720 كل هذه المربعات الثلاثة الجديدة. 1100 00:46:16,720 --> 00:46:17,636 الجمهور: [INAUDIBLE]. 1101 00:46:17,636 --> 00:46:21,060 ديفيد ج. مالان: هذه هي عناوين الأعداد الصحيحة في هذه المرحلة من القصة. 1102 00:46:21,060 --> 00:46:26,820 لكن من الناحية الفنية، ما الذي يشير إليه هذا المربع بالفعل؟ 1103 00:46:26,820 --> 00:46:29,370 هل يشير تحديدًا إلى الأعداد الصحيحة؟ 1104 00:46:29,370 --> 00:46:30,539 الجمهور: [INAUDIBLE]. 1105 00:46:30,539 --> 00:46:33,580 ديفيد ج. مالان: إنه يشير إلي هذا الجزء الكامل من الذاكرة، اذا صح التعبير. 1106 00:46:33,580 --> 00:46:37,020 لذا، إذا بدأت في التفكير بشأن كل هذه المستطيلات على أنها عقدة، 1107 00:46:37,020 --> 00:46:39,910 وكل هذه الأسهم على أنها تشير إلى عقدة أخرى، 1108 00:46:39,910 --> 00:46:45,510 فنحن بحاجة إلى التعبير عن ذلك بطريقة ما، أنا بحاجة إلى تخزين مؤشر إلى عقدة بطريقة ما. 1109 00:46:45,510 --> 00:46:48,510 وبعبارة أخرى، فإن كل هذه الأسهم تحتاج إلى الإشارة إلى عقدة أخرى. 1110 00:46:48,510 --> 00:46:51,500 يمكننا قول هذا، في التعليمة البرمجية. 1111 00:46:51,500 --> 00:46:52,035 أليس كذلك؟ 1112 00:46:52,035 --> 00:46:53,160 على سبيل المثال، دعونا نطلق عليها اسمًا. 1113 00:46:53,160 --> 00:46:55,990 بدلاً من n، والذي هو عبارة عن رقم، دعونا نسميها next. 1114 00:46:55,990 --> 00:46:59,940 إذن next، سيكون اسمًا لهذا الحقل الذي يشير إلى العقدة التالية في الذاكرة. 1115 00:46:59,940 --> 00:47:04,106 والعقدة نجمة، ماذا يعني ذلك باللغة الإنجليزية، إذا صح التعبير؟ 1116 00:47:04,106 --> 00:47:05,147 الجمهور: [INAUDIBLE]. 1117 00:47:05,147 --> 00:47:06,230 ديفيد ج. مالان: كررها مرة أخرى؟ 1118 00:47:06,230 --> 00:47:07,560 الجمهور: الإشارة إلى عنوان. 1119 00:47:07,560 --> 00:47:08,560 ديفيد ج. مالان: الإشارة إلى عنوان. 1120 00:47:08,560 --> 00:47:08,730 أليس كذلك؟ 1121 00:47:08,730 --> 00:47:09,540 يبدو الأمر مختلفًا. 1122 00:47:09,540 --> 00:47:11,550 العقدة هي كلمة جديدة اليوم وهذا جيد. 1123 00:47:11,550 --> 00:47:14,550 لكن العقدة نجمة، فقط تعني مؤشر إلى عقدة. 1124 00:47:14,550 --> 00:47:15,960 عنوان العقدة. 1125 00:47:15,960 --> 00:47:18,750 ومن الواضح أن هذه بنية مخصصة 1126 00:47:18,750 --> 00:47:20,400 لذلك يجب أن نقول هذا في الواقع. 1127 00:47:20,400 --> 00:47:23,760 لكنه نفس المبدأ على الرغم من أن الأشياء تتصاعد بسرعة 1128 00:47:23,760 --> 00:47:29,606 هنا، نحن بحاجة فقط إلى قيم، عدد صحيح، ومن ثم، مؤشر إلى شيء آخر. 1129 00:47:29,606 --> 00:47:31,480 سيكون هذا الشيء الآخر عقدة أخرى. 1130 00:47:31,480 --> 00:47:35,160 وسنقوم فقط باستخدام عقدة، بصراحة، لتغليف قيمتين-- 1131 00:47:35,160 --> 00:47:36,420 عدد صحيح ومؤشر. 1132 00:47:36,420 --> 00:47:39,075 والطريقة التي تعبر بها في لغة C، وإن كانت مشفرة بطريقة ما، 1133 00:47:39,075 --> 00:47:43,770 عن مؤشر، أو أحد هذه الأسهم، هو أنك تقول أعطني متغيرًا يسمى next، 1134 00:47:43,770 --> 00:47:47,580 احصل عليه ليشير إلى بنية تسمى عقدة. 1135 00:47:47,580 --> 00:47:51,930 أو بالأحرى، احصل عليه ليكون عنوان بنية نوع العقدة. 1136 00:47:51,930 --> 00:47:52,691 أجل؟ 1137 00:47:52,691 --> 00:47:56,619 الجمهور: كيف يمكنك [؟ كشف؟] توقيت struct node [INAUDIBLE]؟؟ 1138 00:47:56,619 --> 00:48:00,321 1139 00:48:00,321 --> 00:48:01,570 ديفيد ج. مالان: سؤال جيد. 1140 00:48:01,570 --> 00:48:06,430 إذن هذا يبدو وكأنه نوع من التعريف العام لأنني أقوم بتعريف عقدة، 1141 00:48:06,430 --> 00:48:08,980 ومع ذلك، بداخل العقدة عقدة. 1142 00:48:08,980 --> 00:48:11,860 هذا جيد بسبب النجمة. 1143 00:48:11,860 --> 00:48:14,350 إنها ضرورية في لغة C-- 1144 00:48:14,350 --> 00:48:18,040 تذكرون أن لغة C دائمًا عبارة عن نوع من القراءة من الأعلى إلى الأسفل. 1145 00:48:18,040 --> 00:48:22,630 لذا وفقًا لذلك، هذا السطر الأول من التعليمات البرمجية هنا، typedef struct node، 1146 00:48:22,630 --> 00:48:25,570 في هذه المرحلة من القصة، عندما قرأ clang ذلك السطر، 1147 00:48:25,570 --> 00:48:28,821 فإنها تعرف أن عبارة struct node، موجودة. 1148 00:48:28,821 --> 00:48:30,820 الجمهور: هذا هو السبب في أنك تقول عُقد [INAUDIBLE].. 1149 00:48:30,820 --> 00:48:32,031 ديفيد ج. مالان: بالضبط. 1150 00:48:32,031 --> 00:48:32,530 بالضبط. 1151 00:48:32,530 --> 00:48:34,150 لم نكن بحاجة إلى القيام بذلك مع الطلاب لأنه لم تكن هناك 1152 00:48:34,150 --> 00:48:36,400 مؤشرات مرتبطة بالطلاب الآخرين. 1153 00:48:36,400 --> 00:48:37,700 لكن ،في هذه الحالة، نعم هناك ترابط. 1154 00:48:37,700 --> 00:48:42,160 إذن باختصار، هذا يخبر clang، مرحبًا، clang، أعطني بنية تسمى عقدة. 1155 00:48:42,160 --> 00:48:45,130 ومن ثم، هنا، نقول، مرحبًا، clang، كل هذه العقد 1156 00:48:45,130 --> 00:48:47,800 يجب أن يكون لديها شيئان، عدد صحيح يسمى n، 1157 00:48:47,800 --> 00:48:52,300 ومؤشر إلى نوع آخر من بنيات البيانات تلك من نوع العقدة، 1158 00:48:52,300 --> 00:48:55,780 ونسمي الأمر برمته، عقدة. 1159 00:48:55,780 --> 00:48:56,870 إنه صعب بعض الشيء. 1160 00:48:56,870 --> 00:48:58,610 لكن هذا كل ما في الأمر، كما يلي. 1161 00:48:58,610 --> 00:49:00,460 دعوني أمضي قدمًا وأمحي كل هذا. 1162 00:49:00,460 --> 00:49:03,190 نوع البيانات هذا بالكامل هو-- 1163 00:49:03,190 --> 00:49:07,360 إذا تخلصنا من الصورة التي رسمناها بشكل سريع هناك. 1164 00:49:07,360 --> 00:49:10,750 --هل هذا يقول، مرحبًا، clang، أعطني بنية بيانات 1165 00:49:10,750 --> 00:49:12,880 والتي تبدو كهذا بشكل تصويري. 1166 00:49:12,880 --> 00:49:14,600 إنها مقسمة الى جزئين. 1167 00:49:14,600 --> 00:49:18,280 الجزء الأول يسمى n، والجزء الثاني يسمى next. 1168 00:49:18,280 --> 00:49:20,380 نوع البيانات هذا هو من النوع int. 1169 00:49:20,380 --> 00:49:24,090 وهذا مؤشر إلى عقدة أخرى مماثلة. 1170 00:49:24,090 --> 00:49:24,910 وهذا كل شيء. 1171 00:49:24,910 --> 00:49:28,180 على الرغم من أن التعليمة البرمجية تبدو معقدة، فإن الفكرة هي ذلك بالضبط. 1172 00:49:28,180 --> 00:49:29,472 أجل؟ 1173 00:49:29,472 --> 00:49:31,952 الجمهور: [INAUDIBLE]؟ 1174 00:49:31,952 --> 00:49:34,930 لماذا يجب عليك قول struct node مرة أخرى؟ 1175 00:49:34,930 --> 00:49:37,450 ديفيد ج. مالان: سؤال جيد. 1176 00:49:37,450 --> 00:49:42,220 السبب هو، كما جاء للتوّ منذ لحظة، clang 1177 00:49:42,220 --> 00:49:43,870 ولغة C، بشكل عام، هما أمران سخيفان إلى حد ما. 1178 00:49:43,870 --> 00:49:45,970 فهما يقرآن التعليمات البرمجية من الأعلى إلى الأسفل. 1179 00:49:45,970 --> 00:49:49,450 والمشكلة هي أنه يجب عليك إعلان اسم هذه البنية 1180 00:49:49,450 --> 00:49:52,870 باعتبارها struct node قبل أن تستخدمها في الواقع. 1181 00:49:52,870 --> 00:49:55,930 إنها مماثلة في جوهرها لمناقشتنا عن النماذج الأولية-- حيث تحتاج دوال y 1182 00:49:55,930 --> 00:49:57,580 إلى أن يتم ذكرها بالأعلى. 1183 00:49:57,580 --> 00:50:00,940 هذا فقط يقول لـ clang، أعطني نوعًا يسمى struct node. 1184 00:50:00,940 --> 00:50:02,990 أنت لا تعرف كيف ستبدو حتى الآن. 1185 00:50:02,990 --> 00:50:05,380 لكن سأنهي فكرتي في وقت لاحق. 1186 00:50:05,380 --> 00:50:08,770 ومن ثم هنا، نخبر clang فقط، داخل تلك العقدة 1187 00:50:08,770 --> 00:50:12,680 التي يجب أن تكون عددًا صحيحًا، وكذلك، مؤشرًا لنوع الشيء 1188 00:50:12,680 --> 00:50:14,050 الذي أنا في طريقي إلى تعريفه. 1189 00:50:14,050 --> 00:50:17,350 ولكن إذا قمت بترك كلمة عقدة بالأعلى هناك، وقلنا فقط struct، 1190 00:50:17,350 --> 00:50:21,730 فلا يمكنك القيام بذلك لأنها لم ترَ الكلمة N-O-D-E بعد. 1191 00:50:21,730 --> 00:50:22,750 هذا كل شيء. 1192 00:50:22,750 --> 00:50:24,650 أية أسئلة أخرى؟ 1193 00:50:24,650 --> 00:50:25,150 حسنًا. 1194 00:50:25,150 --> 00:50:29,770 إذا كان لدي الآن بنية بيانات تسمى عقدة، 1195 00:50:29,770 --> 00:50:32,497 يمكنني استخدامها لجمع هذه القوائم المرتبطة نوعًا ما معًا. 1196 00:50:32,497 --> 00:50:34,330 وربما فقط الأشياء قليلاً، 1197 00:50:34,330 --> 00:50:37,150 وللبدء في التخلي عن بعض البط، هل يمكن أن يتطوع 1198 00:50:37,150 --> 00:50:40,680 بعض الأفراد لحل مشكلة هنا؟ 1199 00:50:40,680 --> 00:50:41,180 أجل؟ 1200 00:50:41,180 --> 00:50:41,350 حسنًا. 1201 00:50:41,350 --> 00:50:42,150 تعالوا. 1202 00:50:42,150 --> 00:50:44,488 1، 2-- 1203 00:50:44,488 --> 00:50:45,940 الجمهور: [INAUDIBLE]. 1204 00:50:45,940 --> 00:50:46,889 ديفيد ج. مالان: بالتأكيد. 1205 00:50:46,889 --> 00:50:48,180 أو يمكنك أخذ البطة والذهاب. 1206 00:50:48,180 --> 00:50:48,680 حسنًا. 1207 00:50:48,680 --> 00:50:49,940 1، 2، ماذا عن 3؟ 1208 00:50:49,940 --> 00:50:51,230 تعالي هنا، 3. 1209 00:50:51,230 --> 00:50:54,770 إذن إذا كنت تريد أن تكون أول مؤشر لدينا، فيمكنك أن تكون رقم 5. 1210 00:50:54,770 --> 00:50:55,610 تعال هنا. 1211 00:50:55,610 --> 00:50:57,740 تريد أن تكون رقم 9. 1212 00:50:57,740 --> 00:50:58,610 وواحد آخر. 1213 00:50:58,610 --> 00:50:59,541 متطوع واحد آخر. 1214 00:50:59,541 --> 00:51:00,290 تعال هنا. 1215 00:51:00,290 --> 00:51:01,400 أجل. 1216 00:51:01,400 --> 00:51:02,030 حسنًا. 1217 00:51:02,030 --> 00:51:08,860 إذن-- سألتقي بكم هنا. 1218 00:51:08,860 --> 00:51:10,140 حسنًا، 17. 1219 00:51:10,140 --> 00:51:10,710 حسنًا. 1220 00:51:10,710 --> 00:51:11,744 إذن إذا كنت تريد ذلك-- 1221 00:51:11,744 --> 00:51:14,160 سنقوم باختيار هذا فقط للأشخاص المتابعين من المنزل. 1222 00:51:14,160 --> 00:51:16,326 إذا رغبتِ فقط في قول مرحبًا للجمهور. 1223 00:51:16,326 --> 00:51:17,528 أندريا: مرحبًا ، أنا أندريا. 1224 00:51:17,528 --> 00:51:19,760 [? كومي: ?] مرحبًا، [? أنا كومي. ?] 1225 00:51:19,760 --> 00:51:21,496 [? كيونغ: ?] مرحبًا، [? أنا كيونغ. ?] 1226 00:51:21,496 --> 00:51:22,917 المتحدث 2: مرحبًا، أنا [INAUDIBLE]. 1227 00:51:22,917 --> 00:51:24,000 ديفيد ج. مالان: رائع. 1228 00:51:24,000 --> 00:51:24,270 حسنًا. 1229 00:51:24,270 --> 00:51:26,820 إذا كنتم لا تمانعون في أن ترجعوا جميعًا بمقدار خطوة كبيرة إلى الوراء فوق البط، 1230 00:51:26,820 --> 00:51:28,540 فقط حتى نرجع قليلاً إلى الوراء. 1231 00:51:28,540 --> 00:51:29,790 دعونا نمضي قدمًا ونقوم بذلك. 1232 00:51:29,790 --> 00:51:33,060 إذا كنت أنت أول مؤشر لدينا، لو سمحتم تعالوا إلى هنا على سبيل المثال، 1233 00:51:33,060 --> 00:51:34,470 وقفوا فقط خارج منطقة البط. 1234 00:51:34,470 --> 00:51:37,570 ولو سمحتم يا رفاق تعالوا إلى هنا قليلاً في المقدمة. 1235 00:51:37,570 --> 00:51:40,186 إذن هنا لدينا مقومات قائمة مرتبطة. 1236 00:51:40,186 --> 00:51:41,310 ذكريني باسمك مجددًا؟ 1237 00:51:41,310 --> 00:51:42,351 [? كومي: ?] [? أنا كومي. ?] 1238 00:51:42,351 --> 00:51:45,120 ديفيد ج. مالان: [؟ كومي؟] أول مؤشر لدينا إذا صح التعبير. 1239 00:51:45,120 --> 00:51:47,191 عبر متغير [؟ كومي؟] إننا فقط 1240 00:51:47,191 --> 00:51:49,440 نستمر في تعقب أول عنصر من القائمة المرتبطة. 1241 00:51:49,440 --> 00:51:52,564 لذا من فضلك، باستخدام يدك اليسرى، قومي بتمثيل الأول. 1242 00:51:52,564 --> 00:51:54,480 فقط أشيري إلى-- ذكريني باسمك مجددًا؟ 1243 00:51:54,480 --> 00:51:55,140 أندريا: أندريا. 1244 00:51:55,140 --> 00:51:56,890 دايفيد ج. مالان: إذن أندريا هي الرقم 9. 1245 00:51:56,890 --> 00:51:59,310 من فضلِك استخدمي يدكِ اليسرى للإشارة إلى رقم 5. 1246 00:51:59,310 --> 00:52:02,640 من فضلك استخدم يدك اليسرى، أجل، للإشارة إلى رقم 17. 1247 00:52:02,640 --> 00:52:05,766 ويدك اليسرى للإشارة فقط إلى فارغ، والذي سنطلق عليه الأرضية. 1248 00:52:05,766 --> 00:52:07,556 لذا أنت لا تريد فقط الإشارة إليها بشكل عشوائي 1249 00:52:07,556 --> 00:52:10,620 لأن ذلك سيكون مثل اتباع مؤشر وهمي، لذلك هنا يعني فارغ. 1250 00:52:10,620 --> 00:52:11,120 حسنًا. 1251 00:52:11,120 --> 00:52:12,960 إذن هذه قائمة مرتبطة. 1252 00:52:12,960 --> 00:52:15,900 كل ما تحتاجه للتخزين قائمة مرتبطة من ثلاث قيم 1253 00:52:15,900 --> 00:52:19,410 هو ثلاث عقد، بداخلها ثلاثة أعداد صحيحة، 1254 00:52:19,410 --> 00:52:22,930 وتمثل أيديهم اليسرى الثلاث المؤشر التالي، إذا جاز التعبير. 1255 00:52:22,930 --> 00:52:25,920 [? كومي ?] مختلفة قليلاً، حيث إنها لا تحمل قيمة. 1256 00:52:25,920 --> 00:52:27,210 إنها لا تحمل عددًا صحيحًا. 1257 00:52:27,210 --> 00:52:31,710 وبدلاً من ذلك، تحمل اسم المتغير، الأول. 1258 00:52:31,710 --> 00:52:34,210 إذن أنتِ الوحيدة المختلفة هنا بشكل أساسي. 1259 00:52:34,210 --> 00:52:36,610 إذن لنفترض أني أريد إدراج الرقم 20. 1260 00:52:36,610 --> 00:52:38,470 هل يمكن أن يتطوع شخص ليكون الرقم 20؟ 1261 00:52:38,470 --> 00:52:38,970 حسنًا. 1262 00:52:38,970 --> 00:52:40,690 تعال إلى هنا. 1263 00:52:40,690 --> 00:52:41,640 حسنًا. 1264 00:52:41,640 --> 00:52:43,401 وما هو اسمك؟ 1265 00:52:43,401 --> 00:52:43,900 إريك: إريك. 1266 00:52:43,900 --> 00:52:44,160 ديفيد ج. مالان: إريك. 1267 00:52:44,160 --> 00:52:45,720 إريك، أنت الرقم 20. 1268 00:52:45,720 --> 00:52:47,655 وإريك، في الواقع، دعونا نرى. 1269 00:52:47,655 --> 00:52:50,760 1270 00:52:50,760 --> 00:52:52,290 في الواقع هل يمكننا القيام بذلك؟ 1271 00:52:52,290 --> 00:52:57,461 دعوني أعطي-- دعوني أجعل هذا الأمر مختلفًا أكثر. 1272 00:52:57,461 --> 00:52:57,960 حسنًا. 1273 00:52:57,960 --> 00:52:59,020 هذا لم يحدث أبدًا. 1274 00:52:59,020 --> 00:52:59,670 حسنًا. 1275 00:52:59,670 --> 00:53:02,580 إريك، أعطني ذلك رجاءً. 1276 00:53:02,580 --> 00:53:04,530 أرغب في إدراج إريك كرقم 5. 1277 00:53:04,530 --> 00:53:06,674 إذن إريك، أنا سأحتفظ بهذه القائمة مرتبة. 1278 00:53:06,674 --> 00:53:08,340 إذن إلى أين ستنتقل، بوضوح؟ 1279 00:53:08,340 --> 00:53:09,540 إريك: أنتقل إلى هناك. 1280 00:53:09,540 --> 00:53:09,810 ديفيد ج. مالان: حسنًا. 1281 00:53:09,810 --> 00:53:12,851 ولكن قبل أن تفعل ذلك، دعونا فقط نأخذ في عين الاعتبار كيف يبدو هذا في التعليمة البرمجية. 1282 00:53:12,851 --> 00:53:17,460 من المفترض، في التعليمة البرمجية، أننا ألغينا تخصيص إريك من الجمهور. 1283 00:53:17,460 --> 00:53:20,250 لقد أعطيته قيمة، n من الرقم 5. 1284 00:53:20,250 --> 00:53:23,550 ويده اليسرى، إنها قيمة ضئيلة الآن، لأنها لا 1285 00:53:23,550 --> 00:53:25,170 تشير إلى أي شيء محدد. 1286 00:53:25,170 --> 00:53:28,680 إذن فلديه قيمتان-- عدد صحيح، ويد يسرى تمثل 1287 00:53:28,680 --> 00:53:30,030 المؤشر التالي. 1288 00:53:30,030 --> 00:53:34,600 إذا كان الهدف هو وضع إريك في ترتيب مُحدد. 1289 00:53:34,600 --> 00:53:36,210 فما هي الخطوات التي يجب أن نتبعها؟ 1290 00:53:36,210 --> 00:53:38,690 على سبيل المثال، يد مَن يجب أن تشير إلى أين، وبأي ترتيب؟ 1291 00:53:38,690 --> 00:53:39,190 أجل. 1292 00:53:39,190 --> 00:53:39,900 أعطنا خطوة واحدة. 1293 00:53:39,900 --> 00:53:41,595 الجمهور: يجب أن تشير إلى الرقم 9. 1294 00:53:41,595 --> 00:53:43,720 ديفيد ج. مالان: حسنًا، إذن يجب أن تشير إلى الرقم 9، 1295 00:53:43,720 --> 00:53:46,666 وهو ما يعاد قول، أشر إلى أي كان أولاً. 1296 00:53:46,666 --> 00:53:48,040 إلى أين تشير [؟ كومي؟]. 1297 00:53:48,040 --> 00:53:49,180 إذن امضِ قدمًا وقم بذلك. 1298 00:53:49,180 --> 00:53:50,050 حسنًا، التالي؟ 1299 00:53:50,050 --> 00:53:50,550 ما هي الخطوة التالية؟ 1300 00:53:50,550 --> 00:53:51,091 شخص آخر؟ 1301 00:53:51,091 --> 00:53:54,279 1302 00:53:54,279 --> 00:53:54,820 شخص آخر. 1303 00:53:54,820 --> 00:53:55,420 كدنا نصل. 1304 00:53:55,420 --> 00:53:55,920 أجل؟ 1305 00:53:55,920 --> 00:53:57,337 الجمهور: يجب أن يشير الأول إلى 5. 1306 00:53:57,337 --> 00:53:58,128 ديفيد ج. مالان: حسنًا. 1307 00:53:58,128 --> 00:54:00,154 إذن الأول، أو [؟ كومي،؟] هل يمكنك الإشارة إلى 5. 1308 00:54:00,154 --> 00:54:00,820 وهذا جيد. 1309 00:54:00,820 --> 00:54:01,750 لا يجب عليك التحرك حتى. 1310 00:54:01,750 --> 00:54:01,930 أليس كذلك؟ 1311 00:54:01,930 --> 00:54:03,430 وهذه هي ميزة القائمة المرتبطة. 1312 00:54:03,430 --> 00:54:05,474 لا يهم أين أنت في الذاكرة، 1313 00:54:05,474 --> 00:54:08,140 هذه هي الميزة الكلية لهذه المؤشرات، حيث يمكنك حرفيًا 1314 00:54:08,140 --> 00:54:09,454 الإشارة إلى هذا الموقع الآخر. 1315 00:54:09,454 --> 00:54:12,370 انها ليست مصفوفة حيث يحتاجون إلى العودة على التوالي مع بعضهم البعض. 1316 00:54:12,370 --> 00:54:13,660 يمكنهم أن يشيروا إلى أي مكان. 1317 00:54:13,660 --> 00:54:14,160 حسنًا. 1318 00:54:14,160 --> 00:54:15,760 دعونا نمضي قدمًا ونقوم بإدخال واحد آخر. 1319 00:54:15,760 --> 00:54:17,436 مَن يريد قول، 55؟ 1320 00:54:17,436 --> 00:54:17,935 قيمة كبيرة. 1321 00:54:17,935 --> 00:54:18,435 أجل. 1322 00:54:18,435 --> 00:54:20,930 تعال إلى هنا. 1323 00:54:20,930 --> 00:54:21,430 حسنًا. 1324 00:54:21,430 --> 00:54:21,730 ما هو اسمك؟ 1325 00:54:21,730 --> 00:54:22,620 [? كيونغ: ?] [? أنا كيونغ. ?] 1326 00:54:22,620 --> 00:54:23,350 ديفيد ج. مالان: [؟ كيونغ. ؟] حسنًا. 1327 00:54:23,350 --> 00:54:24,290 إذن تعال إلى هنا. 1328 00:54:24,290 --> 00:54:26,498 إذن نحن نقوم فقط بإلغاء تخصيص موقع لـ [؟ كيونغ؟] من الجمهور. 1329 00:54:26,498 --> 00:54:28,600 لقد أعطيته قيمته النهائية 55. 1330 00:54:28,600 --> 00:54:31,570 يده اليسرى ليست سوى قيمة ضئيلة في الوقت الحالي. 1331 00:54:31,570 --> 00:54:34,360 كيف يمكننا إدراج [؟ كيونغ؟] في الترتيب الصحيح؟ 1332 00:54:34,360 --> 00:54:36,999 إلى أين من المفترض أن ينتقل بشكل واضح؟ 1333 00:54:36,999 --> 00:54:39,040 في الترتيب المحدد، من الواضح أنه ينتمي إلى النهاية. 1334 00:54:39,040 --> 00:54:42,220 ولكن ها هو المغزى من القائمة المرتبطة. 1335 00:54:42,220 --> 00:54:45,160 تمامًا كما ناقشنا البحث والترتيب في الماضي، 1336 00:54:45,160 --> 00:54:48,550 الكمبيوتر أعمى إلى حد ما عن الكل باستثناء قيمة واحدة فقط. 1337 00:54:48,550 --> 00:54:50,150 والقائمة المرتبطة، في الوقت الحالي-- 1338 00:54:50,150 --> 00:54:52,810 على سبيل المثال، أنا لا أعرف أن هذه الثلاثة، هذه الأربعة، موجودة. 1339 00:54:52,810 --> 00:54:55,150 كل ما أعرفه حقًا، هو أن [؟ كومي؟] موجودة. 1340 00:54:55,150 --> 00:54:58,600 لأنه عبر هذا المؤشر الأول، المدخل الوحيد 1341 00:54:58,600 --> 00:55:00,100 إلى بقية العناصر. 1342 00:55:00,100 --> 00:55:03,250 إذن ما هو الرائع في القائمة المرتبطة، لكنه ربما ليس واضحًا، 1343 00:55:03,250 --> 00:55:04,450 هو أنك فقط-- 1344 00:55:04,450 --> 00:55:06,702 القيمة الأكثر أهمية هي القيمة الأولى. 1345 00:55:06,702 --> 00:55:09,160 لأنه من القيمة الأولى، يمكنك الوصول إلى أي شخص آخر. 1346 00:55:09,160 --> 00:55:12,190 الأمر ليس مفيدًا-- اعذرني، لتذكرها، أندريا؟ 1347 00:55:12,190 --> 00:55:14,770 --أندريا لوحدها، لأنني إذا قمت بذلك، فلقد فقدتُ فقط 1348 00:55:14,770 --> 00:55:18,340 مسار [؟ كومي؟] والأهم من ذلك، بسبب رقمه، 1349 00:55:18,340 --> 00:55:18,934 إريك. 1350 00:55:18,934 --> 00:55:21,100 لذلك كل ما يجب القيام به حقًا، هو تذكر [؟ كومي. ؟] 1351 00:55:21,100 --> 00:55:27,240 إذن إذا كان الهدف الآن هو إدخال الرقم 55، فما هي الخطوات التي يجب أن تأتي أولاً؟ 1352 00:55:27,240 --> 00:55:28,484 لا أقصد التورية. 1353 00:55:28,484 --> 00:55:29,400 الجمهور: [INAUDIBLE]. 1354 00:55:29,400 --> 00:55:30,483 ديفيد ج. مالان: كررها مرة أخرى. 1355 00:55:30,483 --> 00:55:31,909 الجمهور: العثور على المساحة الأولى. 1356 00:55:31,909 --> 00:55:32,700 ديفيد ج. مالان: حسنًا. 1357 00:55:32,700 --> 00:55:33,490 العثور على المساحة الأولى. 1358 00:55:33,490 --> 00:55:36,615 إذن سأبدأ [؟ بكومي،؟] وسأتبع هذا المؤشر. 1359 00:55:36,615 --> 00:55:39,011 رقم 5، هل ينتمي رقم 55 إلى هنا؟ 1360 00:55:39,011 --> 00:55:39,510 لا. 1361 00:55:39,510 --> 00:55:42,240 إذن سأتبع هذا المؤشر وأنتقل إلى أندريا. 1362 00:55:42,240 --> 00:55:43,461 هل ينتمي 55 إلى هنا؟ 1363 00:55:43,461 --> 00:55:43,960 لا. 1364 00:55:43,960 --> 00:55:46,931 سأتبع مؤشرها، و22، هل ينتمي إلى هنا؟ 1365 00:55:46,931 --> 00:55:47,430 لا. 1366 00:55:47,430 --> 00:55:48,810 سأتبع هذا المؤشر، 26؟ 1367 00:55:48,810 --> 00:55:49,350 لا. 1368 00:55:49,350 --> 00:55:51,000 لكن يدك حرّة، كما يتضح الأمر. 1369 00:55:51,000 --> 00:55:52,874 إذن ما هي الخطوة التالية؟ 1370 00:55:52,874 --> 00:55:54,850 الجمهور: [INAUDIBLE]. 1371 00:55:54,850 --> 00:55:58,600 ديفيد ج. مالان: يمكننا جعله يشير إلى 55، والآن انتهينا. 1372 00:55:58,600 --> 00:56:02,702 إذن هذا أمر بسيط نسبيًا، ولكن ما هو وقت تشغيل هذا؟ 1373 00:56:02,702 --> 00:56:04,047 الجمهور: [INAUDIBLE]. 1374 00:56:04,047 --> 00:56:05,380 ديفيد ج. مالان: إنه حرف O كبير من n. 1375 00:56:05,380 --> 00:56:06,220 إنه خطي. 1376 00:56:06,220 --> 00:56:08,530 لأنه كان يجب أن أبدأ أولاً، حتى لو 1377 00:56:08,530 --> 00:56:10,210 توفر لدينا نحن البشر رفاهية استراق النظر إليها فقط. 1378 00:56:10,210 --> 00:56:11,860 أن أقول، أوه، من الواضح، أنه ينتمي في طريقه إلى النهاية. 1379 00:56:11,860 --> 00:56:12,400 امم-امم. 1380 00:56:12,400 --> 00:56:13,150 ليس في التعليمة البرمجية. 1381 00:56:13,150 --> 00:56:16,108 مثلما، يجب أن نبدأ في البداية بعكس القائمة اللعينة بالكامل، 1382 00:56:16,108 --> 00:56:17,770 حتى نصل بشكل خطي إلى النهاية. 1383 00:56:17,770 --> 00:56:18,860 والآن ها قد انتهينا. 1384 00:56:18,860 --> 00:56:20,080 دعونا نجرب شيئًا أخيرًا. 1385 00:56:20,080 --> 00:56:21,890 ماذا عن 20؟ 1386 00:56:21,890 --> 00:56:22,550 أجل. 1387 00:56:22,550 --> 00:56:22,780 عظيم. 1388 00:56:22,780 --> 00:56:23,330 تعال إلى هنا. 1389 00:56:23,330 --> 00:56:24,049 ما هو اسمك؟ 1390 00:56:24,049 --> 00:56:24,590 جيمس: أنا جيمس. 1391 00:56:24,590 --> 00:56:25,506 ديفيد ج. مالان: جيمس. 1392 00:56:25,506 --> 00:56:26,230 حسنًا، جيمس. 1393 00:56:26,230 --> 00:56:26,570 حسنًا. 1394 00:56:26,570 --> 00:56:28,750 إذن ألغينا تخصيص جيمس، ومنحناه الرقم 20. 1395 00:56:28,750 --> 00:56:30,541 من الواضح تقريبًا أنه ينتمي إلى المنتصف. 1396 00:56:30,541 --> 00:56:32,500 ما هي الخطوة الأولى؟ 1397 00:56:32,500 --> 00:56:33,460 الجمهور: [INAUDIBLE]. 1398 00:56:33,460 --> 00:56:34,514 ديفيد ج. مالان: معذرةً؟ 1399 00:56:34,514 --> 00:56:35,430 الجمهور: [INAUDIBLE]. 1400 00:56:35,430 --> 00:56:35,860 ديفيد ج. مالان: حسنًا. 1401 00:56:35,860 --> 00:56:36,980 إذن نبدأ مع [؟ كومي،؟] مجددًا. 1402 00:56:36,980 --> 00:56:37,479 حسنًا. 1403 00:56:37,479 --> 00:56:37,980 أولاً، حسنًا. 1404 00:56:37,980 --> 00:56:39,220 5، هل ينتمي إلى هنا؟ 1405 00:56:39,220 --> 00:56:40,132 لا. 1406 00:56:40,132 --> 00:56:41,090 دعوني أتبع الرابط. 1407 00:56:41,090 --> 00:56:42,370 حسنًا 9، هل ينتمي إلى هنا؟ 1408 00:56:42,370 --> 00:56:43,060 لا. 1409 00:56:43,060 --> 00:56:44,822 هل تنتمي إلى 22-- أوه. 1410 00:56:44,822 --> 00:56:46,030 ولكن ما الخطأ الذي ارتكبتُه للتو؟ 1411 00:56:46,030 --> 00:56:48,740 1412 00:56:48,740 --> 00:56:49,582 لقد ذهبتُ بعيدًا للغاية. 1413 00:56:49,582 --> 00:56:50,540 على الأقل في هذا الأمر. 1414 00:56:50,540 --> 00:56:52,330 مثل، أنا حرفيًا-- أندريا خلفي الآن. 1415 00:56:52,330 --> 00:56:52,830 حسنًا. 1416 00:56:52,830 --> 00:56:55,360 هل يمكنني أن أتبع المؤشر من الخلف؟ 1417 00:56:55,360 --> 00:56:55,900 لا يمكنك. 1418 00:56:55,900 --> 00:56:58,000 على سبيل المثال في كل صورة قمنا برسمها، وفي كل مثال 1419 00:56:58,000 --> 00:57:00,400 قمنا به باستخدام عنوان، لدينا فقط عنوان مؤشر next. 1420 00:57:00,400 --> 00:57:03,632 ليس لدينا ما يسمى، بالقائمة المرتبطة بشكل مضاعف، على الأقل في هذا الأمر، 1421 00:57:03,632 --> 00:57:04,840 حيث يمكنني فقط الالتفاف. 1422 00:57:04,840 --> 00:57:05,590 إذن كان هذا خطأ. 1423 00:57:05,590 --> 00:57:06,923 لذا أحتاج إلى البدء من جديد بدلاً من ذلك. 1424 00:57:06,923 --> 00:57:09,100 أولاً، حسنًا 5، حسنًا 19-- 1425 00:57:09,100 --> 00:57:11,200 ما أحتاجه حقًا في التعليمة البرمجية، في نهاية المطاف، هو 1426 00:57:11,200 --> 00:57:14,200 إلقاء نظرة خاطفة إلى الأمام وليس التحرك بالفعل-- بعيدًا هكذا. 1427 00:57:14,200 --> 00:57:15,180 تحديدًا نحو 22. 1428 00:57:15,180 --> 00:57:19,250 سألقي نظرة خاطفة إلى الأمام على 22، وأدرك، أوه، سيكون هذا بعيدًا للغاية. 1429 00:57:19,250 --> 00:57:20,810 هذا ليس بعيدًا بما فيه الكفاية. 1430 00:57:20,810 --> 00:57:22,654 لذلك دعونا نمضي قدمًا ونحضر جيمس إلى هنا. 1431 00:57:22,654 --> 00:57:24,570 حسنًا، في الواقع، يمكنك البقاء هناك من الناحية المادية. 1432 00:57:24,570 --> 00:57:26,230 لكن ما هي الخطوة التي يجب أن تحدث أولاً؟ 1433 00:57:26,230 --> 00:57:29,999 أعرف الآن أنه ينتمي إلى هنا. 1434 00:57:29,999 --> 00:57:31,040 هل تريدين أن تشيري إليه؟ 1435 00:57:31,040 --> 00:57:31,540 حسنًا. 1436 00:57:31,540 --> 00:57:32,294 أشيري إليه. 1437 00:57:32,294 --> 00:57:32,794 أندريا: أوه. 1438 00:57:32,794 --> 00:57:34,190 معذرة، يشير هو أولاً. 1439 00:57:34,190 --> 00:57:35,940 ديفيد ج. مالان: حسنًا، دعونا نفعل ذلك، فقط لأنه غير صحيح. 1440 00:57:35,940 --> 00:57:36,470 هذا جيد. 1441 00:57:36,470 --> 00:57:36,970 حسنًا. 1442 00:57:36,970 --> 00:57:40,330 اقترحت أندريا أن نشير إلى هنا، ولكنها حطمت للتو القائمة المترابطة بالكامل. 1443 00:57:40,330 --> 00:57:40,830 لماذا؟ 1444 00:57:40,830 --> 00:57:42,664 أندريا: لأنه لا يوجد شيء نشير إليه. 1445 00:57:42,664 --> 00:57:43,580 ديفيد ج. مالان: صحيح. 1446 00:57:43,580 --> 00:57:45,110 لا أحد يتذكر-- ما هو اسمك مجددًا؟ 1447 00:57:45,110 --> 00:57:45,470 [? كيونغ: ?] [? كيونغ. ?] 1448 00:57:45,470 --> 00:57:47,140 ديفيد ج. مالان: لا أحد يتذكر أين كان [؟ كيونغ ؟]. 1449 00:57:47,140 --> 00:57:47,660 لذا لا يمكنك فعل ذلك. 1450 00:57:47,660 --> 00:57:49,034 يجب أن تظل يدك اليسرى تشير إلى هناك. 1451 00:57:49,034 --> 00:57:50,802 إذن ما هي الخطوات التي يجب أن تحدث أولاً بدلاً من ذلك؟ 1452 00:57:50,802 --> 00:57:52,220 الجمهور: [INAUDIBLE]. 1453 00:57:52,220 --> 00:57:54,590 ديفيد ج. مالان: يجب على جيمس أن يشير إلى أي شيء 1454 00:57:54,590 --> 00:57:56,280 تشير إليه أندريا، من المحتمل؟ 1455 00:57:56,280 --> 00:57:58,614 لذا يوجد تكرار بعض الشيء في هذه اللحظة، مثلما كان الأمر من قبل. 1456 00:57:58,614 --> 00:57:59,113 حسنًا. 1457 00:57:59,113 --> 00:58:00,060 الآن ما الذي يحدث بعد ذلك؟ 1458 00:58:00,060 --> 00:58:00,726 هذه هي الخطوة الأولى. 1459 00:58:00,726 --> 00:58:01,882 أندريا: الآن يمكنني أن أشير. 1460 00:58:01,882 --> 00:58:03,590 ديفيد ج. مالان: الآن يمكنك أن تشيري إليه. 1461 00:58:03,590 --> 00:58:04,089 حسنًا. 1462 00:58:04,089 --> 00:58:05,040 يمكنك القيام بذلك. 1463 00:58:05,040 --> 00:58:05,540 حسنًا. 1464 00:58:05,540 --> 00:58:08,360 والآن، يبدو هذا فوضويًا بالكامل، 1465 00:58:08,360 --> 00:58:10,790 لكن إذا عرفنا أن [؟ كومي ؟] هي الأولى، 1466 00:58:10,790 --> 00:58:16,910 يمكننا أن نتبع الآثار إلى إريك، ثم إلى أندريا، ثم إلى جيمس، 1467 00:58:16,910 --> 00:58:20,810 ثم بقية قائمتنا خطوة تلو الأخرى. 1468 00:58:20,810 --> 00:58:23,270 إذن إنها كمية كبيرة من الدالة المنطقية الآن. 1469 00:58:23,270 --> 00:58:24,712 لكن ما المشكلة التي قمنا بحلها؟ 1470 00:58:24,712 --> 00:58:26,670 وأعتقد أننا حددنا ذلك هنا في وقت سابق. 1471 00:58:26,670 --> 00:58:29,632 ما هي المشكلة أولاً وقبل كل شيء بالمصفوفات؟ 1472 00:58:29,632 --> 00:58:30,880 الجمهور: [INAUDIBLE]. 1473 00:58:30,880 --> 00:58:33,640 ديفيد ج. مالان: يجب أن تقرر حجمهم مسبقًا. 1474 00:58:33,640 --> 00:58:36,890 وبمجرد قيامك بذلك، إذا أردت إضافة عنصر إضافي، 1475 00:58:36,890 --> 00:58:38,611 فيجب عليك تغيير حجم الشيء كله. 1476 00:58:38,611 --> 00:58:41,110 والذي يُعد مكلفًا لأنك يجب أن تحرك الجميع. 1477 00:58:41,110 --> 00:58:43,239 الآن وبصراحة، سأصبح طماعًا قليلاً هنا. 1478 00:58:43,239 --> 00:58:45,280 وفي كل مرة نقوم بإدخال هذه العناصر الجديدة، 1479 00:58:45,280 --> 00:58:46,904 كنت أُبقيها في ترتيب محدد. 1480 00:58:46,904 --> 00:58:50,530 لذا يبدو أنك إذا أدرجتَ الأشياء بترتيب مُحدد، حدث حرف o كبير، 1481 00:58:50,530 --> 00:58:51,070 كل مرة. 1482 00:58:51,070 --> 00:58:52,600 لأنه في أسوأ الحالات، قد ينتهي العنصر الجديد 1483 00:58:52,600 --> 00:58:54,280 بالتأكيد في النهاية. 1484 00:58:54,280 --> 00:58:55,840 ولكن ماذا لو خفّفنا هذا القيد؟ 1485 00:58:55,840 --> 00:58:59,950 ماذا لو لم أكن متوترًا للغاية وأحتاج إلى أن يكون كل شيء لطيفًا ومنظمًا ومرتبًا؟ 1486 00:58:59,950 --> 00:59:02,950 ماذا لو أردتُ فقط الاستمرار في زيادة القائمة بأي ترتيب عشوائي؟ 1487 00:59:02,950 --> 00:59:05,200 وقمتُ بتخصيص الرقم 34. 1488 00:59:05,200 --> 00:59:06,560 وسأشغّل الرقم 34. 1489 00:59:06,560 --> 00:59:08,090 Malloc 34. 1490 00:59:08,090 --> 00:59:11,710 ما هو أسرع مكان لأنتقل إليه؟ 1491 00:59:11,710 --> 00:59:12,490 أجل؟ 1492 00:59:12,490 --> 00:59:14,180 الجمهور: أشر إلى 5، ثم احصل على [INAUDIBLE].. 1493 00:59:14,180 --> 00:59:14,430 ديفيد ج. مالان: حسنًا. 1494 00:59:14,430 --> 00:59:16,450 سأشير إلى 5، ثم، [؟ كومي، ؟] إذا أمكنك الإشارة إليّ. 1495 00:59:16,450 --> 00:59:17,290 تم. 1496 00:59:17,290 --> 00:59:18,530 خطوة-- حسنًا، خطوتان. 1497 00:59:18,530 --> 00:59:19,030 حسنًا. 1498 00:59:19,030 --> 00:59:22,384 لنفترض الآن، أنني أخصص جزءًا من الذاكرة لـ 17 مع شخصٍ آخر، والذي سنتظاهر 1499 00:59:22,384 --> 00:59:23,300 بأنه هنا مباشرةً. 1500 00:59:23,300 --> 00:59:25,744 ما هو أفضل مكان للرقم 17 للانتقال إليه؟ 1501 00:59:25,744 --> 00:59:26,950 الجمهور: [INAUDIBLE]. 1502 00:59:26,950 --> 00:59:28,783 ديفيد ج. مالان: مباشرةً بعد [? كومي ?] أيضًا. 1503 00:59:28,783 --> 00:59:33,320 لذا الآن، [? كومي ?] يمكن أن تشير إلى 17، 17 يمكن أن يشير إليّ، ويمكنني أن أشير إلى إريك، 1504 00:59:33,320 --> 00:59:34,490 وهكذا. 1505 00:59:34,490 --> 00:59:35,740 وهاتان الخطوتان مرة أخرى. 1506 00:59:35,740 --> 00:59:38,073 خطوتان-- إذا كان نفس عدد الخطوات في كل مرة، 1507 00:59:38,073 --> 00:59:39,310 سنطلق على ذلك، الوقت الثابت. 1508 00:59:39,310 --> 00:59:41,440 ونكتبه كحرف o كبير من 1. 1509 00:59:41,440 --> 00:59:43,120 وهنا أيضًا، إنها مجرد مقايضة. 1510 00:59:43,120 --> 00:59:46,570 إذا كنت تريد إدراجات سريعة بالفعل، لا تقلق بشأن الترتيب. 1511 00:59:46,570 --> 00:59:48,820 ضَعهم فقط في البداية وتعامل معهم لاحقًا. 1512 00:59:48,820 --> 00:59:52,904 إذا كنت تريد إمكانية تغيير حجم ديناميكية لا تستخدم مصفوفة، استخدم قائمة مرتبطة، 1513 00:59:52,904 --> 00:59:55,570 وفقط حافظ على التخصيص أكثر وأكثر حيثما تنتقل دون إهدار 1514 00:59:55,570 --> 00:59:56,819 كمية كبيرة من المساحة أيضًا. 1515 00:59:56,819 --> 00:59:59,110 لاحظوا أن، هذه مشكلة كبيرة أخرى بالمصفوفة. 1516 00:59:59,110 --> 01:00:02,930 إذا كنت تخصص مساحة أكثر من اللازم، وتستخدم فقط جزءًا منها، فأنت تهدر مساحة فقط. 1517 01:00:02,930 --> 01:00:04,404 لذا لا يوجد حل واحد هنا. 1518 01:00:04,404 --> 01:00:06,820 ولكن الآن لدينا القدرات، والفضل يعود إلى البنيات 1519 01:00:06,820 --> 01:00:11,440 والمؤشرات لجمع هذه المشكلات الجديدة معًا، إذا أردتَ. 1520 01:00:11,440 --> 01:00:12,145 نعم، من فضلك. 1521 01:00:12,145 --> 01:00:13,936 المتحدث 2: لماذا لا تستطيع العقدة [INAUDIBLE]؟؟ 1522 01:00:13,936 --> 01:00:17,360 1523 01:00:17,360 --> 01:00:19,464 ديفيد ج. مالان: ومن أنا في هذه القصة؟ 1524 01:00:19,464 --> 01:00:20,432 المتحدث 2: [INAUDIBLE]. 1525 01:00:20,432 --> 01:00:21,390 ديفيد ج. مالان: أوه، حسنًا. 1526 01:00:21,390 --> 01:00:22,000 قطعًا. 1527 01:00:22,000 --> 01:00:24,330 لذا فكرة أخرى معقولة جدًا ستكون، حسنًا، 1528 01:00:24,330 --> 01:00:26,610 لماذا لا نضع تلك الجديدة في النهاية؟ 1529 01:00:26,610 --> 01:00:30,220 هذا جيد إذا كنت أقوم بمتابعة مسار مَن هو في النهاية. 1530 01:00:30,220 --> 01:00:32,250 المشكلة، هي في هذه اللحظة في القصة، 1531 01:00:32,250 --> 01:00:35,416 وسنرى في النهاية هذا في التعليمة البرمجية، أتذكر فقط [؟ كومي. ؟] 1532 01:00:35,416 --> 01:00:37,800 ومن [? كومي ?] سأحصل على أي مكان آخر. 1533 01:00:37,800 --> 01:00:40,230 يمكنني الحصول على مؤشر آخر، مؤشر ثانٍ، 1534 01:00:40,230 --> 01:00:42,750 وأطلق عليه حرفيًا، الأخير، هذا يعادلك. 1535 01:00:42,750 --> 01:00:44,400 أو يشير هذا دائمًا إليك. 1536 01:00:44,400 --> 01:00:46,860 أنا فقط بحاجة إلى مؤشرين، أحدهما يسمى حرفيًا الأول، 1537 01:00:46,860 --> 01:00:47,943 وواحد يسمى حرفيًا الثاني. 1538 01:00:47,943 --> 01:00:48,630 هذا جيد. 1539 01:00:48,630 --> 01:00:52,230 هذا تحسين جيد إذا أردت إلقاء كل العناصر في النهاية. 1540 01:00:52,230 --> 01:00:54,570 وبصراحة، يمكنني أن أكون خياليًا حقًا-- 1541 01:00:54,570 --> 01:00:57,300 ولحل المشكلة التي ذكرتها أندريا في وقت سابق-- 1542 01:00:57,300 --> 01:01:00,870 إذا قمت بتخزين ليس فقط عدد صحيح ومؤشر، ولكن بدلاً من ذلك، 1543 01:01:00,870 --> 01:01:03,570 عدد صحيح ومؤشرين، يمكنني جعل كل شخص 1544 01:01:03,570 --> 01:01:05,850 من هؤلاء الشباب أن يشيروا بأيديهم اليسرى واليمنى 1545 01:01:05,850 --> 01:01:10,530 في قائمة مرتبطة بشكل مضاعف، وذلك لحل المشكلة التي ذكرتها أندريا، والتي 1546 01:01:10,530 --> 01:01:12,580 كانت إذا ذهبت بعيدًا للغاية فليس هذا بالأمر المهم. 1547 01:01:12,580 --> 01:01:13,535 ارجع خطوة للخلف. 1548 01:01:13,535 --> 01:01:15,840 ليس علي أن أفكر بجد حول هذا المنطق. 1549 01:01:15,840 --> 01:01:17,220 لذا هناك أيضًا، مقايضة. 1550 01:01:17,220 --> 01:01:18,510 دعونا نمضي قدمًا ونأخذ خمس دقائق استراحة. 1551 01:01:18,510 --> 01:01:19,200 سأشغل بعض الموسيقى. 1552 01:01:19,200 --> 01:01:20,250 التقط بطة الآن، إذا كنت ترغب في ذلك. 1553 01:01:20,250 --> 01:01:22,650 وسنعود مع بعض بنيات البيانات الأكثر خيالاً إلى الآن. 1554 01:01:22,650 --> 01:01:23,950 شكرًا. 1555 01:01:23,950 --> 01:01:24,450 حسنًا. 1556 01:01:24,450 --> 01:01:24,949 عدنا. 1557 01:01:24,949 --> 01:01:27,577 لذلك دعونا الآن نترجم بعض هذه الأفكار إلى تعليمة برمجية. 1558 01:01:27,577 --> 01:01:29,910 بحيث يمكننا في الواقع حل هذه المشكلة بشكل 1559 01:01:29,910 --> 01:01:32,770 ملموس أكثر من مجرد وجود بشر يشيرون إلى بعضهم البعض. 1560 01:01:32,770 --> 01:01:34,830 لذا على سبيل المثال، دعونا نحاول استخلاص كل شيء 1561 01:01:34,830 --> 01:01:37,350 كنا نتحدث عنه في مجرد هدف في التعليمة البرمجية 1562 01:01:37,350 --> 01:01:39,180 الخاصة بتخزين قائمة من الأرقام. 1563 01:01:39,180 --> 01:01:42,630 أقترح أنه يمكننا أخذ ثلاث بطاقات في هذه المسألة. 1564 01:01:42,630 --> 01:01:45,622 ستكون الأولى، دعونا فقط نقرر مسبقًا كم عدد الأرقام التي 1565 01:01:45,622 --> 01:01:47,580 نريد تخزينها بحيث لا نضطر إلى التعامل مع كل 1566 01:01:47,580 --> 01:01:50,550 هذا التعقيد في الإشارة والمؤشرات وكل هذا، 1567 01:01:50,550 --> 01:01:53,730 وفقط التعليمة البرمجية الثابتة والتي لها قيمة بطريقة ما، ونتوقف فقط 1568 01:01:53,730 --> 01:01:56,670 عندما يُدخل المستخدم العديد من الأرقام وليس أكثر من ذلك. 1569 01:01:56,670 --> 01:02:01,410 الثانية، يمكننا تحسين ذلك وعلى الأقل ندع المستخدم يقوم بتغيير حجم 1570 01:02:01,410 --> 01:02:02,250 مصفوفته بشكل ديناميكي. 1571 01:02:02,250 --> 01:02:05,040 لذا إذا قرر إدخال أرقام أكثر مما كنا نتطلع إليه، 1572 01:02:05,040 --> 01:02:06,720 ستنمو وتتعامل مع هذا. 1573 01:02:06,720 --> 01:02:08,670 بالطبع، المصفوفات ليست بالضرورة مثالية 1574 01:02:08,670 --> 01:02:11,550 لأنها يجب عليها أن تقوم بكل هذا النسخ من القديم إلى الجديد. 1575 01:02:11,550 --> 01:02:12,600 هذا زمن خطي. 1576 01:02:12,600 --> 01:02:14,905 سيبدو أكثر ذكاء للحصول على subversion 3، الذي 1577 01:02:14,905 --> 01:02:16,530 سيستخدم في الواقع قائمة مرتبطة. 1578 01:02:16,530 --> 01:02:20,670 إذن نحن فقط بكل تواضع نقوم بتخصيص مساحة لرقم آخر، 1579 01:02:20,670 --> 01:02:23,490 ورقم آخر، ورقم آخر، أو عقدة بالفعل. 1580 01:02:23,490 --> 01:02:25,150 رقم واحد في كل مرة. 1581 01:02:25,150 --> 01:02:27,190 لذا دعوني أمضي قدمًا وأبدأ على النحو التالي. 1582 01:02:27,190 --> 01:02:33,420 سأمضي قدمًا وسأضمّن بعض السطور المألوفة في قائمة 0.c، 1583 01:02:33,420 --> 01:02:36,900 من مكتبة CS50، فقط لجعل الأمر سهلاً للحصول على بعض مدخلات المستخدم لهذا الغرض. 1584 01:02:36,900 --> 01:02:38,970 وstandard iO نقطة h، لأجل printdef. 1585 01:02:38,970 --> 01:02:42,264 ودعوني أمضي قدمًا وأعلن عن الدالة الرئيسية الخاصة بي كالمعتاد. 1586 01:02:42,264 --> 01:02:44,180 وبعد ذلك، هنا دعونا نقوم ببعض الأشياء. 1587 01:02:44,180 --> 01:02:48,630 أولاً، دعونا نطلب من المستخدم سعة المصفوفة 1588 01:02:48,630 --> 01:02:49,650 التي سنستخدمها. 1589 01:02:49,650 --> 01:02:50,941 أو بالأحرى، دعونا نقوم بذلك أولاً. 1590 01:02:50,941 --> 01:02:53,250 دعوني أولاً أرجع وأقول، أتعرفون ما الأمر؟ 1591 01:02:53,250 --> 01:02:55,290 عدد صحيح، أرقام، 50. 1592 01:02:55,290 --> 01:02:58,080 حسنًا، سيكون هذا الأمر مزعجًا للكتابة في 50 رقمًا. 1593 01:02:58,080 --> 01:03:01,610 سنعطي المستخدم رقمين في البداية، وهي هنا، يمكنها الكتابة فيها. 1594 01:03:01,610 --> 01:03:05,660 بعد ذلك، دعونا نمضي قدمًا ونطلب من المستخدم لهذه الأرقام. 1595 01:03:05,660 --> 01:03:09,107 لذا دعوني أمضي قُدمًا وأقول-- 1596 01:03:09,107 --> 01:03:09,690 لنقم بذلك. 1597 01:03:09,690 --> 01:03:13,500 دعونا على الأقل نقوم بتنظيف هذا قليلاً حتى نتمكن من إعادة استخدام هذه القيمة. 1598 01:03:13,500 --> 01:03:14,910 إذن ليس لدينا رقم سحري. 1599 01:03:14,910 --> 01:03:16,830 ظهر هذا للتو في المناقشة في الواقع. 1600 01:03:16,830 --> 01:03:20,721 لذا بينما-- هل أريد القيام بذلك؟ 1601 01:03:20,721 --> 01:03:21,220 كلا. 1602 01:03:21,220 --> 01:03:22,140 دعوني أصلح هذا. 1603 01:03:22,140 --> 01:03:24,817 ستكون هذه سعتي من الحجم 2. 1604 01:03:24,817 --> 01:03:26,400 وهذا سيعطيني هذا الحجم. 1605 01:03:26,400 --> 01:03:28,710 وبعد ذلك، سأستمر في تعقب كم عدد الأعداد الصحيحة 1606 01:03:28,710 --> 01:03:30,624 التي طلبتها من المستخدم حتى الآن. 1607 01:03:30,624 --> 01:03:33,040 لذا في البداية، سيكون حجم هذه البنية 0. 1608 01:03:33,040 --> 01:03:35,280 لكن ستكون سعتها، إذا جاز التعبير، 2. 1609 01:03:35,280 --> 01:03:36,960 لذا الحجم يشير إلى عدد الأشياء الموجودة بها. 1610 01:03:36,960 --> 01:03:39,370 تشير السعة إلى عدد الأشياء التي يمكن أن تكون بها. 1611 01:03:39,370 --> 01:03:43,200 وفي نفس الوقت حجم البنية أقل من سعتها، 1612 01:03:43,200 --> 01:03:45,460 لنمضِ قدمًا ونحصل على بعض المدخلات من المستخدم. 1613 01:03:45,460 --> 01:03:49,740 دعونا نمضي قدمًا ونطلب منه رقمًا، وذلك باستخدام صديقنا القديم، get int. 1614 01:03:49,740 --> 01:03:51,450 ولنقل فقط، أعطني رقمًا. 1615 01:03:51,450 --> 01:03:54,810 ثم، دعوني أمضي قدمًا وأدخل الرقم 1616 01:03:54,810 --> 01:04:00,390 الذي كتبه في هذه المصفوفة في حجم موقع، هكذا. 1617 01:04:00,390 --> 01:04:02,970 وبعد ذلك، أكتب حجم زائد، زائد. 1618 01:04:02,970 --> 01:04:03,660 أعتقد. 1619 01:04:03,660 --> 01:04:05,410 لقد كتبته بسرعة. 1620 01:04:05,410 --> 01:04:07,200 لكن لنفكر في ما فعلته للتو. 1621 01:04:07,200 --> 01:04:10,530 قمت بتهيئة الحجم إلى 0، لأنه لا يوجد شيء فيه من البداية. 1622 01:04:10,530 --> 01:04:13,980 ثم أقول، بينما يكون الحجم أقل من سعة كل شيء-- 1623 01:04:13,980 --> 01:04:15,810 والسعة هي 2 افتراضيًا-- 1624 01:04:15,810 --> 01:04:17,100 فامضِ قدمًا وقم بما يلي. 1625 01:04:17,100 --> 01:04:19,460 أعطني عددًا صحيحًا من المستخدم. 1626 01:04:19,460 --> 01:04:19,960 حسنًا. 1627 01:04:19,960 --> 01:04:21,720 إذن int number = get-int. 1628 01:04:21,720 --> 01:04:25,920 ثم ضَع في الموقع، الحجم، في أرقامي، مصفوفة، 1629 01:04:25,920 --> 01:04:28,020 أيًا كان ما كتبه الشخص فيها، فهو رقم. 1630 01:04:28,020 --> 01:04:30,850 ثم، قم بزيادة الحجم باستخدام زائد، زائد. 1631 01:04:30,850 --> 01:04:31,350 حسنًا. 1632 01:04:31,350 --> 01:04:33,090 لذا في التكرار الأول الحجم يساوي 0. 1633 01:04:33,090 --> 01:04:35,280 لذا الأرقام، قوس، 0، تحصل على الرقم الأول. 1634 01:04:35,280 --> 01:04:37,380 الأرقام، قوس، 1، تحصل على الرقم الثاني. 1635 01:04:37,380 --> 01:04:39,190 ثم، الحجم يساوي السعة. 1636 01:04:39,190 --> 01:04:40,440 لذلك يتوقف، منطقيًا. 1637 01:04:40,440 --> 01:04:44,531 أي أسئلة حول منطق هذه التعليمة البرمجية؟ 1638 01:04:44,531 --> 01:04:45,030 حسنًا. 1639 01:04:45,030 --> 01:04:48,240 لذا بمجرد حصولنا على هذه الأرقام، فلنقم فقط بشيء بسيط. 1640 01:04:48,240 --> 01:04:50,730 على سبيل المثال، for int, i get 0. 1641 01:04:50,730 --> 01:04:53,970 I أقل من الحجم الفعلي I، زائد، زائد. 1642 01:04:53,970 --> 01:05:00,210 دعونا فقط نمضي قدمًا ونطبع الرقم 1643 01:05:00,210 --> 01:05:07,300 الذي أدخلته، %i، خط مائل عكسي n، ونكتب الأرقام، قوس، i. 1644 01:05:07,300 --> 01:05:07,800 حسنًا. 1645 01:05:07,800 --> 01:05:12,780 لذلك إذا لم أقم بأية أخطاء في القائمة 0 نقطة C، إذن، سأمضي قدمًا 1646 01:05:12,780 --> 01:05:16,180 وأكتب نقطة، خط مائل، o، نقطة، C. وسيطلب مني كتابة رقمين. 1647 01:05:16,180 --> 01:05:18,690 لنمضِ قدمًا ونقوم بكتابة 1، 2. 1648 01:05:18,690 --> 01:05:19,991 قمت بإدخال 1، وقمت بإدخال 2. 1649 01:05:19,991 --> 01:05:20,490 حسنًا. 1650 01:05:20,490 --> 01:05:21,360 ليس سيئًا. 1651 01:05:21,360 --> 01:05:23,820 ولكن هذا تصميم سيء، بالتأكيد، لماذا؟ 1652 01:05:23,820 --> 01:05:27,160 1653 01:05:27,160 --> 01:05:29,610 فقط اعثروا على خطأ واحد. إنه صحيح. 1654 01:05:29,610 --> 01:05:32,332 ولكن التصميم سيئ. 1655 01:05:32,332 --> 01:05:33,974 الجمهور: متكرر. 1656 01:05:33,974 --> 01:05:36,890 ديفيد ج. مالان: متكرر، لأنني أستخدم زوجًا من التكرارات الحلقية، بالتأكيد. 1657 01:05:36,890 --> 01:05:39,560 وهو في الأساس-- محدود للغاية في الدالة. 1658 01:05:39,560 --> 01:05:40,160 لماذا؟ 1659 01:05:40,160 --> 01:05:42,297 ما مدى فائدة هذا البرنامج؟ 1660 01:05:42,297 --> 01:05:43,760 الجمهور: تم ترميزه بشكل ثابت في 2. 1661 01:05:43,760 --> 01:05:43,917 ديفيد ج. مالان: أجل. 1662 01:05:43,917 --> 01:05:44,930 تم ترميزه بشكل ثابت في 2. 1663 01:05:44,930 --> 01:05:47,210 لذا دعونا على الأقل نقوم بتحسين هذا قليلاً، 1664 01:05:47,210 --> 01:05:48,650 والتخلص من هذه التعليمة البرمجية الثابتة. 1665 01:05:48,650 --> 01:05:52,110 لماذا لا أطلب على الأقل من المستخدم شيئًا كهذا؟ 1666 01:05:52,110 --> 01:05:56,857 حسنًا، بدلاً من مجرد الإعلان عن السعة، دعوني أمضي قدمًا وأقول، 1667 01:05:56,857 --> 01:05:57,440 أتعلمون ماذا؟ 1668 01:05:57,440 --> 01:05:58,580 دعونا فقط نستبدل 2. 1669 01:05:58,580 --> 01:06:01,651 get int، ولنقل فقط السعة، على سبيل المثال. 1670 01:06:01,651 --> 01:06:02,150 حسنًا. 1671 01:06:02,150 --> 01:06:05,360 والآن إذا قمت بهذا، سيُطلب مني-- 1672 01:06:05,360 --> 01:06:07,600 إذن make list0. 1673 01:06:07,600 --> 01:06:10,040 نقطة خط مائل list 0. 1674 01:06:10,040 --> 01:06:12,020 ستكون السعة 2. 1675 01:06:12,020 --> 01:06:14,190 1، 2، هذا لطيف. 1676 01:06:14,190 --> 01:06:17,120 ولكن إذا قمت بتشغيله مرة أخرى، وأعطيته السعة 3-- 1677 01:06:17,120 --> 01:06:21,266 1، 2، 3، أحصل على المزيد من السعة. 1678 01:06:21,266 --> 01:06:21,890 لذا هذا لطيف. 1679 01:06:21,890 --> 01:06:23,240 إنه تحسن بالتأكيد. 1680 01:06:23,240 --> 01:06:25,160 يوجد خطأ هنا. 1681 01:06:25,160 --> 01:06:33,134 قبل أن أخضعه لمزيد من الاختبارات، هل يمكن لأحد أن يُعرّف الخطأ أو بطريقة ما يقوم بتعطيل هذا؟ 1682 01:06:33,134 --> 01:06:34,050 الجمهور: [INAUDIBLE]. 1683 01:06:34,050 --> 01:06:34,904 ديفيد ج. مالان: أوه، امضِ قدمًا. 1684 01:06:34,904 --> 01:06:36,571 الجمهور: إذا لم تقم بإدخال عدد صحيح. 1685 01:06:36,571 --> 01:06:38,320 ديفيد ج. مالان: إذا لم أقم بإدخال رقم صحيح. 1686 01:06:38,320 --> 01:06:39,844 أو-- هل هو نفس التعليق بالأعلى هنا؟ 1687 01:06:39,844 --> 01:06:42,219 الجمهور: سأقول، ماذا يحدث إذا رجعت للوراء 1688 01:06:42,219 --> 01:06:47,419 ووضعت في [INAUDIBLE] تلك [INAUDIBLE] الأخرى التي ستكون في الذاكرة. 1689 01:06:47,419 --> 01:06:48,210 ديفيد ج. مالان: أوه. 1690 01:06:48,210 --> 01:06:48,530 لا. 1691 01:06:48,530 --> 01:06:50,113 لأنني أعيد تشغيله في كل مرة. 1692 01:06:50,113 --> 01:06:53,210 لا أحتاج إلى القلق بشأن عمليات إعادة التشغيل السابقة للبرنامج. 1693 01:06:53,210 --> 01:06:53,832 أجل؟ 1694 01:06:53,832 --> 01:06:56,160 الجمهور: في التكرار الحلقي من نوع for، إنه فقط 1، 1695 01:06:56,160 --> 01:06:59,786 2، 3، إنه لا يهتم في الواقع كيف وضعتَه. 1696 01:06:59,786 --> 01:07:03,560 ديفيد ج. مالان: [INAUDIBLE] 1، 2، 3-- حسنًا، أنا أتحدث عن الحجم، 1697 01:07:03,560 --> 01:07:04,640 والذي يمكن أن يكون السعة. 1698 01:07:04,640 --> 01:07:06,650 لأنهما في النهاية الآن متعادلان. 1699 01:07:06,650 --> 01:07:08,180 لأنني أقوم بتعبئة كل شيء. 1700 01:07:08,180 --> 01:07:08,780 لكن دعونا نجرب ذلك. 1701 01:07:08,780 --> 01:07:10,010 إذا لم تكتب قيمة. 1702 01:07:10,010 --> 01:07:12,670 لذا دعوني أمضي قُدمًا وأعيد تشغيل هذا. 1703 01:07:12,670 --> 01:07:15,871 ستكون سعتي duck. 1704 01:07:15,871 --> 01:07:16,370 حسنًا. 1705 01:07:16,370 --> 01:07:17,780 لذا تعاملنا مع ذلك. 1706 01:07:17,780 --> 01:07:19,380 لأن getInt قام بذلك لأجلي. 1707 01:07:19,380 --> 01:07:21,920 لكنني أراهن أنه ما يزال بإمكاني تعطيل هذا. 1708 01:07:21,920 --> 01:07:24,260 أوه، نعم، دعونا دائمَا نحاول تجربة شيء سلبي. 1709 01:07:24,260 --> 01:07:25,160 أوه، حسنًا. 1710 01:07:25,160 --> 01:07:25,750 سيء جدًا. 1711 01:07:25,750 --> 01:07:27,500 مثل الرسالة التي تبدو مشفرة، ولكن بوضوح، 1712 01:07:27,500 --> 01:07:28,980 لها علاقة بقيمة سالبة. 1713 01:07:28,980 --> 01:07:31,260 لذا ربما يجب أن أكون أكثر ذكاء قليلاً بشأن هذا الأمر. 1714 01:07:31,260 --> 01:07:33,459 وتذكرون أننا من الأسبوع 1، قمنا بذلك. 1715 01:07:33,459 --> 01:07:35,000 مع ماريو، قد قمت بذلك. 1716 01:07:35,000 --> 01:07:41,840 حتى أتمكن من القيام بشيء على سبيل المثال، القيام، عندما تكون السعة أقل من 1. 1717 01:07:41,840 --> 01:07:46,520 يمكنني أن أمضي قدمًا وأقول، السعة getInt السعة. 1718 01:07:46,520 --> 01:07:50,100 لذا التحقق من الخطأ إلى حد ما لإغلاق الخطأ الذي قمت بتحديده. 1719 01:07:50,100 --> 01:07:50,600 حسنًا. 1720 01:07:50,600 --> 01:07:52,340 لذا لنمضي قُدمًا ونعد تحويل هذا برمجيًا. 1721 01:07:52,340 --> 01:07:57,044 Make lists 0-- عذرًا سنبدأ بسماع هذا كثيرًا اليوم. 1722 01:07:57,044 --> 01:07:57,960 ألم [INAUDIBLE]؟ 1723 01:07:57,960 --> 01:08:00,330 Make list0، نقطة، خط مائل، list0. 1724 01:08:00,330 --> 01:08:01,490 ستكون السعة 3. 1725 01:08:01,490 --> 01:08:02,987 1، 2، 3. 1726 01:08:02,987 --> 01:08:04,320 ستكون السعة الآن -1. 1727 01:08:04,320 --> 01:08:05,890 لا تسمح بذلك. 1728 01:08:05,890 --> 01:08:07,410 السعة 0، لا تسمح بذلك. 1729 01:08:07,410 --> 01:08:09,300 السعة 1، نعم. 1730 01:08:09,300 --> 01:08:11,010 لذا بشكل غير شامل، لقد اختبرت ذلك. 1731 01:08:11,010 --> 01:08:12,240 يبدو الأمر كما لو كان في شكل أفضل. 1732 01:08:12,240 --> 01:08:12,740 حسنًا. 1733 01:08:12,740 --> 01:08:16,410 لكن هذا البرنامج، في حين أنه صحيح، وبه ميزات أكثر، 1734 01:08:16,410 --> 01:08:18,390 ما يزال لديه هذا الحد الأساسي. 1735 01:08:18,390 --> 01:08:21,779 ألن يكون من الجيد السماح للمستخدم بمواصلة كتابة الأرقام فقط، 1736 01:08:21,779 --> 01:08:26,410 بقدر ما يريد، ثم الخروج بمجرد الانتهاء من إدخال الأرقام. 1737 01:08:26,410 --> 01:08:26,910 أليس كذلك؟ 1738 01:08:26,910 --> 01:08:29,100 إذا كنت بصدد إنشاء برنامج لبرمجة GPA الخاص بشخصٍ ما، 1739 01:08:29,100 --> 01:08:31,350 قد يشترك طلاب مختلفون في دورات مختلفة، 1740 01:08:31,350 --> 01:08:33,930 أنت لا تريد أن يسجل جميعهم في الدورات 32 كلها. 1741 01:08:33,930 --> 01:08:35,680 إذا كانوا أصغر سنًا ولم يشتركوا في جميع هذه الدورات. 1742 01:08:35,680 --> 01:08:38,471 على سبيل المثال توجد العديد من السيناريوهات إذا كنت لا تعرف مسبقًا عدد 1743 01:08:38,471 --> 01:08:40,319 الأرقام التي يريد المستخدم تقديمها. 1744 01:08:40,319 --> 01:08:43,950 لكنك تريد دعم بضعة أرقام، الكثير من الأرقام، أو ما يفوق ذلك. 1745 01:08:43,950 --> 01:08:46,319 لذلك لنقم بذلك في إصدار ثانٍ. 1746 01:08:46,319 --> 01:08:52,720 في list 1 نقطة C، دعوني أمضي قدمًا وأقوم بتحسين هذا المثال على النحو التالي. 1747 01:08:52,720 --> 01:08:57,420 أولاً، دعوني أعطي أصدقائي المعروفين هنا CS50 نقطة لمعيار IO، 1748 01:08:57,420 --> 01:09:02,910 standard iO نقطة h، ثم، هنا، int main void. 1749 01:09:02,910 --> 01:09:05,130 ومن ثم، دعونا نبدأ في كتابة هذا. 1750 01:09:05,130 --> 01:09:10,986 لذا الآن، لا أعرف مسبقًا، بالضرورة، ما عدد الأرقام 1751 01:09:10,986 --> 01:09:11,819 الذي سيكتبه المستخدم. 1752 01:09:11,819 --> 01:09:13,819 على سبيل المثال الهدف هو، أنني أريدهم قادرين على كتابة 1753 01:09:13,819 --> 01:09:16,140 رقم، ورقم آخر، ورقم آخر، ومن ثم 1754 01:09:16,140 --> 01:09:19,651 أضرب المعادل من هذا، q، للخروج، عند الانتهاء من إدخال الأرقام. 1755 01:09:19,651 --> 01:09:22,859 كما أنني لا أريدهم أن يفكروا مسبقًا، ما هو عدد الأرقام 1756 01:09:22,859 --> 01:09:24,930 الذي يدخلوه. 1757 01:09:24,930 --> 01:09:26,140 لكن كيف يمكنني فعل ذلك؟ 1758 01:09:26,140 --> 01:09:30,100 كما لو أنه لا يمكنني فقط إنشاء مصفوفة تُسمى أرقام، وقول، 50. 1759 01:09:30,100 --> 01:09:32,580 لأنه إذا أراد المستخدم كتابة 51 رقمًا، 1760 01:09:32,580 --> 01:09:34,050 سأضطر إلى تغيير حجم ذلك. 1761 01:09:34,050 --> 01:09:36,495 لكن كيف يمكنك تغيير حجم مصفوفة؟ 1762 01:09:36,495 --> 01:09:39,470 1763 01:09:39,470 --> 01:09:41,791 كيف تقوم بتغيير حجم مصفوفة؟ 1764 01:09:41,791 --> 01:09:43,010 الجمهور: [INAUDIBLE]. 1765 01:09:43,010 --> 01:09:43,270 ديفيد ج. مالان: ما هذا؟ 1766 01:09:43,270 --> 01:09:44,069 الجمهور: لا يمكنك ذلك. 1767 01:09:44,069 --> 01:09:44,850 ديفيد ج. مالان: لا يمكنك ذلك. 1768 01:09:44,850 --> 01:09:45,029 حسنًا. 1769 01:09:45,029 --> 01:09:47,720 لم نر مثالاً حيث تم تغيير حجم مصفوفة من قبل. 1770 01:09:47,720 --> 01:09:49,470 تحدثنا عن ذلك على اللوح هنا. 1771 01:09:49,470 --> 01:09:52,700 حسنًا، فقطمثل، تخصيص واحدة أكبر ونسخ كل شيء فيها. 1772 01:09:52,700 --> 01:09:54,720 وقد حددنا realloc. 1773 01:09:54,720 --> 01:09:57,600 لكن لا يمكنك في الواقع استخدام realloc على مصفوفة. 1774 01:09:57,600 --> 01:10:01,350 يقبل realloc بالفعل عنوان جزء من الذاكرة 1775 01:10:01,350 --> 01:10:04,050 الذي تريد تكبيره، أو تقليصه. 1776 01:10:04,050 --> 01:10:06,420 لذا يتضح أنه، إذا بدأنا الآن في استغلال 1777 01:10:06,420 --> 01:10:10,470 هذا النوع من التعريف الأساسي لما تعنيه المصفوفة، جزء من الذاكرة، 1778 01:10:10,470 --> 01:10:13,500 يمكننا في الواقع بناء المصفوفات بأنفسنا. 1779 01:10:13,500 --> 01:10:16,710 إذا كانت المصفوفة فقط جزءًا من الذاكرة، أو بشكل أكثر تحديدًا، 1780 01:10:16,710 --> 01:10:21,000 إنها مثل عنوان وحدة البايت الأولى من جزء من الذاكرة، 1781 01:10:21,000 --> 01:10:25,620 يبدو أنني سأتمكن من إعلان مصفوفتي، وليس باستخدام أقواس مربعة 1782 01:10:25,620 --> 01:10:27,940 كما كنا نفعل لمدة أسابيع، ولكن يمكنني القول، 1783 01:10:27,940 --> 01:10:31,020 أنتم تعرفون ما هي الأرقام حقًا، إنها مجرد مؤشر فقط. 1784 01:10:31,020 --> 01:10:33,570 وأنا في البداية سأقوم بتهيئتها إلى فارغ. 1785 01:10:33,570 --> 01:10:35,470 لأنه لا توجد مصفوفة. 1786 01:10:35,470 --> 01:10:37,950 لكن الآن لدي القدرة للإشارة إلى هذا المؤشر 1787 01:10:37,950 --> 01:10:41,010 في أي جزء من الذاكرة، صغيرًا كان أو كبير. 1788 01:10:41,010 --> 01:10:42,160 الآن لماذا هذا مفيد؟ 1789 01:10:42,160 --> 01:10:44,460 حسنًا دعوني في البداية أزعم أن سعتي هي 0، 1790 01:10:44,460 --> 01:10:45,780 لأن لا شيء يحدث حتى الآن. 1791 01:10:45,780 --> 01:10:47,820 أنا لم أطلب malloc أو أي شيء. 1792 01:10:47,820 --> 01:10:52,080 وفي البداية، يكون حجمي هو 0 لأنه لا يوجد شيء في المصفوفة. 1793 01:10:52,080 --> 01:10:53,640 وليس لديها حجم. 1794 01:10:53,640 --> 01:10:55,770 لكن دعوني أفعل هذا إلى الأبد. 1795 01:10:55,770 --> 01:10:59,220 تمامًا كما كان في سكراتش، لدينا كتلة أبدية يمكنك استخدامها، عندما تكون صحيحة، وC، 1796 01:10:59,220 --> 01:11:02,850 لأقول فقط استمر في فعل هذا حتى يعطل المستخدم هذا. 1797 01:11:02,850 --> 01:11:06,690 ودعوني أمضي قدمًا وأطلب من المستخدم، أعطني رقمًا، getInt. 1798 01:11:06,690 --> 01:11:09,060 وأطلب منه رقم فقط. 1799 01:11:09,060 --> 01:11:11,580 ثم، نحتاج فقط إلى مكان لوضع ذلك فيه. 1800 01:11:11,580 --> 01:11:14,580 إذن أين أضع هذا الرقم؟ 1801 01:11:14,580 --> 01:11:18,000 حسنًا، هل لدي، في هذه اللحظة، أي مكان لوضع الرقم فيه؟ 1802 01:11:18,000 --> 01:11:18,600 لا. 1803 01:11:18,600 --> 01:11:20,790 ومن الناحية الفنية، كيف يمكنك التعبير عن ذلك؟ 1804 01:11:20,790 --> 01:11:25,110 كما هو الحال في رمز زائف، أريد أن أقول، إذا لم يكن هناك مكان لرقم. 1805 01:11:25,110 --> 01:11:26,700 لكن من الناحية الفنية، يمكنني القيام بذلك. 1806 01:11:26,700 --> 01:11:33,030 حسنًا، إذا كان حجم المصفوفة في هذه اللحظة، يساوي سعتها، 1807 01:11:33,030 --> 01:11:36,360 هذا يبدو وكأنه وسيلة ذات مستوى أقل للتعبير عن نفس الشيء. 1808 01:11:36,360 --> 01:11:41,130 أيَا كانت السعة، إذا كان الحجم هو نفسه، لا توجد مساحة إضافية. 1809 01:11:41,130 --> 01:11:47,100 كما تخفي هذه العبارة البسيطة أيضًا السيناريو حيت تكون السعة 0، 1810 01:11:47,100 --> 01:11:48,570 وبالتالي الحجم 0. 1811 01:11:48,570 --> 01:11:50,280 لذا إنه نفس السؤال. 1812 01:11:50,280 --> 01:11:52,590 سواء لم تكن لدينا مساحة للكل، أو كانت لدينا بعض المساحة 1813 01:11:52,590 --> 01:11:56,260 ولكننا استخدمناها كلها-- الحجم يساوي، يساوي، السعة. 1814 01:11:56,260 --> 01:11:59,730 لذا إذا كان الحجم يساوي السعة، أو أضعه بشكل مباشر أكثر، 1815 01:11:59,730 --> 01:12:01,290 إذا لم تكن لدي مساحة كافية. 1816 01:12:01,290 --> 01:12:03,804 فما الذي أرغب في فعله بديهيًا؟ 1817 01:12:03,804 --> 01:12:04,789 الجمهور: [INAUDIBLE]. 1818 01:12:04,789 --> 01:12:06,330 ديفيد ج. مالان: تخصيص المزيد من الذاكرة. 1819 01:12:06,330 --> 01:12:09,060 ويتضح أنه، كما اقترحت، أو كما اقترح شخص ما في وقت سابق، 1820 01:12:09,060 --> 01:12:10,290 إعادة تخصيص الذاكرة. 1821 01:12:10,290 --> 01:12:13,000 يمكننا استخدام هذه الدالة لأول مرة. 1822 01:12:13,000 --> 01:12:14,617 دعوني أمضي قدمًا وأقول ذلك-- 1823 01:12:14,617 --> 01:12:16,950 الجانب السلبي لاستخدام realloc هو أنه يجب عليك أن تكون ذكيًا حول هذا الأمر، 1824 01:12:16,950 --> 01:12:18,158 لأنه يعيد مؤشر. 1825 01:12:18,158 --> 01:12:19,980 لذا دعوني أقترح هذه التعليمات البرمجية أولاً. 1826 01:12:19,980 --> 01:12:23,250 أولاً، فقط أعطني متغير مؤقت، أطلق عليه، temp، 1827 01:12:23,250 --> 01:12:25,760 سيُخزِّن ما يلي. 1828 01:12:25,760 --> 01:12:26,400 في الواقع، لا. 1829 01:12:26,400 --> 01:12:28,710 دعوني أبدأ هذا ببساطة أكثر. 1830 01:12:28,710 --> 01:12:34,640 دعوني أمضي قدمًا وأقول، إنه يجب إعادة تخصيص الأرقام من فضلك، 1831 01:12:34,640 --> 01:12:39,010 realloc عن طريق تمريرها. 1832 01:12:39,010 --> 01:12:43,140 وهذه المرة، أعطني حجم عدد صحيح، المرات-- 1833 01:12:43,140 --> 01:12:47,160 كم عدد الأعداد الصحيحة التي أريدها هذه المرة؟ 1834 01:12:47,160 --> 01:12:52,320 كم عدد الأرقام التي يدخلها الإنسان افتراضيًا فقط؟ 1835 01:12:52,320 --> 01:12:53,640 الجمهور: [INAUDIBLE]. 1836 01:12:53,640 --> 01:12:54,240 ديفيد ج. مالان: واحد فقط. 1837 01:12:54,240 --> 01:12:54,740 حسنًا. 1838 01:12:54,740 --> 01:12:57,570 لأنه حرفيًا، نحن نستدعي getInt مرة واحدة في هذه القصة. 1839 01:12:57,570 --> 01:13:03,550 لذا أيًا كان حجم هذه المصفوفة الآن، نحتاج إلى زيادتها بمقدار 1. 1840 01:13:03,550 --> 01:13:04,470 هذا كل شيء. 1841 01:13:04,470 --> 01:13:09,790 إذن هذا السطر من التعليمات البرمجية هنا يقول، مرحبًا جهاز الكمبيوتر، 1842 01:13:09,790 --> 01:13:15,630 أمضي قدمًا وأعد تخصيص هذه المصفوفة من أيًا كان حجمها الحالي، 1843 01:13:15,630 --> 01:13:18,840 واجعلها بهذا الحجم بدلاً من ذلك. 1844 01:13:18,840 --> 01:13:22,542 حجم أيًا كان، زائد 1، مرات حجم عدد صحيح. 1845 01:13:22,542 --> 01:13:24,750 لأن هذا هو ما نحاول تخزينه، وهو عدد صحيح. 1846 01:13:24,750 --> 01:13:26,430 لذلك علينا القيام بهذا الضرب. 1847 01:13:26,430 --> 01:13:28,759 وrealloc، كما ذكرنا في وقت سابق، أداة رائعة. 1848 01:13:28,759 --> 01:13:31,050 ستأخذ مؤشر، أيًا كان جزء الذاكرة 1849 01:13:31,050 --> 01:13:34,830 الذي قمت بإعادة تخصيصها بالفعل، ثم ستقوم بعد ذلك بإعادة تخصيص 1850 01:13:34,830 --> 01:13:36,090 جزء أكبر من الذاكرة. 1851 01:13:36,090 --> 01:13:38,070 آمل، أن ما سيحدث هو هذا-- 1852 01:13:38,070 --> 01:13:41,520 إذا بدا جزء الذاكرة الخاص بك في البداية هكذا، 1853 01:13:41,520 --> 01:13:44,239 آمل أن نلاحظ، أوه، تم تحرير هذه الذاكرة. 1854 01:13:44,239 --> 01:13:46,030 دعوني فقط أعود بكم إلى نفس العنوان. 1855 01:13:46,030 --> 01:13:48,450 لذلك إذا كان هذا هو العنوان 100، وكنت محظوظًا 1856 01:13:48,450 --> 01:13:51,550 وهذا العنوان أيضًا متاح، وستتذكر دالة realloc 1857 01:13:51,550 --> 01:13:53,550 ذلك لنظام التشغيل. 1858 01:13:53,550 --> 01:13:55,200 ستعيد الرقم 100 مرة أخرى. 1859 01:13:55,200 --> 01:13:56,116 والانتقال أمر جيد. 1860 01:13:56,116 --> 01:13:57,750 يمكنك لمس الذاكرة بأمان هنا. 1861 01:13:57,750 --> 01:14:03,390 أو إذا كان هذا قيد الاستخدام بالفعل، هذا الجزء من الذاكرة، وبالتالي لا 1862 01:14:03,390 --> 01:14:06,810 لا يمكننا ملائمة وحدة بايت آخرى هنا لأن بعض التعليمات البرمجية الأخرى التي كتبتها 1863 01:14:06,810 --> 01:14:08,080 تستخدم تلك الذاكرة. 1864 01:14:08,080 --> 01:14:11,640 ولكن هناك ضعف الذاكرة المتوفرة هنا. 1865 01:14:11,640 --> 01:14:14,760 ما سيفعله realloc، هو إذا قمت بتخزين الرقم 50، 1866 01:14:14,760 --> 01:14:18,040 سيعالج عملية نسخ 50 إلى القيمة الجديدة. 1867 01:14:18,040 --> 01:14:20,820 سيُترك هذا كقيمة ضئيلة لك لتعالجها. 1868 01:14:20,820 --> 01:14:24,970 وسيعيد إليك عنوان الجزء الجديد من الذاكرة، 1869 01:14:24,970 --> 01:14:27,360 بعد أن قام بالنسخ لأجلك. 1870 01:14:27,360 --> 01:14:30,640 لذلك على الرغم من أنه من الناحية الفنية إعادة تخصيص المصفوفة، 1871 01:14:30,640 --> 01:14:32,610 لن يقوم حتمًا بتكبيرها فقط. 1872 01:14:32,610 --> 01:14:36,030 قد يقوم بإعادة تخصيصها في الذاكرة إلى جزء أكبر، 1873 01:14:36,030 --> 01:14:39,150 ثم يعطيك العنوان الجديد لتلك الذاكرة. 1874 01:14:39,150 --> 01:14:39,951 أي سؤال؟ 1875 01:14:39,951 --> 01:14:42,060 الجمهور: هل هذه العملية هي مفضلة حقًا 1876 01:14:42,060 --> 01:14:45,260 لإتشاء ذاكرة إضافية في مكانها فقط. 1877 01:14:45,260 --> 01:14:50,104 ومن ثم توفير الوقت والطاقة في إعادة تخصيصها [؟ جميعًا مرة واحدة. ؟] 1878 01:14:50,104 --> 01:14:52,020 ديفيد ج. مالان: هذا سؤال جيد حقًا. 1879 01:14:52,020 --> 01:14:55,410 بصراحة، يمكننا تجنب هذه المشكلة قليلاً عن طريق القيام بذلك، أتعرفون ماذا، 1880 01:14:55,410 --> 01:14:57,960 أعطني على الأقل-- 1881 01:14:57,960 --> 01:15:01,330 أمضي قدمًا وأعطني على الأقل حجم عدد صحيح، مرات-- 1882 01:15:01,330 --> 01:15:04,330 أنا لا أعرف، لن يكتب معظم البشر أكثر من 50 رقمًا. 1883 01:15:04,330 --> 01:15:05,460 دعونا نختار فقط 50. 1884 01:15:05,460 --> 01:15:08,582 لذا يمكنك القيام بذلك، وهذا بالفعل سيوفر لك الوقت. 1885 01:15:08,582 --> 01:15:10,290 لأن النهج الذي أتبعه حاليًا 1886 01:15:10,290 --> 01:15:13,710 غير فعّال إلى حد ما لأن كل مرة يستدعي المستخدم 1887 01:15:13,710 --> 01:15:17,040 getInt، ويعطي عدد صحيح، نحن نقوم بتغيير الحجم، بتغيير الحجم، بتغيير الحجم. 1888 01:15:17,040 --> 01:15:18,450 مكلّف للغاية. 1889 01:15:18,450 --> 01:15:20,250 بالنسبة إلى أفضل قيمة هي على الرغم من ذلك-- 1890 01:15:20,250 --> 01:15:20,910 50؟ 1891 01:15:20,910 --> 01:15:21,990 هل يجب أن تكون 25؟ 1892 01:15:21,990 --> 01:15:23,190 هل يجب أن تكون 1000؟ 1893 01:15:23,190 --> 01:15:25,260 سأقوم بتقليل الرهان أو زيادته. 1894 01:15:25,260 --> 01:15:30,240 ويعتمد الأمر عليك لتقرير أيًا من هذه الطرق هو القرار الأسوأ. 1895 01:15:30,240 --> 01:15:32,610 الجمهور: ولكن، من حيث البرامج، 1896 01:15:32,610 --> 01:15:36,150 إنه مكلف إلى حد ما أيضًا للحصول على ذاكرة لا تستخدمها 1897 01:15:36,150 --> 01:15:37,980 أو بشكل عام، هل هو عادة أكثر من جيد؟ 1898 01:15:37,980 --> 01:15:39,230 ديفيد ج. مالان: سؤال جيد. 1899 01:15:39,230 --> 01:15:42,330 في البرامج التي تكتبها، هل من الأفضل الحصول على المزيد من الذاكرة أكثر من الذي تستخدمه، 1900 01:15:42,330 --> 01:15:43,950 أو يجب أن تكون معتدلاً بالفعل؟ 1901 01:15:43,950 --> 01:15:45,420 هذه الأيام، الذاكرة رخيصة. 1902 01:15:45,420 --> 01:15:47,280 نمتلك جميعًا وحدات جيجابايت من الذاكرة. 1903 01:15:47,280 --> 01:15:52,320 لذا إهدار 50 وحدة بايت أو 200 وحدة بايت، 4 أضعاف، من الذاكرة، ليس بالإمر الهام. 1904 01:15:52,320 --> 01:15:54,780 مجرد القيام بالوظيفة بسرعة وسهولة. 1905 01:15:54,780 --> 01:15:57,960 لكن في الأجهزة محدودة الموارد، ربما، الأشياء مثل الهواتف 1906 01:15:57,960 --> 01:16:00,120 أو أجهزة المصممة بتقنية إنترنت الأشياء قليلاً 1907 01:16:00,120 --> 01:16:04,134 والتي لديها موارد أقل، أنت لا تريد حقًا إهدار وحدات بايت. 1908 01:16:04,134 --> 01:16:06,300 ولكن بصراحة، وحدات المعالجة المركزية (CPU)، الأدمغة الموجودة في أجهزة الكمبيوتر الخاصة بنا، 1909 01:16:06,300 --> 01:16:08,820 سريعة جدًا هذه الأيام، حتى لو قمت باستدعاء malloc 1910 01:16:08,820 --> 01:16:11,550 10 مرات، 1000 مرة، يحدث ذلك بسرعة 1911 01:16:11,550 --> 01:16:13,200 لا يلاحظها الإنسان حتى. 1912 01:16:13,200 --> 01:16:13,819 لذا هناك أيضًا. 1913 01:16:13,819 --> 01:16:15,610 هذه ما يُطلق عليها قرارات التصميم. 1914 01:16:15,610 --> 01:16:17,560 وهذه أنواع الأشياء التي، في العالم الحقيقي، 1915 01:16:17,560 --> 01:16:19,440 قد تناقشها مع شخص ما في الواقع على لوحة بيضاء، 1916 01:16:19,440 --> 01:16:21,540 قائلاً، لا، هذا غباء لهذا السبب. 1917 01:16:21,540 --> 01:16:23,498 أو ربما يدفعك أو تدفعك للخلف لأسباب أخرى. 1918 01:16:23,498 --> 01:16:25,110 وليس بالضرورة أن يكون أي منكما على صواب. 1919 01:16:25,110 --> 01:16:27,650 الهدف وراء هذا كله هو عملية التفكير أولاً 1920 01:16:27,650 --> 01:16:29,130 حتى تكون على الأقل واثقًا في اختيارك. 1921 01:16:29,130 --> 01:16:29,630 أجل؟ 1922 01:16:29,630 --> 01:16:32,525 الجمهور: عندما نكتب في ملف في PSET الأخيرة، 1923 01:16:32,525 --> 01:16:36,900 هل تقوم بتخزينها في الذاكرة أولاً أو تضعها مباشرة على محرك الأقراص الصلبة؟ 1924 01:16:36,900 --> 01:16:39,630 ديفيد ج. مالان: عندما تستدعي fread، 1925 01:16:39,630 --> 01:16:42,870 فأنت تقرأ من خلال تعريف مجموعة مشاكل الأدلة الجنائية 1926 01:16:42,870 --> 01:16:45,990 وحدات البايت من القرص في الذاكرة. 1927 01:16:45,990 --> 01:16:51,800 عندما تدعو fwrite، فأنت تقوم بنسخ وحدات البايت من الذاكرة إلى القرص. 1928 01:16:51,800 --> 01:16:53,070 إذا كان هذا يجيب على السؤال. 1929 01:16:53,070 --> 01:16:53,320 حسنًا. 1930 01:16:53,320 --> 01:16:53,830 أي أسئلة أخرى؟ 1931 01:16:53,830 --> 01:16:54,484 أجل؟ 1932 01:16:54,484 --> 01:16:58,570 الجمهور: لماذا قلت، حجم + 1، في السطر 16؟ 1933 01:16:58,570 --> 01:17:01,180 ديفيد ج. مالان: لماذا قلت، الحجم + 1، في السطر 16؟ 1934 01:17:01,180 --> 01:17:06,010 لأن الهدف كله هو تخصيص مساحة في هذه المصفوفة للرقم الذي تم إدخاله حديثًا 1935 01:17:06,010 --> 01:17:08,080 والذي كتبه الإنسان للتو. 1936 01:17:08,080 --> 01:17:10,240 وبغض النظر عن الحجم الحالي للمصفوفة، 1937 01:17:10,240 --> 01:17:11,770 من الواضح أنني بحاجة إلى مساحة أخرى. 1938 01:17:11,770 --> 01:17:14,475 1939 01:17:14,475 --> 01:17:17,062 الجمهور: هذا إذن يتكرر مرارًا وتكرارًا؟ 1940 01:17:17,062 --> 01:17:18,770 ديفيد ج. مالان: إنه يتكرر مرارًا وتكرارًا. 1941 01:17:18,770 --> 01:17:22,620 لأنه في هذه اللحظة، أنا داخل هذا أثناء التكرار الحلقي. 1942 01:17:22,620 --> 01:17:26,219 لذلك نحن بحاجة لطرح سؤال، عندما يقوم الإنسان بالإدخال. 1943 01:17:26,219 --> 01:17:28,010 ويتضح أنه-- وهذا ليس واضحًا. 1944 01:17:28,010 --> 01:17:31,310 وهذه ليست أفضل تجربة للمستخدم على لوحة المفاتيح للشخص. 1945 01:17:31,310 --> 01:17:35,900 لكن يمكننا في الواقع اكتشاف الآراء التالية-- 1946 01:17:35,900 --> 01:17:42,380 إذا قام المستخدم بإدخال أرقام، ثم دعونا نمضي قدما ونقسمها. 1947 01:17:42,380 --> 01:17:45,530 ولكن السؤال هنا هو، كيف يمكنك التعبير عن هذا الرمز الزائف؟ 1948 01:17:45,530 --> 01:17:49,610 حسنًا، يمكنك في بعض البرامج ربما كتابة q للخروج. 1949 01:17:49,610 --> 01:17:52,610 ولكن هل ينجح هذا عند استخدام getInt؟ 1950 01:17:52,610 --> 01:17:54,740 هل يمكننا اكتشاف q؟ 1951 01:17:54,740 --> 01:17:55,250 لمَ لا؟ 1952 01:17:55,250 --> 01:17:58,722 1953 01:17:58,722 --> 01:18:01,700 الجمهور: لأن getInt يطلب منك على الفور عدد صحيح آخر. 1954 01:18:01,700 --> 01:18:02,290 ديفيد ج. مالان: بالضبط. 1955 01:18:02,290 --> 01:18:04,310 لأن GetInt يطلب منك على الفور عدد صحيح آخر. 1956 01:18:04,310 --> 01:18:07,280 وبسبب الطريقة التي صممنا بها مكتبة CS50، لا يمكنك اكتشاف q، 1957 01:18:07,280 --> 01:18:11,690 أو لا يمكن أن يكون لديك النوع البشري خروج، إلا إذا كنت لا تستخدم getInt. 1958 01:18:11,690 --> 01:18:14,072 ماذا تستخدم بدلاً من ذلك؟ 1959 01:18:14,072 --> 01:18:15,846 الجمهور: getString. 1960 01:18:15,846 --> 01:18:17,470 دايفيد ج. مالان: يمكننا استخدام getString. 1961 01:18:17,470 --> 01:18:20,230 ومن ثم في كل مرة يكتب فيها الشخص رقمًا، يمكننا استخدام، 1962 01:18:20,230 --> 01:18:23,140 على سبيل المثال، A2i لتحويله إلى عدد صحيح. 1963 01:18:23,140 --> 01:18:26,020 ولكن إذا كان الشخص يكتب q أو خ-ر-و-ج-- 1964 01:18:26,020 --> 01:18:30,190 سلسلة أيضًا-- يمكن أن يكون لدينا شرط إذا باستخدام سلسلة المقارنة والخروج. 1965 01:18:30,190 --> 01:18:32,800 لكن بصراحة، أنت بعد ذلك تعيد تنفيذ getInt-- 1966 01:18:32,800 --> 01:18:34,030 لذا هي مقايضة. 1967 01:18:34,030 --> 01:18:36,490 على أي حال، ستكون الطريقة المشتركة للعمل بشأن هذا، 1968 01:18:36,490 --> 01:18:39,610 هي معرفتك أن برامج خروج Control-C، ربما، 1969 01:18:39,610 --> 01:18:41,050 يتم إلغاؤها من برنامجك. 1970 01:18:41,050 --> 01:18:43,870 هناك ضغطات مفاتيح أخرى شائعة، Control-D، 1971 01:18:43,870 --> 01:18:45,760 التي ترسل ما يسمى بنهاية الملف. 1972 01:18:45,760 --> 01:18:48,240 إنها تحاكي نهاية الملف. 1973 01:18:48,240 --> 01:18:50,161 وتحاكي نهاية مدخل الشخص. 1974 01:18:50,161 --> 01:18:52,910 لذا هي مثل النقطة في نهاية الجملة الإنجليزية. 1975 01:18:52,910 --> 01:18:56,467 لذا إذا كنت تريد إرسال إشارة إلى جهاز كمبيوتر ينتظر مدخلاً منك 1976 01:18:56,467 --> 01:18:59,050 ولا تريد أن يخرج من البرنامج -- والذي سيكون Control-C-- 1977 01:18:59,050 --> 01:19:02,350 ولكنك تريد فقط أن تنهي إدخال مدخل إلى الكمبيوتر، 1978 01:19:02,350 --> 01:19:04,435 فتضغط على Control-D، المعروف أيضًا باسم EOF. 1979 01:19:04,435 --> 01:19:07,060 وهو طريقة للتعبير عن هذا-- وستعرف ذلك فقط من 1980 01:19:07,060 --> 01:19:09,740 الوثائق-- والتي ستكون كقول شيء من هذا القبيل، 1981 01:19:09,740 --> 01:19:13,760 إذا كان الرقم الذي كتبه الشخص يعادل نهاية ملف-- 1982 01:19:13,760 --> 01:19:16,060 لكن لا يوجد شيء كهذا في هذا السياق-- 1983 01:19:16,060 --> 01:19:19,930 تقوم بذلك بالفعل لأن مكتبة CS50 تعمل. 1984 01:19:19,930 --> 01:19:23,290 وتبين أنه إذا كانت القيم الوحيدة التي يمكن أن تعيدها دالة 1985 01:19:23,290 --> 01:19:28,390 هي أعداد صحيحة، وهذا يعني أنه يمكنك إرجاع 0، 1، -1، 2 مليار، 1986 01:19:28,390 --> 01:19:30,220 -2 مليار معطاة أو مأخوذة. 1987 01:19:30,220 --> 01:19:33,390 ما فعل البشر لسنوات باستخدام لغات البرمجة القديمة 1988 01:19:33,390 --> 01:19:35,860 هو أنهم سرقوا رقمًا واحدًا أو بضعة أرقام فقط. 1989 01:19:35,860 --> 01:19:39,700 على سبيل المثال، قد تسرق الرقم 2 مليار وتطلق عليه intmax-- 1990 01:19:39,700 --> 01:19:41,050 الحد الأقصى للعدد الصحيح. 1991 01:19:41,050 --> 01:19:43,720 وستقول فقط، أنه لا يمكنك أبدًا كتابة 2 مليار بالفعل، 1992 01:19:43,720 --> 01:19:46,750 لأننا نستخدم ذلك كقيمة خاصة للدلالة 1993 01:19:46,750 --> 01:19:49,750 على أن البشر ضغطوا على Control-D. أو يمكنك كتابة -2 مليار، 1994 01:19:49,750 --> 01:19:51,640 أو يمكنك كتابة 0، أو 50. 1995 01:19:51,640 --> 01:19:55,630 ولكن في مرحلة ما، يتعين عليك سرقة رقم واحد من أرقام 4 مليارات المتاحة 1996 01:19:55,630 --> 01:19:58,300 لاستخدامها كقيمة مُطلقة، قيمة خاصة 1997 01:19:58,300 --> 01:20:00,700 يمكنك بعد ذلك فحصها كقيمة ثابتة. 1998 01:20:00,700 --> 01:20:04,090 إذن على أي حال، هذا يعني فقط، عندما ينتهي المستخدم من كتابة مدخل، 1999 01:20:04,090 --> 01:20:06,650 امضي قدمًا وقم بتقسيم هذا أثناء التكرار الحلقي. 2000 01:20:06,650 --> 01:20:08,990 وكملاحظة جانبية، دعوني أقوم بإصلاح شيء واحد. 2001 01:20:08,990 --> 01:20:11,770 تبين أن الأمور يمكن أن تسوء باستخدام realloc. 2002 01:20:11,770 --> 01:20:15,070 وإذا فشل realloc في تخصيص ذاكرة، فيمكنه 2003 01:20:15,070 --> 01:20:19,340 إرجاع فارغ، قيمة خاصة تعني فقط، آه، حدث خطأ ما. 2004 01:20:19,340 --> 01:20:20,410 إنه مؤشر غير صالح. 2005 01:20:20,410 --> 01:20:21,790 إنه العنوان 0. 2006 01:20:21,790 --> 01:20:25,930 وهكذا تبين أن هناك خطأ خفي هنا حيث، من الناحية الفنية، ينبغي 2007 01:20:25,930 --> 01:20:27,370 أن أقوم بهذا في الواقع-- 2008 01:20:27,370 --> 01:20:31,400 تخزين قيمة معادة من realloc في متغير مؤقت. 2009 01:20:31,400 --> 01:20:35,650 لأنه إذا كان temp = فارغ، فقد حدث خطأ ما. 2010 01:20:35,650 --> 01:20:39,640 ويجب أن أمضي قدمًا وأخرج من هذا البرنامج بالفعل. 2011 01:20:39,640 --> 01:20:42,792 ولكن دعونا لا نتطرق لهذا الآن لأن لديه أكثر من حالة حرجة. 2012 01:20:42,792 --> 01:20:46,000 ولكنكم سترون في إصدار هذا البرنامج عبر الإنترنت أننا تحققنا من خطأ إضافي 2013 01:20:46,000 --> 01:20:50,440 الذي يفحص فقط، في الحالة النادرة التي يفشل فيها realloc، 2014 01:20:50,440 --> 01:20:52,330 وتنظيفه والإرجاع بشكل صحيح. 2015 01:20:52,330 --> 01:20:54,940 ولكن سأنتقل إلى التعليمات البرمجية عبر الإنترنت من أجل ذلك. 2016 01:20:54,940 --> 01:20:55,820 حسنًا. 2017 01:20:55,820 --> 01:20:59,846 أي أسئلة على هذا المثال قبل أن نمضي قدمًا؟ 2018 01:20:59,846 --> 01:21:00,345 أجل؟ 2019 01:21:00,345 --> 01:21:06,040 الجمهور: إذن في realloc، عندما تقوم بإنشاء المؤشر الجديد لـ [INAUDIBLE]،، 2020 01:21:06,040 --> 01:21:08,302 هل تقوم بمحو الذاكرة من المؤشر الأصلي؟ 2021 01:21:08,302 --> 01:21:09,594 هل يتم محوها تلقائيًا؟ 2022 01:21:09,594 --> 01:21:10,843 ديفيد ج. مالان: سؤال جيد. 2023 01:21:10,843 --> 01:21:13,840 عندما تستدعي realloc وينتهي الأمر بتخصيص مساحة أكبر، 2024 01:21:13,840 --> 01:21:16,690 هل تمحو الذاكرة الأصلية؟ 2025 01:21:16,690 --> 01:21:17,320 لا. 2026 01:21:17,320 --> 01:21:21,474 وهذا هو المكان الذي تأتي منه القيم الضئيلة، على سبيل المثال. 2027 01:21:21,474 --> 01:21:23,890 لأنهم فقط قم تم تركهم في الذاكرة من الاستخدام السابق. 2028 01:21:23,890 --> 01:21:24,820 أي أسئلة أخرى؟ 2029 01:21:24,820 --> 01:21:25,320 أجل؟ 2030 01:21:25,320 --> 01:21:29,140 الجمهور: ماذا يكتب المستخدم في الواقع للتقسيم؟ 2031 01:21:29,140 --> 01:21:33,460 ديفيد ج. مالان: أوه، Control-D. Control-D. وهو ليس تقسيمًا. 2032 01:21:33,460 --> 01:21:36,410 وإنما لإرسال نهاية ملف، نهاية مدخل. 2033 01:21:36,410 --> 01:21:38,710 يوقف Control-C أو يُعطّل البرنامج نفسه. 2034 01:21:38,710 --> 01:21:41,080 الجمهور: وهل هذا يبدو مثل intmax؟ 2035 01:21:41,080 --> 01:21:43,911 ديفيد ج. مالان: تمامًا مثل intmax؟ 2036 01:21:43,911 --> 01:21:44,410 نعم. 2037 01:21:44,410 --> 01:21:46,090 الحضور: لأنك لا تقوم بإضافة، على سبيل المثال، قيمة عملاقة. 2038 01:21:46,090 --> 01:21:47,090 ديفيد ج. مالان: صحيح. 2039 01:21:47,090 --> 01:21:50,270 في مكتبة CS50، intmax، نعم، هو الرمز. 2040 01:21:50,270 --> 01:21:50,770 حسنًا. 2041 01:21:50,770 --> 01:21:51,405 أجل؟ 2042 01:21:51,405 --> 01:21:55,170 الجمهور: هل يمكنك أيضًا فقط الطلب من المستخدم قول، 2043 01:21:55,170 --> 01:21:57,290 هل تريد أن تدخل رقمًا آخر نعم أم لا؟ 2044 01:21:57,290 --> 01:21:58,030 ديفيد ج. مالان: بالتأكيد. 2045 01:21:58,030 --> 01:21:59,080 يمكننا جعل الأمر منطقيًا أكثر. 2046 01:21:59,080 --> 01:22:00,190 ويمكنك استخدام getString. 2047 01:22:00,190 --> 01:22:02,830 ويمكننا أن نطلب منه أو منها، مرحبًا، هل تريد إدخال رقم آخر. 2048 01:22:02,830 --> 01:22:04,580 الجانب السلبي الوحيد من هذا سيكون، الآن، يجب 2049 01:22:04,580 --> 01:22:07,580 أن أكتب ليس فقط رقمي، ولكن نعم أو لا باستمرار. 2050 01:22:07,580 --> 01:22:10,281 إذن إنها مجرد واجهة مستخدم مقايضة. 2051 01:22:10,281 --> 01:22:10,780 حسنًا. 2052 01:22:10,780 --> 01:22:12,280 إذن دعوني أمضي قُدمًا. 2053 01:22:12,280 --> 01:22:16,720 ودعوني أمضي قدمُا وأعيد 0 هنا تمامًا مثل حلي البسيط 2054 01:22:16,720 --> 01:22:19,900 لهذه المشكلة المتعلقة بحدوث شيء خاطىء. 2055 01:22:19,900 --> 01:22:21,610 لقد قمت للتو بتحويل هذا البرنامج برمجيًا. 2056 01:22:21,610 --> 01:22:22,780 دعوني أمضي قُدمًا وأشغّله. 2057 01:22:22,780 --> 01:22:27,220 سأكتب رقمًا واحدًا، رقمين، ثلاثة أرقام. 2058 01:22:27,220 --> 01:22:27,970 والآن أشعر بالملل. 2059 01:22:27,970 --> 01:22:29,303 لا أريد الاستمرار في فعل هذا. 2060 01:22:29,303 --> 01:22:31,030 كيف أخبر الكمبيوتر أنني انتهيت؟ 2061 01:22:31,030 --> 01:22:31,930 الجمهور: Control-D. 2062 01:22:31,930 --> 01:22:34,600 ديفيد ج. مالان: Control-D. عذرًا. 2063 01:22:34,600 --> 01:22:35,119 أوه، حسنًا. 2064 01:22:35,119 --> 01:22:37,285 هذا هو التصرف الصحيح لأنني نسيت خطوة رئيسية. 2065 01:22:37,285 --> 01:22:39,830 2066 01:22:39,830 --> 01:22:41,100 ما هي؟ 2067 01:22:41,100 --> 01:22:42,045 الجمهور: [INAUDIBLE]. 2068 01:22:42,045 --> 01:22:42,920 ديفيد ج. مالان: أجل. 2069 01:22:42,920 --> 01:22:44,920 أنا لا أقوم في الواقع بفعل أي شيء باستخدام القيم. 2070 01:22:44,920 --> 01:22:49,235 ربما يجب أن أقوم بذلك لـ int I تساوي 0، وI أقل من حجم، 2071 01:22:49,235 --> 01:22:52,140 التعليمات البرمجية I + + التي كانت لدينا من قبل. 2072 01:22:52,140 --> 01:22:57,990 ومن المحتمل أنه يجب أن أطبع لقد قمت بإدخال %I، هذا. 2073 01:22:57,990 --> 01:22:59,270 حفظ ذلك. 2074 01:22:59,270 --> 01:23:00,680 Make list1. 2075 01:23:00,680 --> 01:23:03,320 إذن كل ما فعلته هو إعادة إضافة تعليمات الطباعة البرمجية. 2076 01:23:03,320 --> 01:23:08,100 الآن إذا أعدت تشغيل هذا-- واحد، اثنين ثلاثة، Control-D-- 2077 01:23:08,100 --> 01:23:08,928 اللعنة. 2078 01:23:08,928 --> 01:23:10,579 الجمهور: [INAUDIBLE]. 2079 01:23:10,579 --> 01:23:11,370 ديفيد ج. مالان: أوه. 2080 01:23:11,370 --> 01:23:11,869 حسنًا. 2081 01:23:11,869 --> 01:23:14,620 الآن عطلّت تعليماتي البرمجية هنا. 2082 01:23:14,620 --> 01:23:15,586 دعوني أقوم بهذا. 2083 01:23:15,586 --> 01:23:17,460 سنتخلص من فحص الخطأ هذا 2084 01:23:17,460 --> 01:23:19,590 لأنني لن أقوم بتغيير الحجم في الواقع. 2085 01:23:19,590 --> 01:23:21,630 تحصل الأرقام على realloc. 2086 01:23:21,630 --> 01:23:24,570 أوه، وربما يتناغم شخص ما باستخدام هذا-- 2087 01:23:24,570 --> 01:23:29,760 أرقام قوس حجم يساوي مدخل المستخدم. 2088 01:23:29,760 --> 01:23:34,110 الحجم + +-- كان هذا هو التفصيل الرئيسي الذي أراد شخص أن أقوم به؟ 2089 01:23:34,110 --> 01:23:34,610 حسنًا. 2090 01:23:34,610 --> 01:23:36,960 لذا لم أنهي في الواقع البرنامج في وقت سابق. 2091 01:23:36,960 --> 01:23:39,110 لاحظوا أننا حذفنا ما يلي-- 2092 01:23:39,110 --> 01:23:43,130 مرحبًا، جهاز الكمبيوتر، أعطني مصفوفة من الحجم 0 في البداية 2093 01:23:43,130 --> 01:23:45,210 هذا فارغ-- لا توجد ذاكرة لذلك. 2094 01:23:45,210 --> 01:23:47,780 وبالتالي، حجم هذه المصفوفة هو 0. 2095 01:23:47,780 --> 01:23:49,460 قم بما يلي للأبد. 2096 01:23:49,460 --> 01:23:51,710 احصل على رقم من الشخص. 2097 01:23:51,710 --> 01:23:54,580 إذا كان الرقم يساوي هذه القيمة الخاصة، وتعطّل intmax فقط 2098 01:23:54,580 --> 01:23:57,680 بسبب إنهاء البرنامج. 2099 01:23:57,680 --> 01:23:59,990 وفي الواقع، معذرة. 2100 01:23:59,990 --> 01:24:04,505 وهذا هو سبب قيامي بكتابة هذا مسبقًا أيضًا. 2101 01:24:04,505 --> 01:24:05,960 حسنًا. 2102 01:24:05,960 --> 01:24:08,300 امضي قدمًا واطلب رقمًا من المستخدم. 2103 01:24:08,300 --> 01:24:12,180 إذا قام بإدخال Control-D، فقط قم بتقسيم هذا التكرار الحلقي. 2104 01:24:12,180 --> 01:24:15,920 ومع ذلك، إذا كان حجم المصفوفة يساوي سعتها الحالية، 2105 01:24:15,920 --> 01:24:21,170 امضي قدمًا وأعد تخصيص مساحة لهذا الشيء والذي يكون رقمًا واحدًا أكبر مما 2106 01:24:21,170 --> 01:24:22,580 كان عليه في السابق. 2107 01:24:22,580 --> 01:24:25,580 الآن، لنفترض أن الأمر نجح ولدينا ذاكرة، 2108 01:24:25,580 --> 01:24:30,170 امضي قدمًا، وفقط مثل list0 لدينا، قم بالتخزين في مصفوفة الأرقام 2109 01:24:30,170 --> 01:24:34,160 في الموقع الحالي، الذي هو 0، مهما كان الرقم الذي يكتبه الشخص. 2110 01:24:34,160 --> 01:24:38,460 ثم قم بزيادة الحجم بمقدار واحد لتذكر ما قمنا به. 2111 01:24:38,460 --> 01:24:41,840 أنا أيضًا وعلى الرغم من ذلك سأحتاج إلى إنشاء سعة + + هنا 2112 01:24:41,840 --> 01:24:44,550 لتذكر ما قمنا بزيادة سعة المصفوفة. 2113 01:24:44,550 --> 01:24:45,860 إذن مجددًا، مقياسان جديدان. 2114 01:24:45,860 --> 01:24:48,330 السعة هي مقدار المساحة هناك إجماليًا. 2115 01:24:48,330 --> 01:24:50,120 الحجم هو مقدار ما نستخدمه. 2116 01:24:50,120 --> 01:24:52,640 يصادف أنهما متطابقان في الوقت الراهن 2117 01:24:52,640 --> 01:24:56,560 لأننا ننمي هذا الشيء خطوة بخطوة بخطوة. 2118 01:24:56,560 --> 01:24:57,060 حسنًا. 2119 01:24:57,060 --> 01:24:58,430 دعوني أمضي قدمًا وأضغط على حفظ. 2120 01:24:58,430 --> 01:25:01,380 دعوني أمضي قدمًا وأحول هذا برمجيًا لآخر مرة. 2121 01:25:01,380 --> 01:25:05,060 ./list1 والمدخل 1 و2 و3. 2122 01:25:05,060 --> 01:25:07,070 Control-D. حسنًا. 2123 01:25:07,070 --> 01:25:08,660 الآن أصبح مجرد خطأ جمالي. 2124 01:25:08,660 --> 01:25:10,810 لقد نسيت /n الخاص بي. 2125 01:25:10,810 --> 01:25:18,770 إذن فقط لإثبات أنه يمكنني في الواقع تشغيل برنامج، ./list1؛ 1، 2، 3؛ Control-D. 2126 01:25:18,770 --> 01:25:19,700 بكل سرور. 2127 01:25:19,700 --> 01:25:20,450 حسنًا. 2128 01:25:20,450 --> 01:25:21,336 إذن قمت بإدخال 1. 2129 01:25:21,336 --> 01:25:23,210 والسبب وراء أنه لم ينتقل إلى سطر آخر 2130 01:25:23,210 --> 01:25:26,630 هو لأن Control-D يساوي الإرسال على الفور دون الضغط على Enter. 2131 01:25:26,630 --> 01:25:27,402 حسنًا. 2132 01:25:27,402 --> 01:25:28,550 بكل سرور. 2133 01:25:28,550 --> 01:25:29,660 تستخدم جميعها المصفوفات. 2134 01:25:29,660 --> 01:25:35,000 الآن دعونا نقوم بأمر قمنا به بالفعل وننتهي منه. 2135 01:25:35,000 --> 01:25:38,780 المثال الثالث والأخير هنا هو list2. 2136 01:25:38,780 --> 01:25:41,972 وفي الواقع، قبل أن نصل إلى هناك، دعوني أوضح شيئًا واحدًا. 2137 01:25:41,972 --> 01:25:43,430 نعم، لنقم بشيء آخر هنا. 2138 01:25:43,430 --> 01:25:49,380 دعوني أمضي قدمًا وأشغل، أولاً، صديقنا الجديد valgrind في list1. 2139 01:25:49,380 --> 01:25:50,690 Enter. 2140 01:25:50,690 --> 01:25:54,140 إنه في انتظاري ليقوم بكتابة 1، 2، 3. 2141 01:25:54,140 --> 01:25:57,590 دعوني أمضي قدمًا وأضغط على Control-D. مثير للاهتمام. 2142 01:25:57,590 --> 01:26:01,190 يبدو أن لديّ برنامج خاطىء على الرغم من أنني زعمت منذ لحظات أنني 2143 01:26:01,190 --> 01:26:02,390 أعرف ما كنت أفعله. 2144 01:26:02,390 --> 01:26:06,054 بالتأكيد تم فقدان 12 وحدة بايت في كتلة واحدة في السجل المفقود 1 من 1. 2145 01:26:06,054 --> 01:26:07,970 مجددًا، لا أفهم معظم هذه الكلمات. 2146 01:26:07,970 --> 01:26:10,490 لكن من المؤكد أنه تم فقدان 12 وحدة بايت-- 2147 01:26:10,490 --> 01:26:13,580 ربما هذا خطأي. لمَ هي 12؟ 2148 01:26:13,580 --> 01:26:16,870 وما هي 12 وحدة بايت تلك؟ 2149 01:26:16,870 --> 01:26:17,485 أجل؟ 2150 01:26:17,485 --> 01:26:19,629 الجمهور: أعتقد أنك قدمت ثلاثة أعداد صحيحة. 2151 01:26:19,629 --> 01:26:21,045 ديفيد ج. مالان: نعم، 1، و2، و3. 2152 01:26:21,045 --> 01:26:22,098 الجمهور: وكل واحد عبارة عن 4 وحدات بايت. 2153 01:26:22,098 --> 01:26:23,810 وأنت لم تقم بتحرريهم مطلقًا بعد استخدام malloc. 2154 01:26:23,810 --> 01:26:24,290 ديفيد ج. مالان: بالضبط. 2155 01:26:24,290 --> 01:26:25,160 لقد كتبت ثلاثة أرقام-- 2156 01:26:25,160 --> 01:26:25,721 1، و2، و3. 2157 01:26:25,721 --> 01:26:27,470 كل واحد يمثل 4 وحدات بايت على جهاز الكمبيوتر هذا. 2158 01:26:27,470 --> 01:26:29,360 هذا 12 - 3 ضرب 4. 2159 01:26:29,360 --> 01:26:32,840 وهكذا فإن أمر تحريري لهم لم يكن مصدر المشكلة مطلقًا. 2160 01:26:32,840 --> 01:26:36,020 لذا في النهاية، دعونا فقط نثبت أن valgrind 2161 01:26:36,020 --> 01:26:37,850 يمكنه الكشف عن الصحة أيضًا. 2162 01:26:37,850 --> 01:26:40,340 تحرير أرقامي، فاصلة منقوطة. 2163 01:26:40,340 --> 01:26:43,220 دعوني أمضي قدمًا وأعيد تشغيل make list1. 2164 01:26:43,220 --> 01:26:47,240 والآن دعوني أقوم بزيادة حجم هذا وأقوم بإنشاء valgrind مجددًا 2165 01:26:47,240 --> 01:26:49,760 على list1، كتابة نفس القيم-- 2166 01:26:49,760 --> 01:26:50,570 1، و2، و3. 2167 01:26:50,570 --> 01:26:53,360 Control-D. تم تحرير جميع الكتل. 2168 01:26:53,360 --> 01:26:54,774 لا توجد تسريبات ممكنة. 2169 01:26:54,774 --> 01:26:56,190 إذن مجددًا، valgrind هو صديقك. 2170 01:26:56,190 --> 01:26:58,210 يجد المشاكل التي لم تلاحظها بالضرورة. 2171 01:26:58,210 --> 01:27:00,710 ولم يجب عليك قراءتها خلال سطور تعليماتك البرمجية مرارًا 2172 01:27:00,710 --> 01:27:03,510 وتكرارًا لتحديد مصدر المشكلة دون داعٍ. 2173 01:27:03,510 --> 01:27:04,010 حسنًا. 2174 01:27:04,010 --> 01:27:08,540 أي أسئلة بعد ذلك على تلك المصفوفات التي يتم تخصيصها بشكل ديناميكي 2175 01:27:08,540 --> 01:27:12,100 والأخطاء التي نجدها فيها باستخدام valgrind؟ 2176 01:27:12,100 --> 01:27:12,630 حسنًا. 2177 01:27:12,630 --> 01:27:17,610 إذن سيكون الإثبات الأخير من التعليمات البرمجية هو هذا. 2178 01:27:17,610 --> 01:27:21,810 لقد استعرت، لهذا المثال الأخير، بعض الكتل البنائية 2179 01:27:21,810 --> 01:27:23,580 التي كانت لدينا على الشاشة في وقت سابق. 2180 01:27:23,580 --> 01:27:28,740 في تعليماتي البرمجية لـ list2.c، أحتاج إلى بنية تسمى عقدة. 2181 01:27:28,740 --> 01:27:31,620 وتلك العقدة، كما زعمنا في وقت سابق مع الأشخاص المتطوعين، 2182 01:27:31,620 --> 01:27:33,420 ستحتوي على رقم يسمى رقم، 2183 01:27:33,420 --> 01:27:35,190 كما سنطلق عليه هذه المرة، بدلاً من n. 2184 01:27:35,190 --> 01:27:40,050 وسيحتوي على ptr يطلق عليه next للعقدة الأخرى تلك. 2185 01:27:40,050 --> 01:27:43,140 لذا تم نسخ ذلك ولصقه في وقت سابق، وإن كان باستخدام العدد الصحيح الذي تمت إعادة تسميته 2186 01:27:43,140 --> 01:27:45,010 برقم من أجل الوضوح. 2187 01:27:45,010 --> 01:27:47,820 الآن، لاحظوا ما سأفعله في main أولاً. 2188 01:27:47,820 --> 01:27:53,250 امضي قدمًا وخصّص مصفوفة دون أي مساحة في البداية. 2189 01:27:53,250 --> 01:27:56,910 إذن بدا هذا مثلما كانت كومي تمسك الأول وتمثل 2190 01:27:56,910 --> 01:27:58,990 بداية بنية البيانات لدينا. 2191 01:27:58,990 --> 01:28:02,220 هذا هو التناظر باستخدام مصفوفة، أن قطعة الورق التي 2192 01:28:02,220 --> 01:28:04,050 سيتم عدّها هنا ستكون الأرقام. 2193 01:28:04,050 --> 01:28:06,390 وهي فقط لا تشير إلى شيء، فارغ-- مثل اليد اليسرى 2194 01:28:06,390 --> 01:28:07,430 التي تشير إلى الأرض. 2195 01:28:07,430 --> 01:28:09,810 لأنه لم يتم تخصيص ذاكرة بعد. 2196 01:28:09,810 --> 01:28:13,890 ولكن بعد ذلك، في while true، امضي قدمًا واحصل على عدد صحيح 2197 01:28:13,890 --> 01:28:16,380 من المستخدم باستخدام تلك التعليمات البرمجية هنا. 2198 01:28:16,380 --> 01:28:21,810 تحقق إذا كان المستخدم ضغط على Control-D، كما هو الحال مع هذه التقنية الغامضة. 2199 01:28:21,810 --> 01:28:25,260 ثم تصبح تعليماتنا البرمجية مشابهة جدًا في جوهرها، لكن 2200 01:28:25,260 --> 01:28:27,520 يتعين علينا تجميع تلك الأشياء معًا. 2201 01:28:27,520 --> 01:28:29,470 خصّص مساحة للرقم. 2202 01:28:29,470 --> 01:28:32,220 لذا عندما قمت بتخصيص متطوع إضافي من الجمهور 2203 01:28:32,220 --> 01:28:35,430 وقام أو قامت بالمجيء، المعادل في التعليمات البرمجية هو هذا-- 2204 01:28:35,430 --> 01:28:41,430 مرحبًا، جهاز الكمبيوتر، قم بتخصيص مساحة كافية لتناسب حجم العقدة باستخدام malloc، 2205 01:28:41,430 --> 01:28:44,460 ثم قم بتخزين النتائج في ptr التي يطلق عليه n. 2206 01:28:44,460 --> 01:28:49,290 إذن node *n تشير فقط إلى، أعطني مؤشر إلى عقدة، وأطلق عليه n، 2207 01:28:49,290 --> 01:28:53,070 وقم بتخزين العنوان الذي قمنا للتو بتخصيصه من الجمهور كما فعلنا من قبل. 2208 01:28:53,070 --> 01:28:56,100 لماذا لدي هذه السطور من التعليمات البرمجية هنا التي ميزتها باللون الأزرق؟ 2209 01:28:56,100 --> 01:28:57,474 ما الذي يعبر عنه هذا؟ 2210 01:28:57,474 --> 01:29:03,900 2211 01:29:03,900 --> 01:29:08,270 إذا إشارة التنبيه n، إذا ليس n كيف سيكون نطقها-- 2212 01:29:08,270 --> 01:29:10,610 ما الذي يحدث هناك؟ 2213 01:29:10,610 --> 01:29:11,530 أجل؟ 2214 01:29:11,530 --> 01:29:15,360 الجمهور: إذا لم يوجد المزيد من الذاكرة التي يمكنك الإشارة إليها، فهذا يعني أنه فشل. 2215 01:29:15,360 --> 01:29:16,360 ديفيد ج. مالان: بالضبط. 2216 01:29:16,360 --> 01:29:18,110 هذا لن يحدث كله في كثير من الأحيان. 2217 01:29:18,110 --> 01:29:21,580 لكن إذا نفدت الذاكرة من جهاز الكمبيوتر، وبالتالي سيفشل malloc، 2218 01:29:21,580 --> 01:29:23,750 أنت لا تريد أن يتعطل البرنامج أو يتوقف عن العمل فقط. 2219 01:29:23,750 --> 01:29:26,360 على سبيل المثال، كلنا نكره الأمر عندما يحدث ذلك على Mac OS أو Windows. 2220 01:29:26,360 --> 01:29:27,370 لذا تحقق من ذلك. 2221 01:29:27,370 --> 01:29:33,160 إذا ليس n، أو معادلاً لها، إذا n = = فارغ، فأعد 1 فقط. 2222 01:29:33,160 --> 01:29:35,410 واخرج بشكل لائق، وحتى لو كان بشكل مزعج. 2223 01:29:35,410 --> 01:29:37,690 لكن لا تقم بتعطيله أو لا تقم بشيء غير متوقع فقط. 2224 01:29:37,690 --> 01:29:43,750 لذا يمكنك تبسيط هذا الفحص إلى فقط إذا ليس n-- إذا كان n ليس ptr صالحًا، 2225 01:29:43,750 --> 01:29:44,980 أعد 1. 2226 01:29:44,980 --> 01:29:49,270 الآن، ها هي التعليمات البرمجة التي كنا ننفذ الإثبات باستخدامها 2227 01:29:49,270 --> 01:29:49,960 مع هؤلاء المتطوعين. 2228 01:29:49,960 --> 01:29:52,390 وهذه هي النظرة الأكثر رعبًا أو الأكثر غموضًا على الأقل 2229 01:29:52,390 --> 01:29:54,820 للتعليمات البرمجية التي سنراها في C. 2230 01:29:54,820 --> 01:29:59,290 اليوم هو يومنا الأخير في C. لقد قمنا بتشغيل 2231 01:29:59,290 --> 01:30:01,810 تلة شديدة الانحدار في الآونة الأخيرة، وتعلمنا عن الذاكرة، 2232 01:30:01,810 --> 01:30:03,930 والآن بنيات البيانات والصيغة. 2233 01:30:03,930 --> 01:30:06,280 هذه هي آخر صيغة في C. 2234 01:30:06,280 --> 01:30:09,700 إذن ما هي الرموز التي يجب أن تكون على دراية بها؟ 2235 01:30:09,700 --> 01:30:15,700 سطر التعليمات البرمجية هذا هنا هو كيف أسلم أحد المتطوعين قطعة من الورق. 2236 01:30:15,700 --> 01:30:18,270 على الجانب الأيمن، الرقم الذي تمت كتابته-- 2237 01:30:18,270 --> 01:30:21,460 55، أو 5، أو 20، أو أيًا كانت القيمة. 2238 01:30:21,460 --> 01:30:24,130 على الجانب الأيسر هو حيث تريد وضعه. 2239 01:30:24,130 --> 01:30:29,080 n ومن ثم حرفيًا رقم السهم الذي يقوم بهذا. 2240 01:30:29,080 --> 01:30:34,300 لديه، باستخدام malloc، سطر أو ما كان قبل ذلك، المعطى في الذاكرة 2241 01:30:34,300 --> 01:30:36,310 أحد هذه المستطيلات الكبيرة فقط. 2242 01:30:36,310 --> 01:30:40,420 ومرة أخرى، يُطلق على الجزء العلوي من هذا في هذا المثال الرقم 2243 01:30:40,420 --> 01:30:42,070 ويطلق على الجزء السفلي next. 2244 01:30:42,070 --> 01:30:45,280 إذن هذا هو الشخص الذي وقف بنهاية الغرفة. 2245 01:30:45,280 --> 01:30:49,870 عندما أسلم هذا الشخص رقم، مثل 55، فإنه ينتقل إلى هناك بشكل مرئي. 2246 01:30:49,870 --> 01:30:53,230 سطر التعليمات البرمجية الذي تحقق ذلك باستخدامه هو هذا هنا. 2247 01:30:53,230 --> 01:30:57,850 لأنه لاحظوا في السطر 31 هنا، عندما أقوم بتخصيص تلك العقدة، 2248 01:30:57,850 --> 01:31:02,080 قمت بتخزين عنوانها في متغير يسمى n. 2249 01:31:02,080 --> 01:31:05,920 وهذا مؤشر، كما هو مرسوم باستخدام سهم، إلى هذه العقدة الكبيرة. 2250 01:31:05,920 --> 01:31:08,920 أو إذا كنا نريد حقًا أن نصعب الأمر، إذا كان هذا في عنوان 100، 2251 01:31:08,920 --> 01:31:11,590 نعم، لذا لدى المؤشر في الواقع القيمة 100 بداخله. 2252 01:31:11,590 --> 01:31:13,540 ولكن مجددًا، وهذه معلومة مفيدة نادرة. 2253 01:31:13,540 --> 01:31:16,610 لذا يمكننا فقط التجريد باستخدام سهم فقط. 2254 01:31:16,610 --> 01:31:21,370 لذا، فإن السطر 31 هو الذي ينشئ تلك المربعات على الشاشة. 2255 01:31:21,370 --> 01:31:25,120 السطر 38 هو الذي يضع الرقم-- 2256 01:31:25,120 --> 01:31:30,250 على سبيل المثال، 55-- في المربع بالضبط، مثلما سلمت قطعة 2257 01:31:30,250 --> 01:31:31,030 من الورق. 2258 01:31:31,030 --> 01:31:32,630 إذن ما هذا؟ 2259 01:31:32,630 --> 01:31:35,620 هذا هو الترميز الجديد الحقيقي الوحيد اليوم، 2260 01:31:35,620 --> 01:31:38,180 على الرغم من أننا نستخدم الكثير من النجوم في مكان آخر-- 2261 01:31:38,180 --> 01:31:43,660 سهم هذه هي المرة الأولى بشكل رائع في C التي نقوم بتعيينه فعليًا على صورنا. 2262 01:31:43,660 --> 01:31:46,550 إذا كان n هو المتغير، فأنت تقوم بكتابة n سهم إلى شيء ما، 2263 01:31:46,550 --> 01:31:48,049 وهذا يعني متابعة السهم-- 2264 01:31:48,049 --> 01:31:50,590 شيء مثل السلم والثعبان إذا ترعرعت وأنت تلعب تلك اللعبة-- 2265 01:31:50,590 --> 01:31:57,190 ومن ثم ضع الرقم الذي قادك إليه السهم في الحقل الذي يطلق عليه رقم. 2266 01:31:57,190 --> 01:32:02,830 لذا كملاحظة جانبية، يمكننا التفكير في هذا بطريقة مختلفة. n هو أي نوع من أنواع البيانات؟ 2267 01:32:02,830 --> 01:32:04,010 ما هو هذا الشيء الموجود باللون الأزرق-- 2268 01:32:04,010 --> 01:32:04,510 n؟ 2269 01:32:04,510 --> 01:32:07,807 2270 01:32:07,807 --> 01:32:08,750 الجمهور: مؤشر. 2271 01:32:08,750 --> 01:32:10,041 ديفيد ج. مالان: إنه مؤشر. 2272 01:32:10,041 --> 01:32:12,927 وهو مؤشر إلى أحد هذه الأشياء التي قمنا بإنشاءها في وقت سابق. 2273 01:32:12,927 --> 01:32:15,260 لذلك نحن لا نقوم بإنشاء students بعد الآن باستخدام بنياتنا. 2274 01:32:15,260 --> 01:32:18,920 نحن ننفّذ العقد، والتي تحتوي على أرقام ومؤشرات next. 2275 01:32:18,920 --> 01:32:24,440 لذا يتضح أنه إذا كانت n مؤشر إلى عقدة-- 2276 01:32:24,440 --> 01:32:27,570 تذكرون تدوين النقطة من قبل-- 2277 01:32:27,570 --> 01:32:29,570 هذه ليست طريقة الوصول إلى رقم في هذه الحالة. 2278 01:32:29,570 --> 01:32:30,950 لأن n ليس عقدة بنفسها. 2279 01:32:30,950 --> 01:32:32,090 إنه مؤشر. 2280 01:32:32,090 --> 01:32:35,480 ولكن إذا كان n مؤشر، كيف يمكنك الانتقال إلى مؤشر؟ 2281 01:32:35,480 --> 01:32:37,130 كيف يمكنك الانتقال إلى عنوان؟ 2282 01:32:37,130 --> 01:32:38,906 باستخدام أي تدوين؟ 2283 01:32:38,906 --> 01:32:39,530 الجمهور: نجمة. 2284 01:32:39,530 --> 01:32:40,470 ديفيد ج. مالان: نجمة. 2285 01:32:40,470 --> 01:32:44,280 لذا تذكرون أنه من الأسبوع الماضي، إذا كنا نريد الانتقال إلى عنوان، 2286 01:32:44,280 --> 01:32:45,641 يمكنكم القيام بصيغة من هذا القبيل. 2287 01:32:45,641 --> 01:32:47,140 تجاهلوا الأقواس للحظة. 2288 01:32:47,140 --> 01:32:52,290 فقط *n تعني إذا كان n هو عنوان جزء من الذاكرة، *n تعني الانتقال إلى هناك. 2289 01:32:52,290 --> 01:32:56,520 وبمجرد أن تكون هناك، ستكون على صواب من الناحية النظرية هنا-- أعلى الزاوية اليسرى. 2290 01:32:56,520 --> 01:32:59,670 كيف يمكنك الوصول إلى حقول فردية مثل رقم أو next؟ 2291 01:32:59,670 --> 01:33:01,420 تستخدم تدوين النقطة. 2292 01:33:01,420 --> 01:33:08,400 إذا كنت تقوم حرفيًا بإنشاء *n.number، هذا يعني الانتقال إلى العنوان والوصول 2293 01:33:08,400 --> 01:33:09,620 إلى حقل الرقم. 2294 01:33:09,620 --> 01:33:12,090 توجد صيغة لطيفة في C، وهي 2295 01:33:12,090 --> 01:33:16,110 مجرد طريقة خيالية لقول تدوين شديد الاقتضاب، حيث إنه مجرد السهم. 2296 01:33:16,110 --> 01:33:17,070 لكن هذا هو كل ما فيه. 2297 01:33:17,070 --> 01:33:19,450 تدوين السهم هذا لا يقوم بأي شيء جديد. 2298 01:33:19,450 --> 01:33:24,990 إنه يقوم فقط بالتجميع، الانتقال إلى هناك، باستخدام، الوصول إلى حقل في struct، جميعًا في نفس واحد 2299 01:33:24,990 --> 01:33:26,200 إذا صح التعبير. 2300 01:33:26,200 --> 01:33:28,560 وهذا فقط يبدو أجمل قليلاً. 2301 01:33:28,560 --> 01:33:30,990 عندما قلت للمتطوعين في وقت سابق، أشيروا بأيديكم 2302 01:33:30,990 --> 01:33:33,760 إلى الأرضية، هذا كل ما يفعله هذا السطر من التعليمات البرمجية. 2303 01:33:33,760 --> 01:33:38,700 إنه يقول، انتقل إلى عنوان n، الموجود هنا، وقم بالوصول إلى حقل next، 2304 01:33:38,700 --> 01:33:41,100 واكتب في هذا الحقل فارغ، وهو فقط 2305 01:33:41,100 --> 01:33:46,110 العنوان 0-- العنوان الافتراضي الخاص، مثل الإشارة إلى الأرضية. 2306 01:33:46,110 --> 01:33:49,530 هذا السطر من التعليمات البرمجية، 40، هو فقط فحص خطأ سريع. 2307 01:33:49,530 --> 01:33:51,540 if (numbers)---- ما الذي يعادل ذلك؟ 2308 01:33:51,540 --> 01:33:54,150 هذا يقول في الواقع فقط، if numbers، لا يساوي فارغ. 2309 01:33:54,150 --> 01:33:59,310 لذا إذا كانت الأرقام صحيحة، إذا كان malloc يعمل بشكل صحيح، إذن دعونا نمضي قدمًا 2310 01:33:59,310 --> 01:34:01,458 ونقم بما يلي. 2311 01:34:01,458 --> 01:34:02,270 بكل سرور. 2312 01:34:02,270 --> 01:34:04,050 هذا هو النطق. 2313 01:34:04,050 --> 01:34:05,990 ما الذي يحدث هنا؟ 2314 01:34:05,990 --> 01:34:08,500 إذن هذا هو التكرار الحلقي الذي لا يستخدم أرقام. 2315 01:34:08,500 --> 01:34:09,487 حسنا ، أم هل يستخدم؟ 2316 01:34:09,487 --> 01:34:12,320 تقريبًا كل تكرار حلقي قمنا بكتابته وربما كنت قد كتبته للتو 2317 01:34:12,320 --> 01:34:16,660 باستخدام I، J، ربما K، لكن من المحتمل أعداد صحيحة فقط. 2318 01:34:16,660 --> 01:34:18,550 لكن لا يجب أن يكون هذا هو الحال. 2319 01:34:18,550 --> 01:34:19,594 ما هو المؤشر؟ 2320 01:34:19,594 --> 01:34:20,260 إنه عنوان. 2321 01:34:20,260 --> 01:34:21,051 ما هو العنوان؟ 2322 01:34:21,051 --> 01:34:23,484 2323 01:34:23,484 --> 01:34:24,650 الجمهور: مكان في الذاكرة. 2324 01:34:24,650 --> 01:34:26,570 ديفيد ج. مالان: مكان في الذاكرة، أو رقم بالفعل. 2325 01:34:26,570 --> 01:34:29,270 لذا يمكنك بالتأكيد استخدام التكرارات الحلقية فقط لتضمين عناوين. 2326 01:34:29,270 --> 01:34:30,230 ولكن ما هي الكيفية؟ 2327 01:34:30,230 --> 01:34:32,280 لذلك سنأخذ هذا السطر من التعليمات البرمجية بعين الاعتبار. 2328 01:34:32,280 --> 01:34:35,240 هذا يبدو مختلفًا هنا اليوم، لكنه كل شيء 2329 01:34:35,240 --> 01:34:36,620 قبل تلك الفاصلة المنقوطة الأولى. 2330 01:34:36,620 --> 01:34:38,640 هذا فقط حيث يمكنك تهيئة قيمة. 2331 01:34:38,640 --> 01:34:42,260 إذن هذا مثل قول، مرحبًا، مرحبًا جهاز الكمبيوتر، امضي قدمًا وأعطني 2332 01:34:42,260 --> 01:34:51,420 متغير يُسمى ptr وقم بتهيئته ليكون بداية القائمة الخاصة بي. 2333 01:34:51,420 --> 01:34:57,350 ثم أقول، مرحبًا، جهاز الكمبيوتر، قم بهذا طالما ptr لا يساوي فارغ. 2334 01:34:57,350 --> 01:34:59,310 وبعد ذلك ماذا سأفعل؟ 2335 01:34:59,310 --> 01:35:02,930 إذا-- ودعونا نتجاهل هذا في الوقت الحالي، إنه فحص خطأ-- 2336 01:35:02,930 --> 01:35:08,930 امضي قدمًا و-- معذرة، دعوني أفكر لثانية واحدة. 2337 01:35:08,930 --> 01:35:13,330 2338 01:35:13,330 --> 01:35:13,830 حسنًا. 2339 01:35:13,830 --> 01:35:14,685 لنقم بذلك. 2340 01:35:14,685 --> 01:35:17,340 2341 01:35:17,340 --> 01:35:19,770 ماذا تفعل هذه السطور من التعليمات البرمجية؟ 2342 01:35:19,770 --> 01:35:21,670 هذه هي التعليمات البرمجية التي تم اقتراحها بالفعل 2343 01:35:21,670 --> 01:35:23,400 في نهاية مثالنا البشري. 2344 01:35:23,400 --> 01:35:26,460 على سبيل المثال، ماذا لو أردنا إدراج جميع العناصر 2345 01:35:26,460 --> 01:35:28,500 في نهاية قائمة الارتباط؟ 2346 01:35:28,500 --> 01:35:30,030 كيف يمكن التعبير عن ذلك؟ 2347 01:35:30,030 --> 01:35:34,050 إذن في هذه الخطوط المظللة من التعليمات البرمجية، نحن نطرح السؤال، 2348 01:35:34,050 --> 01:35:38,370 إذا كان حقل next للمؤشر الحالي هو فارغ، فقد وجدنا النهاية. 2349 01:35:38,370 --> 01:35:42,810 امضي قدمًا وقم بتحديث حقل next هذا ليصبح مساويًا لـ n ومن ثم break. 2350 01:35:42,810 --> 01:35:45,140 إذن دعوني أترجم هذا إلى صورة حقيقية، 2351 01:35:45,140 --> 01:35:49,830 ولكن باستخدام مربعات أصغر توضح الأمر عندما يحدث شيء. 2352 01:35:49,830 --> 01:35:53,410 لذا لنفترض أن هذا البرنامج تم تشغيله لبعض الوقت 2353 01:35:53,410 --> 01:35:57,480 ولدينا قائمة مستفيضة تبدو بهذا الشكل، 2354 01:35:57,480 --> 01:36:02,200 حيث يشير هذا إلى هنا وربما يشير هذا إلى هنا. 2355 01:36:02,200 --> 01:36:04,350 وهذا يقول فارغ هنا. 2356 01:36:04,350 --> 01:36:05,400 وهذا يشير إلى هنا. 2357 01:36:05,400 --> 01:36:11,310 والأرقام هي، كما كنا نستخدمها اليوم، 42، 50، 13. 2358 01:36:11,310 --> 01:36:14,655 لذا يطلق على بداية هذه القائمة أرقام. 2359 01:36:14,655 --> 01:36:17,180 2360 01:36:17,180 --> 01:36:19,220 هذا يشير إلى بداية القائمة. 2361 01:36:19,220 --> 01:36:21,020 ماذا أفعل في هذا التكرار الحلقي؟ 2362 01:36:21,020 --> 01:36:24,650 أنا أقوم فقط بتنفيذ المنطق التالي باستخدام التكرار الحلقي-- 2363 01:36:24,650 --> 01:36:27,320 أعطني متغير يُسمى Ptr، كما هو مُمثل 2364 01:36:27,320 --> 01:36:30,800 في القصة في اتجاه إصبعي الأيسر، هنا، وقم بتهيئة 2365 01:36:30,800 --> 01:36:33,120 هذا ليكون بداية القائمة. 2366 01:36:33,120 --> 01:36:42,500 إذا كان مؤشر next للعقدة يساوي فارغ، أضف عقدة جديدة هنا. 2367 01:36:42,500 --> 01:36:43,880 لكنه لا يساوي فارغ. 2368 01:36:43,880 --> 01:36:46,820 أريد تتبع الآثار إلى هنا. 2369 01:36:46,820 --> 01:36:48,680 ومن ثم، أوه، نحن في نهاية القائمة. 2370 01:36:48,680 --> 01:36:50,600 أريد إدراج هذا الشيء الجديد هنا. 2371 01:36:50,600 --> 01:36:55,640 إذن كيف يمكننا التعبير عن هذه التعليمات البرمجية في C في الواقع؟ 2372 01:36:55,640 --> 01:37:01,760 لذا إذا نظرت إلى الوراء هنا، هذا هو سطر التعليمات البرمجية 2373 01:37:01,760 --> 01:37:05,980 الذي يخصص إصبعي الأيسر هنا المُسمى ptr ويقوم بتهيئته 2374 01:37:05,980 --> 01:37:09,320 ليصبح مساويًا للأرقام، وهو الأمر نفسه عند الإشارة إلى العنصر الأول. 2375 01:37:09,320 --> 01:37:11,930 يبدو مثل ما كانت تمثله كومي في وقت سابق. 2376 01:37:11,930 --> 01:37:13,940 ولكن الآن يطلق على مصفوفتنا أرقام. 2377 01:37:13,940 --> 01:37:16,280 وبعد ذلك ماذا سأفعل؟ 2378 01:37:16,280 --> 01:37:17,610 هل ptr يساوي فارغ؟ 2379 01:37:17,610 --> 01:37:18,560 حسنًا، لا. 2380 01:37:18,560 --> 01:37:21,620 إذا كانت يدي اليسرى تشير إلى هنا، فإنه من الواضح لا يساوي فارغ. 2381 01:37:21,620 --> 01:37:23,210 لذلك لا داعي للقلق بعد الآن. 2382 01:37:23,210 --> 01:37:25,010 ثم ماذا أريد أن أفعل؟ 2383 01:37:25,010 --> 01:37:28,680 إذا كان ptr next يساوي فارغ، حسنًا، فما الذي يعنيه ذلك؟ 2384 01:37:28,680 --> 01:37:30,170 حسنًا، Ptr هنا. 2385 01:37:30,170 --> 01:37:32,720 يشير ptr سهم next إلى هنا. 2386 01:37:32,720 --> 01:37:35,842 هل هذا يساوي فارغ في هذه القصة؟ 2387 01:37:35,842 --> 01:37:37,050 ما أعنيه، أنه لا يساويه حرفيًا. 2388 01:37:37,050 --> 01:37:39,630 لأن فارغ لا يُكتب هناك. فارغ موجود هناك في الأسفل. 2389 01:37:39,630 --> 01:37:42,460 إذن لم يتحقق الشرط. 2390 01:37:42,460 --> 01:37:44,130 إذن ماذا أفعل بعد ذلك؟ 2391 01:37:44,130 --> 01:37:50,250 إذا كان ptr يساوي null لا ينطبق، فها هو تحديث غريب. 2392 01:37:50,250 --> 01:37:52,890 ptr يساوي ptr next. 2393 01:37:52,890 --> 01:37:54,780 إذن هذه صيغة تبدو مشفرة. 2394 01:37:54,780 --> 01:37:58,920 ولكن إذا كان ptr يشير إلى هنا، فما هو ptr next؟ 2395 01:37:58,920 --> 01:38:00,120 إنه هو هذا فقط، أليس كذلك؟ 2396 01:38:00,120 --> 01:38:00,750 هذا هو n. 2397 01:38:00,750 --> 01:38:01,621 هذا هو next. 2398 01:38:01,621 --> 01:38:02,370 أو هذا هو رقم. 2399 01:38:02,370 --> 01:38:03,270 هذا هو next. 2400 01:38:03,270 --> 01:38:05,860 إذن هذا هو ptr next. 2401 01:38:05,860 --> 01:38:07,270 إذن ما هي تلك القيمة؟ 2402 01:38:07,270 --> 01:38:09,420 حسنًا، هذا مؤشر يشير إلى هنا. 2403 01:38:09,420 --> 01:38:13,890 إذن كتلة التعليمات البرمجية المُظللة هذه، ptr يساوي ptr next، 2404 01:38:13,890 --> 01:38:17,910 لديه تأثير بشكل مرئي للقيام بذلك. 2405 01:38:17,910 --> 01:38:18,660 لماذا؟ 2406 01:38:18,660 --> 01:38:22,200 إذا كانت الأسهم هي سحرية تمامًا قليلاً، فكّروا فقط في هذه باعتبارها عناوين. 2407 01:38:22,200 --> 01:38:25,830 إذا كان هذا يقول،عنوان next هو الموقع 100، 2408 01:38:25,830 --> 01:38:30,450 ptr يساوي ptr next مثل قول، حسنًا، هذا أيضًا يساوي 100. 2409 01:38:30,450 --> 01:38:33,270 أيًا كانت 100، على سبيل المثال، هنا 2410 01:38:33,270 --> 01:38:35,410 ما الذي يجب أن يشير إليه السهمان الآن. 2411 01:38:35,410 --> 01:38:38,160 وإذا كررت الآن هذه العملية وكررتها مجددًا، 2412 01:38:38,160 --> 01:38:41,970 ففي النهاية يكون السؤال الذي سألته في وقت سابق سيطبّق-- 2413 01:38:41,970 --> 01:38:46,150 إذا Ptr next يساوي فارغ، ما الذي أريد فعله؟ 2414 01:38:46,150 --> 01:38:53,760 حسنًا، إذا كان Ptr next يساوي فارغ، ويوجد سطران ينتقلان. ptr next يساوي n. 2415 01:38:53,760 --> 01:38:56,310 إذن لم يعد ptr next هو فارغ. 2416 01:38:56,310 --> 01:39:00,390 يجب أن يشير بدلاً من ذلك إلى n، وهو العقدة الجديدة. 2417 01:39:00,390 --> 01:39:02,340 ومن ثم هذا كل شيء. 2418 01:39:02,340 --> 01:39:04,230 لأنه تمت تهيئة هذا بالفعل لفارغ. 2419 01:39:04,230 --> 01:39:06,180 ودعونا نفترض أن هذا كان 55. 2420 01:39:06,180 --> 01:39:07,310 ها قد انتهينا. 2421 01:39:07,310 --> 01:39:09,810 من السهل جدًا القيام به، هذا واضح، بشكل شخصي مع أفراد فقط، 2422 01:39:09,810 --> 01:39:12,720 والتحرك، والإشارة باستخدام أيديهم اليسرى. 2423 01:39:12,720 --> 01:39:16,480 ولكن في التعليمات البرمجية، يتعين عليك فقط التفكير في كتل البناء الأساسية. 2424 01:39:16,480 --> 01:39:17,970 ما هي كل هذه القيم؟ 2425 01:39:17,970 --> 01:39:20,130 إلى أين تشير كل واحدة منها؟ 2426 01:39:20,130 --> 01:39:22,290 وأي من هذه الحقول تحتاج إلى تحديثها؟ 2427 01:39:22,290 --> 01:39:25,800 والتعليمات البرمجية الوحيدة هنا-- حتى لو قمنا بتجميعها كلها في 2428 01:39:25,800 --> 01:39:26,700 مثال هائل-- 2429 01:39:26,700 --> 01:39:27,480 هي هذه. 2430 01:39:27,480 --> 01:39:31,230 نحن في الواقع نستخدم تدوين السهم لنقول، انتقل إلى هذا العنوان 2431 01:39:31,230 --> 01:39:34,320 وقم بالوصول إلى قيمة فيه. 2432 01:39:34,320 --> 01:39:37,140 وهذا الشرط هنا، الذي، لن أتطرق إليه الآن، 2433 01:39:37,140 --> 01:39:41,990 يتعامل فقط مع هذا الموقف حيث تكون القائمة فارغة في البداية. 2434 01:39:41,990 --> 01:39:45,680 أي أسئلة أخرى حول هذا حتى الآن؟ 2435 01:39:45,680 --> 01:39:46,730 حسنًا. 2436 01:39:46,730 --> 01:39:52,730 إذن دعونا نلقي نظرة بصورة بيانية أكثر على بعض المشاكل النهائية التي يمكننا حلها. 2437 01:39:52,730 --> 01:39:56,090 والذي سترونه في الأيام المقبلة هو كما يلي 2438 01:39:56,090 --> 01:39:58,340 عندما يتعلق الأمر بهذه القوائم المرتبطة وأكثر من ذلك. 2439 01:39:58,340 --> 01:40:01,619 لدينا الآن القدرة بالفعل على تخصيص الأشياء في الذاكرة بشكل ديناميكي. 2440 01:40:01,619 --> 01:40:04,160 نحن لا نعرف بالضرورة مسبقًا كم عدد الأرقام الموجودة لدينا 2441 01:40:04,160 --> 01:40:06,950 أو، في حالة مجموعة المشاكل التالية، كم عدد الكلمات الموجودة لدينا. 2442 01:40:06,950 --> 01:40:10,040 لدينا القدرة رغم ذلك على استخدام malloc، وربما حتى realloc، 2443 01:40:10,040 --> 01:40:12,500 لنزيد وننمّي بنية البيانات في الذاكرة. 2444 01:40:12,500 --> 01:40:14,600 ولدينا القدرة في التعليمات البرمجية لاجتياز 2445 01:40:14,600 --> 01:40:17,360 تلك القيم بالفعل بطريقة يمكننا 2446 01:40:17,360 --> 01:40:20,150 من خلالها الوصول إلى الذاكرة الموجودة كلها على اللوحة الآن 2447 01:40:20,150 --> 01:40:22,620 وليس بالضرورة العودة على التوالي. 2448 01:40:22,620 --> 01:40:26,780 ولكن ما الذي سيحدث إذا كنا مازلنا نريد جمع هذه الأفكار 2449 01:40:26,780 --> 01:40:27,650 بحلول أفضل؟ 2450 01:40:27,650 --> 01:40:29,700 حسنًا، دعونا نلقي نظرة على ذلك. 2451 01:40:29,700 --> 01:40:35,490 وتحديدًا، إذا انتقلت دوعنا نقل إلى هنا إلى ما يلي، 2452 01:40:35,490 --> 01:40:38,000 دعونا نفكر في مشكلة يمكننا حلها الآن. 2453 01:40:38,000 --> 01:40:42,710 إذا أردت تخزين اسم كل شخص في هذه الغرفة في بنية البيانات، 2454 01:40:42,710 --> 01:40:44,760 يمكنني القيام بماذا؟ 2455 01:40:44,760 --> 01:40:46,170 حسنًا، يمكننا استخدام مصفوفة. 2456 01:40:46,170 --> 01:40:48,770 إذن يمكنني في الواقع أن أقرر كم عدد الأشخاص في الغرفة-- 2457 01:40:48,770 --> 01:40:49,790 دعونا نطلق عليه n-- 2458 01:40:49,790 --> 01:40:52,790 ونرسم مربعات n بالفعل على اللوحة، ومن ثم نطلب بشكل متكرر 2459 01:40:52,790 --> 01:40:55,340 اسم كل شخص، وندوّنه هنا بالفعل. 2460 01:40:55,340 --> 01:40:59,660 إذا أردت أخذ الحضور بعد ذلك وأقول، أوه، هل أليس موجودة هنا، 2461 01:40:59,660 --> 01:41:02,240 أو بوب هنا، أو كريم هنا، أو براين، 2462 01:41:02,240 --> 01:41:05,960 يمكنني فقط النظر في تلك المصفوفة وقول نعم أو لا، هذا الشخص موجود هنا. 2463 01:41:05,960 --> 01:41:08,060 ولكن ما هي مدة تشغيل هذه الخوارزمية؟ 2464 01:41:08,060 --> 01:41:11,540 كم من الوقت سيستغرق البحث عن الاسم في بنية البيانات 2465 01:41:11,540 --> 01:41:14,242 حيث قمت برسمها كمصفوفة فقط، قائمة كبيرة على اللوحة؟ 2466 01:41:14,242 --> 01:41:15,200 الجمهور: حرف O كبير من n. 2467 01:41:15,200 --> 01:41:15,716 ديفيد ج. مالان: ما هذا؟ 2468 01:41:15,716 --> 01:41:16,450 الجمهور: حرف O كبير من n. 2469 01:41:16,450 --> 01:41:17,420 ديفيد ج. مالان: حرف O كبير من n، أليس كذلك؟ 2470 01:41:17,420 --> 01:41:20,253 لأنه إذا كانت مجرد قائمة أسماء، فستأخذ حرف O كبير من n. 2471 01:41:20,253 --> 01:41:22,310 وبصراحة، يبدو ذلك أمرًا بطيئًا بعض الشيء. 2472 01:41:22,310 --> 01:41:24,410 كيف يمكنني القيام بتحسين؟ 2473 01:41:24,410 --> 01:41:26,630 حسنًا، ماذا لو قمنا بجمع بعض هذه الأفكار؟ 2474 01:41:26,630 --> 01:41:28,700 المصفوفات جيدة لأنها تمنحني ترتيبًا عشوائيًا 2475 01:41:28,700 --> 01:41:31,410 من الوصول الفوري إلى مواقع الذاكرة. 2476 01:41:31,410 --> 01:41:35,720 لكن القوائم المرتبطة جيدة لأنها تتيح لي إضافة عناصر أو طرحها 2477 01:41:35,720 --> 01:41:38,282 بشكل ديناميكي حتى لو أردت ذلك من القائمة. 2478 01:41:38,282 --> 01:41:38,990 إذن أتعلمون ماذا؟ 2479 01:41:38,990 --> 01:41:44,210 بدلاً من كتابة اسم كل شخص، مثل أليس وبوب، 2480 01:41:44,210 --> 01:41:52,340 وتشارلي، وما شابه ذلك في مصفوفة واحدة كبيرة فقط من حجم ثابت قد 2481 01:41:52,340 --> 01:41:55,310 يبقيني في زاوية - الآن لديّ فقط مساحة لاسم واحد آخر-- 2482 01:41:55,310 --> 01:41:57,950 ماذا لو قمت بدلاً من ذلك بأشياء بصورة أكثر ذكاء؟ 2483 01:41:57,950 --> 01:42:01,160 إذن في الواقع عندما أدون اسم كل شخص في الغرفة، ماذا 2484 01:42:01,160 --> 01:42:04,290 لو كتبت بدلاً من ذلك، حسنًا، هل أليس موجودة هنا. 2485 01:42:04,290 --> 01:42:04,790 حسنًا. 2486 01:42:04,790 --> 01:42:06,190 أليس موجودة هنا. 2487 01:42:06,190 --> 01:42:07,865 ثم براين هنا. 2488 01:42:07,865 --> 01:42:09,140 سأضع اسم براين هنا. 2489 01:42:09,140 --> 01:42:11,221 ومن ثم ربما تشارلي هنا. 2490 01:42:11,221 --> 01:42:11,720 حسنًا. 2491 01:42:11,720 --> 01:42:13,760 إذن تشارلي. 2492 01:42:13,760 --> 01:42:16,287 ومن ثم ربما أرنولد هنا. 2493 01:42:16,287 --> 01:42:17,370 أين يجب أن أضع أرنولد؟ 2494 01:42:17,370 --> 01:42:19,160 إذن يبدأ أيضًا بالحرف أ. أتعلمون ماذا؟ 2495 01:42:19,160 --> 01:42:21,770 دعونا فقط نضع أرنولد هنا. 2496 01:42:21,770 --> 01:42:23,510 أرنولد. 2497 01:42:23,510 --> 01:42:24,542 وآبي موجودة هنا. 2498 01:42:24,542 --> 01:42:25,250 إذن أتعلمون ماذا؟ 2499 01:42:25,250 --> 01:42:27,960 دعونا فقط نضع آبي هنا أيضًا. 2500 01:42:27,960 --> 01:42:29,270 لقد حضر بوب كذلك. 2501 01:42:29,270 --> 01:42:31,520 إذن بوب-- إذن ما هو النمط الذي أتبعه بوضوح 2502 01:42:31,520 --> 01:42:35,107 حيث أسمع الأسماء التي ينادى عليها؟ 2503 01:42:35,107 --> 01:42:36,440 الجمهور: مرتبة أبجديًا. 2504 01:42:36,440 --> 01:42:37,860 ديفيد ج. مالان: مرتبة أبجديًا-- 2505 01:42:37,860 --> 01:42:38,490 نوعًا ما. 2506 01:42:38,490 --> 01:42:41,280 مثلما، انتهى المطاف بآبي في مكان غريب هنا. 2507 01:42:41,280 --> 01:42:44,400 لكن لا بأس لأنني لم أسمع اسمها أولاً. 2508 01:42:44,400 --> 01:42:49,080 لكنني قمت بترتيب الأشخاص نوعًا ما في صفوف مختلفة من اللوحة. 2509 01:42:49,080 --> 01:42:50,820 وبعبارة أخرى، جميع الأسماء التي تبدأ بحرف أ يبدو لي 2510 01:42:50,820 --> 01:42:53,050 أنني كتبتهم فقط في الأعلى لتيسير الأمر، 2511 01:42:53,050 --> 01:42:54,720 ومن ثم جميع الأسماء التي تبدأ بحرف ب معاً، والأسماء التي تبدأ بحرف س. 2512 01:42:54,720 --> 01:42:56,490 وربما إذا تابعت، يمكني القيام بذلك على طول الطريق 2513 01:42:56,490 --> 01:42:58,420 إلى الحرف ي في الأبجدية العربية. 2514 01:42:58,420 --> 01:43:01,770 لذا ما هو الأمر الجيد في هذا هو أن، نعم، أنني أقوم بإنشاء قوائم أسماء، 2515 01:43:01,770 --> 01:43:03,990 ولكن ما هو طول كل هذه القوائم؟ 2516 01:43:03,990 --> 01:43:06,780 إذا كان هناك n من الأشخاص في الغرفة، فلن تكون كل القوائم الخاصة بي 2517 01:43:06,780 --> 01:43:09,720 طول n ، وهو بطيء. 2518 01:43:09,720 --> 01:43:14,505 سيكون ماذا؟ n مقسومة على 26، معطاة أو مأخوذة. 2519 01:43:14,505 --> 01:43:16,630 إذا افترضنا أن هناك عدد متساوي من الأشخاص 2520 01:43:16,630 --> 01:43:20,710 وأسماؤهم تبدأ بحرف ي وأ، سيكون تقريبًا n مقسومًا على 26 إذن 2521 01:43:20,710 --> 01:43:23,500 لدي هذه السلاسل من أسماء الأشخاص، ولكنها 2522 01:43:23,500 --> 01:43:26,890 أقصر بكثير مما سيكونوا عليه إذا قمت فقط بتجميع الكل معًا. 2523 01:43:26,890 --> 01:43:31,480 وتعد هذه تقنية أساسية في البرمجة تسمى علامات تجزئة. 2524 01:43:31,480 --> 01:43:34,640 اتضح أنه يوجد أشياء في هذا العالم تسمى بداول علامات تجزئة. 2525 01:43:34,640 --> 01:43:39,100 هي مجرد دوال رياضية، أو حرفية، أو مُنفذة من تعليمات برمجية 2526 01:43:39,100 --> 01:43:43,990 التي تأخذ كإدخال شيء ما وتنتج كإخراج رقم تمامًا-- رقم 2527 01:43:43,990 --> 01:43:46,930 من 0 إلى، لنقل، 25، أو من 1 إلى 26. 2528 01:43:46,930 --> 01:43:49,750 ولكن يمكنها أيضًا إخراج سلاسل في سياقات أخرى أيضًا. 2529 01:43:49,750 --> 01:43:53,545 إذن دالة علامة التجزئة الخاصة بي هنا في عقلي هي، إذا سلمتني اسمًا، 2530 01:43:53,545 --> 01:43:55,670 سألقي نظرة على الحرف الأول من اسمك. 2531 01:43:55,670 --> 01:43:57,910 وإذا كان أ، سأقوم بوضعك في الموقع 0. 2532 01:43:57,910 --> 01:44:00,180 إذا كان ب، سأضعك في الموقع 1. 2533 01:44:00,180 --> 01:44:03,540 إذا كان هو ي، سأضعك في الموقع 25 في النهاية. 2534 01:44:03,540 --> 01:44:05,620 إذن هذه كل الحزمات الموجودة لديّ، إذا جاز التعبير، 2535 01:44:05,620 --> 01:44:08,080 في علوم الكمبيوتر-- على سبيل المثال 26 حزمة أو مساحة 2536 01:44:08,080 --> 01:44:11,350 على اللوحة التي تمثل بدايات أسماء الأشخاص. 2537 01:44:11,350 --> 01:44:12,670 إذن ما هذا؟ 2538 01:44:12,670 --> 01:44:16,690 حسنًا، يبدو أنه إذا لم أكن اعرف مسبقًا كم عدد الأسماء التي تبدأ بالحرف أ لدي، 2539 01:44:16,690 --> 01:44:19,880 هذا يبدو كرسم لهذه كقائمة مرتبطة، إذا صح التعبير، 2540 01:44:19,880 --> 01:44:22,360 وقد يستغرق ذلك وقتًا أطول وأطول. 2541 01:44:22,360 --> 01:44:27,250 لكنني أعرف أن لديّ فقط عدد محدود من الأحرف الأولى. 2542 01:44:27,250 --> 01:44:30,790 لذلك-- في مجازفة للرسم بصورة عشوائية إلى حد ما-- 2543 01:44:30,790 --> 01:44:32,639 هو نوع من أنواع الرسم لأي بنية من بنيات البيانات؟ 2544 01:44:32,639 --> 01:44:33,430 الجمهور: مصفوفة. 2545 01:44:33,430 --> 01:44:34,305 ديفيد ج. مالان: أجل. 2546 01:44:34,305 --> 01:44:39,610 إنه نوع من أنواع رسم المصفوفة التي بها فقط 26 مكان. 2547 01:44:39,610 --> 01:44:42,970 والأمر الجيد بشأن المصفوفة هو أن لديّ وصول عشوائي. 2548 01:44:42,970 --> 01:44:47,270 يمكنني الانتقال مباشرة إلى أي حرف من حروف الأبجدية في وقت ثابت، خطوة واحدة. 2549 01:44:47,270 --> 01:44:50,530 وبمجرد أن أصل إلى هناك، سأستمر في رؤية قائمة الأسماء. 2550 01:44:50,530 --> 01:44:54,180 لحسن الحظ، بفضل القوائم المرتبطة، تلك القائمة التي يمكن أن تكون قصيرة أو طويلة. 2551 01:44:54,180 --> 01:44:55,930 ولكن في المتوسط، دعونا نقول أنه سيكون 2552 01:44:55,930 --> 01:45:02,070 الطول 126 الأمر الذي سيحدث إذا استخدمت للتو مصفوفة واحدة أو قائمة مرتبطة 2553 01:45:02,070 --> 01:45:02,950 واحدة. 2554 01:45:02,950 --> 01:45:06,940 إذن تقنية استخدام دالة علامة التجزئة هذه-- والتي قمت، مجددًا، 2555 01:45:06,940 --> 01:45:09,760 بتحدديها كما قمتم بإعطائي اسمًا؛ وأخذت ذلك كإدخال؛ 2556 01:45:09,760 --> 01:45:13,840 وأنظر إلى الحرف الأول؛ وأعيده كإخراج رقم من 0 إلى 25-- 2557 01:45:13,840 --> 01:45:17,194 تتيح لك دالة علامة التجزئة إنشاء جدول علامة تجزئة. 2558 01:45:17,194 --> 01:45:19,360 وهناك طرق مختلفة لتنفيذ جداول علامات التجزئة، 2559 01:45:19,360 --> 01:45:22,540 ولكن ربما الطريقة الأكثر شيوعًا هي بالفعل هكذا. 2560 01:45:22,540 --> 01:45:26,170 عليك أن تقرر مسبقًا حجم المصفوفة. 2561 01:45:26,170 --> 01:45:30,070 لكن هذه المصفوفة لا تحتوي على السلاسل أو أسماء الأشخاص. 2562 01:45:30,070 --> 01:45:34,270 تحتوي هذه المصفوفة بالفعل على قوائم مرتبطة. 2563 01:45:34,270 --> 01:45:37,210 وهي القوائم المرتبطة التي تحتوي على الأسماء. 2564 01:45:37,210 --> 01:45:39,010 إذن نحن نستعير أفكارًا من، على سبيل المثال، الأسبوع الثاني. 2565 01:45:39,010 --> 01:45:42,580 نقوم بدمجهم باستخدام فكرة اليوم من الأسبوع الرابع من إضافة المصفوفات 2566 01:45:42,580 --> 01:45:44,180 إلى القائمة المرتبطة على التوالي. 2567 01:45:44,180 --> 01:45:46,360 ونحصل على الأفضل في كلتا الحالتين. 2568 01:45:46,360 --> 01:45:49,760 لأنه يمكني الانتقال فورًا إلى أي حرف من الأحرف الأبجدية بسرعة فائقة. 2569 01:45:49,760 --> 01:45:51,560 وعندما أصل إلى هناك، نعم، توجد قائمة، 2570 01:45:51,560 --> 01:45:55,540 ولكنها لن تكون قريبة طالما لا أستخدم هذه الخدعة. 2571 01:45:55,540 --> 01:45:57,650 إذن ما هو وقت التشغيل لكل هذا؟ 2572 01:45:57,650 --> 01:46:01,450 حسنًا، تبين أن جدول علامة التجزئة في أسوأ الحالات 2573 01:46:01,450 --> 01:46:04,300 قد يظل يستغرق عدد من الخطوات للعثور على اسم شخص بمجرد 2574 01:46:04,300 --> 01:46:06,000 أن تتم إضافته إلى القائمة؟ 2575 01:46:06,000 --> 01:46:09,644 في أسوأ الحالات، كم عدد الخطوات، إذا كان هناك n من الأشخاص في الغرفة؟ 2576 01:46:09,644 --> 01:46:10,640 الجمهور: n. 2577 01:46:10,640 --> 01:46:11,640 ديفيد ج. مالان: ربما n. 2578 01:46:11,640 --> 01:46:12,850 لماذا؟ 2579 01:46:12,850 --> 01:46:14,320 إنه وضع منحرف إلى حد ما. 2580 01:46:14,320 --> 01:46:17,001 ولكن هل يمكنك استنباط سيناريو حيث، 2581 01:46:17,001 --> 01:46:19,000 على الرغم من أننا نقوم بهذا الأمر الرائع، فما زال 2582 01:46:19,000 --> 01:46:21,510 يستغرق n من الخطوات لتأكيد أو إنكار وجود شخص ما هنا؟ 2583 01:46:21,510 --> 01:46:21,800 أجل؟ 2584 01:46:21,800 --> 01:46:23,310 الجمهور: يبدأ اسم الجميع بنفس الحرف. 2585 01:46:23,310 --> 01:46:25,150 ديفيد ج. مالان: يبدأ اسم الجميع بالحرف نفسه 2586 01:46:25,150 --> 01:46:26,287 لسبب ما غريب. 2587 01:46:26,287 --> 01:46:28,120 الآن، يصبح الأمر سخيفًا قليلاً في عالم البشر. 2588 01:46:28,120 --> 01:46:29,870 ولكن يمكن أن يحدث ذلك إذا كنت تتناول فقط 2589 01:46:29,870 --> 01:46:32,080 عن البيانات أو أيًا كان في عالم الكمبيوتر. 2590 01:46:32,080 --> 01:46:37,240 يمكن أن يتحول هذا إلى، بالتأكيد، مصفوفة بقائمة مرتبطة واحدة فقط بالفعل. 2591 01:46:37,240 --> 01:46:39,985 ولكن في الواقع، ليس من المحتمل أن يحدث هذا، أليس كذلك؟ 2592 01:46:39,985 --> 01:46:42,860 إذا استغرقنا بالفعل الوقت هنا وطلبنا من الجميع ذكر أسمائهم، 2593 01:46:42,860 --> 01:46:46,240 ربما نحصل على توزيع منسق بشكل منطقي للرسائل، 2594 01:46:46,240 --> 01:46:49,720 على الأقل كما هو محتمل من الناحية الإحصائية باستخدام أسماء الأشخاص فقط. 2595 01:46:49,720 --> 01:46:51,550 إذن هذا عبارة عن نشر للأشياء. 2596 01:46:51,550 --> 01:46:55,150 ولذا يوجد هذا التمييز الأساسي بين وقت التشغيل 2597 01:46:55,150 --> 01:46:58,390 لعالم حقيقي إلى حد ما، أو وقت ساعة الحائط-- كم عدد الثواني التي تدور بالفعل 2598 01:46:58,390 --> 01:46:59,080 في الساعة-- 2599 01:46:59,080 --> 01:47:00,850 مقابل وقت تشغيل مُقارب. 2600 01:47:00,850 --> 01:47:04,150 لقد تحدثنا لبضعة أسابيع حتى الآن حول وقت التشغيل كحرف O الكبير من n. 2601 01:47:04,150 --> 01:47:08,590 وقد يظل هذا هو الحال، حيث جدول علامة التجزئة-- نعم، في أسوأ الحالات، 2602 01:47:08,590 --> 01:47:10,481 ما يزال حرف O الكبير من بنية بيانات n. 2603 01:47:10,481 --> 01:47:12,730 لأنه في أسوأ حالة، سيأخذ خطوات n. 2604 01:47:12,730 --> 01:47:18,550 ولكن في العالم الحقيقي، يكون حرف O الكبير من n هو حرف O كبير من n بالفعل مقسومًا على 26، 2605 01:47:18,550 --> 01:47:21,320 حتى لو أننا دائمًا ما نتجاهل تلك المصطلحات ذات الترتيب الأدنى. 2606 01:47:21,320 --> 01:47:24,940 ولكن عندما تقوم، كشخص، بتشغيل التعليمة البرمجية وتحليل البيانات، 2607 01:47:24,940 --> 01:47:30,280 ويعد تشغيلها بمقدار 26 مرة بشكل أسرع في الواقع هو توفير للوقت الحقيقي، 2608 01:47:30,280 --> 01:47:33,610 حتى لو قال عالم رياضيات، آه، هذا هو الأساس نفسه. 2609 01:47:33,610 --> 01:47:36,610 وبالفعل، إحدى المشكلات التي ستواجهنا في مجموعة المشاكل التالية 2610 01:47:36,610 --> 01:47:39,670 هي بالضبط معرفة ما هي الآثار 2611 01:47:39,670 --> 01:47:43,270 في تعليمتك البرمجية لوقت تشغيل ساعة الحائط الفعلي. 2612 01:47:43,270 --> 01:47:46,570 وإعداد قرارات تصميم أكثر ذكاء، مثل شيء من هذا القبيل، 2613 01:47:46,570 --> 01:47:50,200 يمكنه بالفعل تسريع تعليمتك البرمجية لتكون 26 مرة أسرع، حتى لو، 2614 01:47:50,200 --> 01:47:52,030 نعم، سيقول باحث في الجانب النظري ذلك، آه، 2615 01:47:52,030 --> 01:47:55,630 ولكن هذا ما يزال معادلاً بشكل متقارب أو بشكل حسابي 2616 01:47:55,630 --> 01:47:58,000 لشيء خطي فقط. 2617 01:47:58,000 --> 01:48:01,090 إذن هذا هو الضبط الدقيق الذي من شأنه أن يحسن تعليمتك البرمجية بشكل أفضل وأفضل. 2618 01:48:01,090 --> 01:48:03,460 الآن، بصراحة، من المحتمل أن علامات التجزئة على الأسماء الأولى 2619 01:48:03,460 --> 01:48:05,320 ليست الشيء الوحيد الأكثر ذكاء، أليس كذلك؟ 2620 01:48:05,320 --> 01:48:09,151 على سبيل المثال، هل يوجد أي شخص-- وسيكون هذا صعبًا. 2621 01:48:09,151 --> 01:48:11,260 هل يبدأ اسم أي شخص بـ X هنا؟ 2622 01:48:11,260 --> 01:48:12,625 الجمهور: [INAUDIBLE]. 2623 01:48:12,625 --> 01:48:13,620 ديفيد ج. مالان: ليست هنا. 2624 01:48:13,620 --> 01:48:15,540 لكن شكرًا لك على ذلك المثال المضاد المثالي. 2625 01:48:15,540 --> 01:48:16,350 لكنها ليست هنا. 2626 01:48:16,350 --> 01:48:17,700 إذن انظروا، لا يوجد أسماء مبدوءة بـ Z. 2627 01:48:17,700 --> 01:48:19,999 نحن الآن نصل إلى 25 قيمة ممكنة. 2628 01:48:19,999 --> 01:48:22,290 وقد يمكنني ربما اختيار بعض الأحرف الأقل شيوعًا. 2629 01:48:22,290 --> 01:48:25,260 المغزى أنه من المحتمل أن يوجد عدد أسماء قليل تبدأ بحرف أ أكثر من التي تبدأ بحرف ي 2630 01:48:25,260 --> 01:48:28,860 أو عدد آخر من الأسماء التي تبدأ بحرف ب هناك أكثر من تلك التي تبدأ بحرف ك فقط حسب طبيعة أسماء الأشخاص. 2631 01:48:28,860 --> 01:48:32,260 ولذلك ربما يكون استخدام الحرف الأول فقط أمرًا ليس جيدًا بما يكفي. 2632 01:48:32,260 --> 01:48:35,700 وبصراحة، باستخدام 26 اسمًا-- لنفترض أننا فعلنا ذلك لجميع الأشخاص في جامعة هارفارد 2633 01:48:35,700 --> 01:48:37,140 ولدينا الآلاف من الأسماء. 2634 01:48:37,140 --> 01:48:40,290 قد تظل كل سلسلة من سلاسلي تحتوي على المئات أو الآلاف من الأسماء. 2635 01:48:40,290 --> 01:48:43,680 لذلك فإن سؤال التصميم الآخر سيكون، حسنًا، كم عدد الحِزم التي يجب 2636 01:48:43,680 --> 01:48:45,285 أن تكون لديك، ما هو الحجم الذي يجب أن تكون به المصفوفة. 2637 01:48:45,285 --> 01:48:47,160 ربما لا يجب أن تنظروا إلى الحرف الأول. 2638 01:48:47,160 --> 01:48:50,820 ماذا لو نظرتم إلى الحرف الأول والثاني معًا-- إذن AA، وAB، 2639 01:48:50,820 --> 01:48:55,680 وAC، ومن ثم نقطة نقطة نقطة، BA ،BB ،BC، حتى يمكنكم الحصول 2640 01:48:55,680 --> 01:48:57,090 على المزيد والمزيد من الحِزم؟ 2641 01:48:57,090 --> 01:48:57,750 لكن ماذا أيضًا؟ 2642 01:48:57,750 --> 01:49:01,740 وإلا كيف يمكننا أن نوزع الأشخاص بشكل منتظم إلى حد ما؟ 2643 01:49:01,740 --> 01:49:06,366 ما الذي يتوفر لديكم جميعًا يمكن أن نستخدمه كمدخل إلى دالة علامة التجزئة؟ 2644 01:49:06,366 --> 01:49:07,330 الجمهور: اسم العائلة. 2645 01:49:07,330 --> 01:49:07,510 ديفيد ج. مالان: حسنًا. 2646 01:49:07,510 --> 01:49:09,551 حسنًا، يمكنك استخدام اسم العائلة، والذي قد يمنحنا 2647 01:49:09,551 --> 01:49:11,081 توزيعًا مختلفًا أو مماثلاً. 2648 01:49:11,081 --> 01:49:11,580 أجل؟ 2649 01:49:11,580 --> 01:49:12,240 الجمهور: رقم الهوية. 2650 01:49:12,240 --> 01:49:12,820 ديفيد ج. مالان: ماذا؟ 2651 01:49:12,820 --> 01:49:13,450 الجمهور: رقم الهوية. 2652 01:49:13,450 --> 01:49:13,870 ديفيد ج. مالان: أجل. 2653 01:49:13,870 --> 01:49:17,036 يمكننا استخدام رقم هويتك وبالفعل نلقي نظرة على الرقم الأول من رقم هويتك. 2654 01:49:17,036 --> 01:49:19,470 والاحتمالات هي، من 0 إلى 9. 2655 01:49:19,470 --> 01:49:21,880 إذن ربما يمكننا الحصول على 10 حِزم على الأقل بهذه الطريقة. 2656 01:49:21,880 --> 01:49:23,890 ومن المحتمل أن هذا تم توزيعه بشكل منتظم. 2657 01:49:23,890 --> 01:49:24,700 لست متأكدًا. 2658 01:49:24,700 --> 01:49:27,430 يمكننا استخدام تواريخ الميلاد بطريقة ما. 2659 01:49:27,430 --> 01:49:29,650 على سبيل المثال، يمكننا وضع كل حديثي الولادة في حِزمة واحد، 2660 01:49:29,650 --> 01:49:31,690 والأكبر سنًا في حِزمة آخرى، والآخرين أيضًا، 2661 01:49:31,690 --> 01:49:34,689 وهكذا، في الحزمات الخاصة بهم، والتي من شأنها أن تعطينا بعض المدخلات. 2662 01:49:34,689 --> 01:49:38,360 إذن مجددًا، دالة علامة التجزئة متروكة لكم تمامًا لتقوموا ببرمجتها وتصميمها. 2663 01:49:38,360 --> 01:49:41,140 ومع ذلك الهدف هو تسهيل الأمور. 2664 01:49:41,140 --> 01:49:44,860 تريدون أن تحتوي كل قائمة مرتبطة على نفس العدد من الأشياء 2665 01:49:44,860 --> 01:49:48,250 فقط حتى يكون لديكم تقريبًا الأداء نفسه 2666 01:49:48,250 --> 01:49:50,784 عبر جميع تلك المُدخلات المختلفة. 2667 01:49:50,784 --> 01:49:53,200 لذا دعونا نلقي نظرة على زوجين من بنيات البيانات الأخرى، 2668 01:49:53,200 --> 01:49:54,790 مجددًا، بهذه الطريقة المجردة. 2669 01:49:54,790 --> 01:49:58,090 والآن قد عرفنا أن، على الرغم من أن الأمر لم يكن واضحًا في المحاولة الأولى، 2670 01:49:58,090 --> 01:49:59,800 عرفنا كيف نقوم بإنشاء مصفوفات. 2671 01:49:59,800 --> 01:50:02,320 نعرف الآن كيفية إنشاء القوائم المرتبطة. 2672 01:50:02,320 --> 01:50:05,620 ومن المنطقي أنه يمكننا تنفيذها معًا في التعليمة البرمجية. 2673 01:50:05,620 --> 01:50:08,650 ماذا أيضًا يمكننا فعله الآن مع كتل البناء هذه؟ 2674 01:50:08,650 --> 01:50:13,765 على سبيل المثال، هذه البنية هنا هي بنية شائعة جدًا، تُعرف بالشجرة. 2675 01:50:13,765 --> 01:50:16,641 شجرة مثل شجرة العائلة، حيث يوجد هناك أب واحد أو أم واحدة 2676 01:50:16,641 --> 01:50:19,390 في الأعلى، ومن ثم أبناؤهم، ومن ثم أحفادهم، 2677 01:50:19,390 --> 01:50:21,310 وأولاد أحفادهم، وهكذا. 2678 01:50:21,310 --> 01:50:25,090 والأمر الجيد في بنية شجرة هو أنه، إذا كنت تقوم بتخزين البيانات، 2679 01:50:25,090 --> 01:50:28,930 يمكنك في الواقع تخزين البيانات بطرق ذكية للطفل الموجود على اليسار، 2680 01:50:28,930 --> 01:50:32,410 وللطفل الموجود على اليمين، وهكذا، على النحو التالي. 2681 01:50:32,410 --> 01:50:37,390 لاحظوا هنا، يوجد شيء غريب بشأن جميع الأرقام في بنية البيانات 2682 01:50:37,390 --> 01:50:38,800 تلك. 2683 01:50:38,800 --> 01:50:41,522 ما هو الجدير بالملاحظة بشأنها؟ 2684 01:50:41,522 --> 01:50:44,639 2685 01:50:44,639 --> 01:50:45,430 ما هو الجدير بالذكر؟ 2686 01:50:45,430 --> 01:50:45,856 أجل؟ 2687 01:50:45,856 --> 01:50:46,710 الجمهور: مضاعفات الرقم 11. 2688 01:50:46,710 --> 01:50:47,110 ديفيد ج. مالان: ما هذا؟ 2689 01:50:47,110 --> 01:50:48,310 الجمهور: إنها مضاعفات للرقم 11. 2690 01:50:48,310 --> 01:50:50,018 ديفيد ج. مالان: هي مضاعفات للرقم 11. 2691 01:50:50,018 --> 01:50:53,281 كان ذلك فقط لجعلها تبدو جميلة من قِبل المؤلف هنا. 2692 01:50:53,281 --> 01:50:53,780 أجل؟ 2693 01:50:53,780 --> 01:50:55,415 الجمهور: [INAUDIBLE]. 2694 01:50:55,415 --> 01:50:56,290 ديفيد ج. مالان: أجل. 2695 01:50:56,290 --> 01:50:58,120 هناك دلالة رياضية أيضًا. 2696 01:50:58,120 --> 01:51:02,560 مثل، بغض النظر عن العقدة أو الدائرة التي تنظر إليها، فإن القيمة فيها 2697 01:51:02,560 --> 01:51:08,276 أكبر من تلك للطفل الموجود على اليسار وأصغر من تلك للطفل الموجود على اليمين. 2698 01:51:08,276 --> 01:51:09,400 إذن هي بينهما نوعًا ما. 2699 01:51:09,400 --> 01:51:11,710 أي دائرة تنظر إليها، يكون الرقم لناحية اليسار هو أصغر، 2700 01:51:11,710 --> 01:51:13,126 والرقم من ناحية اليمين هو أكبر. 2701 01:51:13,126 --> 01:51:15,730 وأعتقد أن هذا ينطبق عالميًا في كل مكان. 2702 01:51:15,730 --> 01:51:16,540 نعم؟ 2703 01:51:16,540 --> 01:51:17,560 إذن ماذا يعني هذا؟ 2704 01:51:17,560 --> 01:51:23,400 سنتذكر من، على سبيل المثال، الأسبوع 0 عندما كانت لدينا مجموعة كاملة من صفحات دليل الهاتف 2705 01:51:23,400 --> 01:51:24,400 التي كنا نبحث فيها عن-- 2706 01:51:24,400 --> 01:51:26,000 1، 2، 3، 4، 5، 6. 2707 01:51:26,000 --> 01:51:27,560 دعونا نمنح أنفسنا خانة 7. 2708 01:51:27,560 --> 01:51:30,550 تذكرون أنه عندما قمنا بإنشاء خوارزمية فرق تسد، أو البحث الثنائي، 2709 01:51:30,550 --> 01:51:31,719 فعلنا ذلك في مصفوفة. 2710 01:51:31,719 --> 01:51:34,510 وما كان لطيفًا في البحث الثنائي أننا بدأنا في المنتصف، 2711 01:51:34,510 --> 01:51:36,430 وبعد ذلك ربما انتقلنا إلى اليسار، أو ربما انتقلنا إلى اليمين، 2712 01:51:36,430 --> 01:51:38,346 وقمنا بإنشاء خوارزمية فرق تسد لحل المشكلة 2713 01:51:38,346 --> 01:51:41,920 بشكل أكثر كفاءة في وقت لوغاريتمي 2714 01:51:41,920 --> 01:51:44,500 عن ما كان يمكن أن يكون إذا فعلنا ذلك خطيًا. 2715 01:51:44,500 --> 01:51:48,610 لكننا نعرف الآن بعد عدة أسابيع أن المصفوفات محدودة نوعًا ما، أليس كذلك؟ 2716 01:51:48,610 --> 01:51:51,320 إذا تابعت تخزين جميع قيمي في مصفوفة، 2717 01:51:51,320 --> 01:51:53,512 فما الذي لا يمكنني فعله باستخدام المصفوفة؟ 2718 01:51:53,512 --> 01:51:56,470 2719 01:51:56,470 --> 01:51:57,610 أن أجعلها أكبر، صحيح؟ 2720 01:51:57,610 --> 01:52:00,760 لا يمكنني إضافة عنصر إليها دون نسخ كل عنصر، 2721 01:52:00,760 --> 01:52:02,770 كما ناقشنا ذلك حتى الآن اليوم. 2722 01:52:02,770 --> 01:52:04,990 ولكن ماذا لو كنت أذكى قليلاً بشأن ذلك؟ 2723 01:52:04,990 --> 01:52:07,900 ماذا لو قمت بتخزين قيمي، ليس فقط في مصفوفة، 2724 01:52:07,900 --> 01:52:10,540 ولكن بدأت في تخزينها في تلك الدوائر-- 2725 01:52:10,540 --> 01:52:12,010 دعونا نطلق عليها عُقد-- 2726 01:52:12,010 --> 01:52:18,400 وكل واحدة من تلك العُقد هي في الواقع مجرد عدد صحيح بالإضافة إلى قيمتين إضافيتين؟ 2727 01:52:18,400 --> 01:52:20,820 كيف لنا أن ننفذ بنية البيانات تلك في الذاكرة؟ 2728 01:52:20,820 --> 01:52:24,250 حسنًا، إليك int int-- يمكنها أن تمثل الرقم المعني. 2729 01:52:24,250 --> 01:52:26,260 ويمكننا وضع ذلك الرقم في بنية بيانات 2730 01:52:26,260 --> 01:52:29,860 التي تسمى عقدة وهي فقط تحتوي على الصيغة نفسها كما وضحنا في وقت سابق اليوم، 2731 01:52:29,860 --> 01:52:31,760 لكني تركت مساحة لحقلين آخرين. 2732 01:52:31,760 --> 01:52:34,540 ما الذي أرغب في تمثيله في تعليمة برمجية إذا 2733 01:52:34,540 --> 01:52:38,410 أردت البدء في تخزين أرقامي، ليس في مصفوفة المدرسة القديمة تلك من الأسبوع 0، 2734 01:52:38,410 --> 01:52:42,142 ولكن في شجرة؟ 2735 01:52:42,142 --> 01:52:43,110 الجمهور: مؤشران. 2736 01:52:43,110 --> 01:52:43,600 ديفيد ج. مالان: اثنان-- 2737 01:52:43,600 --> 01:52:44,580 الجمهور: مؤشران. 2738 01:52:44,580 --> 01:52:44,975 ديفيد ج. مالان: مؤشران. 2739 01:52:44,975 --> 01:52:45,630 حسنًا؟ 2740 01:52:45,630 --> 01:52:49,070 شجرة، كما هو مرسوم هنا حرفيًا باستخدام الأسهم، 2741 01:52:49,070 --> 01:52:51,870 هو فقط مثل قول كل واحدة من تلك العقد أو الدوائر 2742 01:52:51,870 --> 01:52:53,760 تحتوي على طفل في جهة اليسار وطفل في جهة اليمنى. 2743 01:52:53,760 --> 01:52:55,560 كيف تقوم بتنفيذ الأطفال؟ 2744 01:52:55,560 --> 01:52:58,600 حسنًا، يمكنك حرفيًا استخدام تدوين المؤشر فقط أيضًا هنا. 2745 01:52:58,600 --> 01:53:01,920 الطفل على الجهة اليسرى هو مجرد مؤشر إلى بنية أخرى على اليسار. 2746 01:53:01,920 --> 01:53:05,100 والطفل على الجهة اليمنى هو مجرد مؤشر آخر للطفل على اليمين. 2747 01:53:05,100 --> 01:53:08,730 والأمر الجيد في ذلك في النهاية أنه يمكننا الآن 2748 01:53:08,730 --> 01:53:14,580 اجتياز تلك الشجرة بقدر من الكفاءة التي تمكننا من اجتياز تلك المصفوفة. 2749 01:53:14,580 --> 01:53:18,400 لأنه لاحظوا أنني إذا أردت البحث عن الرقم 66، 2750 01:53:18,400 --> 01:53:23,655 فكم عدد الخطوات التي سأقوم بها إذا بدأت من الأعلى؟ 2751 01:53:23,655 --> 01:53:26,030 فقط كما كانت كومي تمثل بداية القائمة المرتبطة الخاصة بنا، 2752 01:53:26,030 --> 01:53:29,450 لذا في عالم الشجرة هل للجذور أهمية خاصة. 2753 01:53:29,450 --> 01:53:31,220 وهذا هو المكان الذي منه نبدأ دائمًا. 2754 01:53:31,220 --> 01:53:33,904 إذن كم عدد الخطوات لأعثر على 66 المُعطى في الأعلى؟ 2755 01:53:33,904 --> 01:53:34,570 الجمهور: ثلاث خطوات. 2756 01:53:34,570 --> 01:53:35,450 الجمهور: خطوتان. 2757 01:53:35,450 --> 01:53:36,741 ديفيد ج. مالان: يبدو-- 2758 01:53:36,741 --> 01:53:37,929 أجل، خطوتان أو ثلاث خطوات، أليس كذلك؟ 2759 01:53:37,929 --> 01:53:38,720 سأبدأ من الأعلى. 2760 01:53:38,720 --> 01:53:41,240 أنظر إليه وأقول، امم، 55، أي طريق سأسلك. 2761 01:53:41,240 --> 01:53:42,200 سأنتقل إلى اليمين. 2762 01:53:42,200 --> 01:53:43,110 وبعد ذلك أرى 77. 2763 01:53:43,110 --> 01:53:43,610 حسنًا. 2764 01:53:43,610 --> 01:53:44,600 أي طريقٍ سأسلك؟ 2765 01:53:44,600 --> 01:53:45,560 سأنتقل إلى اليسار. 2766 01:53:45,560 --> 01:53:49,220 إذن إنه المنطق نفسه كما في الأسبوع 0 في خوارزمية فرق تسد التي استخدمناها في دليل الهاتف 2767 01:53:49,220 --> 01:53:51,170 أو في المصفوفة بعد أسبوعين من ذلك. 2768 01:53:51,170 --> 01:53:54,440 لكننا ننتقل إلى الرقم الذي نهتم به بسرعة كبيرة. 2769 01:53:54,440 --> 01:53:55,634 وهو ليس خطيًا. 2770 01:53:55,634 --> 01:53:57,800 وفي الواقع، إذا أجرينا بالفعل العملية الحسابية، ما الذي يُعد 2771 01:53:57,800 --> 01:54:00,910 رائعًا حقًا بشأن شجرة البحث الثنائي هو إذا كانت لديك عناصر n، 2772 01:54:00,910 --> 01:54:06,920 دوائر n، فارتفاع تلك الشجرة حسب التعريف وبشكل حسابي هو log n. 2773 01:54:06,920 --> 01:54:09,050 لذا ارتفاع الشجرة يتم فقط 2774 01:54:09,050 --> 01:54:12,920 ليتوافق بالضبط مع عدد المرات التي يمكن أن تأخذ فيها n، 2775 01:54:12,920 --> 01:54:15,440 وتقسّمها، تقسّمها، تقسّمها، تقسّمها إلى اثنين. 2776 01:54:15,440 --> 01:54:18,523 ويمكنك في الواقع أن ترى هذا إذا فكرت في ذلك الأمر بالاتجاه المعاكس. 2777 01:54:18,523 --> 01:54:21,490 في الصف السفلي، كم عدد العناصر الموجودة هناك؟ 2778 01:54:21,490 --> 01:54:21,990 حسنًا؟ 2779 01:54:21,990 --> 01:54:23,323 وفي الصف الأوسط، توجد؟ 2780 01:54:23,323 --> 01:54:23,907 الجمهور: عنصران. 2781 01:54:23,907 --> 01:54:24,739 ديفيد مالان: عنصران. 2782 01:54:24,739 --> 01:54:26,210 وفي الصف العلوي، يوجد عنصر واحد. 2783 01:54:26,210 --> 01:54:27,860 إذن يمكنكم في الواقع رؤية ذلك في الاتجاه المعاكس. 2784 01:54:27,860 --> 01:54:30,920 هذا مثل خوارزمية فرق تسد، لكن بطريقة مختلفة من الناحية النظرية. 2785 01:54:30,920 --> 01:54:33,930 2786 01:54:33,930 --> 01:54:38,160 يحتوي كل صف في الشجرة على نصف عدد العناصر الموجود في الصف أدناه. 2787 01:54:38,160 --> 01:54:41,450 وبالتالي أثر هذا فقط مثل ما رأيناه في الأسبوع 0 في دليل الهاتف 2788 01:54:41,450 --> 01:54:45,360 عندما نقوم بالتقسيم، والتقسيم، والتقسيم إلى نصف، ونصف، ونصف. 2789 01:54:45,360 --> 01:54:48,410 إذن هذا فقط لأقول، الآن لدينا بنيات ومؤشرات، 2790 01:54:48,410 --> 01:54:50,310 يمكننا بناء شيء من هذا القبيل. 2791 01:54:50,310 --> 01:54:53,150 ولكن دعونا نجرب مثالاً آخر هنا أيضًا. 2792 01:54:53,150 --> 01:54:55,580 هذا يبدو مثالاً مجنونًا. 2793 01:54:55,580 --> 01:54:57,350 لكنه مدهش إلى حد ما. 2794 01:54:57,350 --> 01:55:01,550 لنفترض أنه، إذا أردنا تخزين قاموس من الكلمات-- 2795 01:55:01,550 --> 01:55:04,130 ليست أسماء أشخاص هذه المرة، لكن من الكلمات الإنجليزية. 2796 01:55:04,130 --> 01:55:06,710 إذن ما الذي يحتوي عليه قاموس Merriam Webster أو قاموس Oxford الإنجليزي؟ 2797 01:55:06,710 --> 01:55:08,570 الآلاف، مئات الآلاف من الكلمات 2798 01:55:08,570 --> 01:55:10,697 المتداولة هذه الأيام باللغة الإنجليزية على سبيل المثال؟ 2799 01:55:10,697 --> 01:55:12,030 كيف تقوم بتخزين هذه الكلمات في الواقع؟ 2800 01:55:12,030 --> 01:55:15,260 حسنًا، إذا كنت تبحث عن كلمات في القاموس مجددًا في السنة الماضية، 2801 01:55:15,260 --> 01:55:16,040 هذا خطي. 2802 01:55:16,040 --> 01:55:18,290 يجب عليك أن تبدأ من البداية وتنظر بداخله 2803 01:55:18,290 --> 01:55:19,676 صفحة بصفحة، بحثًا عن الكلمات. 2804 01:55:19,676 --> 01:55:21,050 أو قد تكون أكثر ذكاءً قليلاً. 2805 01:55:21,050 --> 01:55:23,930 لأن الكلمات في أي قاموس آمل، أن تكون مرتبة ترتيبًا أبجديًا، 2806 01:55:23,930 --> 01:55:27,280 يمكنك القيام بخوارزمية فرق تسد الخاصة بأسلوب محمد محمود عن طريق الانتقال إلى الوسط، 2807 01:55:27,280 --> 01:55:29,360 ثم وسط المنتصف، وهكذا-- 2808 01:55:29,360 --> 01:55:30,290 سجل n. 2809 01:55:30,290 --> 01:55:34,700 لكن ماذا لو أخبرتكم، أنه يمكنكم البحث عن الكلمات في وقت ثابت-- 2810 01:55:34,700 --> 01:55:36,519 عدد محدد من الخطوات؟ 2811 01:55:36,519 --> 01:55:38,310 ولا شيء من هذا التعقيد المتعلق بخوارزمية فرق تسد. 2812 01:55:38,310 --> 01:55:39,170 لا log n. 2813 01:55:39,170 --> 01:55:43,610 فقط وقت ثابت-- تريد كلمة، اذهب واحصل عليها على الفور. 2814 01:55:43,610 --> 01:55:46,940 هنا حيث تظهر البنية الأخيرة، والتي يُطلق عليها trie-- 2815 01:55:46,940 --> 01:55:51,110 T-R-I-E-- اختصار لكلمة استرجاع، على الرغم من كونها تنطق العكس. 2816 01:55:51,110 --> 01:55:57,450 إذن trie عبارة عن شجرة تعد كل عقدة منها مصفوفة. 2817 01:55:57,450 --> 01:56:00,900 لذا فإنها تشبه وحش فرانكشتاين الغريب الذي يمثل نوع من بنية البيانات. 2818 01:56:00,900 --> 01:56:04,250 نحن فقط نجمع العديد من الأفكار المختلفة بالفعل، على النحو التالي. 2819 01:56:04,250 --> 01:56:10,250 والطريقة التي تعمل بها trie، كما هو موضح في هذا الرسم البياني الجزئي على اللوحة، 2820 01:56:10,250 --> 01:56:14,000 هي إذا كنت تريد تخزين اسم براين، على سبيل المثال، 2821 01:56:14,000 --> 01:56:15,980 في قاموسك-- إنها الكلمة الأولى-- 2822 01:56:15,980 --> 01:56:19,940 الأمر الذي ستقوم به هو البدء بإنشاء شجرة بعقدة واحدة فقط. 2823 01:56:19,940 --> 01:56:22,430 لكن تلك العقدة هي بفعالية مصفوفة. 2824 01:56:22,430 --> 01:56:26,120 هذه المصفوفة هي من الحجم، دعونا نقل للتبسيط، 26. 2825 01:56:26,120 --> 01:56:32,360 لذلك من أ إلى ي. وبالتالي يمثل هذا الموقع هنا ب لبراين. 2826 01:56:32,360 --> 01:56:37,010 لذا إذا أردت إدراج براين في هذه الشجرة، سأنشئ عقدة واحدة في الأعلى. 2827 01:56:37,010 --> 01:56:39,830 ثم للحرف الثاني في اسمه، ر، 2828 01:56:39,830 --> 01:56:44,030 سأُنشئ عقدة أخرى، مصفوفة أيضًا، من أ إلى ي. 2829 01:56:44,030 --> 01:56:48,080 ولذا هنا، سأضع مؤشر لهذه العقدة هنا. 2830 01:56:48,080 --> 01:56:51,560 ب-ر-ا. لذا يجب أن أرسم بعض المربعات الإضافية. 2831 01:56:51,560 --> 01:57:01,701 أ، ب، ت، ث، ج، ح، خ، د، ذ. لذا هنا، سأرسم مؤشر آخر إلى ب-- 2832 01:57:01,701 --> 01:57:02,200 انتظروا. 2833 01:57:02,200 --> 01:57:02,700 Bian. 2834 01:57:02,700 --> 01:57:04,211 [LAUGHTER] 2835 01:57:04,211 --> 01:57:04,710 حسنًا. 2836 01:57:04,710 --> 01:57:07,020 هذا خطأ. 2837 01:57:07,020 --> 01:57:09,540 سيكون بيلي هو الاسم. 2838 01:57:09,540 --> 01:57:12,870 بيلي في ب. انتظروا. 2839 01:57:12,870 --> 01:57:14,560 لا. 2840 01:57:14,560 --> 01:57:15,060 اللعنة. 2841 01:57:15,060 --> 01:57:18,610 ب، ب. ب-ي-ا-- نعم، ينجح هذا الأمر. 2842 01:57:18,610 --> 01:57:19,110 هذا الأمر ينجح. 2843 01:57:19,110 --> 01:57:19,440 حسنًا. 2844 01:57:19,440 --> 01:57:20,040 معذرة. 2845 01:57:20,040 --> 01:57:20,770 ها نحن ذا. 2846 01:57:20,770 --> 01:57:23,520 نحن نقوم بإدراج بيلي في بنية البيانات الرائعة هذه. 2847 01:57:23,520 --> 01:57:25,485 لذلك تمثل العقدة الأولى الحرف الأول. 2848 01:57:25,485 --> 01:57:27,360 تمثل العقدة الثانية الحرف الثاني. 2849 01:57:27,360 --> 01:57:29,350 تمثل العقدة الثالثة الحرف الثالث. 2850 01:57:29,350 --> 01:57:30,340 وهكذا. 2851 01:57:30,340 --> 01:57:32,700 لكن الأمر الرائع في ذلك هو إمكانية إعادة الاستخدام. 2852 01:57:32,700 --> 01:57:36,690 إذن لاحظوا إذا كان ذلك هو الحرف الثانى وأنا قمت بالعد بشكل صحيح، 2853 01:57:36,690 --> 01:57:39,510 أنا، هذا سيقودنا بشكل أعمق إلى عقدة ثالثة 2854 01:57:39,510 --> 01:57:44,520 فى الشجرة حيث حرف ل الذي سنهتم به لاحقًا، ثم حرف آخر 2855 01:57:44,520 --> 01:57:47,562 فى الأسفل هنا الذي يمثل ل آخر. 2856 01:57:47,562 --> 01:57:49,020 وسأبدأ برسم الأحرف. 2857 01:57:49,020 --> 01:57:53,860 L. هذا B. هذا I. L. وسنسميها L. 2858 01:57:53,860 --> 01:57:59,350 ومن ثم، أخيرًا، واحدة أخرى هنا، وهي Y. وهذه 2859 01:57:59,350 --> 01:58:00,780 تشير إلى الأسفل هنا. 2860 01:58:00,780 --> 01:58:02,310 هذه تشير إلى هنا. 2861 01:58:02,310 --> 01:58:03,490 وهكذا. 2862 01:58:03,490 --> 01:58:06,660 إذن باختصار، نحن لدينا عقدة واحدة بشكل أساسي 2863 01:58:06,660 --> 01:58:11,290 لكل حرف فى الكلمة التي ندرجها فى بنية البيانات. 2864 01:58:11,290 --> 01:58:14,250 الآن، هذا يبدو غير فعّال بغباء في هذه اللحظة. 2865 01:58:14,250 --> 01:58:20,580 لأنه لتخزين ب، ي، ل، ي، كم حجم الذاكرة الذي استَخدمتُه؟ 2866 01:58:20,580 --> 01:58:26,370 26 زائد 26 زائد 26 زائد 26 زائد 26. 2867 01:58:26,370 --> 01:58:30,660 فقط لتخزين خمسة أحرف، استخدمتُ 26 ضرب 5. 2868 01:58:30,660 --> 01:58:33,060 لكن هذا النوع من الموضوعية في علوم الكمبيوتر-- 2869 01:58:33,060 --> 01:58:36,450 يشغل المزيد من المساحة قليلاً، وأراهن أنه ما يزال بإمكاني تقليل كمية الوقت 2870 01:58:36,450 --> 01:58:37,980 التي يستغرقها العثور على أي شخص. 2871 01:58:37,980 --> 01:58:42,390 لأنه لا يهم الآن عدد الطلاب الآخرين في بنية البيانات هذه-- 2872 01:58:42,390 --> 01:58:44,370 وعلى سبيل المثال، دعونا نقوم بمثال واحد آخر. 2873 01:58:44,370 --> 01:58:48,390 لو حصلنا على اسم شخص آخر، مثل بوب-- 2874 01:58:48,390 --> 01:58:51,000 إذن ب هو الحرف الأول نفسه. 2875 01:58:51,000 --> 01:58:52,740 هذا يقودنا إلى العقدة الثانية هذه. 2876 01:58:52,740 --> 01:58:57,360 O في مكان آخر في هذه المصفوفة، لنقل، هنا. 2877 01:58:57,360 --> 01:59:00,480 إذن هذا يمثل O. ومن ثم يحتوي بوب على حرف آخر. 2878 01:59:00,480 --> 01:59:02,280 إذن ستكون هنا مصفوفة أخرى. 2879 01:59:02,280 --> 01:59:06,870 وهذا هو السبب وراء توضيح الصورة الموجودة بالأعلى لهذا بشكل مختصر للغاية. 2880 01:59:06,870 --> 01:59:08,490 هذه هي الكيفية التي قد نُخزن اسم بوب بها. 2881 01:59:08,490 --> 01:59:16,980 إذن ب، ي، ل، ي. أو قد تتبع مسارًا مختلفًا، ب، و، ب. 2882 01:59:16,980 --> 01:59:19,016 إذن يمكننا أن نبدأ في إعادة استخدام بعض هذه المصفوفات. 2883 01:59:19,016 --> 01:59:21,390 إذن هنا حيث تبدأون في الحصول على بعض الفاعلية. 2884 01:59:21,390 --> 01:59:25,020 في أي وقت تتشارك الأسماء في بعض الأحرف، ثم تبدأون في إعادة استخدام نفس العُقد. 2885 01:59:25,020 --> 01:59:27,160 إذن هذا ليس إهدارًا كبيرًا للغاية. 2886 01:59:27,160 --> 01:59:30,690 لكن السؤال الآن هو، لو أنه يوجد 1000 طالب مثلاً في الصف الدراسي، 2887 01:59:30,690 --> 01:59:33,360 أو 1000 طالب في الغرفة، سيكون لدينا الكثير من العُقد 2888 01:59:33,360 --> 01:59:34,980 هناك على اللوحة. 2889 01:59:34,980 --> 01:59:38,430 لكن ما هو عدد الخطوات التي سيستغرقها العثور على بيلي، 2890 01:59:38,430 --> 01:59:44,930 أو بوب، أو أي اسم آخر في بنية البيانات تلك، ولمعرفة هل الطالب 2891 01:59:44,930 --> 01:59:48,440 موجود في الصف الدراسي نعم أم لا؟ 2892 01:59:48,440 --> 01:59:51,950 لذا، مثلاً، خمسة لبيلي، ثلاثة لبوب. 2893 01:59:51,950 --> 01:59:56,030 ولاحظوا أنه لا توجد أي علاقة بين أي من هذه العمليات الحسابية 2894 01:59:56,030 --> 01:59:58,100 وعدد الطلاب الموجودين في الغرفة. 2895 01:59:58,100 --> 02:00:02,120 وبدلاً من ذلك، لو كتبنا قائمة طويلة من 1000 اسم، في أسوء الحالات، 2896 02:00:02,120 --> 02:00:04,482 قد يستغرق الأمر 1000 خطوة للعثور على بيلي أو بوب. 2897 02:00:04,482 --> 02:00:06,440 ربما يمكنني أن أكون أكثر ذكاء قليلاً إذا رتبتها. 2898 02:00:06,440 --> 02:00:08,720 لكن في أسوء الحالات، حرف O الكبير من n، هو خطي. 2899 02:00:08,720 --> 02:00:12,140 أو لو استخدمت جدول علامة التجزئة من قبل، وربما يوجد 2900 02:00:12,140 --> 02:00:14,150 1000 طالب فى الغرفة، لكن، حسنًا، هناك 2901 02:00:14,150 --> 02:00:16,220 26 حرفًا في الأبجدية الإنجليزية على الأقل. 2902 02:00:16,220 --> 02:00:17,140 إذن توجد 26 حزمة. 2903 02:00:17,140 --> 02:00:19,790 لذا ربما يكون 1000 مقسومًا على 26، في أسوأ الحالات، 2904 02:00:19,790 --> 02:00:23,510 إذا كنت أستخدم هذه القوائم المرتبطة داخل مصفوفتي. 2905 02:00:23,510 --> 02:00:24,470 لكن انتظروا دقيقة. 2906 02:00:24,470 --> 02:00:28,400 إذا كنت أستخدم هذه البنية، trie، حيث كل عقدة في الشجرة 2907 02:00:28,400 --> 02:00:34,287 هي فقط في مصفوفة تقودني إلى العقدة التالية، مثل الآثار، B، I، L، L، 2908 02:00:34,287 --> 02:00:36,170 Y هي 5 ودائمًا 5. 2909 02:00:36,170 --> 02:00:38,390 B، O، B دائمًا 3. 2910 02:00:38,390 --> 02:00:41,910 B، R، I، A، N سيكون 5 أيضًا. 2911 02:00:41,910 --> 02:00:46,130 ليس لأي من هذه الأرقام الإجمالية أي أثر أو أي تأثير 2912 02:00:46,130 --> 02:00:49,890 من الرقم الإجمالي للأسماء في بنية البيانات. 2913 02:00:49,890 --> 02:00:54,260 لذلك Trie بشكل منطقي هي هذه الكأس المقدسة المدهشة 2914 02:00:54,260 --> 02:00:57,650 في ذلك، من خلال جمع بنيات البيانات المختلفة هذه، والآن يمكنكم الحصول على وقت ثابت، 2915 02:00:57,650 --> 02:00:59,410 لكن ستدفعون ثمن ذلك. 2916 02:00:59,410 --> 02:01:02,666 وفقط للتوضيح، ما هو الثمن الذي يبدو أننا سندفعه؟ 2917 02:01:02,666 --> 02:01:03,772 الجمهور: الذاكرة. 2918 02:01:03,772 --> 02:01:04,730 ديفيد ج. مالان: الذاكرة. 2919 02:01:04,730 --> 02:01:07,310 في الواقع، هذا هو السبب الذي جعلني لا أرسم المزيد بالفعل. 2920 02:01:07,310 --> 02:01:09,851 لأنها تصبح مجرد فوضى كبيرة على الشاشة لأنه 2921 02:01:09,851 --> 02:01:11,660 من الصعب رسم بنيات البيانات الكبيرة هذه. 2922 02:01:11,660 --> 02:01:13,160 إنها تأخذ كمية هائلة من الذاكرة. 2923 02:01:13,160 --> 02:01:15,750 لكن من الناحية النظرية، الأمر يحدث بشكل أسرع. 2924 02:01:15,750 --> 02:01:16,250 أجل؟ 2925 02:01:16,250 --> 02:01:17,630 سؤال. 2926 02:01:17,630 --> 02:01:20,420 الجمهور: إذن هل تتعامل مع حالة إذا كان هناك شخص باسم بوب، 2927 02:01:20,420 --> 02:01:22,411 ولكن بعد ذلك هناك طفل آخر باسم بوبي؟ 2928 02:01:22,411 --> 02:01:23,660 ديفيد ج. مالان: سؤال جيد. 2929 02:01:23,660 --> 02:01:25,100 إذن، هذا جزء من التبسيط. 2930 02:01:25,100 --> 02:01:28,430 إذا كنت تخزن كل من بوب وبوبي، فستستمر في الواقع. 2931 02:01:28,430 --> 02:01:31,220 لذا كل هذه العناصر ليست حرفًا واحدًا فقط. 2932 02:01:31,220 --> 02:01:35,660 لديك أيضًا بشكل أساسي عقدة هناك أو بعض بنيات البيانات الأخرى 2933 02:01:35,660 --> 02:01:37,807 التي تقول إما توقف هنا أو تابع. 2934 02:01:37,807 --> 02:01:39,890 وسترون هذا في الواقع في المشاكل التي سنقوم 2935 02:01:39,890 --> 02:01:42,098 باقتراحها عليكم كيف يمكنكم تمثيل هذه الفكرة إذا 2936 02:01:42,098 --> 02:01:43,340 اخترتم سلوك هذا الطريق. 2937 02:01:43,340 --> 02:01:46,670 بالفعل، التحدي الذي ينتظرنا هو في الواقع شيء من هذا القبيل. 2938 02:01:46,670 --> 02:01:48,811 ستقومون بتنفيذ المدقق الإملائي الخاص بكم. 2939 02:01:48,811 --> 02:01:51,560 وسنقدم لكم تعليمة برمجية لكي تبدأون هذه العملية. 2940 02:01:51,560 --> 02:01:53,893 وبالطبع، يقوم المدقق الإملائي هذه الأيام في مستندات Google 2941 02:01:53,893 --> 02:01:56,397 وMicrosoft Word فقط بتمييز الكلمات التي بها أخطاء إملائية باللون الأحمر. 2942 02:01:56,397 --> 02:01:57,230 لكن ما الذي يحدث؟ 2943 02:01:57,230 --> 02:01:59,390 وكيف يمكن لـ Word أو مستندات Google 2944 02:01:59,390 --> 02:02:02,720 القيام بالتدقيق الإملائي للغتك الإنجليزية أو أيًا كانت اللغة بهذه السرعة؟ 2945 02:02:02,720 --> 02:02:05,570 حسنا، لديها قاموس في الذاكرة، ربما مع عشرات الآلاف 2946 02:02:05,570 --> 02:02:07,460 أو مئات الآلاف من الكلمات. 2947 02:02:07,460 --> 02:02:10,850 وكل ما تفعلانه باستمرار هو، في كل مرة تكتب كلمة 2948 02:02:10,850 --> 02:02:13,100 وتضغط على مفتاح المسافة، أو النقطة، أو Enter 2949 02:02:13,100 --> 02:02:16,220 تبحث بسرعة عن تلك الكلمة الجديدة أو هذه الكلمات في قاموسها 2950 02:02:16,220 --> 02:02:20,610 وتقول، نعم أم لا، يجب أن أضع خط أحمر تحت هذه الكلمة. 2951 02:02:20,610 --> 02:02:23,720 ولذا ما سنقوم بفعله هو إعطاؤكم ملف نصي كبير، نص ASCII، 2952 02:02:23,720 --> 02:02:26,010 يحتوي على ألف ومئة كلمة. 2953 02:02:26,010 --> 02:02:28,010 وسيتعين عليكم أن تقرروا كيفية تحميل ذلك 2954 02:02:28,010 --> 02:02:32,517 في الذاكرة، ليس فقط بشكل صحيح، ولكن بطريقة جيدة التصميم. 2955 02:02:32,517 --> 02:02:34,850 وسنمنحكم أداة، إذا اخترتم استخدامها، 2956 02:02:34,850 --> 02:02:36,560 في تلك الأوقات التي تستغرقها تعليماتكم البرمجية. 2957 02:02:36,560 --> 02:02:39,110 كما أنها تحسب مقدار ذاكرة الوصول العشوائي التي تستخدمونها بالفعل. 2958 02:02:39,110 --> 02:02:42,312 لكن الأهداف الرئيسية لهذا الأسبوع وأسبوعنا الأخير في لغة C 2959 02:02:42,312 --> 02:02:44,270 هي تناول بعض هذه الكتل البنائية الأساسية، 2960 02:02:44,270 --> 02:02:48,680 مثل المصفوفات، والمؤشرات، والبنيات، 2961 02:02:48,680 --> 02:02:51,980 واتخاذ القرار بأنفسكم للكيفية التي تقومون بها بتجميعها بشكل مريح أكثر 2962 02:02:51,980 --> 02:02:55,580 معًا، إلى أي مدى تريدون أن تضبطوا تعليماتكم البرمجية بشكل دقيق وتتجاوزون مجرد 2963 02:02:55,580 --> 02:03:00,050 الحصول عليها صحيحة، ولإعطائكم أفضل إحساس كامن من التعليمة البرمجية الأساسية 2964 02:03:00,050 --> 02:03:02,450 التي قد كتبها الأشخاص منذ سنوات في المكتبات 2965 02:03:02,450 --> 02:03:05,022 لجعل البرمجة قابلة للتنفيذ، مثل سكراتش. 2966 02:03:05,022 --> 02:03:07,730 لأنه في غضون بضعة أسابيع، سنقوم بالترجمة إلى Python. 2967 02:03:07,730 --> 02:03:10,490 وسيتم ضم عشرات السطور من التعليمة البرمجية التي قمت بكتابتها الآن 2968 02:03:10,490 --> 02:03:12,714 إلى سطر واحد، سطرين، 2969 02:03:12,714 --> 02:03:15,380 لأننا سنحصل على المزيد من الميزات من هذه اللغات الحديثة، 2970 02:03:15,380 --> 02:03:16,280 والرائعة. 2971 02:03:16,280 --> 02:03:18,860 لكن آمل أنه سيكون لديكم تقدير لما سيكون في الواقع 2972 02:03:18,860 --> 02:03:20,600 أسفل هذا الغطاء. 2973 02:03:20,600 --> 02:03:22,130 لذا سأبقى هنا لبعض الوقت من أجل الأسئلة الفردية. 2974 02:03:22,130 --> 02:03:22,790 دعونا نتوقف هنا. 2975 02:03:22,790 --> 02:03:24,873 خذوا بطة في طريقكم إلى الخروج ولزملائكم كذلك. 2976 02:03:24,873 --> 02:03:26,920 وسأراكم في المرة القادمة.