
Arabic: 
[MUSIC PLAYING]
[VIDEO PLAYBACK]
- --نحن نعلم؟
- أنه في الساعة 9:15، كان راي
سانتويا عند جهاز الصراف الآلي.
- إذن السؤال هو،
ماذا كان يفعل في الساعة 9:16؟

English: 
[MUSIC PLAYING]
[VIDEO PLAYBACK]
- --we know?
- That at 9:15, Ray
Santoya was at the ATM.
- So the question is,
what was he doing at 9:16?

Arabic: 
- إطلاق عيار ناري
9 ملليمتر على شيء ما.
ربما رأى القناص.
- أو كان يعمل معه.
- حسنًا.
ارجع للصورة السابقة.
- ماذا ترى؟
- قرّب وجهه.
في وضع ملء الشاشة.
- نظّارته.
- هناك انعكاس.
- هذا فريق نيوفيتاس للبيسبول.
هذا هو شعارهم.
- وهو يتحدث إلى الشخص الذي
يرتدي تلك السترة.
- قد يكون لدينا شاهد.
- لعمليتي إطلاق النار.
[END PLAYBACK]
ديفيد مالان: هذه هي دورة CS50،
وهذه هي المحاضرة الثالثة، وتلك
ليست الكيفية التي تعمل بها علوم الكمبيوتر.
وبالفعل، بحلول نهاية
اليوم، سنوضح
بالضبط ما هو صحيح،
وما هو غير صحيح في ذلك،
وآمل أن أجعلكم تفكرون قليلاً في أي
وقت تشاهدون فيه التلفاز أو الأفلام فيما بعد

English: 
- Shooting the
nine-millimeter at something.
Maybe he saw the sniper.
- Or he was working with him.
- Right.
Go back one.
- What do you see?
- Bring his face up.
Full screen.
- His glasses.
- There's a reflection.
- That's Neuvitas baseball team.
That's their logo.
- And he's talking to whoever
is wearing that jacket.
- We may have a witness.
- To both shootings.
[END PLAYBACK]
DAVID MALAN: This is he is CS50,
and this is lecture 3, and that
is not how computer science works.
And indeed, by the end
of today, we'll make
clear exactly what's right,
what's not right about that,
and hopefully give you some pause any
time you watch TV or movies hereafter

English: 
and notice these little things
that all too many writers seem
to take for granted.
So recall that last time, we took a look
lower level at what compiling actually
is.
And recall that it was a few things,
these four steps of pre-processing
and compiling and
assembling and linking,
so that when you start
with their source cod,
that might look like this code
that we have written in the past,
you first have to preprocess it, and
the first step in pre-processing was
converting all of those
processor instructions--
anything starting with a hash at the
beginning-- to their equivalents.
So opening the files and effectively
copying and pasting the contents
there so that programs and the
compiler know what get_string
is and know what printf is.
The next step that came
after that was actually
compiling, whereby compiling
technically means taking that source
code, once it's been preprocessed,
and printing and generating
this very cryptic-looking
stuff called assembly code.
And those assembly codes or assembly
instructions are really what the CPU--
the brain of your computer--
actually understands,
although technically the computer
understands them only in the form
of 0's and 1's.

Arabic: 
وتلاحظوا هذه الأشياء الصغيرة
التي يبدو أن الكثير من المؤلفين
يعدونها من المسلمات.
إذن تذكرون آخر مرة، ألقينا فيها نظرة
على ماهية التحويل البرمجي
في الواقع.
وتذكرون أنه كان عبارة عن بضعة أشياء،
هذه الخطوات الأربع من المعالجة المسبقة
والتحويل البرمجي
والتجميع والربط،
إذن عندما تبدأ
بتعليمة المصدر البرمجية الخاصة بها،
التي قد تبدو مثل هذه التعليمة البرمجية
التي كتبناها في الماضي،
يتعين عليك أولاً أن تعالجها مسبقًا،
وكانت الخطوة الأولى في المعالجة المسبقة
هي تحويل جميع تعليمات
المعالج تلك--
أي شيء يبدأ بعلامة تجزئة في البداية--
إلى ما يعادله.
إذن فتح الملفات ونسخ
ولصق المحتويات بفعالية
هناك لكي تعرف تلك البرامج
وأداة التحويل البرمجي ما هو get_string
وما هي printf.
كانت الخطوة التالية التي جاءت
بعد ذلك في الواقع
هي التحويل البرمجي، حيث إن التحويل البرمجي
من الناحية الفنية يعني أخذ تعليمة مصدر
برمجية، بمجرد أن تتم معالجتها مسبقًا،
وطباعة وإنشاء
هذه الأشياء التي تبدو مشفرة للغاية والتي تسمّى
تعليمة التجميع البرمجية.
وتعليمات التجميع البرمجية تلك أو تعليمات التجميع
هي ما تستوعبه وحدة المعالجة المركزية--
عقل جهاز الكمبيوتر لديك--
في الواقع،
على الرغم من أن الكمبيوتر
من الناحية الفنية يستوعبها فقط في شكل
الأصفار والواحدات.

English: 
And so when you "assemble-- step three--
that assembly code, you actually
get out those 0's and 1's.
But even that simplest of programs where
we just prompt the user for a string
and then print out their name
still involved a couple more files.
There was not only cs50.h
and stdio.h at the top,
somewhere in the computer system
there's probably files called cs50.c,
and in the case of stdio, printf.c,
in which actually the code is
for those two functions, those
two have to get compiled down
to 0's and 1's, and then we need
to link everything together,
merging those 0's and 1's so that
the computer has access to your code
and to printf's code and to the
cs50 library's code And so forth.
But all of that we can just generally
wrap up in the descriptor of compiling.
And so that's one of the
looks we took last week.
And we also have introduced, last
week and previously, a few tools.
And odds are, you're having as
many frustrations perhaps already
with the p-sets as you
are accomplishments
and sense of satisfaction.
And that's normal, and rest assured
that the scales will eventually tip more

Arabic: 
ولذا عندما تقوم بـ "تجميع-- الخطوة الثالثة--
تعليمة التجميع البرمجية تلك، فأنت في الواقع
تُخرِج تلك الأصفار والواحدات.
ولكن حتى أبسط البرامج التي
نطالب المستخدم فيها فقط بسلسلة
ثم نطبع اسمه
والذي ما زال يتضمّن بضعة ملفات أخرى.
لم يكن هناك فقط cs50.h
وstdio.h في الأعلى،
فهناك على الأرجح في مكان ما في نظام الكمبيوتر
ملفات باسم cs50.c،
وفي حالة stdio، وprintf.c،
التي تكون التعليمة البرمجية فعليًا فيها
لهاتين الدالتين، ويجب تحويل
هاتين الدالتين برمجيًا إلى
أصفار وواحدات، ثم نحتاج
إلى ربط كل شيء معًا،
ودمج تلك الأصفار والواحدات وبذلك
يصل جهاز الكمبيوتر إلى التعليمة البرمجية الخاصة بك
وإلى تعليمة printf البرمجية وإلى
تعليمة مكتبة cs50 البرمجية وهكذا.
ولكن يمكننا إنهاء كل ذلك فقط بشكل عام
في أداة وصف التحويل البرمجي.
إذن هذه إحدى المسائل
التي تناولناها الأسبوع الماضي.
وقدمنا أيضًا، الأسبوع
الماضي والذي قبله، بضع أدوات.
وتوجد احتمالات، بأنكم تواجهون
إحباطات كثيرة من المحتمل أنها موجودة بالفعل
مع "p-sets" لأنكم
حققتم إنجازات
ولديكم شعور بالرضا.
وهذا أمر طبيعي، وتؤكد البقية
أن المقاييس ستميل في النهاية أكثر

English: 
toward happiness and away
from sadness, but we'll
give you indeed more tools today
than these for actually finding
problems or shortcomings in your code.
help50, recall, helps
you with what process?
When you instinctively
consider using help50?
When you see error
messages on the screen.
Something you don't understand
that's the result of some mistake you
probably made but you don't quite
understand what the computer is telling
you, run help50, and then that
same command and we, the staff,
with our code will try to
understand the message for you
and provide you with feedback.
style50 does exactly that.
It helps you see with red and green
color coding exactly what spaces should
be there, shouldn't be there--
it just helps you pretty
your code so that you can read it
better and other humans can as well.
And then printf, which is kind of like
the coarsest tool in your tool box,
this is just helping you see not
only messages you want to see,
but just the values of variables.
You can print ints and
strings, whatever you want,
and then you can delete
those lines of printf
once you're confident
your program's working.
But that gets a little tedious, and
honestly, as our programs get bigger,

Arabic: 
صوب السعادة وبعيدًا
عن الحزن، لكننا سنقدم
لكم في الواقع المزيد من الأدوات اليوم
مقارنة بما سبق للعثور على
المشاكل أو أوجه القصور في التعليمة البرمجية لديك.
help50، أتذكرون، يساعد
في أي معالجة؟
عندما تفكر
بديهيًا في استخدام help50؟
عندما ترى رسائل خطأ
على الشاشة.
شيء لا تفهمه
هذا هو نتيجة خطأ من المحتمل أنك قمت
به ولكنك لا تدرك
تمامًا ما الذي يخبرك به جهاز الكمبيوتر،
قم بتشغيل help50، ثم نفس ذلك الأمر
ونحن، طاقم العمل،
باستخدام تعليمتنا البرمجية سنحاول
فهم الرسالة من أجلك
وتزويدك بالملاحظات.
يقوم style50 بذلك بالضبط.
يساعدك في رؤية ما هي الفراغات
التي يجب أن توجد بالضبط، وما التي لا يجب
أن توجد هناك باستخدام ترميز باللونين الأحمر والأخضر--
إنه يساعدك فقط في تزيين
تعليمتك البرمجية بحيث يمكنك قراءتها
بشكل أفضل أنت والأشخاص الآخرون أيضًا.
ثم printf، وهو نوع من الأدوات الفظة
إلى حد ما الموجودة في مربع الأدوات لديك،
هذا يساعدك ليس فقط في رؤية
الرسائل التي تريد أن تراها،
ولكن أيضًا في رؤية قيم المتغيرات.
يمكنك طباعة الأعداد الصحيحة
والسلاسل، أيًا كان ما تريد،
ثم يمكنك حذف
تلك الأسطر من printf
بمجرد أن تكون واثقًا
من عمل برنامجك.
لكن يصبح هذا الأمر مملاً قليلاً،
وبصراحة، حيث تصبح برامجنا أكبر،

English: 
we're going to want more powerful tools
than like manually printing things
out, recompiling, rerunning, it
very quickly it gets tedious.
And the goal of programming is not
to be tedious, but to be empowering,
and that's where we'll
step to today via this.
So CS50 IDE is sort of
fancier version of what
you've been using called CS50
Sandbox, and in turn, CS50 Lab.
Now recall that both of those
tools, the Sandbox and the Lab,
have a terminal window
where you can type commands,
they have a code editor where
you can actually write your code,
and then they have a file
browser with icons and such
where you can actually see
your files and folders.
So it turns out that CS50 IDE is
another tool that at first glance
is very, very similar, even though
it's laid out a little differently,
but it has as many features as the
Sandbox and the Lab, but some more.
More features that actually help
you solve problems in your code
and even collaborate come final project
time with others if you would like.
So this we'll see is
this is the CS50 IDE.
It comes with the
so-called night mode so you
can make everything a little darker on
your screen, especially if p-setting

Arabic: 
سنرغب في وجود أدوات أكثر قدرة
منها مثل طباعة الأشياء يدويًا،
وإعادة التحويل البرمجي، وإعادة التشغيل،
فتصبح مملة بشكل أسرع.
وليس الهدف من البرمجة
أن تشعر بالملل، بل أن تكون مُمكنًا،
وهذا ما نرمي إلى القيام به
اليوم عبر هذا.
إذن CS50 IDE هو إصدار أروع
مما
كنت تستخدمه المسمّى CS50
Sandbox، وبدوره، CS50 Lab.
الآن تذكّروا أن كلا الأداتين،
Sandbox وLab،
لديها نافذة طرفية
حيث يمكنك كتابة الأوامر،
لديهما محرر تعليمات برمجية حيث
يمكنك كتابة تعليماتك البرمجية في الواقع،
ثم لديهما متصفح ملفات
مع الرموز وحيث
يمكنك بالفعل رؤية
الملفات والمجلدات الخاصة بك.
لذلك يتضح أن CS50 IDE هي
أداة أخرى للوهلة الأولى
وهي مشابهة جدًا، وعلى الرغم من
أنه تم وضعها بشكل مختلف قليلاً،
لكنها تحتوي على العديد من الميزات مثل
Sandbox وLab، ولكن يوجد المزيد.
الميزات الأخرى التي تساعدك في الواقع
في حل المشاكل في تعليماتك البرمجية
والتعاون مع الآخرين لإنهاء مشروع
بحلول موعده النهائي إذا كنت ترغب في ذلك.
إذن سنرى هل
هذا هو CS50 IDE.
إنه يأتي مع ما يسمّى
بالوضع الليلي إذًا
يمكنك جعل كل شيء داكن أكثر
على شاشتك، خاصةً إذا كان إعداد p

English: 
at night, and let's
actually take a look then
at what you can do
with this kind of tool.
When you log into this tool for the
very first time in the next problem set,
you'll see an interface that's
almost the same as before.
The colors are a little different,
the font sizes are a little different,
but at the bottom by default, you
have your so-called terminal window,
though instead of the
dollar sign now, you'll
see a little more detailed
workspace, but more on that in a bit.
Up here you just have
the code editor window,
nothing's really going on there.
And then we have the added
feature of Ceiling Cat
in the top right-hand corner.
And we'll also see some
other features along the way.
So let's actually write a program
in CS50 IDE, which, to be clear,
is just another web-based programming
environment that also gives you
access to your own cloud-based server.
It, too, is running Ubuntu Linux, which
is a popular operating system that
is not macOS and it's not Windows.
But unlike the sandbox environment
where you don't even log in
and you lose your files
eventually, as you
may know from when your cookies
are lost or something goes wrong,
the IDE saves everything.
And you'll log in with
your account, and whatever

Arabic: 
ليلاً، ودعونا في
الواقع نلقي نظرة فيما بعد
على ما يمكنكم القيام به
باستخدام هذه الأداة.
عندما تسجّل دخولك إلى هذه الأداة للمرة
الأولى في مجموعة المشاكل التالية،
سترى أن الواجهة تكون
كما كانت عليه من قبل تقريبًا.
تبدو الألوان مختلفة قليلاً،
وأحجام الخطوط مختلفة قليلاً،
ولكن في الجزء السفلي بشكل افتراضي،
لديك ما تسمّى بالنافذة الطرفية،
وبدلاً من علامة الدولار
الآن، سترى
مساحة عمل أكثر تفصيلاً،
ولكن المزيد حول ذلك بعد قليل.
هنا في الأعلى لديك فقط
نافذة محرر التعليمات البرمجية،
لا يحدث شيء هناك حقًا.
ثم لدينا الميزة
المضافة Ceiling Cat
في أعلى الزاوية اليمنى.
كما سنرى بعض
الميزات الأخرى أثناء النقاش.
لذا دعونا في الواقع نكتب برنامج
في CS50 IDE، وهو، لنكن واضحين،
مجرد بيئة برمجية
قائمة على الويب ويتيح لك أيضًا
الوصول إلى الخادم القائم على السحابة الخاص بك.
كما يقوم بتشغيل نظام التشغيل Ubuntu Linux، والذي يعد
من أشهر أنظمة التشغيل
وهو ليس macOS ولا Windows.
ولكن على عكس بيئة أداة تحديد الوصول
حيث لا تقوم حتى بتسجيل الدخول
وتفقد ملفاتك
في نهاية المطاف، لأنه قد
تعرف من أين يتم فقد ملفات تعريف الارتباط الخاصة بك
أو عندما يحدث خطأ ما،
يحفظ IDE كل شيء.
وستقوم بتسجيل الدخول باستخدام
حسابك، وأيًا كان ما

Arabic: 
وضعته هناك الأسبوع الماضي سيكون
هناك هذا الأسبوع والأسبوع المقبل
وما بعدها.
إذن دعوني أمضي قُدمًا إلى قائمة الملف، ملف جديد،
أو يمكنني فقط النقر فوق رمز علامة الجمع الصغير
في أعلى الزاوية اليمنى،
ودعوني أمضي قدمًا وأضغط بشكل استباقي
على Control-S أو Command-S
أو أنتقل إلى الملف، وحفظ--
يجب أن تجد الواجهة
مشابهة تمامًا لأي برنامج Mac أو جهاز كمبيوتر شخصي--
ودعوني أمضي قدمًا
وأحفظ هذا الملف على النحو التالي.
سأسمي هذا hello.c.
ومن الهام
ذِكر ملحق الملف،
وإلا فإن IDE، مثل
Sandbox وLab،
لن يعرف ما هو نوع
البرنامج الذي تكتبه.
ثم دعوني أمضي قدمًا وأكتب
فقط أبسط برامجي.
إذن دعوني أمضي قدمًا وأقوم بكتابة
include stdio.h, int main void.
دعوني أمضي قدمًا وأفتح
الأقواس المتعرجة، printf--
مرحبًا، بالعالم، خط مائل
عكسي n، وفاصلة منقوطة.
إذن ستلاحظوا أن تقريبًا
كل شيء هو نفسه.
الألوان مختلفة
قليلاً، ربما،
قد ترون بعض
ميزات مساعدة
مختلفة أثناء كتابة التعليمات البرمجية،
ولكن النتيجة النهائية هي نفسها.
وترميز اللون الذي حصلت عليه للتو
مجانًا لأنه يساعد
في جذب انتباهك إلى
أجزاء مختلفة من التعليمات البرمجية.
دعوني أمضي قُدمًا الآن و--

English: 
you put there last week is going
to be there this week and next week
and beyond.
So let me go ahead up to File, New File,
or I could just click this little plus
icon in the top right-hand corner, and
let me go ahead and preemptively hit
Control-S or Command-S
or go to File, Save--
you should find the interface very
similar to any Mac or PC program--
and let me go ahead and
save this file as follows.
I'm going to call this hello.c.
And it's important to
mention the file extension,
otherwise the IDE, like
the Sandbox and the Lab,
won't know what type of
program you're writing.
And then let me go ahead and just
write my simplest of programs.
So let me go ahead and include
stdio.h, int main void.
Let me go ahead and open
my curly braces, printf--
hello, world, backslash
n, and a semi-colon.
So you'll notice that almost
everything is the same.
The colors are a little
different, perhaps,
and you might see some
different assistive
features as you're typing your code,
but the end result is the same.
And the color coding you just
get for free because it's helping
draw your attention to
different parts of the code.
Let me go ahead now and--

Arabic: 
أوه لاحظوا هذا.
يوجد اختلاف واحد.
هو أن IDE أداة أكثر قدرةً،
إلا أنها، تعد أداة يدوية أكثر
ولا تقوم فقط بحفظ التعليمات البرمجية
من أجلك تلقائيًا.
هذا الأمر جيد كما كان بأداة تحديد
الوصول، لدرجة أنك لن تقوم أبدًا
بالضغط على
Command-S أو Control-S في الواقع--
وإذا كان الأمر كذلك، فأنت
لست بحاجة للقيام بذلك، حيث سيقوم IDE
بحفظ الأشياء عندما
تريد ذلك بحيث لن يحدث شيء
بطريقة سحرية بعد الآن.
لذا الأمر الذي يتعين عليّ القيام به هو الرجوع
للأعلى هنا، الملف، حفظ، أو Command-S
أو Control-S، سترى
نقطة خضراء صغيرة
لفترة وجيزة، والآن إلى المحث الخاص بي.
سأمضي قدمًا الآن وأكتب
الأمر المألوف الخاص بي، make hello، Enter،
وسترون تقريبًا أمر العميل نفسه
الذي يبدو مشفرًا
كما كان من قبل لأنه تم تكوين IDE
تمامًا مثل أداة تحديد الوصول.
وإذا أردت المضي قدمًا وقمت بتشغيل
هذا الآن، كيف يمكنني تشغيل هذا البرنامج؟
فحص سريع؟
./hello، إنه بالضبط
الأمر نفسه كما كان من قبل.
./hello، وهناك يكون
لدينا، مرحبًا، العالم.
القصة الطويلة جدًا باختصار، واجهة المستخدم
حتى الآن مختلفة قليلاً،
لكن من الناحية الوظيفية هي نفسها.
سنبدأ الآن في رؤية
بعض ميزات إضافية.
إذن ما هي تلك الميزات؟

English: 
oh notice this.
There's one difference.
The IDE is a more powerful tool,
but as such, it's a more manual tool
and it's not just going to
auto-save your code for you.
Nice as that's been with the
Sandbox, such that you'd never
actually had the hit
Command-S or Control-S--
and if you were, you
didn't need to be, the IDE
is only going to save things when
you want it to so that nothing
will happen magically anymore.
So what I'm going to have to do is go
back up here, File, Save, or Command-S
or Control-S, you'll
see a little green dot
briefly, and now and back at my prompt.
I'm going to go ahead now and type my
familiar command, make hello, Enter,
and you'll see pretty much the
same cryptic-looking client
command as before because the IDE is
configured quite like the Sandbox.
And if I want to go ahead and run
this now, how do I run this program?
Quick check?
./hello, it's exactly
the same as before.
./hello, and there we
have it, hello, world.
So long story short, the user interface
thus far is a little different,
but functionally it's the same.
We're just going to now start
to see some more features.
So what are those features?

English: 
And let's introduce new some
capabilities that were actually
possible in the Sandbox, we just didn't
really introduce them at the time.
If I click this folder icon at top left,
you'll see all of my files and folders.
And today for lecture I have
a lot of pre-made examples
that are already on the course's
website, some of which we'll look at,
some of which we'll
refer to the website,
but these are just
familiar files and folders.
And you can see that
everything in my account
is apparently in something
called Workspace, which
is just a folder, name, or a directory.
Here's my sc3 directory,
which again, comes
from the website for
today's lecture, lecture 3.
And then here's the file I just
compiled in the program and the file
that I wrote, hello.c.
You'll notice too that there's
this funky symbol here, tilde,
that you might not have occasion
to write often in English,
but in Spanish in other languages
you might use this character.
This is actually a shorthand notation
for what's called your home directory.
In this environment, CS50 IDE, you
have your own home directory, which
means your folder of files and other
folders that you get to create,
you own, and that persists every
time you log in-- you're not

Arabic: 
ودعونا نقدم بعض القدرات الجديدة
التي كانت في الواقع
ممكنة في أداة تحديد الوصول، ولم نقم
بتقديمهم بالفعل في ذلك الوقت.
إذا قمت بالنقر فوق رمز هذا المجلد في أعلى اليسار،
سترون كل الملفات والمجلدات الخاصة بي.
واليوم لهذه المحاضرة قمت بإعداد
أمثلة متعددة مسبقًا
وهي موجودة بالفعل على موقع الويب الخاص بالدورة،
وسنلقي نظرة على بعضها،
وسنشير إلى بعض منها على موقع الويب،
ولكن هذه ليست سوى
ملفات ومجلدات مألوفة.
ويمكنكم رؤية أن
كل شيء في حسابي
على ما يبدو أنه في شيء ما
يسمّى مساحة العمل، وهي
مجرد مجلد، أو اسم، أو دليل.
ها هو دليل Sc3 الخاص بي،
والذي يأتي، مجددًا
من موقع الويب
لمحاضرة اليوم، المحاضرة الثالثة.
ومن ثم ها هو الملف الذي
حولته فقط برمجيًا في البرنامج والملف
الذي كتبته، hello.c.
كما ستلاحظون أنه يوجد
رمز غريب هنا، tilde،
حيث قد لا تسنح لكم فرصة
لكتابته في كثير من الأحيان باللغة الإنجليزية،
ولكن باللغة الإسبانية، وبلغات أخرى
قد تستخدمون هذا الحرف.
هذا في الواقع تدوين شديد الاقتضاب
لما يطلق عليه دليلك الرئيسي.
في هذه البيئة، CS50 IDE، يوجد لديك
الدليل الرئيسي الخاص بك، والذي
يقصد به مجلد ملفاتك والمجلدات
الأخرى التي قمت بإنشائها،
والموجودة لديك، والشيء الموجود في كل
مرة تقوم فيها بتسجيل الدخول-- ولن

English: 
going to lose the contents therein.
So this just means that in your
home directory, a.k.a. tilde,
there is a folder called workspace
in which I'm currently working.
And that's just one folder in which
all of my work is going to be done,
because there's so many other files
and folders in this cloud environment,
just like there are in your
Mac and PC, we just generally
don't care what they are.
But notice what we can do at this
terminal window besides compile
and run code.
There are other commands.
For instance, this blue text here,
similarly to the file browser up top,
indicates now not just that this
is my prompt per the dollar sign,
but that in my home directory's
workspace directory.
So that means I can be
elsewhere even though I haven't
specified where I want to go yet.
And in fact, I can do
this. ls stands for list,
it's just shorthand notation for that.
And now I see a textual version
of my file tree, so to speak.
So you'll see here, sc3
is a folder, and you

Arabic: 
تفقد المحتويات الموجودة فيه.
إذن هذا يعني أنه في دليلك الرئيسي،
والمعروف أيضًا باسم tilde،
يوجد مجلد يسمى مساحة العمل
الذي أعمل فيه حاليًا.
وهذا مجلد واحد فقط حيث
سيتم كل عملي فيه،
نظرًا لوجود عدد كبير جدًا من
المجلدات والملفات الأخرى في بيئة السحابة هذه،
تمامًا كما هو الحال في جهاز Mac
و جهاز الكمبيوتر الشخصي لديك، فنحن فقط لا
نهتم بماهيتهم عمومًا.
ولكن لاحظوا ما يمكننا القيام به في هذه النافذة
الطرفية إلى جانب التحويل البرمجي
وتشغيل التعليمات البرمجية.
هناك أوامر أخرى.
على سبيل المثال، هذا النص باللون الأزرق هنا،
وعلى نحو مشابه لمتصفح الملفات في الأعلى،
يشير الآن ليس فقط إلى أن هذا
هو المحث الخاص بي لكل علامة دولار،
ولكن أيضًا في دليل مساحة العمل
الخاصة بدليلي الرئيسي.
لذا هذا يعني أنه يمكنني الانتقال إلى
أي مكان آخر على الرغم من أنني لم
أحدد إلى أين أريد أن أنتقل بعد.
وفي الواقع، يمكنني القيام
بهذا. يرمز ls إلى القائمة،
إنه مجرد تدوين شديد الاقتضاب لذلك.
والآن أرى نسخة نصية
من شجرة ملفاتي، إذا جاز التعبير.
إذن سترى هنا، أن sc3
هو مجلد، ويمكنك

English: 
can tell as much because there's
a slash at the end of it.
hello.c is of course the
file I wrote a moment ago.
And then hello in green is my
program that I compiled, and the star
or asterisk there is just--
it's not the name of the file,
it's just indicating to me
visually that that is executable.
That's a program I can run
just so I know what's compiled
and what maybe is source code.
So when you're running ./hello, the
reason all this time this has been
working is because in dot, your current
folder, there is a file called hello,
and when you hit Enter, you
are running that program there.
So if after today you go back onto
CS50 Sandbox or CS50 Lab and type ls,
you'll see exactly the same thing
as you might by the little folder
icon in those programs as well.
But suppose I want to
go into a directory.
In macOS or Windows or even
the IDE, I could, of course,
go my File icon, and then
per the little triangle
here, which might seem
intuitive, you just click it
and you can see what's going
on inside, not surprising.
But how do you do that textually?

Arabic: 
القول بقدر كافٍ لأن هناك
خط مائل في نهايته.
hello.c هو بالطبع الملف
الذي كتبته منذ لحظات.
ثم مرحبًا باللون الأخضر هو برنامجي
الذي قمت بتحويله برمجيًا، والنجمة
أو رمز النجمة يوجد فقط--
وليس اسم الملف،
إنه يوضح ليّ فقط
وبشكل مرئي أن هذا قابل للتنفيذ.
هذا برنامج يمكنني تشغيله
فقط حتى أعرف ما تم تحويله برمجيًا
وما قد تكون تعليمات المصدر البرمجية.
إذن عندما تقوم بتشغيل ./hello، فإن السبب وراء عمل هذا
طوال هذا الوقت
هو لأنه يوجد ملف باسم مرحبًا،
في نقطة، مجلدك الحالي،
وعندما تضغط على Enter، فأنت
تقوم بتشغيل هذا البرنامج هناك.
لذا إذا رجعتم بعد اليوم إلى
CS50 Sandbox أو CS50 Lab وكتبتم ls،
سترون بالضبط الشيء نفسه
كما كان بواسطة رمز المجلد
الصغير في تلك البرامج أيضًا.
ولكن لنفترض أنني أرغب في
الانتقال إلى الدليل.
في macOS أو Windows أو حتى
IDE، يمكنني، بالطبع،
الانتقال إلى رمز الملف، ثم
في المثلث الصغير
هنا، والذي قد يبدو
بديهيًا، فتقوموا بالنقر فوقه فقط
ويمكنكم رؤية ما يحدث
في الداخل، ليس الأمر مفاجئًا.
لكن كيف تقوم بذلك نصيًا؟

English: 
At a command prompt, well
it's not all that hard.
You just need to change your directory.
So if I do cd space sc3, Enter,
nothing seems to happen quite yet
except that my prompt changed.
Here's the indication that-- this
is my prompt, but to the left of it
you see in blue that I'm now in my
home directory's workspace folder,
in my sc3 folder there.
So it's just a text-based version of
the GUIs, the Graphical User Interfaces
that all of us have
certainly come to take
for granted in the world of
macOS and Windows thus far.
Well, suppose that I'm a little
done with my hello program
and I want to delete it.
Well in the IDE, like in the Sandbox,
you can actually go up here and you can
click on it, and then you can
typically right-click or control-click,
and you'll get a whole menu of other
options, one of which is Delete--
and feel free to tinker like
that in your own environment.
But what about the command line?
If I zoom in down here and I
want to remove hello, you're
not going to type remove because
that just feels a little verbose
and humans decades ago decided
that's too tedious to type,

Arabic: 
في محث الأوامر، حسنًا
الأمر ليس بتلك الصعوبة.
تحتاج فقط إلى تغيير الدليل الخاص بك.
إذن إذا كتبت cd مسافة sc3، Enter،
يبدو أن لا شيء يحدث تمامًا حتى الآن
باستثناء أن المحث قد تغيّر.
ها هي الإشارة إلى أن-- هذا
هو المحث الخاص بي، ولكن ترون على يساره
باللون الأزرق أنني الآن في مجلد مساحة العمل الخاص
بدليلي الرئيسي،
في مجلد sc3 الخاص بي هناك.
إذن هو مجرد إصدار قائم على نص من
GUIs، واجهات المستخدم الرسومية
والتي بالتأكيد نعدها جميعًا
من المسلمات في عالم
macOS و Windows حتى الآن.
حسنًا، لنفترض أنني انتهيت
إلى حد ما من برنامج مرحبًا الخاص بي
وأرغب في حذفه.
حسنًا في IDE، كما في أداة تحديد الوصول،
يمكنك بالفعل الانتقال هنا ويمكنك
النقر فوقه، ثم يمكنك
عادةً النقر بزر الماوس الأيمن أو النقر فوق زر التحكم
وستحصل على قائمة كاملة من
الخيارات الأخرى، أحد هذه الخيارات هو حذف--
ولا تتردد في إصلاح مثل
هذا في بيئتك الخاصة.
ولكن ماذا عن سطر الأوامر؟
إذا قمت بالتكبير بالأسفل هنا ورغبت
في إزالة مرحبًا، ولن تكتب
إزالة لأن
هذا يبدو أكثر إطنابًا قليلاً
ومنذ عقود قرر البشر
أن أمر الكتابة ممل جدًا،

English: 
let's just call this command rm--
for remove-- hello, you're going
to see a somewhat cryptic prompt.
rm-- remove regular file 'hello?'
This is more arcane than it needs
to be, but it's just asking,
are you sure you want to delete 'hello?'
Then it's just waiting for you.
And here you can type y or yes
or sometimes other commands too,
now I've confirmed that
my intentions were yes.
If I type ls again, I--
whoops, in the wrong folder.
If I type ls again after doing hello--
no-- after doing hello
and do ls, now I'll
see just those two
things-- sc3 and hello.c.
What if I want to make a folder?
Well notice this.
If I type at the bottom
here, make directory--
mkdir-- test just to
make a test folder, I'm
about to hit Enter, but watch
the top left-hand corner
where I currently have those other
files and folders, and when I hit Enter,
now I have a test folder.
So these things are identical.
One is graphical, one is command
line, and there's even other commands
if I decide I don't want that.

Arabic: 
دعونا نسمّي هذا الأمر rm--
للإزالة-- مرحبًا، سترون
محث مشفر إلى حد ما.
rm-- إزالة الملف المنتظم "مرحبًا؟"
هذا أمر غامض أكثر مما يجب
أن يكون عليه، لكنه يسأل فقط،
هل أنت متأكد من أنك تريد حذف "مرحبًا؟"
ثم إنه فقط في انتظارك.
وهنا يمكنك كتابة y أو نعم
أو أحيانًا أوامر أخرى أيضًا،
الآن لقد أكدت أن
نواياي كانت نعم.
إذا كتبت ls مجددًا، أنا--
عذرًا، في المجلد الخاطىء.
إذا كتبت ls مجددًا بعد كتابة مرحبًا--
لا-- بعد كتابة مرحبًا
وls ، الآن سأرى
شيئين اثنين فقط
sc3 وhello.c.
ماذا لو أردت إنشاء مجلد؟
حسنًا لاحظوا ذلك.
إذا كتبت في الجزء السفلي
هنا، make directory--
mkdir-- test فقط لإنشاء
مجلد اختبار، وأنا
على وشك الضغط على Enter، ولكن شاهدوا
في أعلى الزاوية اليسرى
حيث لديّ هذه المجلدات والملفات
الأخرى حاليًا، وعندما أضغط على Enter،
الآن لديّ مجلد اختبار.
إذن هذه الأشياء متطابقة.
واحدة تكون رسومية، والأخرى
سطر أوامر، وتوجد أوامر أخرى
إذا قررت أنني لا أرغب في ذلك.

English: 
rmdir is remove directory,
and it just goes away
because it's empty and thus safe.
Any questions then on
any of those commands
or just the overall layout of
what it is we're looking at?
All right, so don't get hung
up on any of those commands,
and the problem set
and beyond will always
remind you of those kinds of features.
The point for now is just that
we're in a somewhat new environment,
but it's fundamentally still the
same, it has the same capabilities.
So what are other tools we looked at?
So you might have heard rumors about
a tool called check50, and indeed,
this is a tool that the staff use to
evaluate problem set 1 and problems set
2 to evaluate the correctness of them
so that we ourselves don't have to type
./mario or ./caesar again and again
and again to test students' code.
But starting this week, you, too,
have access to the same program.
check50 is a command from the staff
that checks the correctness of your code
just like style50 checks
the style of your code.
And in fact, if I go
back over to my IDE,
let's try to use this for the first
time by making the same version of hello

Arabic: 
rmdir هو إزالة الدليل،
ثم يختفي فقط
لأنه فارغ وبالتالي آمن.
أي أسئلة لاحقًا على
أي من تلك الأوامر
أو فقط التخطيط العام
لما ننظر إليه؟
حسنًا، لذلك لا تتوقفوا
أمام أي من تلك الأوامر،
ومجموعة المشاكل
وما بعدها والتي ستذكركم دائمًا
بأنواع الميزات هذه.
فالنقطة التي نحن بصدد مناقشتها الآن هي فقط أننا
في بيئة جديدة إلى حد ما،
ولكنها ما تزال كما هي في الأساس،
ولديها القدرات نفسها.
إذن ما هي الأدوات الأخرى التي نظرنا إليها؟
إذن ربما سمعتم شائعات عن
أداة تسمى check50، وفي الحقيقة،
هذه أداة يستخدمها طاقم العمل في
تقييم مجموعة المشاكل 1 ومجموعة المشاكل
2 لتقييم مدى صحتهما
حتى لا يتعين علينا كتابة
./mario أو ./caesar مرارًا وتكرارًا
لاختبار التعليمات البرمجية الخاصة بالطلاب.
ولكن بداية من هذا الأسبوع، أنتم، أيضًا،
يمكنكم الوصول إلى البرنامج نفسه.
check50 هو أمر من طاقم العمل
يتحقق من صحة التعليمات البرمجية الخاصة بك
تمامًا مثلما يفحص style50
أسلوب التعليمات البرمجية لديك.
وفي الواقع، إذا انتقلت
مجددًا إلى IDE،
دعونا نحاول استخدام هذا للمرة الأولى
عن طريق جعل الإصدار نفسه من مرحبًا

English: 
that you did perhaps for
your first problem set.
So if I go ahead and include
not just stdio, but cs50.h,
and I go ahead and get
a string from the user
with get_string, prompting them
for their name, and then go ahead
and print not just hello, world,
but hello, percent s comma name,
this I believe was the same
program you yourselves probably
wrote, or some variant thereof.
So if I go ahead now
and test this myself--
make hello, Enter, seems OK, ./hello.
I'm going to go ahead and type in
my name, and voila, hello, David.
Now suppose you're feeling
pretty good, you're
pretty confident that
your code is correct,
and most importantly, you have
tested your code yourselves.
It's not sufficient to
rely on our tool alone
to test your code because it,
too, might not be exhaustive.
So once you've tried a few inputs,
not just David, but perhaps
Veronica's name as well, seems to work.
Brian's name as well, seems to work.
No name at all, doesn't
seem to work, maybe?
But we'll have to look
back to the problem set
to see if that's actually a problem.
Let me go ahead now and run check50.

Arabic: 
والذي من المحتمل أنك قمت به في
مجموعة مشاكلك الأولى.
لذا إذا مضيت قدمًا وقمت بتضمين
ليس فقط stdio، ولكن cs50.h أيضًا،
ومضيت قدمًا وحصلت
على سلسلة من المستخدم
باستخدام get_string، وقمت بطلب
الاسم منه، ثم مضيت قدمًا
وطبعت ليس فقط مرحبًا، بالعالم،
ولكن أيضًا مرحبًا، النسبة المئوية s فاصلة اسم،
أعتقد أن هذا هو البرنامج
نفسه الذي من المحتمل أنكم قمتم
بكتابته بأنفسكم، أو بديلاً عنه تقريبًا.
إذن إذا مضيت قدمًا الآن
واختبرت ذلك بنفسي--
make hello, Enter، يبدو هذا الأمر على ما يرام، ./hello.
سأمضي قدمًا واكتب فيه
اسمي، وها هو ذا، مرحبًا، ديفيد.
الآن لنفترض أنكم تشعرون
بالرضا، وواثقين
للغاية أن تعليماتكم البرمجية
صحيحة،
والأهم من ذلك، أنكم
اختبرتم التعليمات البرمجية بأنفسكم.
لا يكفي الاعتماد
على الأداة الخاصة بنا وحدها
من أجل اختبار التعليمات البرمجية لأنها،
أيضًا، قد لا تكون شاملة.
إذن بمجرد أنك قد جربت بعض المدخلات،
ليس فقط ديفيد، ولكن ربما
اسم فيرونيكا أيضًا، يبدو أنه يعمل.
اسم براين كذلك، يبدو أنه يعمل.
لا يوجد اسم على الإطلاق، لا يبدو أنه
يعمل، ربما؟
ولكن يتعين علينا أن ننظر
مجددًا إلى مجموعة المشاكل
لمعرفة ما إذا كانت هذه مشكلة بالفعل.
دعوني أمضي قُدمًا وأشغّل check50.

English: 
check50 expects a special
slug, so to speak.
Just a unique identifier for the
problem that you want to check.
And you would only know
this from reading a problem
set or a documentation online.
I just happened to recall that the
command that the staff had been using
to grade and evaluate hello
is just cs50/2018/fall/hello.
And the slash is to just kind of
visually distinguish those words,
this isn't a folder or files or
anything like that in your own account.
So I'm going to run check50
cs50/2018/fall/hello in the same
directory that hello.c is in.
Enter.
It's going to go ahead and connect
to GitHub, which is the backend,
recall, that we use
for storing your code.
It's authenticating me now, which means
what's your username and password?
I'm going to go ahead and
use one of my test accounts.
And now it's prompting
me for my password,
and I'm going to go
ahead and type that in.
You'll notice you're seeing stars
like you see bullets in a website
just so that someone looking over your
shoulder can't see what you're typing.
Now I'm going to go ahead
and watch the progress.
It's preparing, let me
go ahead and zoom in.
Dot-dot-dot.

Arabic: 
تتوقع check50
وحدة كتلة خاصة، إذا جاز التعبير.
مجرد معّرف فريد للمشكلة
التي ترغب في التحقق منها.
وستعرف هذا فقط
من خلال قراءة مجموعة
المشاكل أو الوثائق عبر الإنترنت.
تذكرتُ للتو فقط أنه الأمر
الذي كان طاقم العمل يستخدمونه
لتصحيح وتقييم مرحبًا
هو فقط cs50/2018/fall/hello.
والخط المائل هو لتمييز
تلك الكلمات بشكل مرئي،
هذا ليس مجلدًا أو ملفات أو
أي شيء من هذا القبيل في حسابك الخاص.
إذن سأقوم بتشغيل check50
cs50/2018/fall/hello في الدليل
نفسه حيث يوجد hello.c بداخله.
Enter.
ستمضي قُدمًا وتتصل
بـ GitHub، وهو الطرف الخلفي،
تذكّروا، أننا نستخدمه
لتخزين التعليمات البرمجية.
تتم المصادقة الخاصة بي الآن، وهذا يعني
ما هو اسم المستخدم وكلمة المرور لديك؟
سأمضي قُدمًا
وأستخدم إحدى حسابات الاختبار الخاصة بي.
والآن تطلب مني
كلمة المرور الخاصة بي،
وسأمضي قُدمًا
وأكتب ذلك فيها.
ستلاحظون أنكم تشاهدون نجوم
مثلما ترون النقاط في موقع ويب
فقط وبذلك لا يختلق شخص النظر
إلى ما تكتبه.
الآن سأمضي قُدمًا
وأراقب التقدم.
إنه يستعد، دعوني
أمضي قُدمًا وأقوم بالتكبير.
نقطة-نقطة-نقطة.

English: 
It's looking at my code, it's
getting ready for submission,
it's now uploading it to GitHub.com,
and once it's on the servers,
then it's going to tell CS50 server,
here is so-and-so's submission,
go ahead and run a few
automated tests on it,
checking therefore its correctness,
and hopefully we're about to see some
green, happy smiley
faces, and voila, yes,
it looks like this check50
command for this problem--
or slug, so to speak--
checked that hello.c exists, because
if I forgot to write the file
or if I misnamed it,
nothing's going to work.
We checked that it
compiles successfully,
so that, too, is a happy green face.
Then it apparently checked--
what if we type in Veronica?
Do we see hello, Veronica?
Apparently yes.
What if we typed in another word, Brian?
Yes, apparently we say hello, Brian.
And so with high
probability, we're going
to conclude, based on those four tests,
that your code is, in fact, correct,
at least with respect to those inputs.
And there's often some more
detail via URL at the bottom
where you can actually see
more graphically just more
feedback on your code.

Arabic: 
إنه يفحص التعليمات البرمجية الخاصة بي،
ويستعد لتقديمها،
الآن يتم تحميلها إلى GitHub.com،
وبمجرد وجودها على الخوادم،
ستقوم بإبلاغ خادم CS50،
هنا بأنه يتم تقديم كذا وكذا،
سأمضي قدمًا وأشغّل بعض
الاختبارات الآلية عليه،
وبالتالي سيتحقق من صحة ذلك،
ونأمل أننا على وشك رؤية بعض
الوجوه الخضراء الباسمة والسعيدة،
وها هي ذا، نعم،
إنه يبدو مثل أمر check50 ذاك
لهذه المشكلة--
أو وحدة الكتلة، إذا جاز التعبير--
تم التحقق من وجود hello.c، لأنه
إذا نسيت كتابة الملف
أو إذا أخطأت في تسميته،
فلن يعمل أي شيء.
لقد تحققنا من أنه تم
تحويله برمجيًا بنجاح،
إذن، سيكون أيضًا، وجهًا أخضرًا سعيدًا.
من الواضح أنه تم فحصه إذًا--
ماذا لو كتبنا في فيرونيكا؟
هل نرى مرحبًا، فيرونيكا؟
على ما يبدو نعم.
ماذا لو كتبنا في كلمة أخرى، براين؟
نعم، من الواضح أننا قولنا مرحبًا، براين.
وهكذا مع احتمالية عالية،
أننا سننتهي،
بناء على تلك الاختبارات الأربعة،
إلى أن تعليماتك البرمجية صحيحة، في الواقع،
على الأقل فيما يتعلق بتلك المدخلات.
وغالبًا ما توجد تفاصيل أكثر عبر عنوان URL في الأسفل
حيث يمكنك في الواقع رؤية
ملاحظات أكثر وبشكل بياني
في تعليماتك البرمجية.

Arabic: 
بالطبع، للمرة الأولى، الثانية،
الثالثة من المحتمل أنك تقوم بتشغيل هذا الأمر،
وقد لا تشاهد بعض
الوجوه السعيدة الخضراء،
أو قد تشاهد بعض الوجوه التعيسة الحمراء
أو بعض الوجوه المسطحة الصفراء،
وهي فقط تعني أنه لا يمكننا تشغيل
عمليات الفحص لوجود شيء آخر
خاطئ.
لكن مع مرور الوقت، سيساعدك هذا على الشعور
براحة أكثر والثقة بأن
تعليماتك البرمجية صحيحة قبل
أن تستخدم submit50 وتقوم بتقديمها.
بالمضي قدمًا في ذلك ستشعروا
بالتحسن أو بالإحباط قليلاً
لمعرفة ذلك مسبقًا-- انتظروا لحظة،
أنا على وشك تقديم هذا ولكن كلا،
إنه ليس صحيحًا بعد.
إذن لابد أن تدركوا أنه سلاح ذو حدين.
أي أسئلة حول check50 أو
أي من هذه الأوامر حتى الآن؟
أي شيء على الإطلاق؟
لا؟
حسنًا.
لذلك دعونا نلقي نظرة على
الأداة النهائية والأكثر قدرة
وهي الآن متوفرة لكم
في بيئة IDE.
تم إنشاؤها في CS50 IDE، والتي
تشير إلى بيئة التنمية
المتكاملة، والتي لا تخص CS50--
هذا مصطلح شائع في الصناعة
للأدوات التي تُسهّل
كتابة التعليمات البرمجية،
اتضح أن هناك ميزة أخرى
بالإضافة إلى القطة في الأعلى هنا.

English: 
Of course, the first time, second time,
third time maybe you run this command,
you might not see some
green happy faces,
you might see some red unhappy
faces or some yellow flat faces,
which just means we couldn't even run
the checks because something else is
wrong.
But over time, this will help you feel
more comfortable and more confident
that your code's correct before you
actually use submit50 and submit.
Going into it you'll feel a little
better or a little frustrated
to know in advance-- wait a minute,
I'm about to submit this but nope,
it's not yet correct.
So realize it's a two-edged sword.
Any questions about check50 or
any of these commands thus far?
Anything at all?
No?
All right.
So let's take a look at
the final and most powerful
tool now available to you
in the IDE environment.
Built in to CS50 IDE, which
stands for Integrated Development
Environment, which isn't a CS50 thing--
this is a common term in industry
for tools that make it
easier to write code,
it turns out that there's some other
feature besides the cat over here.

Arabic: 
تحديدًا، التي بها، يمكنك
مشاركة مساحة العمل الخاصة بك
مع زملاء التدريس
ومساعدي الدورة
لذا ربما يمكنهم مساعدتك في الوقت الحقيقي
مثل Google Docs، وحتى في إجراء الدردشة
معك في الوقت الحقيقي.
ولكنه يوفر لك أيضًا
ما يسمّى بمصحح الأخطاء.
مصحح الأخطاء، كما يُوحي
اسمه، يزيل الأخطاء--
أو بالأحرى، يساعدك
في إزالة الأخطاء من تعليماتك البرمجية
عن طريق السماح لك
بالوصول إلى printf--
وطباعة الأعداد الصحيحة
والسلاسل وأي
شي جيد يحدث في
برنامجك، إنه يجعل الأمر تلقائيًا
نوعًا ما ويجعله عملية مملة جدًا بالنسبة لك.
ويتيح لك الانتقال
من خلال تعليماتك البرمجية إلى سطر واحد
في آنً واحد على
وتيرتك المريحة الخاصة
وترى على طول الطريق جميع قيم
المتغيرات الخاصة بك في هذا البرنامج.
لتنشيط مصحح الأخطاء هذا،
سأمضي قدمًا وأفعل ما يلي.
سأقوم بالتحويل البرمجي لتعليماتي البرمجية
كما جرت العادة مع make hello.
يجب أن يتم تحويلها برمجيًا
وإلا قد أرغب في
استخدام help50 وأكتشف
لماذا لا يتم تحويلها برمجيًا،
ولكن يبدو أنه تم تحويلها برمجيًا.
والآن سأمضي قدمًا
وأقوم بتشغيل debug50، مسافة، ثم
اسم البرنامج الذي
أردت تصحيحه من الأخطاء.
واسم البرنامج الذي
أردت تصحيحه من الأخطاء في الوقت الحالي
هو ملف الدليل الحالي
وهو ما يسمّى مرحبًا.
دعونا نفترض أنه قد يوجد
شيء خاطئ به.

English: 
Namely, one, you can
share your workspace
with teaching fellows
and course assistants
so they can perhaps help you in real
time a la Google Docs, even chatting
with you in real time.
But it also provides you with
what's called a debugger.
A debugger, as the name
suggests, removes bugs--
or rather, helps you
remove bugs from your code
by allowing you to not
just resort to printf--
printing out ints and
strings and whatever
is good that's going on your
program, it kind of automates
that very tedious process for you.
And it lets you walk
through your code one
line at a time at your
own comfortable pace
and see along the way all of the values
of your variables in that program.
To activate this debugger, I'm going
to go ahead and do the following.
I'm going to compile my code
as always with make hello.
It has to compile,
otherwise I might want
to use help50 and figure
out why it's not compiling,
but it does seem to have compiled.
And now I'm going to go ahead
and run debug50, space, and then
the name of the program
I wanted to debug.
And the name of the program I
wanted to debug at the moment
is the current directory's
file called hello.
Let's assume that there's
perhaps something wrong with it.

Arabic: 
في المرة الأولى التي قمت بتشغيل هذا
الأمر، رغم أن، debug50
لن يكون راضيًا
عني لأنه سيقول،
يبدو أنك لم تقم
بتعيين أي نقاط توقف.
قم بتعيين نقطة توقف واحدة على الأقل
بالنقر فوق يسار رقم السطر
ثم أعد تشغيل debug50.
حسنًا ما هي نقطة التوقف؟
حسنً هل يقترح الاسم
نوعًا ما، أنه يتيح
لك إلغاء أو إيقاف تشغيل
التعليمات البرمجية لديك مؤقتًا في أي سطر من سطورك.
وطوال هذا الوقت
للأسابيع القليلة الماضية،
تم ترقيم تعليماتك البرمجية
في كل سطر تلقائيًا.
وهذا مفيد لأن أكثر
سطر مثير للاهتمام في هذا البرنامج،
بمجرد أن يبدأ بالفعل،
ليس تلك الاشياء في الأعلى،
ليس int main void، أليس كذلك؟
هذا كله نسخ ولصق
من البرامج السابقة.
إنه حقًا السطر السادس هنا حيث
لديّ بالفعل بعض المنطق لنفسي.
إذًا في CS50 IDE،
ما يمكنك القيام به الآن هو
النقر فوق يسار
أحد أرقام الأسطر هذه،
ضوء أحمر صغير مثل علامة
التوقف سيظهر قائلاً،
ألغاء أو إيقاف
برنامجي مؤقتًا على هذا السطر حتى
يمكنني التدقيق في تعليماتي البرمجية الفعلية.
لا يمكن أن يقوم Sandbox وLab بذلك.
الآن سأمضي قدمًا وأعيد تشغيل
debug50 بنفس الطريقة بالضبط، وأضغط على

English: 
The first time I run this
command, though, debug50
is not going to be happy with
me because it's going to say,
it looks like you haven't
set any breakpoints.
Set at least one breakpoint by
clicking to the left of a line number
and then rerun debug50.
Well what is a breakpoint?
Well as the name kind
of suggests, it allows
you to break or pause the running
of your code at any of your lines.
And all this time for
the past few weeks,
your code been
automatically line-numbered.
And this is useful because the most
interesting line in this program,
once it really gets going,
isn't this stuff at the top,
it's not int main void, right?
That's all copy-paste
from past programs.
It's really the sixth line here where
I actually have some logic of my own.
And so in CS50 IDE,
what you can now do is
click to the left of one
of these line numbers,
a little red light like a stop
sign is going to appear saying,
break or pause my
program on this line so
that I can poke around my actual code.
Sandbox and Lab cannot do this.
So now I'm going to go ahead and rerun
debug50 in exactly the same way, hit

English: 
Enter, but now I have one breakpoint.
And you'll see on the right-hand
side a fancier menu just popped up
by the cat that provides me
with a bunch of features.
And at first glance, frankly,
it's a little overwhelming
because there's a lot going on
here, but you'll notice first,
and most importantly, there's
some mention of my name variable.
I don't quite understand 0x0 or
whatnot, but I do understand string.
And so what the debug50 program has
realized is oh, on this line and below,
you have a variable called name.
It doesn't seem to have a value yet.
0x0, it turns out, is just going
to mean empty or null or 0.
But that's good, because now,
when I actually execute this line,
hopefully it's going to take on the
name David or Veronica or Brian.
So let's see what happens.
Notice that it's highlighted in
yellow, line 6, which means it
has not yet executed this line of code.
My code has paused at this point
because I set that breakpoint.
And then notice kind of like a music
player up here, there's a few icons.
The Play button is just going
to say, ah, play my program,

Arabic: 
Enter، ولكن الآن لدي نقطة توقف واحدة.
وسترى على الجانب الأيمن
قائمة رائعة منبثقة للتو
بواسطة القطة التي توفر لي
مجموعة من الميزات.
وللوهلة الأولى، وبصراحة،
إنها زاخمة قليلاً
لأنه يوجد الكثير الذي يحدث هنا،
ولكنكم ستلاحظون أولاً،
والأهم من ذلك، أن هناك
بعض الإشارات لمتغير الاسم الخاص بي.
لا أفهم تماما 0x0 أو
أي شيء، ولكني أفهم سلسلة.
إذًا ما يدركه برنامج debug50
هو أوه، على هذا السطر وأدناه،
لديك متغير باسم اسم.
لا يبدو أن لديه قيمة بعد.
يتضح أن، 0x0، يعني فقط
فارغ أو خالي أو صفر.
ولكن هذا أمر جيد، لأنه الآن،
عندما أقوم بتنفيذ هذا السطر بالفعل،
آمل أن يأخذ اسم
ديفيد أو فيرونيكا أو براين.
دعونا نرى ما سيحدث.
لاحظوا أنه مظلل باللون الأصفر،
السطر 6، وهذا يعني أنه
لم يقم بتنفيذ سطر التعليمات البرمجية هذا.
لقد توقفت تعليماتي البرمجية مؤقتًا عند تلك النقطة
لأنني قمت بتعيين نقطة الإيقاف تلك.
ثم لاحظوا وجود ما يشبه مُشغّل الموسيقى
في الأعلى، وتوجد بعض الرموز.
سيقول زر التشغيل فقط،
آه، شغّل برنامجي،

English: 
run it all the way through the end, kind
of like scratch with the green flag.
But more powerful is this.
You can step over this line,
therefore executing it just once.
If it's a function, you
can step into this line
and actually look inside of a function
that you're using, like get_string,
or you can step out of another
function, but more on that another time.
So what I'm going to do is this.
And the button I'm going to click most
commonly when trying to understand
how my program is working is this--
Step Over.
So it's the second icon from the
left, right next to the triangle.
So once I click this, watch
what's going to happen,
even though it's a little small, on the
right-hand side for my name variable.
Notice that I'm being prompted to
type in my name because the program
is still running in my terminal
window, but when I hit Enter now,
providing my own name, automatically
you see on the right-hand side
that this name variable has a
value now of, quote-unquote,
"David" of type string.
There's this 0x1083010-- more on
that later, just a little cryptic,

Arabic: 
شغّله على طول الطريق حتى
النهاية، مثل سكراتش نوعًا ما مع العلم الأخضر.
لكن هذا أكثر قدرةً.
يمكنك تجاوز هذا السطر،
وبالتالي تنفيذه مرة واحدة فقط.
إذا كانت دالة، فيمكنك
الدخول إلى هذا السطر
والنظر في الحقيقة داخل دالة
تستخدمها، مثل get_string،
أو يمكنك الخروج إلى دالة أخرى،
ولكن المزيد عن ذلك مرة أخرى.
إذن ما سأفعله هو هذا.
والزر الذي سأقوم بالنقر فوقه كثيرًا
عند محاولة فهم
كيفية عمل برنامجي هو هذا--
Step Over.
إذن هو الرمز الثاني من اليسار،
بجوار المثلث.
إذن بمجرد أن قمت بالنقر فوق هذا، شاهدوا
ما الذي سيحدث،
على الرغم من أنها صغيرة بعض الشيء،
على الجانب الأيمن لمتغير اسمي.
لاحظوا أنه تتم مطالبتي
بكتابة اسمي لأن البرنامج
ما يزال قيد التشغيل في النافذة
الطرفية، ولكن عندما أنقر فوق Enter الآن،
وأقدم اسمي، سترون
تلقائيًا على الجانب الأيمن
أن متغير الاسم هذا له قيمة
الآن، اقتباس-إنهاء الاقتباس،
"ديفيد" لنوع سلسلة.
يوجد 0x1083010 هذا--
المزيد عن ذلك لاحقًا، فقط مُشفر قليلاً،

English: 
but I didn't have to use printf now,
I can actually see what's going on.
Now you can see that
line 7 is highlighted,
because I set a breakpoint above
it, so now I'm on the second line
because I just stepped into it.
Let me go ahead and click
Next again, and you'll
see that in my terminal window,
hello, David just got executed.
And now if I just keep going, it's
going to go ahead and run to the end
and close the debugger.
So not all that useful for this
program because frankly, I'm
pretty sure this is correct, but the
power of debug50 and a debugger more
generally is that it lets you, whether
you're less comfy or more comfy,
walk through your own code at your pace
just like a TF or a CA might say, OK,
what is this line doing?
What is this line doing?
You don't have to resort to printf,
you can just very methodically
walk through your code and find that
damn bug that's been bothering you
for minutes or even hours.
So henceforth, any time you have a
bug in your code that is compiling
but it's just logically incorrect--
the pyramid in Mario isn't quite right,
your encryption of Caesar isn't
quite right, or something else,
your first instinct now should be,
let me compile it, run debug50 on it,

Arabic: 
ولكن لا يتعين عليّ استخدام printf الآن،
يمكنني رؤية ما يحدث بالفعل.
الآن يمكنك رؤية أنه تم
تظليل السطر 7،
لأنني قمت بتعيين نقطة توقف فوقه،
إذًا أنا الآن في السطر الثاني
لأنني قمت بالدخول فيه.
دعوني أمضي قدمًا وانقر فوق
التالي مجددًا، وسترون
ذلك في النافذة الطرفية،
تم تنفيذ مرحبًا، ديفيد للتو.
والآن إذا واصلت الاستمرار، سيمضي
قدمًا ويعمل للنهاية
ويغلق مصحح الأخطاء.
إذن ليس كل ذلك مفيدًا لهذا البرنامج
لأن بصراحة، أنا
متأكد للغاية من أن هذا صحيح، ولكن تلك هي قدرة
debug50 ومصحح الأخطاء
بشكل عمومي أكبر حيث يتيح لك، سواء
كنت معتادًا بشكل كبير أو صغير،
على التنقل خلال تعليماتك البرمجية في وتيرتك الخاصة
تمامًا مثلما قد يقول رفيق التدريس أو مساعد في دورة تدريبية، حسنًا،
ما الذي يفعله هذا السطر؟
لا يتعين عليك اللجوء إلى printf،
يمكنك الانتقال فقط بطريقة منهجية
من خلال تعليماتك البرمجية وإيجاد هذا
الخطأ اللعين الذي يزعجك
لدقائق أو حتى ساعات.
إذن من الآن فصاعدًا، في أي وقت لديك خطأ
في تعليماتك البرمجية التي تتحول برمجيًا
ولكن هذا غير صحيح من الناحية المنطقية--
الهرم في ماريو ليس صحيحًا تمامًا،
تشفيرك لقيصر ليس صحيحًا
تمامًا، أو أي شيء آخر،
يجب أن تكون غريزتك الأولى الآن،
دعوني أحوله برمجيًا، وأشغّل debug50 عليه،

English: 
and just step through the code,
setting a breakpoint wherever I want,
so you focus on just a few
lines, not the whole thing--
like I just did--
and see if you can figure out logically
when a value is not what you expected,
then oh--
go ahead and just click
Resume, fix the bug, and retry.
Such a powerful tool.
Any questions?
Yeah?
What is it?
AUDIENCE: What does it look
like when there is a bug?
DAVID MALAN: What does it
look like when there is a bug?
So the debugger won't find your bugs
and it won't show you your bugs, per se.
It's going to let you see
what line is executing,
it's going to let you
see what's outputting,
it's going to let you
take input, but all it's
going to do on that
right-hand side is just show
you the values of things along the way.
It's up to you to infer
from that information what
it is that's going wrong, just like
if you're using printf in past weeks
to see what's going on in your program.
Other questions?
And let me save this too.
It is so easy to get into the habit,
especially when so many things have
been new over the past few
weeks of just saying, ah,
this is just yet another thing to learn.

Arabic: 
والمضي خلال التعليمات البرمجية فقط،
وتعيين نقطة توقف أينما أريد،
لذا تركز على عدد قليل من السطور،
وليس على الأمر برمته--
مثلما فعلت للتو--
وانظروا إذا كان يمكنكم تبين الأمر بشكل منطقي
عندما لا تكون القيمة ما كنت تتوقعه،
ثم أوه--
امضي قدمًا وانقر فقط على
استئناف، إصلاح الخطأ، وأعد المحاولة.
هذه الأداة الفعّالة.
أي أسئلة؟
أجل؟
ما هو؟
الجمهور: ما الذي يبدو عليه
عندما يكون هناك خطأ؟
ديفيد ج. مالان: ما الذي يبدو عليه
عندما يكون هناك خطأ؟
إذن لن يجد مصحح الأخطاء الأخطاء
ولن يقوم بإظهارها، في حد ذاته.
سيتيح لك مشاهدة
ما السطر الذي يتم تنفيذه،
سيتيح لك مشاهدة
ما هي المخرجات،
سيتيح لك أخذ
المدخل، ولكن كل ما
سيقوم به على الجانب الأيمن هذا
هو مجرد عرض
قيم الأشياء على طول الطريق لك.
الأمر متروك لك لتستنتج
من تلك المعلومات ما
الذي يسبب الخلل، تمامًا
كما كنتم تستخدمون printf في الأسابيع الماضية
لمعرفة ما الذي يجري في برنامجكم.
أي أسئلة أخرى؟
دعوني أقوم بحفظ هذا أيضًا.
من السهل جدا أن تتعودوا على الأمر،
وخصوصًا عندما توجد أشياء كثيرة
جديدة على مدار الأسابيع
القليلة الماضية من قول، آه،
هذا شيء آخر لنتعلمه.

Arabic: 
هذا بدون بذل الكثير من الجهد
نوع من الأدوات التي إذا
قضيت بضع دقائق اضافية هذا
الأسبوع والأسبوع القادم فقط في استخدامها،
ستشعر بالراحة
في استخدامها، وستوفر
عليك ساعات محتملة
على المدى الطويل،
لأنه طوال الوقت الذي كنت
تقضيه في محاولة
إصلاح الأخطاء لديك أو نشر
الأسئلة عبر الإنترنت
ومحاولة فهم الأشياء بشكل يدوي،
هذه أداة
إذا استثمرت تلك
الدقائق مسبقًا في استخدامها
ستساعدك على فهم كل شيء
يجري داخل برنامجك،
وستوفر لك قطعًا خلال الأسابيع
المقبلة المزيد والمزيد من الوقت.
حسنًا، أي أسئلة؟ نعم؟
الجمهور: إذن لديكم تكرار حلقي من نوع for loop
والذي تم تشغيله لعدد [INAUDIBLE] من المرات،
[INAUDIBLE] قام بفصل عبارات break
ومن ثم لا يتعين عليكم [INAUDIBLE]..
ديفيد ج. مالان: آه،سؤال جيد.
إذا كان لديك شيء يشبه تكرارًا حلقيًا
من نوع for loop أو من نوع while loop، شيء
يحدث كثيرًا، فهل يمكنكم
تعيين نقطة توقف بطريقة
تتوقف فقط بحيث لا
يتعين عليكم المرور من خلالها 100 مرة
فقط لرؤية تلك القيمة؟
إجابة مختصرة، نعم.
ودعوني أؤجل قليلاً فقط من هذه
الميزات إلى موارد القسم والموارد عبر الإنترنت،
إلا ميزة واحدة،
أنكم يمكنكم مشاهدة القيم بالفعل،
ويمكنك الحصول على ما يطلق
عليه تعبير watch expression.

English: 
This is hands down the
kind of tool that if you
spend a few extra minutes this
week and next week just using it,
get a little more
comfortable with it, it
will save you potentially
hours in the long run,
because all the time you've
been spending manually
trying to fix your bugs or
posting questions online
trying to understand
things, this is a tool
that if you invest those
minutes upfront will just
help you understand everything
going on inside of your program,
and will absolutely over the next few
weeks save you more and more time.
All right, any questions? yeah?
AUDIENCE: So you have a for
loop that ran [INAUDIBLE] times,
[INAUDIBLE] separate break statements
so you don't have to [INAUDIBLE]..
DAVID MALAN: Ah, good question.
If you have something like a for
loop or a while loop, something
that's happening a lot, can you
set a breakpoint in such a way
that it only breaks so that you don't
have to walk through it 100 times
just to see that value?
Short answer, yes.
And let me defer to section and
online resources for just a few
of these features, but one,
you can actually watch values,
and you can have what's
called a watch expression.

English: 
You can say show me this value
if only when x is greater than 50
or something like that.
Or you yourself can just
add some lines of code.
You could add a, if x equals-equals
50, then print out something,
and you can set a breakpoint
on that new, if temporary line,
so there's a couple of ways to do that.
Good question to anticipate.
Yeah?
Behind.
AUDIENCE: If you run
debug50, aren't you adding
another arugment with the [INAUDIBLE]
in your main method at line 4?
DAVID MALAN: Really good question.
If you're running
debug50, aren't you adding
another argument-- argv-- per our
discussion last week of command line
arguments?
Short answer, no, because
debug50 corrects for that,
so you don't have to worry about that.
It will not shift
things over numerically.
Really good thought.
Other questions?
All right, so with that said, let's
now take some training wheels off.
So the only reason I bought
these training wheels years ago
is to make this very dramatic point
of now taking the training wheels off
today.

Arabic: 
يمكنك أن تقول أرني هذه القيمة
إذا كانت x أكبر من 50 فقط
أو شيئًا من هذا القبيل.
أو يمكنك أن تضيف بنفسك فقط
بعض الأسطر من التعليمة البرمجية.
يمكنكم إضافة دالة، إذا كانت x تساوي-تساوي
50، ثم طباعة شيء ما،
ويمكنك تعيين نقطة توقف
على ذلك السطر الجديد، إذا كان سطرًا مؤقتًا،
فتكون هناك إذن طريقتان للقيام بذلك.
سؤال جيد نتوقعه.
نعم؟
هناك في الخلف.
الجمهور: إذا قمتَ بتشغيل
debug50، ألستَ تقوم
بإضافة وسيطة أخرى مع [INAUDIBLE]
في طريقتك الأساسية في السطر 4؟
ديفيد ج. مالان: سؤال جيد حقًا.
إذا كنتَ تقوم بتشغيل
debug50، ألستَ تقوم
بإضافة وسيطة أخرى-- argv-- في مناقشتنا
الأسبوع الماضي لوسيطات
سطر الأوامر؟
إجابة مختصرة، لا، لأن
debug50 يقوم بالتصحيح لذلك،
لذا لا داعي للقلق بشأن ذلك.
إنها لن تستبق
الأشياء عدديًا.
فكرة جيدة حقًا.
أي أسئلة أخرى؟
حسنًا، مع هذا القول، دعونا
الآن نخرج بعض عجلات التدريب.
إذن السبب الوحيد لشرائي
لعجلات التدريب هذه منذ سنوات
هو جعل هذه النقطة الدراماتيكية جدًا
للوقت الحالي لإخراج عجلات التدريب هي
هذا اليوم.

English: 
OK, so what does this mean?
Well worth the trip to Target.
So what does this mean?
For the past few weeks, we
have been using a whole bunch
of functions from CS50's library.
All of these were meant to just make
it pretty easy, relatively speaking,
in the first few weeks to
get input from the user.
Because it turns out,
as we'll see today,
it's actually a kind of a pain in the
neck to get input from users in C,
and frankly, even in other
languages reliability.
Because you'll recall that get_string
and get_int and all of these functions
take on the burden of like re-prompting
the user if they don't actually
give you an an int or
don't give you a float
or don't give you a char that
you're expecting, they'll re-prompt,
they're using a while loop or
a do-while loop or the like,
so there's just a lot of error
detection built into these functions.
But, most importantly--
and most misleadingly,
has been the last one on this list.
Recall that we introduced a couple
weeks ago now the notion of a string.
And a string is in English what?
An array of characters, good.
It's a sequence of characters, and we
learned last week that a sequence can
be implemented in an array,
which is just a chunk of memory

Arabic: 
حسنًا، ماذا يعني هذا؟
الأمر يستحق زيارة إلى الهدف.
إذن ماذا يعني هذا؟
خلال الأسابيع القليلة الماضية، كنا
نستخدم مجموعة كاملة
من الدوالّ من مكتبة CS50.
وكان من المفترض أن كل هذه الدوالّ
كانت مصممة فقط لتجعلها سهلة جدًا، فلنقل نسبيًا،
في الأسابيع القليلة الأولى
للحصول على إدخال من المستخدم.
لأنه يتبين،
كما سنرى اليوم،
أنها في الواقع تمثل نوعًا ما أمرًا
مزعجًا للحصول على إدخال من المستخدمين في C،
وبصراحة، حتى في موثوقية
اللغات الأخرى.
لأنكم ستتذكرون أن دالة get_string
ودالة get_int وجميع هذه الدوال
تأخذ على عاتقها إعادة مطالبة
المستخدم إذا لم يمنحك فعليًا
عددًا صحيحًا int أو
إذا لم يمنحك قيمة كسرية float
أو إذا لم يمنحك حرفًا char حسب توقعك،
فستقوم هذه الدوال بإعادة المطالبة،
أو تستخدم تكرارًا حلقيًا من النوع while loop أو
من النوع do-while loop أو ما شابه،
إذن يوجد فقط كثير من اكتشافات الأخطاء
المدمجة في هذه الدوال.
ولكن، الأكثر أهمية--
والأكثر تضليلاً،
هي آخر واحدة في هذه القائمة.
تذكّروا أننا طرحنا منذ
أسبوعين من الآن فكرة السلسلة.
وما هو المعنى الحرفي لكلمة سلسلة؟
مصفوفة من الأحرف، عظيم.
إنها تسلسل من الأحرف، ونحن
تعلمنا الأسبوع الماضي أنه يمكن تنفيذ
تسلسل في مصفوفة،
وهي مجرد مجموعة في الذاكرة

English: 
back-to-back-to-back-to-back.
So string, though, is not quite
like any of those other data types.
It turns out that it's not quite like
int or char or even bool or float,
and we can start to see
that now as follows.
I'm going to go ahead and
go into the IDE today--
and henceforth we're going
to just start using the IDE,
but you're welcome to keep using the
Sandbox for quick and dirty programs,
but for anything you
want to keep around,
your instinct should
now be to open your IDE.
I'm going to go ahead
and create a new file,
and I'm going to call it compare0.c from
my first example of comparing things.
And I'm going to go ahead and
whip up a relatively short program
that you would hope would
work right out of the box.
So I'm going to go ahead and
include the familiar cs50.h.
I'm going to go include stdio.h.
I'm going to go ahead
and do int main void.
I'm going to go ahead and in here--
let me a variable called i
using get_int from the user,
and just prompt them for i.
Let me go ahead then and prompt
the user for another get_int.
We'll call it j and get that from them.
And then let's just
compare these things.

Arabic: 
مصفوفة على التوالي.
إذن فالسلسلة، رغم ذلك، ليست تمامًا
كأي من أنواع البيانات الأخرى تلك.
يتضح أنها ليست تمامًا كعدد صحيح int
أو حرف char أو حتى قيمة منطقية bool أو قيمة كسرية float،
ويمكننا أن نبدأ في رؤية
ذلك الآن على النحو التالي.
سأمضي قدمًا و
أنتقل إلى IDE اليوم--
وسنمضي من الآن فصاعدًا
فقط لبدء استخدام IDE،
ولكن لا مانع من استمرارك في استخدام
أداة تحديد الوصول للبرامج السريعة والسيئة،
ولكن لأي شيء تريد
البقاء حوله،
ينبغي أن تخبرك غريزتك
الآن بفتح IDE الخاص بك.
وسأمضي قدمًا
وأُنشئ ملفًا جديدًا،
وسأسميه compare0.c من
مثالي الأول الخاص بمقارنة الأشياء.
وسأمضي قدمًا
وأقوم بتنشيط برنامج قصير نسبيًا
ستأملون أن يعمل
على الفور.
إذن سأمضي قدمًا
وأقوم بتضمين cs50.h المألوف.
سأقوم بتضمين stdio.h.
سأمضي قدمًا
وأجعل int main لاغيًا.
سأمضي قدمًا وهنا--
دعوني أنشىء متغيرًا يسمى i
باستخدام get_int من المستخدم،
ومطالبته فقط بالمتغير i.
دعوني أمضي قدمًا وأطالب المستخدم
بدالة get_int أخرى.
سنسميها j ونحصل على تلك الدالة منه.
ثم دعونا فقط
نقارن هذه الأشياء.

Arabic: 
لذلك إذا كان i يساوي-يساوي j،
إذن فلنمضِ قدمًا ونقوم بطباعة
باستخدام printf نفسه وسطر جديد.
ثم أمضي قدمًا وأطبع
المقابل، والذي يكون مختلفًا.
وبالتالي فإن المكان الوحيد الذي أظن أني أفسدتّه، ربما،
يكون إذا فعلت هذا، وهو
معقول نوعًا ما إذا كنتَ
في طريقك لمعرفة ما تعنيه علامة يساوي.
ولكن مجدّدًا، في التعليمة البرمجية، نحن
نحتاج عادةً إلى علامتي يساوي
لأن ذلك يقارن بين قيمتين.
لذلك لم أقع في ذلك الخطأ، ولديّ
شعور جيد جدًا حول هذا الأمر.
دعوني أحفظه باستخدام الأمر Command-S
أو Control-S أو عن طريق File،
Save؛ وأنتقل إلى مطالبتي
وأشغّل make compare0.
عظيم، كل شيء تم تحويله برمجيًا.
ودعوني أمضي وأشغّل
compare0، إدخال، وسأقوم بكتابة 50،
وسأكتب 50،
ويبدو أنها هي نفسها.
دعوني أمضي قدمًا ونفعل ذلك
مجدّدًا، ودعونا نكتب 42 و13،
وهما مختلفان.
وعلى الأرجح ينبغي عليّ اختبار المزيد قليلاً، ربما
بعض القيم السالبة، وربما بعض
الأصفار، والقيم الموجبة
وما شابه، ولكن لديّ
شعور جيد للغاية حول
مدى صحة هذه التعليمة البرمجية.
حسنًا.
إذن دعونا نغير هذا البرنامج قليلاً.
دعوني أمضي قدمًا
وأنشىء ملفًا آخر، والذي

English: 
So if i equals-equals j,
then go ahead and print out
with printf same and a new line.
Then go ahead and print out the
opposite, which is different.
So the only place I think I
could have screwed up, perhaps,
is if I did this, which is
kind of reasonable if you
come in knowing what an equal sign is.
But again, in code, we
typically need two equal signs
because that compares two values.
So I didn't make that mistake, I'm
feeling pretty good about this.
Let me save it with Command-S
or Control-S or via File,
Save; go to my prompt
and run make compare0.
Good, everything compiled.
And let me go ahead and run
compare0, Enter, and I'll type in 50,
and I'll type in 50, and
they do seem to be the same.
Let me go ahead and do that
again, let's type in 42 and 13,
and they are different.
And I should probably test a few more,
maybe some negative values, maybe some
0's, positive values
and the like, but I'm
feeling pretty good about
the correctness of this code.
All right.
So let's change this program a bit.
Let me go ahead and
create another file, which

English: 
I can do with the little green
plus or via File, New File.
I'm going to go ahead save
this one as compare1.c.
And for the moment I'm going to go
ahead and just paste in that code
from before, but I'm going
to make some changes now.
I'm going to go ahead and rename
and retype my data types as strings.
So give me a string called
s, and will prompt the user
for that using
get_string, then I'm going
to go ahead and change
this 1 to string t,
and I'm going to go
ahead and get get_string.
I, of course, need to now
compare s and t, not i and j.
And s is a common variable name
for a string. t just comes after s,
so that's pretty reasonable too, but I
should of course update that as well.
And so I think everything's
now the same logically.
I just changed my data
types and my variable names.
So I've saved this.
Let me go ahead and run make compare1.
Good, everything's correct.
Let me go ahead and do ./compare1.
Let me go ahead and type
in Brian and Veronica.
And of course, those are different.

Arabic: 
يمكنني القيام به بواسطة علامة زائد
الخضراء الصغيرة أو عن طريق قائمة File، New File.
سأمضي قدمًا وأحفظ هذا كـ compare1.c.
وفي الوقت الحالي سأمضي
قدمًا وأقوم فقط بلصق تلك التعليمة البرمجية
المنسوخة من قبل، لكنني سأجري
بعض التغييرات الآن.
سأمضي قدمًا وأعيد تسمية أنماط
بياناتي وأعيد كتابتها كسلاسل.
إذن يمنحني سلسلة تسمى
s، وستطالب المستخدم
من أجل ذلك باستخدام
get_string، ثم سأمضي
قدمًا وأغير
هذا الواحد إلى السلسلة t،
وسأمضي قُدمًا
وأحصل على get_string.
أنا، بالطبع، بحاجة الآن
لمقارنة s وt، وليس i وj.
و s هو اسم متغير مشترك
لسلسلة. وتأتي t فقط بعد s،
فهي لذلك معقولة للغاية أيضًا، لكن
ينبغي عليّ بالطبع تحديث ذلك أيضًا.
ولذلك أعتقد أن كل شيء
الآن هو متشابه منطقيًا.
غيرتُ للتو أنواع
بياناتي وأسماء المتغيرات لديّ.
لذا قمتُ بحفظ هذا.
دعوني أمضي قدمًا، وأشغّل make compare1.
عظيم، كل شيء صحيح.
دعوني أمضي قدمًا، وأشغّل ./compare1.
دعوني أمضي قدمًا وأكتب
Brian وVeronica.
وبالطبع، فهما مختلفان.

English: 
Now let me go ahead and type in
David, let me type in David again,
and those of course are different?
Huh.
Maybe it's because I just hit
the Spacebar or something.
So let's try Erin.
Her name's a little shorter.
Hmm.
OK, let's try-- oh, what's her name?
TJ.
OK, even shorter, perfect.
TJ, can't go wrong.
Different.
I mean, what is going on?
Let's just say i, i.
Different?
So where's the logical
bug in this program?
What is it that's going on?
Yeah, what do you think?
AUDIENCE: Is it
comparing integer values?
DAVID MALAN: Is it
comparing integer values?
Well maybe.
I mean, thus far when
we've used equal-equals
we've probably used it mostly
for comparing integers,
so maybe I'm just misusing it, sure.
Other thoughts?
AUDIENCE: [INAUDIBLE]
DAVID MALAN: Oh, that's a big word
that we'll get to in just a little bit.
But correct, correct-- but
for very similar reasons.

Arabic: 
والآن دعوني أمضي قدمًا وأكتب
David، ثم دعوني أكتب Da vid مجدّدًا،
وهذان بالطبع مختلفان؟
ها.
ربما لأنني ضغطت على
شريط المسافة أو شيء ما.
إذن دعونا نجرب Erin.
اسمها أقصر قليلاً.
امم.
حسنًا، دعونا نجرب-- أوه، ما اسمها؟
TJ.
حسنًا، اسم أكثر قصرًا، رائع.
TJ، لا يمكن أن يكون خاطئًا.
مختلفان.
أعني، ما الذي يحدث؟
دعونا فقط نقول i،i.
مختلفان؟
إذن أين هو الخطأ
المنطقي في هذا البرنامج؟
ما هذا الذي يجري؟
أجل، ما رأيكم؟
الجمهور: هل
يقارن قيم أعداد صحيحة؟
ديفيد ج. مالان: هل
يقارن قيم أعداد صحيحة؟
حسنًا من الممكن.
أعني، حتى الآن عندما استخدمنا
يساوي-يساوي
فعلى الأرجح استخدمناها غالبًا
لمقارنة أعداد صحيحة،
إذن ربما أسأتُ استخدامه، بالتأكيد.
أي أفكار أخرى؟
الجمهور: [INAUDIBLE]
ديفيد مالان: أوه، هذه كلمة كبيرة
سنصل إليها بعد قليل.
لكنها صحيحة، صحيحة-- ولكن
لأسباب متشابهة جدًا.

Arabic: 
إذن، شيء ما يحدث منطقيًا
يتعلق بالمقارنة،
لأنني أستخدم يساوي-يساوي، ولكن ربما
أستخدمه لأنواع البيانات الخاطئة؟
أعني، أنه من الواضح أنه مقسم لسلاسل.
فلماذا يحدث ذلك فعليًا؟
حسنًا، يتبين أن السلاسل
غير موجودة بالفعل.
إذن فالسلسلة التي نعرفها هي
مجرد تسلسل من الأحرف
أو مصفوفة من الأحرف
لا تعتبر نوع بيانات فعليًا.
بينما يعتبر int، وfloat، وdouble،
وlong ،وbool، وأكثر من ذلك
هي أنواع بيانات فعلية.
فالسلسلة هى كذبة بيضاء
نوعًا ما كنا
نقولها لبضعة أسابيع ويتم
تنفيذها فقط في مكتبة CS50.
الآن كلمة سلسلة هي
شائعة للغاية في البرمجة.
تقريبًا كل مبرمج بالخارج سيعرف
ما الذي تعنيه عندما تقول سلسلة.
إنها ليست كلمة CS50، ولكن استخدامنا
لها في لغة C هو خاص بـ CS50.
لأنه في ذلك الملف
المسمّى cs50.h، بالإضافة إلى
إعلان دوالّ مثل
get_string وget_int وget_float
ومجموعة من الأشياء الأخرى،
لدينا أيضًا سطر خاص يقول،
إنشاء نوع بيانات يسمى سلسلة.

English: 
So something's going on
logically involving comparison,
because I'm using equal-equal, but maybe
I'm using it for the wrong data types?
I mean, it's clearly broken for strings.
So why might that actually be?
Well it turns out that
strings don't actually exist.
So a string that we know is
just a sequence of characters
or an array of characters
is not an actual data type.
int is, float is, double is,
long is, bool is, and even more
are actual data types.
String is kind of a
little white lie we've
been telling for a few weeks that's
implemented only in the CS50 library.
Now the word string is
super common in programming.
Like every programmer out there will
know what you mean when you say string.
That is not a CS50 word, but our
use of it in C is CS50-specific.
Because in that file
called cs50.h, in addition
to declaring functions like
get_string and get_int and get_float
and a bunch of other things, we
also have a special line that says,
create a data type called string.

Arabic: 
ولكن ما الذي يفعله حقيقةً
أو ما الذي يعنيه حقيقةً؟
حسنًا دعونا نمضي قدمًا ونفكر
فيما قد يحدث بالتفصيل
هنا.
لذلك إذا مضيتُ قدمًا ورسمتُ
البرنامج الذي قمنا
بتشغيله للتو، فيحصل ذلك البرنامج compare1
على سلسلة s من المستخدم،
ثم يحصل على سلسلة t من المستخدم،
ومن ثم يقارن بينهما.
إذن نعرف من الأسبوع الماضي ما هي السلسلة،
إنها مجرد مصفوفة.
إذن، عندما أشغّل ذلك السطر الأول من
التعليمة البرمجية وأحصل على سلسلة من المستخدم--
على سبيل المثال، Brian، فسأمضي
قدمًا وأرى B-R-I-A-N،
والتي نعرف من الأسبوع الماضي أنها تعتبر
بالفعل مصفوفة في الذاكرة قد تبدو
مثل هذه من الناحية التصويرية-- وهذه،
أيضًا، كذبة بيضاء نوعًا ما
فهناك شيء آخر.
الجمهور: الفارغ.
ديفيد مالان: نعم، الحرف الفارغ،
إذا جاز التعبير، و ul،
التي نكتبها عادةً فقط باستخدام
/0، وهو عبارة عن كل أصفار البت تحديدًا.
ويتضح، ربما تذكرون من
مصحح الأخطاء في وقت سابق، أنكم رأيتم هذا--
تلك هي الطريقة الأكثر تشفيرًا
للتعبير عن الحرف الفارغ،
/0.
فقط برامج مختلفة
تعرضها بطرق مختلفة.

English: 
But what does it actually do
or what does it actually mean?
Well let's go ahead and consider what
might be going on underneath the hood
here.
So if I go ahead and draw
the program that we just
ran, that program compare1
gets a string s from the user,
then gets a string t from the
user, and then compares them.
So we know from last week what
a string is, it's just an array.
So when I run that first line of
code and get a string from the user--
for instance, Brian, I'm going
to go ahead and see a B-R-I-A-N,
which we know from last week to actually
be an array of memory that might look
pictorially like this-- and this,
too, is a bit of a white lie,
there's something else.
AUDIENCE: The null.
DAVID MALAN: Yeah, the null
character, so to speak, and ul,
which we typically just write with a
backslash 0, which is just all 0 bits.
And it turns out, you might recall from
the debugger earlier, you saw this--
that's the even more cryptic way
of expressing the null character,
backslash 0.
Just different programs
display it in different ways.

English: 
So when I get_string and type in Brian,
this is what's allocated in memory.
And when I type Veronica, I
can see a V-E-R-O-N-I-C-A.
I'm going to get that
right preemptively.
Backslash 0.
That, too, is a chunk of memory,
which I'll draw like this.
1, 2, and split these up into
interval characters or bytes.
And recall from last time that these
bytes just come from my memory,
and that memory just has a bunch of
bytes in it, maybe millions or even
billions these days.
And so honestly, if you
just have that many things,
any human or computer can
certainly number them.
Like this is byte 1, 2, 3, 4.
So let's just assume for
the sake of discussion
that out of context of
my computer's hardware,
Brian just ended up at location 100, and
location 101, and 102, 103, 104, 105.
So this is the 100th
byte in my computer,
this is 105th byte in
my computer, and Brian
is using that many characters in total.
Veronica, she ended up somewhere else.

Arabic: 
إذن عندما أحصل على دالة get_string وأكتب Brian،
فهذا هو ما يتم تخصيصه في الذاكرة.
وعندما أكتب Veronica، يمكنني
رؤية سلسلة V-E-R-O-N-I-C-A.
سأحصل على تلك السلسلة
مباشرة على نحو استباقي.
/0.
تلك، أيضًا، هي مجموعة في الذاكرة،
سأرسمها على هذا النحو.
1، 2، وأقسّم هذه الأحرف إلى
أحرف أو وحدات بايت كفواصل.
وتذكرون من آخر مرة أن وحدات
البايت هذه تأتي تحديدًا من الذاكرة الموجودة لديّ،
وأن تلك الذاكرة لديها فقط مجموعة من
وحدات البايت بداخلها، ربما الملايين أو حتى
المليارات في الوقت الحالي.
إذن بصراحة، إذا كانت لديك
فقط تلك الأشياء العديدة،
يمكن لأي إنسان أو جهاز كمبيوتر
بالتأكيد ترقيمها.
على هذا النحو بايت 1، 2، 3، 4.
إذن دعونا نفترض فقط
بغرض النقاش
خارج سياق المكونات المادية
بجهاز الكمبيوتر الخاص بي،
أن Brian انتهى للتو عند الموقع 100،
والموقع 101، و102، 103، 104، 105.
إذن هذا هو البايت رقم 100
في جهاز الكمبيوتر الخاص بي،
وهذا هو البايت رقم 105 في
جهاز الكمبيوتر الخاص بي، وBrian
يستخدم تلك الأحرف العديدة في المجمل.
Veronica، انتهى بها المطاف في مكان آخر.

English: 
Maybe she ended up farther away just
because at location 900, 901, 902, 903,
904, 905, 906-- a lot more
memory, 907, and 908--
but you can see even more visually
now that the length of Brian's name--
strlen of Brian is what?
AUDIENCE: [INAUDIBLE]
DAVID MALAN: I hear five and I hear six.
The length of Brian's name--
Brian, how long is your name?
AUDIENCE: Five.
DAVID MALAN: OK, it is
definitively five characters, that
is the length of Brian's
name, but you have
to appreciate that in the computer,
Brian's five-character name does indeed
take up six bytes.
So both answers are kind of correct,
but the length of the string henceforth
is always the number
of actual characters.
The amount of space it takes up is
that plus 1 for the null character.
So you can actually see why Brian's
name takes up six bytes in this picture
rather than just the actual
length, which is five.
So when you call get_string
now, and when you call
get_string and get another string--

Arabic: 
ربما انتهى بها المطاف لأبعد من ذلك
فقط لأنه في الموقع 900، 901، 902، 903،
904، 905، 906-- ذاكرة أكبر
كثيرًا، 907، و908--
ولكن يمكنكك الرؤية بشكل مرئي أكثر
الآن أن طول اسم Brian--
strlen "طول السلسلة" الخاص بـ Brian ما هو؟
الجمهور: [INAUDIBLE]
ديفيد مالان: أسمع خمسة وأسمع ستة.
طول اسم Brian--
Brian، كم يبلغ طول اسمك؟
الجمهور: خمسة.
ديفيد مالان: حسنًا، إنه
بالتأكيد خمسة أحرف، هذا
هو طول اسم Brian،
ولكن يتعين عليك
أن تقدّر ذلك في الكمبيوتر،
فاسم Brian بطول خمسة أحرف في الواقع
يستهلك ست وحدات بايت.
إذن كلتا الإجابتين صحيحتان نوعًا ما،
ولكن طول السلسلة من الآن فصاعدًا
سيكون دائمًا هو عدد
الأحرف الفعلية.
مقدار المساحة الذي تستهلكه هو
ذلك الطول زائد 1 للحرف الفارغ.
إذن يمكنك بالفعل أن ترى لماذا يستهلك اسم Brian
ست وحدات بايت في هذه الصورة
بدلاً من الطول الفعلي
فقط، والذي هو خمسة.
لذلك عندما تطلق اسم get_string
الآن، وعندما تطلق اسم
get_string وget_string أخرى--

English: 
Brian and Veronica respectively,
what is actually being handed back?
A couple weeks ago, Erin
came up and she kind of like
handed me back a string, a
student's name from the audience.
On that piece of paper we
thought was the student's name.
But it's not.
It turns out that when a
function returns a value,
it can pretty much only return
a 1 byte or maybe 2 or 4 bytes.
It can't return an arbitrary number of
bytes, like six for Brian or 1, 2, 3,
4, 5, 6, 7, 8, 9-- it cannot
return 9 bytes for Veronica.
And if you even type a whole
paragraph or page of text,
it can't return all of that text,
it can only return a single value.
So to your instinct
earlier, what might actually
be getting returned by
get_string when the human has
typed in a name like Brian or Veronica?
AUDIENCE: [INAUDIBLE]
DAVID MALAN: The memory location.
Indeed, an integer, or as
you called it, a pointer,
which we'll introduce more
formally in just a moment.
So when get_string string
returns "Brian," quote-unquote,

Arabic: 
Brian وVeronica على الترتيب،
فما الذي تتم إعادة تسليمه بالفعل مجددًا؟
قبل أسبوعين، ظهرت Erin
وقامت نوعًا ما بإعادة
تسليم سلسلة إليّ، اسم طالب
من الجمهور.
اعتقدنا أن اسم الطالب
موجود على تلك الورقة.
لكن الأمر ليس كذلك.
يتضح أنه عندما تقوم دالة
بإرجاع قيمة،
فيمكنها فقط إلى حد كبير إرجاع
1 بايت أو ربما 2 أو 4 بايت.
ولا يمكنها إرجاع عدد مهول من وحدات
البايت، مثل ستة لـ Brian أو 1، 2، 3،
4، 5، 6، 7، 8، 9-- لا يمكنها إرجاع
9 وحدات بايت لـ Veronica.
وإذا قمتَ حتى بكتابة فقرة كاملة
أو صفحة من نص،
فلا يمكنها إرجاع كل ذلك النص،
ويمكنها فقط إرجاع قيمة واحدة.
إذن، وفقًا لغريزتك
فيما سبق، ما الذي
ربما يتم إرجاعه بواسطة
get_string عندما يكتب الشخص
اسمًا مثل Brian أو Veronica؟
الجمهور: [INAUDIBLE]
ديفيد مالان: موقع الذاكرة.
في الحقيقة، عدد صحيح، أو كما
تسمّونها، مؤشر،
وسنقوم بتقديمه بطريقة
رسمية بدرجة أكبر في غضون لحظات.
لذلك عندما تقوم السلسلة get_string
بإرجاع "Brian،" علامة اقتباس-إنهاء الاقتباس،

Arabic: 
فإنها في الواقع لا تقوم بإرجاع B-R-I-A-N
/0، إنما تقوم فقط بإرجاع 100.
وعندما تقوم السلسلة get_string بإرجاع Veronica،
فإنها لا تقوم بإرجاع اسمها،
وإنما تقوم بإرجاع 900.
وبذلك إذا أدركت
ذلك الآن، فعندما تقوم
بالسلسلة s يساوي يساوي t، فما هو السؤال الأكثر
اعتيادًا الذي تسأله فعليًا؟
نعم.
موقع الذاكرة وموقع
الذاكرة-- هل 100 تساوي 900؟
وبالطبع لا.
وذلك هو سبب أن اسم
Brian، واسم Veronica،
واسمي، واسم TJ-- كل كلمة
كتبتها كانت بالطبع مختلفة،
نظرًا لأن كل مُدخل كان ينتهي
في موقع مختلف في الذاكرة.
وحتى لو قمتُ بكتابة الكلمة نفسها مثل
David مرتين، فكلمة David الأولى كانت تنتقل إلى هنا،
وكلمة David الأخرى انتقلت إلى مكان آخر،
فكانتا ينتهي بهما المطاف
في موقعين مختلفين في الذاكرة.
ربما 100، ربما 900،
ربما مكان آخر،
لكن انتهى بهما المطاف في
موقعين مختلفين في الذاكرة.
إذن فالدالة يساوي-يساوي
تقارن بين القيم، ولكن تبًّا
لها إذا لم تكن تقارن القيم الخاطئة.
أجل؟
الحضور: حسنًا ماذا لو
استخدمت دالة char*s؟
ديفيد مالان: آه، إذن
سنعود لتلك النقطة.

English: 
it's actually not returning B-R-I-A-N
backslash 0, it is just returning 100.
And when get_string returns Veronica,
it's not returning her name,
it's returning 900.
And so if you realize
that now, when you do does
s equal-equal t, what question more
mundanely are you actually asking?
Yeah.
Memory location and memory
location-- does 100 equal 900?
And obviously not.
And so that is why Brian's
name, Veronica's name,
my name, TJ's name-- every word I
typed in was of course different,
because each input was ending up
at a different location in memory.
And even if I typed the same word like
David twice, one David was going here,
one David was going somewhere
else, they were ending up
at different memory locations.
Maybe 100, maybe 900,
maybe something else,
but they were ending up in
different locations in memory.
So equal-equals does
compare values, but dammit
if it isn't comparing the wrong values.
Yeah?
AUDIENCE: Well what if
you use some char*s?
DAVID MALAN: Ah, so
we'll come back to that.

Arabic: 
دعوني أعود لتلك
النقطة بعد لحظات.
في الواقع أن الدالة char* مرتبطة بطريقة معقدة.
المزيد حول ذلك في غضون لحظات.
أجل؟
الحضور: إذا قمت بإضافة
عددين صحيحين في الذاكرة--
ديفيد مالان: آها؟
الحضور: ألن يكونا في
مكانين مختلفين في الذاكرة؟
إذن ستقوم بالإرجاع--
لذلك تحتاج إلى قيمة مختلفة.
ديفيد مالان: حسنًا، سؤال جيد حقًا.
إذن انتظروا دقيقة، هذا المنطق نفسه أنني
أقوم بإرجاع عنوان شيء ما
ينطبق بالتأكيد على الأعداد الصحيحة كذلك
أو قيم النقطة الحرة floating كذلك؟
لأنني إذا كتبتُ
الرقم 50 مثلما
فعلتُ سابقًا، ذلك، أيضًا، في مكان ما
في الذاكرة-- مثل مربع في الذاكرة،
وذلك، أيضًا، يحتوي على عنوان
في مكان ما في الذاكرة،
ولكن يتضح، وذلك لأسباب
أشرتم إليها للتو، في الواقع،
أنه يتم إرجاع الأعداد الصحيحة ints كقيمها.
ويتم إرجاع الأحرف Chars كقيمها.
ويتم إرجاع القيم المنطقية Bools كقيمها.
ويتم إرجاع القيم الحرة Floats كقيمها.
بينما تكون السلاسل مختلفة.
حيث يتم إرجاع السلاسل Strings حسب عناوينها.
وتلك العناوين، كما يتضح، سيتم
تسميتها في نهاية المطاف
أحرف char*، والتي سنراها
في غضون لحظات.
إذن، كيف نمضي
ثم نصلح هذا بشكل جذري؟

English: 
Let me come back to
that in just a moment.
char* is actually intricately related.
More on that in a moment.
Yeah?
AUDIENCE: If you add
two integers in memory--
DAVID MALAN: Uh huh?
AUDIENCE: Wouldn't they be in
different places in memory?
So you would return--
so you need a different value.
DAVID MALAN: OK, really good question.
So wait a minute, this same logic that
I'm returning the address of something
surely applies to integers as well
or floating point values as well?
Because if I type in
the number 50 like I
did earlier, that, too, is somewhere
in memory-- like a box in memory,
and that, too, has an
address somewhere in memory,
but it turns out, for reasons that
you just alluded to, actually,
ints are returned as their values.
Chars are returned as their values.
Bools are returned as their values.
Floats are returned as their values.
Strings are different.
Strings are returned by their address.
And those addresses, it turns out,
are ultimately going to be called
char*'s, which we'll
see in just a moment.
So how do we go about then
fixing this fundamentally?

English: 
Like even if you have no idea how
to code this yet, just intuitively,
if I do actually want to delete--
if I do actually want to compare--
sorry.
OK.
If I do want to go ahead and compare
Brian and Veronica for equality,
what do I want to do intuitively?
I can't just compare their addresses.
What do I need to do?
Isolate the characters and
then do what with them?
AUDIENCE: [INAUDIBLE]
DAVID MALAN: Good.
Yeah, good instincts.
Use a for loop, use a while loop--
any kind of looping structure.
And intuitively, compare
the first characters,
and if they're different, well then we
know we don't have to go any further.
B is not a V, so surely
these names are different.
But what about in my case?
If it was David and David, you
would compare the first two.
D and D are the same.
Compare the second two,
A and A are the same.
V and V, I and I, D and D, and
then what am I going to hit last?
Null character.
And should I keep going
beyond the null character?
No.

Arabic: 
تقريبًا حتى لو لم تكن لديك فكرة عن كيفية
تشفير هذا بعد، فبديهيًا،
إذا كنت فعلاً أرغب في حذف--
إذا كنت فعلاً أرغب في مقارنة--
معذرةً.
حسنًا.
إذا أردت المضي قدمًا ومقارنة تساوي
Brian وVeronica،
فما الذي أرغب في فعله بديهيًا؟
فلا يمكنني مجرد مقارنة عنوانهما.
ماذا عليّ أن أفعل؟
أعزل الأحرف
ثم ماذا أفعل بها؟
الجمهور: [INAUDIBLE]
ديفيد مالان: جيد.
أجل، بديهيات جيدة.
استخدم تكرارًا حلقيًا من النوع for loop، استخدم تكرارًا حلقيًا من النوع while loop--
أي نوع من بنية التكرار الحلقي.
وبديهيًا، قارن
الأحرف الأولى،
واذا كانت مختلفة، فمن ثم نعرف
أننا لا يتعين علينا المضي إلى أبعد من ذلك.
B ليست V، لذلك بالتأكيد
فهذان الاسمان مختلفان.
لكن ماذا عن الحالة الموجودة لديّ؟
إذا كانت الحالة هي David وDavid، وكنت
ستقارن أول حرفين.
D وD متشابهان.
قارن التاليين،
A وA متشابهان.
V وV، ثم I وI، ثم D وD،
ثم ما الذي سأضغط عليه أخيرًا؟
حرف فارغ.
وهل يجب عليّ المتابعة
إلى ما بعد الحرف الفارغ؟
لا.

English: 
So this is the beauty of that
super simple design for a string.
Insofar as strings are identified by
their starting address, just the byte
at which they start,
you still need to know
how long they are, because otherwise
how do where one word begins and ends
and another word begins?
And so the simple decision we made
last week-- as did humans decades ago--
to terminate all strings with backslash
0 or all 0's is a super handy trick,
so that if I tell you
that Brian starts at 100,
you can infer that he ends where?
At byte number 105 or 104, if you will,
however you want to think about it,
because all you need
to do in linear time,
if you will, left or right, is
check-- backslash 0, backslash 0-- ah!
Backslash 0, now I know
how long Brian's name is.
So let's consider for a moment
this program called string length.
How does strlen actually work?
When you pass to strlen, a variable
containing a string, like Brian,

Arabic: 
إذن هذا هو جمال ذلك
التصميم الرائع البسيط للسلسلة.
بقدر ما يتم تحديد السلاسل حسب
عنوان بدايتها، فإن وحدة البايت فقط
التي تبدأ منها،
ستظل بحاجة لمعرفة
طولها، لأنه بطريقة تشغيل خلاف ذلك
فأين تبدأ الكلمة الواحدة وأين تنتهي
وأين تبدأ كلمة أخرى؟
وبالتالي فإن القرار البسيط الذي اتخذناه
الأسبوع الماضي-- كما فعل الناس منذ عقود--
لإنهاء جميع السلاسل باستخدام /0
أو كل الأصفار هو خدعة سهلة للغاية،
بحيث إذا قلت لكم
أن Brian يبدأ عند 100،
فيمكنكم استنتاج أين انتهى؟
عند رقم البايت 105 أو 104، إذا شئت،
أيًا كانت الطريقة التي ترغب في التفكير بها،
لأن كل ما عليك
القيام به في الزمن الخطي،
إذا أردت، يسارًا أو يمينًا، هو
التحقق-- /0، /0-- آه!
/0، الآن أعرف
مدى طول اسم Brian.
لذلك دعونا نفكر للحظة في
هذا البرنامج المسمى string length "طول السلسلة".
كيف يعمل طول السلسلة strlen فعليًا؟
عندما تنتقل إلى طول السلسلة strlen، متغير
يحتوي على سلسلة، مثل Brian،

Arabic: 
ما الذي يحتمل أن يفعله طول السلسلة strlen؟
الجمهور: [INAUDIBLE]
ديفيد مالان: بالضبط.
إنه ينظر إلى عنوان
ذلك الحرف الفارغ
وطرح عنوان البداية
وعنوان النهاية،
واستنتاج الفرق
وإرجاع
تلك القيمة فعليًا ناقص 1 من العد الإجمالي.
وعلى نحو ميكانيكي بدرجة أكبر،
سترون في غضون لحظات،
أنه ربما يفعل بالضبط
الشيء نفسه الذي فعلتُه،
وهو، هل هذا /0؟
هل هذا /0؟
هل هذا، هل هذا، هل هذا؟
سألتُ هذا السؤال خمس
مرات قبل أن أرى /0.
strlen هى مجرد دالة
كتبها بعض الأشخاص منذ سنوات
والتي يُحتمل أن يكون بها تكرار حلقي
بسيط من النوع for loop وشرط if،
ومن ثم فهذا كل شيء.
لأن هذا الشخص
أدرك حتى من قبل
أن نُشغّل كيفية تنفيذ
السلاسل فعليًا.
أي أسئلة أخرى؟
حسنًا، إذن دعونا
ننفّذ هذا بالفعل.
دعوني أمضي قدمًا إلى المحرر الموجود لديّ
هنا، وأقدم مثالاً آخر هنا
سأسميه compare2.
سأمضي قدمًا وأقوم
بتضمين cs50.h وأقوم بتضمين stdio.h،
ثم سأجعل
int main لاغيًا، وسأقوم

English: 
what is sterling probably doing?
AUDIENCE: [INAUDIBLE]
DAVID MALAN: Exactly.
It's looking at that
null character's address
and subtracting the start
address and the end address,
figuring out what the difference
is, and actually returning
that minus 1 the total count.
And more mechanically,
we'll see in a moment,
it's probably doing exactly
the same thing I did,
which is, is this backslash 0?
Is this backslash 0?
Is this, is this, is this?
I asked that question five
times before I saw backslash 0.
strlen is just a function
some human wrote years ago
that probably just has a simple
for loop and an if condition,
and then that's it.
Because that person
understood before we even
did how strings are
actually implemented.
Any questions then?
All right, so let's
actually implement this.
Let me go ahead and into my editor
here, and make one other example here
that I'm going to call compare2.
I'm going to go ahead and do
include cs50.h and include stdio.h,
and then I'm going to do
int main void, and I'm

English: 
going to quickly now grab my code
from before where I got strings
and I compared them, but I have
to obviously fix that comparison.
So here's my code from before.
I'm going to do this the right way.
I'm going to call a function called
compare_strings passing in s and t.
Because as you proposed,
we need to do some logic.
We don't have to pass it to
a function, but we could.
We could just do a
for loop here, but I'm
going to go ahead and implement
compare_strings as follows.
If I want to write a function that
returns a yes/no answer, what data type
should it return?
A bool.
So we've not necessarily
done this yet, but you
can return a bool just like you can
int or a char or something else.
I'm going to call this
function compare_strings.
It's going to take in one string
called a and another string called b,
but I could call those anything I want.
And now what's the
easiest thing to check?
If I pass two strings, a and
b, or Brian and Veronica,
what's the easiest question you can
ask and just immediately say, nope,
these are different?
String length, right?

Arabic: 
الآن بالتقاط التعليمة البرمجية الخاصة بي بسرعة
مما سبق حيث حصلت على سلاسل
وقمت بمقارنتها، ولكن يتعين
عليّ تثبيت تلك المقارنة.
إذن، ها هي التعليمة البرمجية الخاصة بي مما سبق.
سأقوم بتنفيذها بالطريقة الصحيحة.
سأسستدعي دالة اسمها
compare_strings تمر في s وt.
لأنه كما اقترحتم،
نحتاج لتنفيذ دالة منطقية ما.
لا يتعين علينا تمريرها إلى
دالة، ولكن يمكننا ذلك.
يمكننا فقط إجراء
تكرار حلقي من النوع for loop هنا، ولكنني
سأمضي قدمًا وأنفذ سلاسل
compare_strings على النحو التالي.
إذا رغبت في كتابة دالة تقوم
بإرجاع إجابة نعم/ لا، فما نوع البيانات
التي يجب أن ترجعها؟
تعبير منطقي bool.
إذن لا يتعين علينا بالضرورة
فعل ذلك بعد، لكن
يمكنك إرجاع قيمة منطقية bool مثلما يمكنك ذلك مع
عدد صحيح int أو حرف char أو أي شيء آخر.
سأسمي هذه الدالة باسم
compare_strings.
ستستوعب سلسلة
تسمّى a وسلسلة أخرى تسمى b،
لكن يمكنني تسميتهما بأي اسم أريده.
والآن ما هو أسهل شيء
يمكن التحقق منه؟
إذا قمت بتمرير سلسلتين، a
وb، أو Brian وVeronica،
فما هو أسهل سؤال يمكنك طرحه
وقوله تحديدًا على الفور، كلا،
هل هذان مختلفان؟
طول السلسلة، أليس كذلك؟

English: 
Like if the B-R-I-A-N is not of
the same length as Veronica's name,
we don't need to do any
logic whatsoever beyond that,
we can just quit and say false.
So let me just do that.
If the strlen of a does not equal
the strlen of b, you know what?
Let's just go ahead and return
false and get out of here.
OK, but now, if we get past
that gateway, so to speak,
that check, that question,
that Boolean expression,
now I have to compare things
character by character by character.
So I can do this in a bunch of ways,
but I like the suggestion of a for loop.
So for int i at 0, n for
efficiency-- actually,
let's do i is less than
the string length--
should I do the string length of a or b?
And it doesn't matter, right?
So let's go with a.
And frankly, had I
been smart early on, I
could have stored the value in
a variable and then reused it,
but we'll just keep going ahead for now.
Then i plus-plus, but I remember
from last time-- this is correct,
but this is not good design.
Why?
Yeah, I keep calling strlen again and
again, because remember, in a for loop,
this condition is
checked again and again

Arabic: 
كما لو أن B-R-I-A-N ليس
بنفس طول اسم Veronica،
فلسنا بحاجة للقيام بأي
دالة منطقية على الإطلاق أبعد من ذلك،
يمكننا فقط الخروج وقول خطأ.
إذن دعوني أفعل ذلك.
إذا كان طول السلسلة strlen لـ a لا يساوي
طول السلسلة strlen لـ b، أتعرفون ماذا إذن؟
دعونا نمضي قدمًا ونقوم
بإرجاع خطأ وإخراجه هنا.
حسنًا، ولكن الآن، إذا تجاوزنا
تلك البوابة، إذا جاز التعبير،
ذلك التحقق، ذلك السؤال،
ذلك التعبير المنطقي،
فيتعين عليّ الآن مقارنة الأشياء
حرفًا بحرف بحرف.
حتى يمكنني القيام بذلك بعدة طرق،
لكني أحب اقتراح تكرار حلقي من النوع for loop.
إذن بالنسبة للعدد الصحيح int i يصل إلى 0، حيث n
تشير إلى الفعالية-- ففي الواقع،
دعونا ننفّذ i أقل من
طول السلسلة--
فهل ينبغي عليّ تنفيذ طول السلسلة a أم b؟
لا يهم، أليس كذلك؟
إذن دعونا نختار a.
وبصراحة، لو كنتُ
ذكيًا في وقت مبكر،
لتمكنتُّ من تخزين القيمة في
متغير ثم إعادة استخدامها،
لكننا سنواصل المضي قدمًا الآن.
ثم i زائد-زائد، ولكن أتذكر
من آخر مرة-- أن هذا صحيح،
لكنه ليس تصميمًا جيدًا.
لماذا؟
نعم، أتابع تسمية طول السلسلة strlen مرارًا
وتكرارًا، لأنه لو تذكرون، في التكرار الحلقي من النوع for loop،
يتم التحقق من
هذا الشرط مرارًا

English: 
and again-- you're just
wasting your own time.
So let me go ahead and actually do this.
n or any variable equals the strlen
of a, then just compare i against n,
because now i is getting
incremented, but n is never changing.
So now let me go ahead and
implement this for loop.
So if-- how about the i-th character
of a does not equal the i-th character
of b, I can immediately conclude--
nope, these strings can't be the
same, because some letter, like a B,
is not the same as another, like a
V, or whatever letter we're actually
comparing.
And then I think that's it.
If I get through these
gauntlets of questions--
are yours lengths different?
Are your characters different?
And I still haven't said false,
what should I return by default?
Yeah.
Like if you make it through all of
those questions and all is well,
then D-A-V-I-D must indeed equal
D-A-V-I-D or whatever the user actually
typed in.
Now I'm not quite done yet.
When I've implemented a
function or a helper function

Arabic: 
وتكرارًا-- فأنتم
تضيعون وقتكم.
لذا دعوني أمضي قُدمًا وأقوم بهذا بالفعل.
n أو أي متغير يساوي طول السلسلة strlen
لـ a، ثم نقارن فقط i مع n،
لأن الآن i
تزيد، ولكن n لا تتغير أبداً.
إذن دعوني أمضي قدمًا
وأنفّذ هذا للتكرار الحلقي.
إذن لو-- ماذا لو أن الحرف صاحب الترتيب رقم i
لـ a لا يساوي الحرف صاحب الترتيب رقم i
لـ b، يمكنني أن أستنتج على الفور
كلا، لا يمكن أن تكون هاتان السلسلتان متشابهتين،
لأن حرفًا ما، مثل حرف B،
ليس متشابهًا كحرف آخر، مثل
حرف V، أو أي حرف نقوم
بمقارنته بالفعل.
ومن ثم أعتقد أن هذا كل شيء.
إذا تجاوزتُ
تحديات الأسئلة هذه--
فهل أطوال السلاسل لديك مختلفة؟
هل الأحرف لديك مختلفة؟
وأنا ما زلتُ لم أقل خطأ،
فما الذي ينبغي عليّ إرجاعه افتراضيًا؟
نعم.
كما لو أنك قمت بكل هذا من خلال جميع
تلك الأسئلة وسيكون كل شيء على ما يرام،
إذًا يجب أن يعادل د-ي-ف-ي-د بالفعل
د-ي-ف-ي-د أو أيًا كان ما كتبه
المستخدم بالفعل.
الآن أنا لم أنتهِ تمامًا بعد.
عندما انتهيتُ من تنفيذ
دالة أو دالة مساعدة

Arabic: 
كهذه، لأنها
تساعدني في القيام بعملي،
ماذا يجب أن أضيفه أيضًا إلى الملف؟
أوه؟
الجمهور: لديّ سؤال منطقي.
ديفيد مالان: بالتأكيد.
الجمهور: في جهاز الكمبيوتر، ألا يمكنك
فقط كتابة David بحرف D كبير
ثم david بحرف d صغير،
وستقوم بتشغيل [INAUDIBLE]،
فلن يتزامنوا لأن
أول حرف ليس
نفس الحرف.
ديفيد مالان: صحيح.
لذلك هذه ميزة،
وليست خطأ في الوقت الراهن.
برنامجي في هذه اللحظة
حساس لحالة الأحرف.
إذا كتبتُ DAVID وجميع الأحرف كبيرة،
فهذا يعني أنها سلسلة مختلفة
أزعم في الوقت الحالي
أن david مكتوبة كلها بأحرف صغيرة.
إذا كنت تريد تجاوز
حالة الأحرف الكبيرة والأحرف الصغيرة،
فيجب عليك جعل الأمر منطقيًا أكثر.
ولكن في الوقت الراهن هذا
هو قرار التصميم الذي أريده.
حسنًا.
ما الذي أحتاج إلى إضافته
إلى الملف أيضًا؟
نعم ، النموذج الأولي في الأعلى.
يمكنك النسخ واللصق حرفيًا--
هذه هي المرة الوحيدة التي يكون فيها النسخ واللصق
الشيء الصحيح للقيام به--
في الأعلى، ثم فاصلة منقوطة--
لا تقم بتنفيذ ذلك مجددًا.
لكنني أحتاج إلى ملف رأس واحد آخر.
أنا أستخدم دالة
ليست في cs50.h أو في stdio.h.
طول السلسلة؟
أين كان طول السلسلة؟
نعم، string.h.

English: 
like this, because it's
helping me do my work,
what else do I have to add to the file?
Oh?
AUDIENCE: I've got a logical question.
DAVID MALAN: Sure.
AUDIENCE: In a computer, couldn't you
just type in David with a capital D
and then david with a lowercase d,
you're going to run [INAUDIBLE],,
they're not going to sync because
your first character's not
the same character.
DAVID MALAN: Correct.
So this is a feature,
not a bug at the moment.
My program at the moment
is case-sensitive.
If I type in DAVID and all
caps, that is a different string
I claim for now than
david in all lowercase.
If you want to tolerate
uppercase and lowercase,
you're going have to add more logic.
But for now that's a design
decision that I intend.
All right.
What else do I need
to add to the program?
Yeah, the prototype at top.
You can literally copy and paste--
this is the only time copy and paste is
probably a legitimate thing to do--
at the top, and then semi-colon--
don't re-implement it.
But I do need one other header file.
I'm using a function that's
not in cs50.h or in stdio.h.
String length?
Where was string length?
Yeah, string.h.

English: 
So I just need this,
include string.h, save.
Now this I think is correct.
We'll see if I eat the word in a moment.
But realize that if you're
writing this code yourself,
like this is not a natural thing to
be writing a program in office hours
or at home in your dorm and just
getting it right the first time.
This is after like 20 years of doing
this, so realize we happen to be--
and I also have a cheat
sheet right here--
we happen to be doing
this correctly often,
but realize that's not
going to be the common case.
So with that reassurance
in mind, let's see
if I have to now take all
that back. make compare2.
OK-- phew.
20 years worked out.
So now I'm going to go
ahead and ./compare2.
Let's type in Brian,
let's type in Veronica.
Those are indeed still
different hopefully.
Now let's try myself, David and David.
Phew!
Those are the same.
And to your point, David in
capitalized and David in all lowercase,
different, but that's what I expect now.
Any questions on compare2?
Yeah?

Arabic: 
لذا أنا بحاجة فقط إلى هذا،
بما في ذلك string.h، حفظ.
الآن أعتقد أن هذا صحيح.
سنرى ما إذا كنت أتذكر الكلمة الآن.
ولكن اعلموا أنه إذا كنتم
تكتبون هذه التعليمات البرمجية بأنفسكم،
كهذه، فلن تكون كتابة برنامج في ساعات العمل
أو في المنزل في غرفة نومكم وإنهاء ذلك
بشكل صحيح من المرة الأولى أمرًا طبيعيًا.
لقد وصلت إلى هذا بعد 20 عامًا من القيام
بذلك، لذلك اعلموا أن هذا سيحدث--
ولدي أيضا ورقة غش
هنا--
سيحدث أن نقوم بهذا
بطريقة صحيحة غالبًا،
ولكن لابد أن تدركوا أنها
لن تكون مسألة مشتركة.
لذا لنضع ذلك في
الاعتبار، لنرى
إذا كان يجب عليّ الآن تناول كل ذلك
مجددًا. make compare2.
حسنًا-- بكل سرور.
لقد أثمرت تلك 20 عامًا.
لذا الآن سأمضي
قدمًا وأقوم بكتابة ./compare2.
دعونا نكتب في براين،
دعونا نكتب في فيرونيكا.
آمل أن هؤلاء في الواقع
ما يزالون مختلفين.
الآن دعونا نجرب، ديفيد وديفيد.
بكل سرور!
إنهم نفس الشيء.
والنقطة التي أشرت إليها، ديفيد
مكتوبة بالأحرف الكبيرة وديفيد بالأحرف الصغيرة،
مختلفين، لكن هذا ما أتوقعه الآن.
أي أسئلة على compare2؟
أجل؟

English: 
AUDIENCE: [INAUDIBLE]
DAVID MALAN: OK.
AUDIENCE: [INAUDIBLE] string
in the program and in general.
DAVID MALAN: OK.
AUDIENCE: Would that
still work [INAUDIBLE]
DAVID MALAN: If you were
to hard code the strings?
Short answer, yes,
that would still work.
If you for whatever reason did
not do this and using get_string,
but you did David, and here, for
instance, David, that would work too.
And whatever your error is, if you
can recreate it, just let us know.
AUDIENCE: It seems to be like a
string that would be increased
for a set that was [INAUDIBLE] only?
And it was having issues
in the little [INAUDIBLE]..
DAVID MALAN: I'd have to see it to
be sure, but happy to chat after.
All right, so let's see
if we can't now clean this
up just a little bit as follows.
Let me go ahead here and reveal
what it is that's actually going on.
So indeed, there is no
such thing as a string.
And indeed, as you
pointed out a moment ago,
it actually goes by a different name.

Arabic: 
الجمهور: [INAUDIBLE]
ديفيد مالان: حسنًا.
الجمهور: [INAUDIBLE] سلسلة
في البرنامج وبشكل عام.
ديفيد مالان: حسنًا.
الجمهور: هل ما يزال
هذا يعمل [INAUDIBLE]
ديفيد مالان: إذا كنت تشير
إلى التعليمات البرمجية الصلبة للسلاسل؟
إجابة مختصرة، نعم،
التي ما تزال تعمل.
إذا كنت لأي سبب
لم تقم بذلك واستخدمت get_string،
لكن يمكنك كتابة ديفيد، وهنا،
على سبيل المثال، ديفيد، هذا من شأنه أن يعمل أيضًا.
ومهما كان خطأك، إذا تمكنت من إعادة
إنشاؤه، فقط أخبرنا بذلك.
الجمهور: يبدو أنه مثل
سلسلة يمكن أن تزيد
لمجموعة كانت [INAUDIBLE] فقط؟
ولديها مشاكل
في [INAUDIBLE].
ديفيد مالان: يجب أن أراه
لأتأكد، وسأكون سعيدًا بالتحدّث بعد ذلك.
حسنًا، دعونا نرى
إذا لم نتمكّن الآن من تنظيف هذا
قليلاً فقط على النحو التالي.
دعوني أمضي قدمًا وأكتشف
ماذا يحدث في الواقع.
لذا بالفعل، لا يوجد
شيء مثل سلسلة.
وبالفعل، كما أشرت
سابقًا منذ قليل،
إنه يحدث في الواقع تحت اسم مختلف.

Arabic: 
السلسلة هي مجرد مرادف
لما يسمى بـ char*.
الآن ما الذي يعنيه ذلك؟
إذن char هو نفسه كما كان دائمًا.
إنه حرف واحد.
قد تعني النجمة في برنامج مكتوب في
C بالطبع الضرب،
لقد رأينا ذلك.
إن هذا استخدام آخر للنجمة.
عندما تراها بعد
نوع من البيانات مثل char،
هذا يعني أن نوع البيانات
في السؤال ليس مجرد char،
إنه عنوان char.
لذا فإن النجمة تعني فقط عنوان
نوع البيانات أيًا كان إلى اليسار،
وهذا هو، كما أشرتم
سابقًا، ما
سنبدأ في تسميته مؤشر.
يُعد المؤشر، لجميع النوايا
والأغراض، عنوانًا.
إنه مجرد كلمة طنانة
لوصف عنوان.
يشير نوع البيانات هذا هنا، char*، إلى أنني أريد
متغيرًا لا يُخزِّن char،
إنه يُخزِّن عنوان char.
الرقم 100، الرقم 900.
لكن هذا العنوان سنسميه
فقط مؤشر.
متغير المؤشر هو متغير
يُخزِّن عنوان شيء ما.
Char أو أنواع البيانات الأخرى أيضًا.

English: 
String is just a synonym
for what's called a char*.
Now what does that even mean?
So char is the same as it's always been.
It's a single character.
Star in a program written in C
could of course mean multiplication,
we have seen that.
This is another use of the star.
Whenever you see it after
a data type like char,
this means that the data type
in question is not just a char,
it's the address of a char.
So the star just means the address of
whatever the data type is to the left,
and this is, as you
pointed out earlier, what
we're going to start calling a pointer.
A pointer is, for all intents
and purposes, an address.
It's just a buzzword
to describe an address.
This data type here, char*, means I want
a variable that doesn't store a char,
it stores the address of a char.
The number 100, the number 900.
But that address is just
going to be called a pointer.
A pointer variable is a variable
that stores the address of something.
A char or even other data types as well.

English: 
So with that in mind, let me actually
quickly create compare3.c, paste this
in, and save it as compare3.c,
and let me take off, if you will,
those training wheels.
It turns out that when you
get a string with get_string,
it doesn't return a string,
per se, because again,
that word doesn't exist in C,
it actually returns a char*.
And when I call it again here and
return another string, it, too,
returns a char*.
Now technically the star
can have spaces around it.
Some people write it like this,
but the sort of right way to do it
or the default way should just be to
put the star next to the variable name
for clarity.
So I have to make a few other changes.
This should change too, because
there is no more string as of today.
I'm going to change this to a char*;
and then I also need to change it here,
char*; and then here, char*;
and that is actually it.
And honestly, the only reason we didn't
introduce this like two weeks ago
is because it just looks cryptic.
Like no one wants to program the first
time they're ever touching a keyboard

Arabic: 
لذلك مع أخذ ذلك في الاعتبار، دعوني في الواقع وبسرعة
أقوم بإنشاء compare3.c، ولصق هذا
وحفظه كـ compare3.c،
ودعوني أخرِج، إذا صح التعبير،
عجلات التدريب تلك.
يتضح أنه عندما تحصل على
سلسلة باستخدام get_string،
فهو لا يعيد سلسلة،
في حد ذاته، لأن مجددًا،
هذه الكلمة غير موجودة في C،
فهو يقوم فعليًا بإرجاع char*.
وعندما أكتبها هنا مجددًا
وأقوم بإرجاع سلسلة أخرى، فإنه يعيد
char* أيضًا.
الآن من الناحية الفنية، يمكن أن
توجد مسافات حول النجمة.
يكتب بعض الناس شيء كهذا،
ولكن نوعًا ما الطريقة الصحيحة للقيام بذلك
أو الطريقة الافتراضية يجب أن تكون فقط بوضع
النجمة بجانب الاسم المتغير
للتوضيح.
لذلك يجب أن أجري بعض التغييرات الأخرى.
يجب أن يتغير هذا أيضًا، لأنه
لا يوجد المزيد من السلاسل اليوم.
سأقوم بتغيير هذا إلى char*؛
ومن ثم أحتاج أيضًا إلى تغييره هنا،
char*؛ ثم هنا، char*؛
وهذا هو في الواقع.
وبصراحة، السبب الوحيد وراء عدم تقديمنا
هذا منذ أسبوعين تقريبًا
هو لأنه يبدو مشفرًا فقط.
لا أحد يريد أن يبرمج في أول مرة
يلمس فيها لوحة المفاتيح

Arabic: 
ويكتب تعليمة برمجية ويرى char*
ويقلق حول ما يعنيه ذلك،
إنها مجرد سلسلة من الناحية النظرية.
لكن التغيير الوحيد الذي أحتاج إلى إجرائه من الناحية الفنية
لإخراج عجلات التدريب تلك
هو فقط تغيير جميع إشارات
السلسلة كأنواع البيانات إلى char*.
وهذا يعني ذلك
فقط أتعلمون ماذا-- a؟
نعم إنها سلسلة، لكن من الناحية الفنية
إنها عنوان السلسلة.
أو بشكل أكثر دقة، هي عنوان
أول بايت من السلسلة،
مثل 100 لبراين أو 900
لفيرونيكا، وأنا لن
أخبرك أين تنتهي السلسلة
لأنك، كمبرمج،
يمكنك اكتشاف ذلك عن طريق كتابة
strlen أو باستخدام التكرار الحلقي فقط
واكتشاف مكان
خط مائل عكسي 0 في الواقع.
إذن هذه معلومات كافية
لتمريرها.
لذا إذا مضيت قدمًا الآن
وقمت بتحويل هذا برمجيًا، make compare3،
ومن ثم مضيت قدمًا وقمت بكتابة ./compare3،
لنمضي قدمًا ونكتب في براين
وفيرونيكا، وهم في الواقع
مختلفان.
الآن دعوني أمضي قدمًا واكتب في
ديفيد وديفيد، وهما في الواقع الشيء نفسه.
لذا عجلات التدريب متوقفة،
لا يوجد أي شيء كسلسلة،
من الآن فصاعدًا إنها char*.

English: 
and writing code and see char* and
need to worry about what that means,
it's just a string conceptually.
But the only change I technically need
to make to take those training wheels
off is just change all mentions
of string as data types to char*.
And that just means
that you know what-- a?
Yes it's a string, but more technically
it's the address of a string.
Or more precisely, it is the address
of the first byte of the string,
like 100 for Brian or 900 for
Veronica, and I'm not even
going to tell you where the string
ends because you, the programmer,
can figure that out by calling
strlen or just by using a loop
and figuring out where that
backslash 0 actually is.
So that is enough information
to pass it around.
So if go ahead now and
compile this, make compare3,
and then I go ahead and do ./compare3,
let's go ahead and type in Brian
and Veronica, those are
indeed still different.
Now let me go ahead and type in David
and David, those are in fact the same.
So the training wheels are off,
there is no such thing as string,
henceforth it's a char*.

Arabic: 
دعونا نمضي قدما ونأخذ استراحة
سريعة هنا لمدة خمس دقائق،
وسنعود ونتعمق في الأمر أكثر.
حسنًا.
لقد عدنا، دعونا نمضي
قدمًا ونقوم بتبسيط هذا الآن،
كما تعودنا.
إنها نوعًا ما مجموعة
من التعليمات البرمجية، ولكن أعتقد
أنه يمكننا أن نجعل هذا أكثر إحكامًا قليلاً.
ولكن بدلاً من كتابة
هذا يدويًا،
دعوني أمضي قدمًا وأفتح فقط
إحدى الأمثلة التي تم إعدادها مسبقًا
من اليوم، والتي توجد جميعها
على موقع الويب الخاص بالدورة، باسم compare4.
وسترون في compare4، هذا هو الأمر.
ليس لدي سوى دالة رئيسية هذه المرة.
لقد تخلصت من دالة
compare_strings الخاصة بي لأنه أتعلمون ماذا؟
يبدو أنني سأستخدم شيئًا بدلاً من ذلك.
ما هي الدالة التي من الواضح أنني قمت بنشرها؟
نعم، S-T-R-C-M-P، أو
قد ينطقها شخص ما،
فقط str compare أو strcmp.
لذا هذا، مثل strlen،
كما تسمى أيضًا بشكل مختصر،
وهي مجرد دالة
يتم الإعلان عنها بالفعل
في إحدى مكتباتنا المألوفة
في الأعلى، string.h،
ويتضح أنه إذا نظرنا في
صفحة man، إذا جاز التعبير،
عن طريق كتابة man strcmp، أو إذا
انتقلت إلى مرجع CS50 وقمت بالفعل
بالنظر إلى وصف أقل ارتياحًا
للدالة هناك،
هذه مجرد دالة
هدفها الوحيد في الحياة
هو مقارنة السلاسل من أجلك.

English: 
Let's go ahead and take a quick
break here for five minutes,
and we'll come back and dive in more.
All right.
So we are back, and let's go
ahead and simplify this now,
as our tendency has been.
It's kind of a bunch
of code, but I think
we can make this a little tighter.
But rather than type
this one out manually,
let me go ahead and just open
one of our pre-made examples
from today, which is all in the
course's website, called compare4.
And you'll see in compare4, that's it.
I only have a main function this time.
I've gotten rid of my compare_strings
function because you know what?
I seem to be using something instead.
What function did I apparently deploy?
Yeah, S-T-R-C-M-P, or
someone with pronounce it,
just str compare or strcmp.
So this, like strlen,
also succinctly named,
is just a function
that's actually declared
in one of our familiar
libraries up top, string.h,
and it turns out if you look
in the man page, so to speak,
by typing man strcmp, or if you
go to CS50 reference and actually
look at the less comfortable
description of the function there,
this is just a function
whose sole purpose in life
is to compare strings for you.

Arabic: 
ولكن الأمر مختلف قليلاً
في السلوك لأنه
أفضل قليلاً من
الذي كتبته للتو.
دعوني أقوم بتكبير هذا،
وسترون أن السطر 14 هنا، أنا
لا أعامله تمامًا بنفس الطريقة.
منطقى مختلف نوعًا ما.
ما الذي أتحقق منه فعليًا في
تعبيري المنطقي هذه المرة؟
الجمهور: [INAUDIBLE]
ديفيد مالان: نعم،
وهو غريب بعض الشيء.
أنا أتحقق وبشكل صريح-- إذا كانت قيمة
إرجاع strcmp يساوي-يساوي 0.
كما قلت للتو، إذا
كان compare_strings s فاصلة
t، لأنني كنت أتوقع مجددًا قيمة منطقية--
صحيح أم خطأ. ويعمل strcmp، غريب نوعًا ما،
بالطريقة المعاكسة.
يتضح أن strcmp
لا يعيد صحيح وخطأ.
إذا قمت بقراءة وثائقه، فهو
يعيد 0 إذا كانت السلاسل متساوية،
لكن بشكل سهل للغاية،
فهو يعيد قيمة موجبة
إذا كان من المفترض أن تأتي s قبل
t، ويعيد قيمة سالبة
إذا كان من المفترض أن تأتي s
بعد t أبجديًا.

English: 
But it's a little different
in behavior because it's
a little fancier than
the one I just wrote.
Let me zoom in on this, and
you'll see that line 14 here, I'm
not quite treating it in the same way.
My logic is ever so slightly different.
What am I actually checking for in
my Boolean expression this time?
AUDIENCE: [INAUDIBLE]
DAVID MALAN: Yeah,
which is a little weird.
I'm checking explicitly-- if strcmp's
return value equal-equal to 0.
Before I just said, if
compare_strings s comma
t, because I was expecting back a bool--
true or false. strcmp, kind of weird,
acts the opposite way.
It turns out that strcmp
doesn't return true and false.
If you read its documentation, it
returns 0 if the strings are equal,
but super conveniently, it
returns a positive value
if s is supposed to come before
t, and it returns a negative value
if s is supposed to come
after t alphabetically.

Arabic: 
لذا يتضح أنه يمكنكم استخدام strcmp
ليس فقط للمقارنة من أجل التعادل،
ولكن أيضًا لعدم التعادل--
أقل من أو يساوي--
أقل من أو أكبر من،
إذا جاز التعبير، أبجديًا،
أو في ترتيب ASCII، إذا جاز التعبير.
سيقارن حرف بحرف في الواقع
بقيم ASCII،
وسيُؤكد على أن
B تأتي بعد A،
وC بعد B، وهكذا.
لذا يمكنك بالفعل استخدام strcmp
إلى حد ما كقاموس،
أو لترتيب جهات الاتصال
في جهاز iPhone الخاص بك أو هاتف Android الخاص بك.
لذا القصة الطويلة باختصار،
هذه دالة يمكننا استخدامها،
لسنا مضطرين لإعادة ابتكار هذه
العجلة، وبالتالي، ليس لدينا المزيد من التعليمات البرمجية
حتى بعد هذا.
علينا فقط استخدامه بشكل صحيح،
وتوجد، هذه الوثائق
فهي بمثابة صديق لك.
لذا إذا قمت بتشغيل هذا البرنامج، فسيعمل
بنفس الطريقة بالضبط،
لذا دعوني أمضي قدمًا
وأقوم بتوضيح بعض الأخطاء.
يتضح أنه طوال هذا الوقت، كنت
كسولاً قليلاً ولم أفحص أخطائي--
فحص الأخطاء.
توجد مجموعة كاملة من الأشياء
التي يمكن أن تسوء في الأسبوع الأول من دورة CS50
ولم نتناولها،
لأنها من شأنها فقط
أن تنقد تعليماتنا البرمجية، وتجعلها أطول
وأقل إثارة للاهتمام ومتعة في الكتابة
ومفهومة بشكل أقل نوعًا ما.
ولكن اليوم، الآن نعرف
ماذا يحدث في الواقع،

English: 
So it turns out that you can use strcmp
not just to compare for equality,
but inequality--
less than or equal--
less than or greater than,
so to speak, alphabetically,
or in ASCII order, so to speak.
It will actually compare character
by character the ASCII values,
and that will make sure
that B comes after A,
and C comes after B, and so forth.
So you can actually use strcmp
to like sort a dictionary,
or to sort the contacts in your
iPhone or your Android phone.
So long story short, this
is a function we can use,
we don't have to reinvent this
wheel, and thus, we have no more code
even after this.
We just have to use it correctly,
and there, the documentation
is your friend.
So if I run this program it's
going to work exactly the same way,
but let me go ahead and
point out some flaws.
It turns out all this time, I've been
a little lazy with my error checking--
checking for errors.
There's a whole bunch of things
that can go wrong in week 1 of CS50
that we just kind of turn a blind
eye to, because it would just
bloat our code, make it longer and sort
of less interesting and fun to write
and less comprehensible.
But today, now that we know
what's actually going on,

Arabic: 
يمكننا أن نبدأ في طرح بعض
الأسئلة الإضافية
ونجعل تعليماتنا البرمجية
أقوى وأكثر متانة لذلك
لن يسوء شيء في الواقع.
يتضح أن، إذا قرأت وثائق
get_string في صفحة man
أو في مرجع CS50،
يتضح أن get_string
يعيد سلسلة-- أوه، ليس تمامًا.
إنه يعيد عنوان السلسلة.
أوه، ليس تمامًا.
إنه يعيد عنوان أول
بايت من السلسلة، من الناحية الفنية.
ولكن إذا حدث خطأ ما، فسيعيد
حرفًا خاصًا باسم فارغ.
وينبغي عدم الخلط مع NUL، فهو
يعيد عنوان خاص باسم فارغ--
اليد اليسرى لا تشبه
اليد اليمنى منذ عقود.
لذا فارغ، ف-ا-ر-غ، تعني فقط العنوان
0، الذي لا يجب أن يوجد في أي شيء على الإطلاق.
إنه مجرد وهم، عنوان غير صالح.
طالما يعيد get_string عنوان
السلسلة في الذاكرة،
مثل 100 لبراين أو 900
لفيرونيكا، إذا حدثت
مشكلة في get_string وحدث
خطأ بجهاز الكمبيوتر،

English: 
we can begin to ask some
additional questions
and make our code
stronger, more robust so
that nothing does, in fact, go wrong.
Turns out, if you read the documentation
for get_string in the man page
or in CS50 reference,
turns out get_string
does return a string-- uh, not really.
It returns the address of a string.
Uh, not really.
It returns the address of the first
byte of a string, technically.
But if something goes wrong, it returns
a special character called null.
Not to be confused with NUL, it
returns a special address called null--
left hand wasn't talking
to right hand decades ago.
So null, N-U-L-L, just means the address
0, which nothing should ever live at.
It's just a bogus, invalid address.
Insofar as get_string returns the
address of a string in memory,
like 100 for Brian or 900 for
Veronica, if get_string ever
runs into a problem and just something
goes wrong with the computer,

English: 
if it ever returns 0,
specifically 0, a.k.a.
null-- N-U-L-L, then you can detect
that something has gone wrong.
So to do that, and it's going
to get a little tedious,
but it's nonetheless
the right thing to do,
I need to be a little more defensive.
If s equals-equals null, otherwise
known as 0, otherwise known as 0x0,
but I'll write it
conventionally like this,
I'm going to go ahead and
return 1 as my exit code.
If t equals-equals null, I'm going to
go ahead and return 1 as my exit code,
or I could return 2 or 3--
I just need to return some
value to signal to the computer
that something went wrong,
but by default we'll
just return 1 whenever something
goes wrong, but if all went well,
I'm going to go ahead and return 0.
So recall again from last week, and
we didn't spend a huge amount of time
on this--
main itself can return values.
By default, ever since week 1,
if you don't return anything,
main is automatically and secretly
returning 0 for you because 0 is good.

Arabic: 
إذا أعاد 0،
على وجه التحديد 0، المعروف أيضًا بهذا الاسم.
فارغ-- ف-ا-ر-غ، ثم يمكنك اكتشاف
حدوث خطأ ما.
إذن للقيام بذلك، سيكون
الأمر مملاً قليلاً،
لكنه مع ذلك
الشيء الصحيح الذي ينبغي عمله،
أحتاج أن أكون أكثر دفاعية قليلاً.
إذا كان s يساوي-يساوي فارغ، وإلا يُعرف
باسم 0، وإلا يُعرف أيضًا باسم 0x0،
ولكنني سأكتبه
بطريقة تقليدية كهذا،
سأمضي قدمًا وأعيد
1 كتعليمات الخروج البرمجية الخاصة بي.
إذا كان t يساوي-يساوي فارغ، فسأمضي
قدمًا وأُعيد 1 كتعليمات الخروج البرمجية الخاصة بي،
أو يمكنني إعادة 2 أو 3--
أنا فقط بحاجة إلى إعادة القيمة
للإشارة إلى الكمبيوتر
أن هناك خطأ ما،
لكن بشكل افتراضي سنعيد
فقط 1 كلما حدث
خطأ، لكن إذا سار كل شيء بشكل جيد،
سأمضي قدمًا وأُعيد 0.
لذا لنتذكر مجددًا من الأسبوع الماضي،
ولم نقضي الكثير من الوقت
في هذا--
يمكن أن يعيد main القيم بنفسه.
بشكل افتراضي، منذ الأسبوع 1،
إذا لم تقم بإعادة أي شيء،
يعيد main بشكل تلقائي وسري
0 لك لأن 0 أمرٌ جيد.

Arabic: 
السبب وراء 0 هو وجود 0
واحد فقط في العالم، بالتأكيد،
ولكن يوجد عدد لا
حصر له على اليسار
وهناك عدد لا حصر له
على اليمين، سالب وموجب.
هذا عظيم، لأنه كما جربت
في الأسابيع القليلة الماضية،
بدا الامر وكأن هناك عدد لا حصر له
من الأشياء التي يمكن أن تسوء عندما
تكتب حتى أقصر البرامج.
وهذا يعني أن لدينا الكثير من
الأرقام التي يمكننا تعيينها لتعليمات الخطأ البرمجية،
إذا جاز التعبير.
الآن لا يهمني حقًا
ما هي تعليمات الخطأ البرمجية،
لذا سأتبنى
التقليد البشري في هذه اللحظة--
إذا حدث أي خطأ، فسيُعيد
أي شيء آخر بخلاف 0.
ولذا سأقوم بإعادة 1 هنا،
ولكن إذا حدث أي خطأ، سأعيد 0.
المغزى هنا أنه بإضافة
هذه السطور الثلاثة هنا وهذه السطور الثلاثة
هنا، سأتجنب ما
يُسمّى
بخطأ تجزئة أو
segfault. هل واجه أحدكم
هذا الخطأ المشفر؟
حسنًا.
إذن، عدد لا بأس به منكم، وإذا لم يكن لديكم
أي فكرة عما يعنيه ذلك،
ولكن بدءًا من اليوم سيكون أكثر قليلاً،
وخلال الأسابيع القادمة،
ستستوعبون ذلك أكثر.
يشير خطأ التجزئة إلى أنك
تطرقت إلى الذاكرة التي لا يجب أن تملكها.
أو حدث خطأ ما
ولم تكتشفه.

English: 
The reason for 0 is because there's
only one 0 in the world, obviously,
but there is an infinite
number to the left
and there's an infinite number of
the right, negative and positive.
That's great, because as you've already
experienced in the past few weeks,
it feels like there's an infinite number
of things that can go wrong when you're
writing even the shortest of programs.
So that means we have a lot of
numbers we can assign to error codes,
so to speak.
Now I don't really care
what the error codes are,
so I'm just going to adopt the
human convention at the moment--
if anything goes wrong,
returns anything other than 0.
And so I'm going to return 1 up here,
but if nothing goes wrong, return 0.
The point here is that by adding
these three lines here and these three
lines here, I'm going
to avoid what's called
a segmentation fault or
segfault. Did any of you
encounter this cryptic error?
OK.
So a decent number of you, and if you
probably had no idea what that means,
but starting today you will a bit
more, and in the weeks to come,
you'll understand even more.
Segmentation fault means you
touched memory you should not have.
Or something went wrong
and you did not detect it.

Arabic: 
إنه عبارة شاملة
للمشاكل المتعلقة بالذاكرة.
هذا يساعد على تجنب
تلك الأنواع من الأخطاء.
إنها ليست الطريقة الوحيدة،
ولكنها إحدى هذه الطرق.
لذا لنبدأ اليوم مع برامج
مجموعة المشاكل وأي شيء
تكتبه في الدورة، ستحتاج دائمًا
إلى التفكير بشأنه،
حتى لو رجعت وأضفته
في وقت لاحق، هل يمكن أن يسوء هذا؟
هل يمكن أن يسوء هذا؟
وأضف فقط بعض
ماذا لو إضافية وماذا لو أخرى
وتعامل مع هذه المواقف بحيث
لا يحدث خطأ ببرنامجك
أو segfault أو تفاجئ
الشخص الذي يستخدمه بالفعل.
حسنًا، دعونا نلقي
نظرة على مثال أخير،
لأنه وبصراحة هذا
ممل بعض الشيء.
سأمضي قدمًا وأفتح--
ويمكن العثور على هذا الملف
في compare5.c.
دعوني أمضي قدمًا وأحفظ هذا
حتى نحصل عليه-- compare5.c.
سأطرح مثال
مقارنة أخير.
سأقوم بحفظ هذا كـ compare6.c.
تبين أن البشر
مثل موجزاتهم.
وفارغ، لأنه
من الناحية الفنية العنوان 0،
يمكنك في الواقع أن تكون أكثر ذكاءً.
إذا لم يكن s وإذا لم يكن t طريقة كافية
للتعبير عن تلك الأشياء نفسها.

English: 
It's kind of a catch-all phrase
for memory-related problems.
This helps ward off
those kinds of errors.
It's not the only way,
but it's one such way.
So starting today with problems
set programs and anything
you write in the course, you
always want to be thinking about,
even if you go back and add
it later, could this go wrong?
Could this go wrong?
And just add some
additional ifs and else-ifs
and handle those situations so that
your program doesn't just crash on you
or segfault or surprise someone
who's actually using it.
All right, let's take a
look at one final example,
because frankly this
is a little tedious.
I'm going to go ahead and open up--
and this file can be
found in compare5.c.
Let me go ahead and save this
so that we have it-- compare5.c.
I'm going to make one
final comparison example.
I'm going to save this as compare6.c.
Turns out that humans
like their succinctness.
And null, because it is
technically the 0 address,
you can actually be a little clever.
If not s and if not t is a sufficient
way to express those same things.

Arabic: 
والسبب هو ما الذي تفعله إشارة التنبيه؟
علامة التعجب
في التعليمة البرمجية إذا كنتم تذكرون؟
إنها تعكس شيئًا ما.
لذا فكما لو أن هذا يقول، إذا كانت s ليست
0، كما هو معروف، إذا كانت s ليست فارغة، أو بالأحرى--
إذن-- أنا في حيرة الآن.
نعم.
فلو أني، كما قلتُ للتو، إذا كانت s،
فهي إذن عنوان صالح
ويجب أن أمضي قدمًا في عملي.
ولكن إذا لم تكن s أو
إذا كانت s فارغة، فأنا أريد
المضي قدمًا وإرجاع 1 لأنه
يوجد خطأ، وتوقف هنا أيضًا.
لذا في أي وقت تتحقق فيه
مما إذا كان هناك شيء ما يساوي قيمة فارغة،
فيمكنك جعلها أكثر إيجازًا
وذلك فقط بقول إذا لم تكن s؛ إذن فهي فارغة،
فيتم إرجاع 1.
إذا كانت فارغة، فيتم إرجاع 1.
إنها مجرد اختزال لبناء الجملة.
أُف!
كان علي التفكير بشأن هذا الواحد.
أي أسئلة؟
الجمهور: لماذا سيقوم [INAUDIBLE]
بتخزين بعض [INAUDIBLE]
ديفيد مالان: صحيح.
أنت تخزن عنوانًا،
ولكن إذا كان ذلك العنوان 0.

English: 
Because what does the bang do?
The exclamation point
in code if you recall?
It inverts something.
So like if this is saying, if s is not
0, a.k.a., if s not null, or rather--
if-- now I'm getting confused.
Yes.
If I had just said, if s,
then it's a valid address
and I should go on with my business.
But if it's not s or
if s is null, I want
to go ahead and return 1 because
there's an error, and down here too.
So any time you're checking
whether something equals null,
you can make it more succinct by
just saying if not s; if it's null,
return 1.
If it's null, return 1.
It's just syntactic shorthand.
Phew!
I had to think about that one.
Any questions?
AUDIENCE: Why does [INAUDIBLE]
will store some [INAUDIBLE]
DAVID MALAN: Correct.
You are storing an address,
but if that address is 0.

English: 
Saying if it's not 0, 0 is like
false, so not false means true,
and so it has the effect
of inverting the logic.
That's all.
Anytime you use a bang or exclamation
point, it changes a 0 to non-0--
AUDIENCE: [INAUDIBLE], but even--
I don't understand why [INAUDIBLE]
implies that it's [INAUDIBLE]..
DAVID MALAN: So you can
think about it this way.
If s-- previously we had this.
If s equals-equals null is like
saying if s literally equals 0.
And you can kind of think
of that informally as
if s doesn't have a valid pointer--
0 is not a valid point or it's
not a valid address by definition.
100 is valid, 900 is valid, 0 is not
valid just by a human convention.
So this is like saying, if s does
not have a value, that's valid.
So the way to succinctly
say that, if not s,
and it's just shorthand for that
is another way to think about it.
All right, so let's take a look
at a very different program,

Arabic: 
فرضًا إذا لم يكن 0، فإن 0
كأنها خطأ، لذلك فقول ليس خطأ تعني صحيح،
وبالتالي فإن لها تأثير
عكس الدالة المنطقية.
هذا كل شيء.
في أي وقت تستخدم فيه إشارة تنبيه أو علامة تعجب،
فإنها تغيّر 0 إلى non-0 "ليس صفرًا"--
الجمهور: [INAUDIBLE]، ولكن حتى--
لو أني لا أفهم لماذا يقوم [INAUDIBLE]
بتضمين أنه [INAUDIBLE]..
ديفيد مالان: حتى تتمكن من
التفكير فيه بهذه الطريقة.
إذا كانت s-- كان لدينا هذا سابقًا.
إذا كانت s تساوي تساوي قيمة فارغة
كأن نقول إذا كانت s تساوي 0 حرفيًا.
ويمكنك نوعًا ما التفكير
في ذلك بشكل رسمي كما
لو كانت s ليس بها مؤشر صالح--
0 ليست نقطة صالحة أو أنها
ليست عنوانًا صالحًا حسب التعريف.
100 صالحة، 900 صالحة، 0 غير صالحة
فقط حسب التقليد البشري.
إذن فهذا كقول، إذا كانت s
ليست لها قيمة، فهي صالحة.
إذن لنقل باختصار،
إذا لم تكن s،
وهو مجرد اختصار لذلك
فهي طريقة أخرى للتفكير في الأمر.
حسنًا، دعونا نلقي
نظرة على برنامج مختلف آخر،

English: 
but that reveals the same
kind of issue as follows.
I'm going to go ahead and
open up an example called
copy0, whose purpose in life
hopefully is to copy a string.
So notice that in my
program here, which I
wrote in advance, I'm getting a
string from the user on line 11,
and I'm storing it in a string called s.
I could change this to char*
now, but we know what it is.
And I'm going to go ahead and copy
the string's address from s into t.
And then I'm going to say, if the
length of t is greater than 0,
then go ahead and just
capitalize the first character.
So it's a little cryptic,
but you might have
done something kind of like this
with Caesar and with recent string
manipulation.
This is just making sure, do
I have at least one character?
And if so, first character is
t bracket 0, as you recall.
toupper is a function in
ctype.h from last week
that just capitalizes this letter.
So this one line of code, 19,
just capitalizes the first letter
in t, that's it.
And then at the very end we just print
out what s is and print out what t is.
That's all.
So this program just copies s into
t, capitalizes t, and that's it.

Arabic: 
لكن هذا يكشف
عن النوع نفسه من المشكلات على النحو التالي.
سأمضي قدمًا
وأفتح مثالاً يُسمّى
copy0، هدفه في الحياة
لحسن الحظ هو نسخ سلسلة.
لذلك لاحظ أنه في برنامجي
هنا، والذي
كتبتُه مقدّمًا، أحصل على سلسلة
من المستخدم في السطر 11،
وأقوم بتخزينها في سلسلة تسمى s.
يمكنني تغيير هذا إلى char*
الآن، ولكننا نعرف ما هو.
وسأمضي قدمًا وأنسخ
عنوان السلسلة من s إلى t.
ثم سأقول، إذا كان طول
t أكبر من 0،
فمن ثم يتم المضي قدمًا والقيام فقط
بجعل الحرف الأول كبيرًا.
لذا فهو مبهم قليلاً،
لكنك ربما فعلت
شيئًا من هذا القبيل مع
Caesar ومع التعامل الأخير
مع السلسلة.
هذا لمجرد التأكد، هل
لدي حرف واحد على الأقل؟
وإذا كان الأمر كذلك، فإن الحرف الأول هو
t قوس 0، كما تذكرون.
toupper دالة في
ctype.h من الأسبوع الماضي
تقوم فقط بجعل هذا الحرف كبيرًا.
إذن هذا السطر من التعليمة البرمجية، 19،
يقوم فقط بجعل الحرف الأول كبيرًا
في t، وهذا كل شيء.
ثم في النهاية نقوم فقط بطباعة ما يمثله
s وطباعة ما يمثله t.
هذا كل شيء.
إذن هذا البرنامج ينسخ فقط s إلى
t، ويجعل أحرف t كبيرة، وهذا كل شيء.

English: 
So let me go ahead and make copy0.
This is in our code from today.
So I'm going to do cd sc3, because I
already wrote it in that directory.
make copy0.
Went well. ./copy0.
Let's go ahead and type
in tj again in lowercase.
Enter.
Huh.
TJ, TJ-- both are capitalized.
All right, maybe it's just
a weird thing with initials.
So let's just do
Veronica, all lowercase.
Huh, that's definitely capital.
Let's do even more obvious
difference, Brian where
the B's really going to look different.
Yet I'm only capitalizing t.
Well let's consider what's
actually going on here.
In this case, when I'm getting a string
from the user, s and t, and I type in,
for instance, brian in all lowercase,
backslash 0, this, of course,
is just an array underneath the hood.
This is taking up six bytes here.
And when I store in s, s is a string.
So you know what?

Arabic: 
إذن دعوني أمضي قدمًا وأقوم بتنفيذ make copy0.
هذا في التعليمة البرمجية الخاصة بنا من هذا اليوم.
لذلك سأقوم بتنفيذ cd sc3، لأنني
كتبتُه بالفعل في هذا الدليل.
make copy0.
سار الأمر على ما يرام. ./copy0.
دعوني أمضي قدمًا وأكتب
tj مرة أخرى بالحروف الصغيرة.
إدخال.
ها.
TJ ،TJ-- كلاهما أصبحا كبيرين.
حسنًا، ربما إنه مجرد
شيء غريب مع الأحرف الأولى.
لذلك دعونا فقط نجرّب
Veronica، كلها أحرف صغيرة.
ها، هذا بالتأكيد حرف كبير.
دعونا نوضح فارقًا أكثر
وضوحًا، Brian حيث
إن حرف B سيبدو مختلفًا حقًا.
ومع ذلك أنا فقط أقوم بجعل حرف t كبيرًا.
حسنًا دعونا نفكر ماذا
يحدث هنا فعلاً.
في هذه الحالة، عندما أحصل على سلسلة
من المستخدم، s وt، وأقوم بالكتابة،
على سبيل المثال، brian بالأحرف الصغيرة كلها،
/0، وهذه، بالطبع،
مجرد مصفوفة غير ظاهرة.
وهذه تستهلك حوالي ست وحدات بايت هنا.
وعندما أقوم بالتخزين في s، فإن s عبارة عن سلسلة.
لذلك أتعرفون ما الأمر؟

Arabic: 
نحن لم نفعل هذا من قبل.
دعوني في الواقع أقوم بإنشاء متغير،
جزء من الذاكرة لـ s وأسمّيه s.
و لنفترض أن Brian موجود تحديدًا
حيثما كان من قبل--
100، و101، و102، و103، و104، و105.
لذا إذا كانت s تساوي get_string
وكانت get_string تقوم بإرجاع Brian،
فما الذي أكتبه في المربع المُسمى s؟
نعم، فقط 100، أليس كذلك؟
هذا كل ما سيحدث
طوال هذا الوقت
حتى رغم أننا لم نتحدث
عنه في هذا المستوى.
وفي الواقع، يتضح أنه-- يمكن استخدام المؤشر
فعليًا بشكل تصويري.
إذا كنت تفضل فعلاً أن تفكر
حول مؤشر كعنوان
أو نوعًا ما كخريطة تقودك
إلى مكانٍ ما، فبطريقة أخرى يمكن لأي شخص
عادةً أن يرسم
مؤشرًا-- لأنه بصراحة،
من يهتم حقًا أن
Brian موجود في العنوان 100؟
فمثل ذلك يعد طريقة ذات مستوى منخفض للغاية،
من مستوى برامج الأسبوع 0.
إنه يشير فقط هناك.
لذلك s هو مؤشر إلى
ذلك الجزء من الذاكرة.
يصادف أن يكون 100، أيًا كان، والسهم
هو الطريقة التي ستقوم
بها حرفيًا للإشارة إلى جزء الذاكرة إذا كنت
ترسم هذا على بعض الملاحظات.
لذا، فذلك، أيضًا، صحيح.

English: 
We didn't do this before.
Let me actually create a variable, a
chunk of memory for s and call it s.
And suppose Brian is just
where he was before--
100, 101, 102, 103, 104, and 105.
So if I do s equals get_string
and get_string returns Brian,
what do I write in the box called s?
Yeah, just 100, right?
This is all that's been
going on all this time
even though we didn't talk
about it at this level.
And actually, it turns out-- pointer
actually can be used pictorially.
If you actually prefer to think
about a pointer as being an address
or like kind of a map that leads
you somewhere, another way a human
would typically draw a
pointer-- because honestly,
who really cares that
Brian is at address 100?
Like that is way too low
level, that's week 0 stuff.
He's just pointing there.
So s is a pointer to
that chunk of memory.
It happens to be 100, whatever, the
arrow is how you would literally
point at the chunk of memory if you
were drawing this on some notes.
So that, too, is correct.

Arabic: 
لذلك تنشأ المشكلة هنا
مع ذلك السطر من التعليمة البرمجية.
عندما أحاول فعليًا نسخ s وتخزينها
في t، فكّر ماذا سيحدث.
الجانب الأيمن هو فقط قيمة
s، والتي تصادف أن تكون 100.
الجانب الأيسر هو مجرد
قول، يا كمبيوتر، أعطني
متغيرًا آخر، أول سلسلة،
وسمّها t.
إذن فذلك كقول، يا، كمبيوتر،
أعطني جزءًا آخر من الذاكرة،
وسمّه t، ثم قم بتخزين s فيه.
لكن ماذا يعني تخزين s؟
حسنًا ما قيمة s
في هذه المرحلة؟
إنها المؤشر إلى Brian،
أو إنها من الناحية التقنية--
سأكتب كليهما فقط من أجل الشمولية--
هي حرفيًا العدد 100.
لذا إذا جعلتَ t تساوي s، فهذا كقول
وضع 100 هناك أيضًا،
وبشكلٍ تصويري كقول هذا.
عند هذه النقطة من القصة،
عندما أنسخ s إلى t،
قام الكمبيوتر بنقلي حرفيًا.
إنه قام بنسخ s في t، ولكن ما هي s؟
إنها العنوان فقط.
إنها ليست B-R-I-A-N خط مائل عكسي
0، إنها مجرد العنوان.

English: 
So the problem arises here
with that line of code.
When I actually try to copy s and store
in t, think about what's going on.
The right-hand side is just s's
value, which happens to be 100.
The left-hand side is just
saying, hey computer, give me
another variable, first
string, and call it t.
So that's like saying, hey, computer,
give me another chunk of memory,
call it t, and then store s in it.
But what does it mean to store s?
Well what is s's value
at this point in time?
It's the pointer to Brian,
or it's technically--
I'll write both just for thoroughness--
it's literally the number 100.
So if you do t equals s, that is
like saying put 100 there too,
and pictorially that's like saying this.
So at this point in the
story, when I copy s into t,
the computer took me literally.
It did copy s into t, but what is s?
It's just the address.
It is not B-R-I-A-N backslash
0, it's just the address.

Arabic: 
لذا عندما أقول بعد ذلك، t
قوس 0 يحصل على toupper--
لذلك دعونا ننظر إلى هذا السطر من التعليمة البرمجية.
هذا السطر من التعليمة البرمجية
هنا الذي تم تظليله،
عندما أقول انتقل إلى الحرف صاحب الترتيب
رقم 0 في t وقم بتخزين
نسخة الأحرف الكبيرة من نفس ذلك الحرف،
فما عليك سوى اتباع الأسهم.
إذا سبق لك أن لعبت السلم
والثعبان وأنت طفل،
فأنت نوعًا ما كنت تتبع
الأسهم، لترى أين ينتهي بك المطاف.
t قوس 0 هو هذا الموقع
هنا، لأنه مرةً أخرى،
إذا كان هذا جزءًا من الذاكرة،
فإنه حسب الأسبوع الماضي يعتبر مصفوفة،
لذا يمكنك التفكير في هذا أيضًا
كقوس 0، هذا قوس 1،
هذا قوس 2، وهكذا دواليك.
لذلك إنها مجرد مصفوفة.
لذا يكون t قوس 0 عبارة عن حرف b
صغير، ودالة toupper لحرف b صغير،
بالتأكيد، تغيِّر حرف b الصغير هذا
إلى حرف B كبير. لكن الآن
كلاً من s وt لا يزالان يشيران
إلى نفس الجزء من الذاكرة،
لذا بالتأكيد فإن كلاً من s وt
سيمثلان Brian بأحرفٍ كبيرة،
أو TJ أيضًا في المثال الأول لديّ.
أي أسئلة على الجزء الذي انتهينا منه
للتو ولماذا حدث ذلك؟
حسنًا، إذن بديهيًا
ما هو الإصلاح؟

English: 
So when I then say, t
bracket 0 gets toupper--
so let's look at this line of code.
The one line of code
here that's highlighted,
when I say go to the 0th
character of t and store
the uppercase version of that same
character, you just follow the arrows.
If you ever played chutes
and ladders as a kid,
you just kind of follow the
arrow, see where you end up.
t bracket 0 is this location
here, because again,
if this is a chunk of memory,
per last week it's an array,
so you can also think of this as
being bracket 0, this is bracket 1,
this is bracket 2, and so forth.
So it's just an array.
So t bracket 0 is lowercase
b, and toupper of lowercase b,
of course, changes this
little b to a B. But now
both s and t are still pointing
at the same chunk of memory,
so of course s and t are both
going to be Bryan capitalized,
or TJ too in my first example.
Any questions then on what we
just did and why that happens?
All right, so intuitively
what's the fix?

English: 
Doesn't matter if you've
no idea how to code it,
like what do we have to do to
fundamentally copy a string, not
an address?
AUDIENCE: [INAUDIBLE]
DAVID MALAN: Create a new what?
AUDIENCE: Basically
create the [INAUDIBLE]..
DAVID MALAN: Yeah.
Create the same string
in a new chunk of memory.
What I really need to do
is allocate or give myself
a bunch of more memory
that's just as big as Brian,
including his backslash 0.
And then logically I just need to
copy every character into that.
So if I go back to my original
when it was a lowercase b,
I need to make a copy logically by
using a for loop or a while loop
or whatever you prefer--
B-R-I-A-N backslash 0, so that when I
copy the string and then store it in t,
It's not actually copying literally s.
And let's suppose that he ends up
at location 300 just arbitrarily--
just making up easy numbers.
t now stores 300, points here.
So when I execute this line in this
version of the story, t bracket 0

Arabic: 
ألا يهم ما إذا لم تكن لديك فكرة
عن كيفية تشفيره،
مثل ما يتعين علينا القيام به في الأساس
لنسخ سلسلة، وليس
نسخ عنوان؟
الجمهور: [INAUDIBLE]
ديفيد مالان: إنشاء أي جديد؟
الجمهور: في الأساس
إنشاء [INAUDIBLE]..
ديفيد مالان: أجل.
إنشاء نفس السلسلة
في جزء جديد من الذاكرة.
ما أحتاج القيام به فعلاً
هو تخصيص أو إعطاء
جزء من حجم أكبر من الذاكرة
لنفسي بحجم كبير مثل Brian،
تتضمن /0 الخاصة به.
ثم من الناحية المنطقية أحتاج
لنسخ كل حرف في ذلك الجزء.
لذا إذا رجعت إلى الأصل لديّ
عندما كان حرف b صغيرًا،
فأنا بحاجة لعمل نسخة منطقيًا
باستخدام تكرار حلقي من نوع for loop أو من نوع while loop
أو أيًا كان ما تفضله--
B-R-I-A-N خط مائل عكسي 0، لذلك فعندما
أنسخ السلسلة ثم أقوم بتخزينها في t،
فإنها لا تقوم بنسخ s حرفيًا.
ودعونا نفترض أنه ينتهي عند الموقع
300 فقط بشكل تعسفي--
ليكوّن فقط أرقامًا سهلة.
والآن t تخزن 300، وتشير إلى هنا.
لذلك عندما أقوم بتنفيذ هذا السطر
في هذا الإصدار من القصة، فإن t قوس 0

English: 
gets toupper, what am I actually doing?
I'm following a
different arrow this time
because I gave myself a different chunk
of memory, capitalizing this Brian,
thereby hopefully fixing the
bug, albeit verbally only.
So how do we do this in code?
We need to do exactly that.
We need to give ourself
some more memory,
so let's introduce one other
feature of C. In copy1.c,
we see the solution to this problem.
Notice at the top I'm doing things a
little lower level-- oop, surprise.
Notice in this version
of the code, copy1.c,
see I've started off almost the
same, but just to be super clear,
I'm just using char*.
I don't want any magic,
so there's no string,
there's no training wheels here.
But this logically is the
exact same as before--
plus the error-checking.
This line is new.
And it looks a little funky,
but let's see what's going on.
And this line of code
here, what am I doing?
The left-hand side, that's shorter,
let's start with the easier one.

Arabic: 
تحصل على toupper، فما الذي أفعله في الواقع؟
أقوم باتباع
سهم مختلف هذه المرة
لأنني أعطيت نفسي جزءًا مختلفًا
من الذاكرة، بجعل Brian هذا بأحرف كبيرة،
وبالتالي يتم إصلاح الخطأ لحسن الحظ،
وإن كان لفظيًا فقط.
إذن كيف نقوم بفعل ذلك في التعليمة البرمجية؟
نحن بحاجة للقيام بذلك تحديدًا.
نحن بحاجة لإعطاء أنفسنا
حيزًا أكثر في الذاكرة،
لذلك دعونا نقدم ميزة
واحدة أخرى للغة C. في دالة copy1.c،
نرى الحل لهذه المشكلة.
لاحظ بأعلى أقوم بأشياء
بمستوى أدنى قليلاً-- عذرًا، مفاجأة.
لاحظ في هذا الإصدار
من التعليمة البرمجية، copy1.c،
لقد بدأت تقريبًا نفس الشيء،
ولكن فقط لنكون واضحين تمامًا،
أستخدم فقط char*.
لا أريد أي سحر،
لذلك لا توجد أي سلسلة،
لا توجد أي عجلات تدريب هنا.
ولكن منطقيًا هذا
نفسه بالضبط كما في السابق--
إضافةً إلى التحقق من الخطأ.
هذا السطر جديد.
ويبدو غير تقليدي بعض الشيء،
لكن دعونا نرى ماذا يحدث.
وسطر التعليمات البرمجية هذا
هنا، ماذا أفعل؟
الجانب الأيسر، إنه الأقصر،
لنبدأ بالأسهل.

Arabic: 
Char* t، فقط بمصطلحات غير المتخصصين،
ماذا يعني هذا التعبير؟ char*؟
مرحبًا جهاز الكمبيوتر، يفعل ماذا؟
ما هذا؟
الجمهور: [INAUDIBLE]
ديفيد مالان: ليس تمامًا.
صياغة مختلفة.
مرحبًا جهاز الكمبيوتر، أعطني--
ليس تمامًا.
كونوا أكثر دقة؟
الجمهور: مصفوفة؟
ديفيد مالان: ليست مصفوفة
تمامًا، فقط هذا الجزء.
لذا دعوني أقوم بإخفاء كل هذا.
إذا لم تكن النجمة هناك--
لا يمكنني فعل هذا بشكل جيد.
لذا هذا-- نعم؟
الجمهور: حرف [INAUDIBLE]؟
ديفيد مالان: جيد، سأتناول ذلك.
لذا مرحبًا جهاز الكمبيوتر، أعطني
مؤشر إلى حرف.
أو حتى مستوى منخفض أكثر،
مرحبًا جهاز الكمبيوتر، أعطني
جزء من الذاكرة حيث يمكنني تخزين
عنوان الحرف به.
أعني، إنه شيء ممل.
ارسم مربع على الشاشة،
وسمّيه s-- أو بالأحرى،
t، لكن فقط أعطني
مسافة لمؤشر، كما قلت.
لذا هذا كل ما يفعله.
إنه يرسم مربعًا على الشاشة
ويطلق عليه t، وهو فارغ حاليًا.
الآن دعونا ننظر إلى الجزء
المرعب على الجانب الأيمن.
malloc، دالة جديدة اليوم.

English: 
Char* t, just in layman's terms,
what does that expression do? char*?
Hey computer, do what?
What's that?
AUDIENCE: [INAUDIBLE]
DAVID MALAN: Not quite yet.
Different formulation.
Hey computer, give me--
not quite.
Be more precise?
AUDIENCE: An array?
DAVID MALAN: Not quite
an array, just this part.
So let me hide all this.
If the star wasn't there--
I can't really do this very well.
So this-- yeah?
AUDIENCE: [INAUDIBLE] character?
DAVID MALAN: Good, I'll take that.
So hey computer, give me
a pointer to a character.
Or even more low level,
hey computer, give me
a chunk of memory in which I can
store the address of a character.
I mean, it is that mundane.
Draw a box on the screen,
call it s-- or rather,
call it t, but just give me
space for a pointer, as you said.
So that's all that's doing.
It's drawing a box on the screen and
calling it t, and it's currently empty.
Now let's look at the scarier
part on the right-hand side.
malloc, new function today.

English: 
Stands for memory allocates.
It's very cryptic-sounding, but it
just means give me a chunk of memory.
It says exactly what you
said in functional terms.
Then it just needs you
to answer one question--
OK, how much memory do you want?
How many bytes do you want?
And now maybe the math, even though
cryptic at first glance, makes sense.
Get the string length of s,
add 1, and then multiply it
by the size of a character.
And we've not seen this before.
sizeof literally does that.
It tells you how many bytes is a char.
Happens to be 1, and in
fact, that's defined.
So if we simplify this in C,
the char is always 1 byte,
so this is equivalent to
just multiplying by 1.
And obviously mathematically
that's a waste of time,
so we can whittle this
down to be even simpler.
I was just being thorough.
So now, hey computer, allocate
me this many bytes of memory.
Why is it plus 1?
AUDIENCE: You need the null character.
DAVID MALAN: I need that null character.
Brian is 1, 2, 3, 4, 5 as he said, but
I need the sixth for his null character,
and I just know that's
going to be there.
So at this point in the
story, what has happened?

Arabic: 
تشير إلى تخصيصات الذاكرة.
إنها تبدو مشفرة، ولكنها تعني
أعطني جزء من الذاكرة.
إنها تقول بالضبط ما تقوله
من الناحية الوظيفية.
ثم تحتاج فقط إلى
إجابة سؤال واحد--
حسنًا، كم من الذاكرة تريد؟
ما عدد وحدات البايت التي تريدها؟
والآن من المحتمل أن تبدو الرياضيات، على الرغم من
أنها مشفرة للوهلة الأولى، منطقية.
احصل على طول سلسلة s،
وقم بإضافة 1، ثم اضربه
في حجم الحرف.
ونحن لم نرَ هذا من قبل.
sizeof حرفيًا يفعل ذلك.
إنه يخبرك عدد وحدات البايت في char.
ويصادف أن يكون 1، وفي الواقع،
إنه محدّد.
لذا إذا قمنا بتبسيط هذا في لغة C،
فإن char دائمًا 1 بايت،
لذا هذا يعادل
فقط الضرب في 1.
ومن الواضح رياضيًا
أن هذا مضيعةً للوقت،
لذا يمكننا أن نضم هذا
حتى يكون أكثر بساطة.
أريد فقط أن أكون دقيقًا.
حتى الآن، مرحبًا جهاز الكمبيوتر، خصّص
لي هذا العدد الكبير من وحدات البايت من الذاكرة.
لماذا هو زائد 1؟
الجمهور: أنت بحاجة إلى الحرف الفارغ.
ديفيد مالان: أحتاج إلى هذا الحرف الفارغ.
براين هو 1، 2، 3، 4، 5 كما قال، ولكن
أحتاج السادس لحرفه الفارغ،
وأنا اعلم فقط أنه
سيكون هناك.
إذن في هذه المرحلة من القصة،
ما الذي حدث؟

Arabic: 
كل ما يفعله malloc هو
إعطائي هذا المربع من الذاكرة
والذي يحتوي على مساحة بها
عدد كبير من وحدات البايت في اسم براين.
ولكن لم تتم تعبئتها حتى الآن.
الآن أنا بحاجة إلى ملء وحدات البايت
تلك منطقيًا مع اسم براين الفعلي.
لذا إذا قمنا بالتمرير إلى أسفل
إلى التكرار الحلقي الخاص بي،
يمكننا بالفعل نسخ السلسلة
إلى تلك المساحة.
وهو طويل بعض الشيء، التعبير،
لكن لا شيء جديدٌ هنا.
قم بتهيئة i إلى 0، n إلى طول s،
i أقل من أو يساوي n--
سنعود إلى ذلك، i++.
لذا هو مجرد معيار جيد للتكرار الحلقي.
ثم انسخ الحرف i من
s إلى الحرف i من t.
الشيء الوحيد الذي يجعلني عصبيًا
قليلاً بصراحة هو هذا الشيء هنا.
كما أشعر في كل مرة
نقوم بفعل شيء أقل من أو يساوي،
نقوم بإنشاء خطأ مثل الأسبوع الماضي.
لكن هذا صحيح، لماذا؟
لماذا أريد أن أنتقل إلى الأعلى
وخلال طول هذا؟
الجمهور: هو الحرف
الفارغ الذي يضيف--
ديفيد مالان: بالضبط.
بسبب الحرف الفارغ.

English: 
All that malloc does is it
gives me this box of memory
containing room for as many
bytes are in Brian's name.
But it doesn't fill them just yet.
Now I need to logically fill those
bytes with Brian's actual name.
So if we scroll down
to my for loop here,
we can actually copy the
string into that space.
And it's a little long, the
expression, but nothing new here.
Initialize i to 0, n to the length
of s, i is less than or equal to n--
we'll come back to that, i++.
So it's just a pretty standard for loop.
Then copy the i-th character of
s into the i-th character of t.
The only thing that's making me a little
nervous honestly is this thing here.
Like I feel like every time
we do less than or equal to,
we create a bug like last week.
But this is correct, why?
Why do I want to go up to and
through the length of this?
AUDIENCE: Is it the null
character that adds--
DAVID MALAN: Exactly.
Because of the null character.

English: 
I actually don't want to stop at the
strlen of s, so I could change this.
If you're just more comfortable
using less than, because you just
got your mind wrapped around why we do
that in the first place, that's fine,
we just need to do this instead.
So this is mathematically-- if you
go to strlen plus 1, the same thing
as not doing that math but
just going one step further.
Just whatever you want to
think about it is fine.
However you want to
think about it is fine.
OK, and then lastly, just a
quick check, is the length
of t at least one or more characters?
Because otherwise there's
nothing to capitalize, and if so,
go ahead and do it.
So if I now run this example,
make-- oop, let me save it.
make copy1, that compiled.
./copy1, now let's type in tj,
tj in lowercase comes back,
but now t is capitalized.
And let's go ahead and do Brian's name
in all lowercase, only one of them
is now capitalized.
So does that make sense
what's now happened?
All right.
So where can we go with this?

Arabic: 
أنا في الواقع لا أريد أن أتوقف عند
strlen من s، حتى أتمكن من تغيير هذا.
إذا كنت مرتاحًا أكثر
باستخدام أقل من، لأن عقلك فقط
لا يستوعب لماذا قمنا بهذا
في المقام الأول، هذا جيد،
نحن بحاجة فقط للقيام بذلك بدلاً من ذلك.
لذا هذا رياضيًا-- إذا انتقلت
إلى strlen زائد 1، نفس الشيء
حيث لا تقوم بتلك العملية الحسابية ولكن
الانتقال خطوة أخرى فقط إلى الأمام.
فقط أيًا كان ما تريد التفكير
فيه على أنه أمرٌ جيد.
وبالكيفية التي تريد التفكير
بها على أنه أمرٌ جيد.
حسنًا، وأخيرًا، فقط
فحص سريع، هل طول
t على الأقل حرف واحد أو أكثر؟
لأنه بخلاف ذلك لا يوجد
شيء ليتم بتكبيره، وإذا كان الأمر كذلك،
أمضي قدمًا وقم بذلك.
لذا إذا قمت الآن بتشغيل هذا المثال،
make-- عذرًا، دعوني أحفظه.
make copy1، الذي تم تحويله برمجيًا.
./copy1، الآن دعونا نكتب tj،
tj بأحرف صغيرة،
ولكن الآن تم تكبير t.
ودعونا نمضي قدمًا ونكتب اسم براين
بأحرف صغيرة، وتم تكبير
واحد منهم الآن.
لذا هل يبدو هذا منطقيًا
ماذا يحدث؟
حسنًا.
إذن إلى أين قد يؤدي هذا الأمر؟

English: 
Well it turns out-- let me
open up one final example here,
because honestly, that's
incredibly tedious,
and no one's ever going to
want to copy strings if you
have to go through all of that work.
Turns out that store copy exists.
So when in doubt, check the man page.
When in doubt, check CS50 reference.
Does the function
exist somewhere related
to some keywords you have in mind?
Like string copy, see
if something comes back.
And indeed, we've had strlen, we've
had strcmp, we now have strcpy,
and if you read the documentation, this
is deliberately reversed like this.
The destination is this variable,
the source or the origin string
is this one, and it copies
from one end to the other,
and then I don't need that for loop.
It just saves me a few lines of code.
All right.
So let's take off one other detail here.
Oh, and you'll notice, actually,
let me make one fix, one fix here.
It turns out that what I'm
doing here is a little lazy.
It turns out that malloc
does have an opposite.
So anytime you allocate
memory, technically
you should also be freeing that memory.

Arabic: 
حسنًا يتضح أنه-- دعوني
أفتح مثال واحد أخير هنا،
لأنه بصراحة، هذا
الأمر ممل بشكل لا يصدق،
ولا أحد يريد
نسخ سلاسل إذا كنت
مضطرًا إلى المرور خلال كل هذا العمل.
يتضح أن نسخة التخزين هذه موجودة.
لذلك في حالة الشك، تحققوا من صفحة man.
في حالة الشك، تحققوا من مرجع CS50.
هل توجد الدالة
في مكان ما مرتبط
ببعض الكلمات الرئيسية التي تتذكرونها؟
مثل نسخ سلسلة، لنرى
إذا استرجعت شيئًا ما.
وبالفعل، كان لدينا strlen، وكان لدينا
أيضًا strcmp، والآن أصبح لدينا strcpy،
وإذا قرأت الوثائق، فإن هذا
يتم عكسه بشكل متعمد هكذا.
الوجهة هي هذا المتغير،
المصدر أو سلسلة المنشأ
هي هذه السلسلة، وتُنسخ
من نهاية إلى أخرى،
ومن ثم أنا لست بحاجة إلى هذا من أجل التكرار الحلقي.
إنه فقط يوفر لي بعض الأسطر من التعليمات البرمجية.
حسنًا.
لذا دعونا نأخذ تفصيلاً آخر هنا.
أوه، وستلاحظوا، في الواقع،
دعوني أقم بإصلاح واحد هنا، إصلاح واحد هنا.
يتضح أن ما أقوم به
هنا يُعد كسلاً بعض الشيء.
يتضح أن malloc
لديه مقابل له.
لذلك في أي وقت تقوم بتخصيص
ذاكرة، من الناحية الفنية
يجب عليك أيضًا تحرير تلك الذاكرة.

English: 
And so C allows you to ask the computer
for as much memory as you want,
but if you never give it back, have you
ever experienced on your own Mac or PC,
like after your computer's
been running a while
or using some new or bloated
program like a browser,
it gets slower and slower and slower?
And in the worse case it just
freezes or hangs or something?
It is quite possible that that
program simply-- was made by humans,
of course--
just has a memory leak.
So some human wrote one or more
lines of code that uses malloc
or some equivalent in another language
that just kept allocating memory
for the user's input.
You're visiting one web
page, two web pages,
that requires memory
whatever the program is.
And if that human never calls the
opposite of allocate-- deallocate,
otherwise known as free, you're
never giving the memory back
to the operating system.
So it gets slower and slower because
it's running lower and lower and lower
on memory, and it might have
to move some things around
to make room for things, that's
what's called a memory leak.
And so indeed, in this program, I should
actually improve this a little bit.
If I go back into this version
here and line 18, recall,

Arabic: 
وتتيح لك C أن تطلب من الكمبيوتر
الحصول على أكبر قدر من الذاكرة كما تريد،
ولكن إذا لم تعيدها، هل قمت بتجربة
ذلك من قبل على جهاز Mac أو جهاز الكمبيوتر الشخصي الخاص بك،
بعد تشغيل الكمبيوتر
لبعض الوقت
أو استخدام بعض البرامج الجديدة
أو الضخمة مثل المتصفح،
فأنه يصبح أبطأ وأبطأ وأبطأ؟
وفي أسوأ الحالات، فأنه يتجمد
فقط أو يتوقف أو شيء من هذا القبيل؟
من المحتمل جدًا أن هذا البرنامج
ببساطة-- قد تم إنشاؤه بواسطة الإنسان،
بالطبع--
فقط لديه تسرب في الذاكرة.
لذا كتب بعض الأشخاص سطر واحد أو أكثر من
التعليمات البرمجية التي تستخدم malloc
أو ما يعادلها في لغة أخرى
والتي تعمل على تخصيص الذاكرة
لمُدخل المستخدم فقط.
تقوم بزيارة صفحة
ويب واحدة، صفحتي ويب،
والتي تتطلب ذاكرة
أيًا كان البرنامج.
وإذا لم يطلب الشخص
عكس التخصيص-- إعادة التخصيص،
والمعروف أنه مجاني، فلن
تستعيد الذاكرة مجددًا
إلى نظام التشغيل.
لذلك يصبح أبطأ وأبطأ لأنه
يُتم تشغيله مع حدوث انخفاض في
الذاكرة بشكل متكرر، وقد يتعين
نقل بعد الأشياء
لإفراغ مساحة لأشياء، وهذا
ما يسمى بتسرب في الذاكرة.
وفي الواقع، في هذا البرنامج، يجب أن
أحسّن هذا قليلاً بالفعل.
إذا عدت إلى هذا الإصدار
هنا والسطر 18، تذكرون،

English: 
I allocated this memory
just to make my copy,
the very last thing I should
actually do in this program
is this line here-- free.
You don't have to tell the computer
how many bytes you want to free,
it will remember for you so long as
you're just pass in the pointer--
the variable that's storing the
address of the chunk of memory
that you allocated.
All right.
So let's now see why we've
been using get_string,
since it's not just to
kind of simplify the code,
it's also to defend against
some very easy problems.
Here is a program called scanf0--
scanned formatted text, another
arcane-sounding function,
but it's pretty straightforward.
This program simply gets in
from the user using scanf.
Up until now for the past three
weeks, you've used get_int.
So this is an alternative
to get_int that you could
have started using a few weeks ago.
Give me an int called x,
print out x colon whatever--
that's just the prompt to the user.

Arabic: 
أنني قمت بتخصيص هذه الذاكرة
فقط لصنع النسخة الخاصة بي،
الشيء الأخير الذي يجب
فعلاً أن أقوم به في هذا البرنامج
هو هذا السطر هنا-- free.
ليس عليك إخبار الكمبيوتر
كم بايت تريد تحريره،
إنه سيتذكر هذا من أجلك طالما
تمر فقط على المؤشر--
المتغير الذي يُخزِّن
عنوان جزء من الذاكرة
الذي قمت بتخصيصه.
حسنًا.
لذا دعونا الآن نرى لماذا
نستخدم get_string،
حيث أنها ليست فقط
نوعًا من تبسيط التعليمات البرمجية،
إنها أيضًا تعمل على حل
بعض المشاكل السهلة جدًا.
ها هو برنامج يُسمى scanf0--
النص المنسق الممسوح ضوئيًا،
دالة أخرى غامضة،
لكنها مباشرة للغاية.
يُفتح هذا البرنامج ببساطة
من المستخدم باستخدام scanf.
حتى الآن وعلى مدار الثلاثة أسابيع الماضية،
كنتم تستخدمون get_int.
لذا هذا بديل
لـ get_int الذي
بدأتم استخدامه منذ بضعة أسابيع.
أعطني int تُدعى x،
اطبع x نقطتين أيًا يكن--
إنه مجرد مُحث للمستخدم.

Arabic: 
scanf %i, &x;، أيًا كان هذا،
ثم اطبع قيمة x باستخدام %i.
إذًا ما الذي يحدث هنا؟
الآن يمكننا أن نبدأ في إدراك
ما يدور حول get_int
في الواقع.
هذا هو get_int بفعالية.
إذا نظرت في الواقع إلى تعليمات المصدر البرمجية
لـ get_int، ستجدها أفضل قليلاً.
ولكن في الأساس، ما يفعله get_int
أنه يعلن عن متغير يُسمى x،
ولا يضع أي شيء
هناك، لأن هذا
من المفترض أن تفعله أنت، كإنسان.
ثم يطلب منك أيًا كانت
السلسلة التي تمررها إلى get_int،
لذا هما أول سطرين.
وهذا هو المظهر الغريب الوحيد.
يُعد Scanf هو مقابل printf.
ما زلتم تستخدمون سلسلة
منسقة-- %s، أو %i، أو%f أو أيًا كان،
ولكن لن تقوموا بإخراج هذا،
ستقومون بإدخال هذا من
لوحة المفاتيح.
و %x هو مقابل--
هو الرمز الخاص في C الذي يقول،
امضي قدمًا واحصل لي على عنوان x.
لذا لا تقم بالتمرير في x،
أعطني عنوان x.
الآن، لماذا هذا؟
سنرى، ولكن هذه هي الطريقة
حيث يمكنك إخبار الكمبيوتر،
لقد قمت بعمل متغير لك
يُسمى x، وهو يوجد هنا.

English: 
scanf %i, &x;, whatever that is, and
then print out x's value using %i.
So what's going on here?
Now today we can actually start to wrap
our minds around what get_int actually
does.
This is effectively get_int.
If you actually look at the source code
for get_int, it's a little fancier.
But in essence, what get_int does
is it declares a variable called x,
and it doesn't put anything
there, because that's
supposed to come from you, the human.
It then prompts you for whatever
string you pass to get_int,
so those are the first two lines.
And this is the only weird-looking one.
Scanf is like the opposite of printf.
You still use a formatted
string-- %s, %i, %f or whatever,
but you're not going to output this,
you're going to input this from
the human's keyboard.
And %x is the opposite of--
is the special symbol in C that says,
go ahead and get me the address of x.
So don't pass in x, give
me the address of x.
Now why is that?
We'll see, but this is the way
where you can tell the computer,
I've made a variable for you
called x, here is where it is.

English: 
It's a treasure map that leads you
to x, go put a value here for me.
And so the end result is that we
do, in fact, end up getting an int.
If I do make scanf0, and then
./scanf0, I'll type in 42, all right?
It's not an interesting program,
it just spits back out what I got,
but that's literally all
that get_int, of course,
is doing if you then
print out the value.
So if I stipulate this is correct, this
is how you get an int from the user,
but honestly, the reason we don't do
this in week 1 of the course is like,
my God, we just took the fun out of even
getting a simple number from the user
by using these lines of
code and whoever knows
what this symbol is-- we don't
want you to think about that,
we want you to just get an int.
But today those training
wheels are off, but we're
going to run into a problem super fast.
Let's try the same thing with a string.
If I were to do this, you would
think that the result is the same.
Or let's just do it as char*.
But there's going to be one tweak.
If I go ahead and give myself space
for the address of a character,

Arabic: 
إنها خريطة كنز تقودك
إلى x، اذهب لتضع قيمة هنا من أجلي.
وبالتالي فإن النتيجة النهائية هي أننا،
في الواقع، نحصل على int.
إذا قمت بإجراء scanf0، ثم
./scanf0، سأكتب في 42، حسنًا؟
إنه ليس برنامجًا مثيرًا للاهتمام،
إنه يعيد لي فقط ما حصلت عليه،
لكن هذا حرفيًا كل
ما يقوم به get_int، بالطبع،
إذا قمت بعد ذلك
بطباعة القيمة.
لذلك إذا أشرت إلى أن هذا صحيح، فإن هذه
هي كيفية حصولك على عدد صحيح من المستخدم،
ولكن بصراحة، السبب في أننا لم نقم
بهذا في الأسبوع 1 من هذه الدورة هو،
يا إلهي، لقد فقدنا المتعة
في الحصول على رقم بسيط من المستخدم
باستخدام هذه السطور من
التعليمات البرمجية ومَن يعرف
ما هو هذا الرمز-- نحن لا نريد
منك أن تفكر في ذلك،
نحن نريد فقط أن تحصل على عدد صحيح.
لكن اليوم هذه العجلات التدريبية
متوقفة، ولكننا
سنكتشف المشكلة بأسرع ما يمكن.
دعونا نحاول نفس الشيء مع سلسلة.
إذا كنت سأقوم بذلك، قد تعتقدوا
أن النتيجة هي ذاتها.
أو دعونا نفعل ذلك فقط كـ char *.
لكن سيكون هناك تغييرًا واحدًا.
إذا مضيت قدمًا وأعطيت نفسي مساحة
للحصول على عنوان الحرف،

English: 
I don't need to use the
ampersand now, because scanf
does need to be told where
the chunk of memory is,
but it's already an address, so
I don't need the ampersand here.
Recall earlier, I declared
int x, which was just an int.
%x gets the address of that int.
Here, I'm saying from the get-go,
get me the address of a char.
I don't need the ampersand cause I
already have the address of a char
by definition of that star symbol.
So what's going on here?
Let me see now.
If I run scanf1, what happens?
So make scanf1 and--
oh, let's see.
Here's a warning I'm getting.
Variable s is uninitialized
when used here.
All right, that's fine.
It wants me to initialize it because
this is a very common mistake.
Those of you who alluded
to segmentation faults
earlier might have encountered
something similar in spirit to this.
So that squelched that error.
Let me go ahead and run scanf1.
All right, here we go, TJ.
Hmm.
That is not your name, but OK.
It didn't crash at least,
it's just a little weird.
David.
Null, OK, that's a little weird.

Arabic: 
أنا لست بحاجة إلى استخدام
علامة العطف الآن، لأن scanf
بحاجة إلى إخباره أين
يوجد جزء الذاكرة،
ولكنه بالفعل عنوان،
لذا لست بحاجة إلى علامة العطف هنا.
تذكرون في وقت سابق، أعلنت عن
int x، والتي كانت فقط مجرد عدد صحيح.
يحصل %x على عنوان العدد الصحيح هذا.
هنا، أنا أقول من البداية،
أحصل لي على عنوان char.
لا أحتاج إلى علامة العطف لأنني
بالفعل لدي عنوان char
من خلال تعريف رمز النجمة هذا.
إذن ما الذي يحدث هنا؟
دعوني أرى الآن.
إذا قمت بتشغيل scanf1، ماذا يحدث؟
لذا make scanf1 و--
أوه، لنرى.
لقد حصلت على تحذير.
لم تتم تهيئة المتغير s
عند استخدامه هنا.
حسنًا، هذا جيد.
يريدني أن أقوم بتهيئته لأن
هذا خطأ شائع جدًا.
الذين أشاروا منكم
إلى أخطاء التجزئة
في وقت سابق قد واجهوا
شيئًا مماثلاً لهذا.
لذا تم سحق هذا الخطأ.
دعوني أمضي قُدمًا وأشغّل scanf1.
حسنًا، ها قد بدأنا، TJ.
امم.
هذا ليس اسمك، لكن حسنًا.
لم يتعطل على الأقل،
إنها مجرد أمور غريبة بعض الشيء.
ديفيد.
فارغ، حسنًا، هذا غريب قليلاً.

English: 
Let's go ahead and do this again.
Let's type in a really long name.
Enter.
Dammit, that didn't work.
So let's try an even longer name.
I'm hitting paste a lot.
OK-- dammit.
Too many times.
Command not found, that's
definitely not a command.
Wow, OK.
Well that's interesting.
Oh, there it is.
Null, same thing.
OK, so what's actually going on?
Well null, which is all
lowercase here, which
is this kind of an aesthetic
thing, well it's not working.
It's not working.
Well what am I actually doing?
In that first line of code, when
I say give me s to be a char*,
otherwise known as a string, all
that's doing is allocating this.
And it's technically
the size of a pointer.
A pointer, we never mentioned
this before, but now we can.

Arabic: 
لذلك دعونا نمضي قدمًا ونقوم بذلك مجددًا.
دعونا نكتب اسم طويل جدًا.
Enter.
اللعنة، هذا لم ينجح.
لذا دعونا نجرب اسمًا أطول.
أنا اضغط على لصق كثيرًا.
حسنًا-- اللعنة.
مراتٍ كثيرة.
لم يتم العثور على الأمر،
هذا بالتأكيد ليس أمرًا.
مدهش، حسنًا.
حسنا هذا مثيرٌ للاهتمام.
أوه، ها هو.
فارغ، نفس الشيء.
حسنًا، ما الذي يحدث بالفعل؟
حسنًا فارغ، وهو جميع الأحرف
الصغيرة هنا، وهي
من الأشياء الجمالية،
حسنًا هذا لا يعمل.
إنه لا يعمل.
حسنًا ماذا أفعل في الواقع؟
في السطر الأول من التعليمات البرمجية، عندما
أقول أعطني s لتكون char*،
والمعروفة كسلسلة بخلاف ذلك، كل
ما تقوم به هو تخصيص هذا.
وهو من الناحية الفنية
حجم المؤشر.
مؤشر، ونحن لم نذكر
هذا سابقًا، ولكن الآن يمكننا ذلك.

English: 
Turns out it is 64 bits or 8 bytes.
8 bits is 1 bytes, so a pointer is
by definition on many computers these
days-- most of your Macs, most of your
PCs, the IDE, the Sandbox, the Lab--
is 64-bit.
So that just means there's 64 bits
here, but we initialized it to null,
so that just means there's
64 0's here, dot-dot-dot.
But when I get a string
using scanf, what
I'm telling the computer to do
with this line of code here,
notice, is hey computer, go to that
address and put a string there.
So what's actually happening?
It turns out that there's just
not enough room to type in TJ.
There's not enough room--
that's a bit of a white lie,
because we could fit you in 64 bits,
but there's not enough room to type in
the long sentence or paragraph of text
I did, right?
What did we not do?
We didn't allocate any space over here.
All we allocated space
for was the address.
And so every time I use scanf saying,
get me a string and put it here,
there's nowhere to put it.

Arabic: 
يتضح أنه 64 وحدة بايت أو 8 وحدات بايت.
8 وحدات بايت هي 1 بايت، وبالتالي فإن المؤشر
عن طريق التعريف على العديد من أجهزة الكمبيوتر هذه
الأيام-- معظم أجهزة Macs، معظم أجهزة
الكمبيوتر الشخصي الخاصة بك، Sandbox، Lab--
هو 64 وحدة بايت.
لذا هذا يعني أن هناك 64 وحدة بايت
هنا، ولكننا قمنا بتهيئتها لتصبح فارغ،
بحيث يعني فقط أن هناك أصفار
64 هنا، نقطة-نقطة-نقطة.
ولكن عندما أحصل على سلسلة
باستخدام scanf، ما
أخبر به الكمبيوتر أن يقوم به
مع هذا السطر من التعليمات البرمجية هنا،
لاحظوا أن، مرحبًا جهاز الكمبيوتر، انتقل إلى هذا العنوان
وضَع سلسلة هناك.
لذا ما الذي يحدث بالفعل؟
يتضح أنه
لا توجد مساحة كافية للكتابة في TJ.
لا توجد مساحة كافية--
هذه كذبة بيضاء،
لأننا يمكن أن نجعلك ملائمًا في 64 وحدة بايت،
ولكن لا توجد مساحة كافية لكتابة
جملة طويلة أو فقرة من نص
قمت بكتابتها، أليس ذلك صحيحًا؟
ما الذي لم نقم به؟
لم نخصص أي مساحة هنا.
كل ما خصصنا له مساحة
كان العنوان.
وهكذا كل مرة أستخدم scanf فيها أقول،
احصل لي على سلسلة وضَعها هنا،
لا يوجد مكان لوضعها.

Arabic: 
وبالتالي فإن القيمة تقول
فقط بشكل دفاعي، لا، تعني لا،
لا يمكن تخزين هذا في أي مكان لك.
لذا أنا بالفعل بحاجة إلى أن أكون
ذكيًا قليلاً بشأن هذا الأمر.
أنا بالفعل بحاجة للحصول على بعض المساحة
حتى أتمكن بالفعل من تخزين شيء
في المكان الصحيح.
لنقم بذلك.
دعوني أمضي قدمًا
وأقوم بإنشاء برنامج جديد.
سأمضي قدمًا
وأسمي هذا scanf2.
نحن بحاجة إلى تعليمة برمجية
سرية لتذكرني بذلك.
أوه، اسم ملف خاطئ.
إذن سأمضي قدمًا
وأقوم بإنشاء ملف باسم scanf2.
scanf2.c.
وسأعيد بسرعة إنشاء
هذا stdio.h، int main void،
وبالأسفل هنا سأمضي
قدمًا و--أتعلمون؟
بدلاً من سلسلة s، والتي
أعرف اليوم أنها ستصبح char* s،
ما هي هذه السلسلة في الواقع؟
حسنًا قلتَ ذلك في وقتٍ سابق.
ما هي هذه السلسلة؟
إنها مصفوفة من الأحرف.
دعوني آخذكم لها بالمعنى الحرفي.
فقط أعطني مصفوفة،
لنَقُل، من خمسة أحرف.
D-A-V-I-D، أو واحد أكثر، هذا جيد،
كافية تمامًا لـ /0.

English: 
And so the value just very
defensively says, no, like no,
cannot store this anywhere for you.
So I actually need to be a
little smarter about this.
I actually need to get myself some space
so that I can actually store something
in the right place.
Let's do that.
Let me go ahead and
create a new program.
I'm going to go ahead
and call this scanf2.
We need a little secret
code to remind me of that.
Oh, wrong file name.
So I'm gone ahead and
create a file called scanf2.
scanf2.c.
And I'm going to quickly recreate
this stdio.h, int main void,
and then down here I'm going to
go ahead and-- you know what?
Instead of a string s, which
I know today to be a char* s,
what is this string really?
Well you said it earlier.
What is this string?
It's an array of characters.
Let me take you literally.
Just give me an array of
let's say five characters.
The D-A-V-I-D, or one more, that's
fine, just enough for my backslash 0.

English: 
Let me just create a
string-- really low level,
but this time give myself
the chunk of memory.
I don't want just the
address of a character,
I want the actual characters themselves.
Let me go ahead and just prompt
the human for their string with s,
just like before.
Then let me call scanf and get a string
from the user using %s and then pass
in s.
And here's a little trick.
It turns out that because a
string is really just an array,
but a string is also just a
pointer, you can actually treat
an array as though it is a pointer--
an address.
And so even though this is
a char* array, this is OK.
This is the equivalent in this context
to being just the address of a string.
Because strings are arrays, arrays
can be treated as pointers as of now.
And then let me go ahead and just
print out whatever the human typed in.
S is actually this.
Pass in s;, save.
Yeah?
AUDIENCE: So [INAUDIBLE] char*?
DAVID MALAN: At this point it
would be redundant to do char*,
because I literally want for
this story six characters.

Arabic: 
دعوني فقط أُنشئ سلسلة--
ذات مستوى منخفض للغاية،
لكن هذه المرة أعطي لنفسي
جزء الذاكرة.
أنا لا أريد فقط
عنوان حرف،
بل أريد الأحرف الفعلية نفسها.
اسمحوا لي بالمضي قدمًا ومطالبة
الشخص المستخدم بالسلسلة s الخاصة به،
تمامًا كما سبق.
ثم دعوني أستدعي scanf وأحصل على سلسلة
من المستخدم باستخدام %s ثم أمررها
في s.
وإليكم حيلة بسيطة.
يتضح أنه نظرًا لأن
السلسلة هي مجرد مصفوفة في الواقع،
لكن السلسلة أيضًا مجرد مؤشر،
يمكنك في الواقع معاملة
مصفوفة كما لو أنها مؤشر--
عنوان.
وحتى بالرغم من أن هذه
مصفوفة char*، فهذا جيد.
هذا هو المعادل في هذا السياق
لكونها مجرد عنوان لسلسلة.
ولأن السلاسل هي مصفوفات، فيمكن
التعامل مع المصفوفات كمؤشرات حتى الآن.
ثم دعوني أمضي قدمًا وأقوم
فقط بطباعة أي شيء كتبه الشخص المستخدم.
S هو بالفعل هذا.
مرّر في s;، حفظ.
أجل؟
الجمهور: إذن هل [INAUDIBLE] بمثابة char*؟
ديفيد مالان: عند هذه النقطة سيكون
تنفيذ char* أمرًا متكررًا،
لأنني حرفيًا أريد
لهذه القصة ستة أحرف.

English: 
I want space, rather,
for six characters.
So this is kind of week 2 stuff
now, there's no pointers involved.
But again, just showing the
equivalence of these ideas for now.
So if I now go into this, and this is
in my other directory at the moment,
make scanf2, Enter, ./scanf2,
s is going to type in--
I'll type in my name, I know I can
fit that, we're back in business.
Like now it's working because I didn't
just create the address for a string,
I created the space for the string.
But let me get a little dangerous--
David Malan?
OK, that kind of worked out OK.
David Malan or some
really long other name?
OK, that worked out too.
Let me go ahead and run it again.
Let me try that really long
string again, see what happens.
I know this didn't work
very well last time.
All right, done.
Ooh, OK.
So now I'm in the club of those of
you who have had segmentation faults.
So let's understand
what's going on here.

Arabic: 
أريد مساحةً، بدلاً من ذلك،
لستة أحرف.
إذن هذا نوعًا ما يمثل برامج الأسبوع الثاني
إلى الآن، وليست هناك مؤشرات متضمنة.
لكن مجددًا، مجرد عرض
المعادل لهذه الأفكار في الوقت الحالي.
لذلك إذا انتقلتُ الآن إلى هذه، وهذه
موجودة في الدليل الآخر لديّ في الوقت الحالي،
make scanf2، إدخال، ./scanf2،
s ستكتب--
سأكتب اسمي، وأنا أعلم أنني
يمكنني إصلاح ذلك، لقد عدنا إلى العمل.
إنها تعمل الآن تقريبًا لأنني
لم أُنشئ فقط العنوان لسلسلة،
إنما قمتُ بإنشاء المساحة للسلسلة.
لكن دعوني أنتقل إلى خطوة خطرة قليلاً--
ديفيد مالان؟
حسنًا، لقد تطور ذلك نوعًا ما، حسنًا.
ديفيد مالان أو
اسم ما آخر طويل حقًا؟
حسنًا، تطور ذلك أيضًا.
دعوني أمضي قُدمًا وأشغّله مجددًا.
دعوني أحاول مع تلك السلسلة
الطويلة مجددًا، ونرى ما سيحدث.
أعلم أن هذا لم ينجح
بشكل كامل في المرة السابقة.
حسنًا، تمت.
أوه، حسنًا.
إذن أنا الآن عضو في نادي هؤلاء
الأشخاص أصحاب الأخطاء في التجزئة من بينكم.
إذن دعونا نفهم
ما يجري هنا.

English: 
Segmentation fault a
moment ago I claimed
was touching a segment, a chunk
of memory that's not your own.
So just happened?
Well with this simple program, I
told the computer, hey computer,
give me room for six
characters, give me six bytes.
With the scanf line, I'm telling
the computer, put the following user
input at that location, in
that array of characters.
D-A-V-I-D backslash 0 fit.
David Malan didn't really, but
it didn't seem to be a huge deal.
David Malan or some really long other
name, also didn't crash the computer.
But that's because unbeknownst to us,
usually when you ask for six bytes,
the computer is kind of sort of--
it's giving you a few extras.
It's not safe to use them,
but it gives you enough
that you're not going to necessarily
see a problem like a segmentation fault.
But it only allocates a
few extra bytes typically,
so if you really keep pasting in
long, long, long, long lines of text,
eventually you're going
exceed not only those six
bytes, but well past the special--
the secret bytes that you got back
that you shouldn't be using anyway,

Arabic: 
خطأ التجزئة الذي ارتكبتُه
منذ دقيقة كان عبارة عن
لمس جزء، قطعة من
الذاكرة لا تخصك.
هل حدث لذلك فقط؟
حسنًا باستخدام هذا البرنامج البسيط، قلتُ
لجهاز الكمبيوتر، يا كمبيوتر،
أعطني حيزًا لستة
أحرف، أعطني ست وحدات بايت.
مع سطر scanf ، أقول لجهاز
الكمبيوتر، ضع إدخال المستخدم
التالي في ذلك الموقع، في
تلك المصفوفة من الأحرف.
D-A-V-I-D خط مائل عكسي 0 هو خيار مناسب.
David Malan لم تكن خيارًا مناسبًا حقًا، ولكن
لم يبدُ أن هذا أمر مهم.
كما لم يتسبب اسم David Malan أو اسم ما آخر
طويل حقًا، في تعطل الكمبيوتر.
ولكن هذا لأنه عادةً من دون علمنا،
عندما تطلب ست وحدات بايت،
يقوم الكمبيوتر بترتيبها نوعًا ما--
فيعطيك بضع عناصر إضافية.
ليس من الآمن استخدامها،
لكنها تعطيك ما يكفي
لكيلا تشاهد بالضرورة
مشكلة مثل خطأ التجزئة.
لكنها عادةً ما تخصص فقط
عددًا قليلاً من وحدات البايت الإضافية،
لذلك إذا تابعت لصق سطور
طويلة، طويلة، طويلة من النص،
فأنت في نهاية المطاف لن
تتجاوز وحدات البايت الست فقط،
إنما أيضًا ستكون بعيدًا تمامًا عن وحدات المساحة الخاصة--
وحدات البايت السرية التي استعدتها
والتي يجب ألا تستخدمها على أي حال،

English: 
and that point the computer
just gives up and says,
you are touching memory
you shouldn't, a.k.a.
segmentation fault.
AUDIENCE: [INAUDIBLE] if
the computer gives you
a few extra bytes, then why isn't
it printing any of the other stuff?
After you said [INAUDIBLE]
it just printed David.
DAVID MALAN: Really good question.
So even though I'm getting
these sort of extra bytes,
why am I not seeing
them after D-A-V-I-D?
I'm probably getting lucky.
Long story short, when
you first run a program,
much of the memory that your program
has access to is by default initialized
to 0's.
0 is the same thing as backslash
0, and so I'm getting lucky.
When I had D-A-V-I-D and then
excess space in that array,
a lot of them are
initialized as 0's already,
and the string is getting
secretly terminated for me.
Or the better answer is,
it's undefined behavior.
Like you should not touch
memory that is not your own.
What happens after that
is your risk alone.
But that's a conjecture as
to why that's happening.
All right, so what is the
fundamental feature than get_int
is providing for us?

Arabic: 
وفي هذه النقطة سيرضخ الكمبيوتر
ويقول،
أنت تلمس الذاكرة
لا ينبغي عليك، وهو ما يعرف أيضًا باسم،
خطأ التجزئة.
الجمهور: [INAUDIBLE] إذا
منحك الكمبيوتر
قليلاً من وحدات البايت الإضافية، فلماذا لا يقوم
بطباعة أي من البرامج الأخرى؟
بعد أن قلتَ [INAUDIBLE]
فإنه قد قام تحديدًا بطباعة اسم David.
ديفيد مالان: سؤال جيد حقًا.
إذن حتى رغم أني أتلقى
وحدات البايت الإضافية نوعًا ما هذه،
لماذا لا أراها
بعد D-A-V-I-D؟
فأنا على الأرجح محظوظ.
خلاصة القول، عندما تقوم
بتشغيل برنامج لأول مرة،
فإنه تتم تهيئة مساحة كبيرة من الذاكرة
التي يحق لبرنامجك الوصول إليها بشكل افتراضي
للأصفار.
0 هو نفسه خط مائل عكسي
0، ولذلك فأنا محظوظ.
فعندما يكون لديّ D-A-V-I-D
ثم مساحة إضافية في تلك المصفوفة،
فتتم تهيئة الكثير منها
بالفعل كأصفار،
ويتم إنهاء السلسلة بشكل سري
بالنسبة لي.
أو الإجابة الأفضل هي،
إنه سلوك غير محدد.
مثلما أنك يحظر عليك لمس
ذاكرة ليست خاصة بك.
ما يحدث بعد ذلك
سيكون مخاطرتك وحدك.
ولكن ذلك تخمين
لسبب حدوث ذلك.
حسنًا، إذن ما هي الميزة الأساسية
عمّا تقدّمه لنا
دالة get_int؟

Arabic: 
طوال هذا الوقت كانت دالة get_int
في الواقع تتعامل مع
كل هذا الصداع نيابةً عنا.
أعني بصراحة، رغم أنني سئمت
التفكير، والحديث
حول الكيفية التي حصلتَ بها
للتو على سلسلة لعينة من المستخدم،
لأنك بحاجة لأن تعرف جيدًا
كم وحدة بايت تحتاجها؟
وماذا لو كانت الأنواع البشرية في وحدة
بايت زيادةً عما كنت تتوقع؟
إذن تحتاج إلى تبديل
صف والحصول على مزيد من الذاكرة.
get_string يريحنا
من كل هذا الصداع.
وهذا لا يعني أنك
في حاجة لاستخدامه إلى الأبد،
إنها بالفعل عجلات
تدريب، ولكن
فقط لأنك عندما تستخدم C
أو العديد من لغات البرمجة،
سيقوم جهاز الكمبيوتر فقط
بفعل ما تقوله للقيام به.
وتبين أنه حتى
طلب المُدخلات من المستخدم،
إذا كنت لا تعرف كم عدد
الأحرف الذي سيقوم أو التي
ستقوم بكتابتها من
get-go، فعليك أن تتعامل مع الأمر.
وما تحت الغطاء-- وأنت
مرحب بك لتلقي نظرة على تعليمات المصدر
البرمجية لمكتبة CS50، والتي
سأقوم بنشرها على الصفحة الرئيسية لاحقًا اليوم،
اتضح أن الطريقة التي نقوم
بـ get_string بها تحقق تقدمًا صغيرًا.
نحن حرفيًا نحصل على
حرف واحد في كل مرة
من المستخدم، شيء كبناء
الطريق بينما نمشي فيه.
وإذا لم يكن لدينا مسافة
كافية، نطلب من جهاز الكمبيوتر،
أن يمنحني بعض وحدات البايت الإضافية
حتى أتمكن من الحصول على المزيد منها،

English: 
All of this time get_int
has actually been dealing
with all of this headache for us.
I mean honestly, even I'm getting
bored like thinking about, talking
about how you just get a
damn string from the user,
because you need to figure out,
well how many bytes do you need?
And what if the human types in one
more bite than you were expecting?
Then you need to do a
switcheroo and get more memory.
get_string is doing all
of this headache for us.
And that's not to say you
need to use it forever,
there are indeed training
wheels, but that's
just because when you're using C
or a lot of programming languages,
the computer will only do
what you tell it to do.
And it turns out that even
asking the user for input,
if you don't know how many
characters he or she is
going to type in from the
get-go, you have to deal with it.
And so underneath the hood-- and you're
welcome to take a look at the source
code for CS50's library, which I'll
post on the home page later today,
it turns out that with the way we're
doing get_string is taking baby steps.
We literally like get
one character at a time
from the user, kind of
building the road as we go.
And if we don't have enough
space, we ask the computer,
give me some more bytes
so I can get more bytes,

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

English: 
and we just get one
character at a time so
that we can handle the user maliciously
or accidentally typing in way
more input than we actually expect.
So let's contextualize all of this then.
Recall that we've been drawing these
pictures the past couple of weeks.
Let's just make this super clear
as to what's been going on.
This is a memory module in a computer.
It's just a green board, it's
way blown out of scale here,
it's easily like yea big inside of
your Mac or PC laptop or desktop,
though can vary in size.
One of these black chips is
the actual memory or the bytes
to which we've been referring.
And if we zoom in on that,
recall that I proposed last week
that you can just think about
this as like a grid, an array.
And it doesn't have to be rectangular,
this is just an artist's rendition,
but each of those squares
represents, we claimed, a byte.
And each of those bytes can be
addressed in some way with a number.
And that number is just its location,
otherwise known as an address.
We can actually see this,
it turns out, as follows.
Let me go ahead and open
up this example here.
Or actually, you know, let's
just write this one from scratch.

Arabic: 
دعوني أكتب برنامجًا
يسمّى addresses.c.
وسيستخدم هذا أصدقائنا القدامى،
ومكتبة CS50 وstdio.h وint
main void.
دعوني أمضي قُدمًا وأفعل هذا.
وسأمضي قُدمًا
وأحصل على سلسلة--
أتعلمون ماذا؟
لا مزيد من السلاسل. char* من المستخدم،
get_string، اطلب من المستخدم s.
ونحصل على سلسلة أخرى، والمعروفة أيضًا.
بـ char*، get_string،
أطلق عليها t من المستخدم.
ومن ثم، لا أرغب في طباعة
السلاسل، التي اعتدت على فعلها هكذا،
طباعة s.
أنا أرغب في طباعة المؤشر
حيث يكون s، هو العنوان.
سيظهر %p للمؤشر الذي لن يقوم
بطباعة السلسلة في موقع الذاكرة هذا،
سيقوم بطباعة موقع الذاكرة
الفعلية لك الخاص بـ s.
ويمكنني فعل الشيء نفسه هنا، %p،
خط مائل عكسي 0، وألصق في t.
وفقط لكي أعرف
ما الفرق بينهما، دعوني أبدأ فيه
مع نص ما-- s نقطتين وt نقطتين.
دعوني أمضي قدمًا الآن في الأسفل
هنا، وأقوم بكتابة make addresses.

English: 
Let me write a program
called addresses.c.
And that's going to use our old friends,
the CS50 library and stdio.h and int
main void.
And let me go ahead and just do this.
I'm going to go ahead and get a string--
you know what?
No more string. char* from the user,
get_string, ask the user for s.
And we get another string, a.k.a.
char*, get_string, call
it t from the user.
And then, I want to print out not the
strings, which I used to do like this,
printing out s.
I want to print out the pointer that
s really is, that is the address.
Turns out %p for pointer will print out
not the string at that memory location,
it will print the actual
memory location for you of s.
And I can do the same thing here,
%p, backslash 0, paste in t.
And just so I know which is
which, let me just prefix it
with some text-- s colon and t colon.
Let me go ahead now down
here and do make addresses.

English: 
Oh, I messed up, missed a semi-colon.
Let me do this again.
make addresses.
And get rid of this.
That compiled OK,
./addresses, and here we go.
Let's type in-- let's do Brian
and Veronica like before.
Enter.
And this is a little funky, but
it turns out the IDE in your Macs
and your PCs have a lot of memory.
So this is the address.
It's not quite as small as 100,
it's not quite as small as 900.
It's actually kind of big.
It's 2331010 with this weird 0x.
Well it turns out, this is
just a human convention.
In week 0 we talked about
decimal and all of us
grew up with decimal,
10 digits from 0 to 9.
Talked a little bit
about binary 0's and 1's.
Turns out there's an infinite
number of base systems--
decimal/dec, binary/bi are just two of
those infinite number of possibilities.
Turns out there's another one that's
super common called hexadecimal.
Hexa meaning 16 in this case.

Arabic: 
أوه، لقد أخطأت، نسيت فاصلة منقوطة.
دعوني أفعل هذا مجددًا.
make addresses.
وأتخلص من هذا.
تم تحويل هذا برمجيًا حسنًا،
./addresses، وها نحن ذا.
دعونا نكتب في-- دعونا نكتب براين
وفيرونيكا كما فعلنا من قبل.
Enter.
وهذا غريب إلى حد ما، ولكن
يتضح أن IDE في أجهزة Mac
وأجهزة الكمبيوتر الشخصي لديك تحتوي على ذاكرة كبيرة.
إذن هذا هو العنوان.
إنه ليس صغيرًا مثل 100،
وليس صغيرًا مثل 900.
إنه في الواقع كبير.
إنه 2331010 مع تلك 0x الغريبة.
إذن يتضح أن، هذا
مجرد تقليد إنساني.
في الأسبوع 0 تحدثنا عن
الأرقام العشرية وجميعنا
على دراية بالأرقام العشرية منذ الصغر،
10 أرقام من 0 إلى 9.
وتحدثنا قليلاً
حول نظام الأصفار والآحاد الثنائي.
يتضح أنه يوجد عدد
لا حصر له من الأنظمة الأساسية--
إن رقم عشري/dec، نظام ثنائي/bi هما اثنين فقط من
تلك الأعداد اللانهائية من الاحتمالات.
يتضح أنه يوجد واحد آخر
وهو شائع للغاية باسم السداسيّ العشريّ.
ويعني السداسيّ 16 في هذه الحالة.

Arabic: 
إذن فإن base-16 يحتوي بالفعل على 16
حرفًا في الأحرف الأبجدية الخاصة به.
0، 1، 2، 3، 4، 5، 6، 7،
8، 9، a، b، c، d، e، f.
إذن تبين أن الأنظمة الأساسية التي تحتاج إلى
حساب أكثر من 10 أحرف
بدأت للتو في استخدام الأحرف
الأبجدية عن طريق التقليد.
قرر البشر هذا فقط.
إذن نحن نحصل فقط على
أرقام في هذه الحالة،
ولكن إذا كانت هذه العناوين
أكبر من ذلك، فقد
نرى بالفعل بعض الأحرف الأبجدية
بين a وf هناك.
وبصراحة لا أعرف
ما هو هذا عنوان،
ولكن Google عادةً ما
يجيد التعامل مع تلك الأمور،
لذا دعوني أفتح
نافذة متصفح أخرى.
إذن Google يصبح صديقك
عندما يتعلق الأمر بهذه الأمور،
أو أي عدد من الحاسبات.
0x2331010 بأرقام عشرية من فضلك.
وقد ترجم Google ذلك.
لذا براين، أنا-- نوعًا ما
أسفل وحدة بايت في وقت سابق.
هو ليس في موقع عنوان
0، هو في الحقيقة
إنما في 36 مليون بايت
داخل جهاز الكمبيوتر الخاص بي

English: 
So base-16 actually has 16
letters in its alphabet.
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, a, b, c, d, e, f.
So it turns out that base systems that
need to count higher than 10 characters
just start using letters of
the alphabet by convention.
Humans just decided this.
So we're getting just
numbers in this case,
but if these addresses
were even bigger, we
might actually see some alphabetical
letters between a and f there.
And frankly I don't know
what address this is,
but Google's usually
pretty good at this stuff,
so let me actually open
up another browser window.
So Google is your friend
when it comes to this stuff,
so let me actually open
up another browser window.
So Google is your friend
when it comes to this stuff,
or any number of calculators.
0x2331010 in decimal please.
And Google has translated that.
So Brian, I-- kind of
under a bit earlier.
He is not at address
location 0, he's actually
in the 36 millionth byte
inside of my computer

Arabic: 
في الوقت الحالي، الموقع 36,900,880.
إذن، عنوان أعلى بقليل من 100.
ثم فيرونيكا، إذا كنا حقًا
نريد أن نجعل الأمور معقدة هنا،
يمكننا القول "بالأرقام العشرية،" ولندع
Google يترجم هذا لنا.
إنها في الموقع 36,900,944.
لماذا؟
مَن يهتم؟
يدير جهاز الكمبيوتر كل هذا
لنا، ولكن عندما يقوم get_string باستخدام malloc،
هذه حرفيًا هي الأرقام
التي تم إرجاعها حيث يمكننا قول أنه،
يمكنك استخدام هذا الجزء من الذاكرة.
ولماذا استخدم البشر السداسيّ العشريّ؟
كما لو أنها طريقة أكثر تعقيدًا قليلاً
لقول 0x2331050، ثم 36900944--
مثلما قمت بحفظ بعض الأرقام،
لذلك فهي تقليدية فقط.
هذا كل شيء، لا يوجد سحر هناك.
لكن، تذكرون في وقت سابق.
هل تتذكرون عندما قمت بفتح
مصحح الأخطاء في وقت سابق،
رأيتم بجانب قيمة متغير اسمي
التي كانت مشفرة 0x0؟
ثم كانت هناك قيمة
أخرى لا أتذكرها--
0X-وشيء ما؟

English: 
right now, location 36,900,880.
So a little higher address than 100.
And then Veronica, if you really
want to get into the weeds here,
we can say "in decimal," let
Google translate that for us.
She's at location 36,900,944.
Why?
Who cares?
The computer is managing all of this
for us, but when get_string used malloc,
these are literally the numbers
that were being returned saying,
you may use this chunk of memory.
And why did humans use hexadecimal?
Like it's just slightly more compact
to say 0x2331050, then 36900944--
like you just save a few digits,
so it's just conventional.
That's all, there's no magic there.
But, recall earlier.
Do you recall that when I had
the debugger open earlier,
you saw next to my name variable
a value that was cryptically 0x0?
Then there was another
value that I don't recall--
0x-something?

English: 
That was just the numeric address
of my name in hexadecimal.
And 0x0 is just the technical
address being used by null.
Yeah?
AUDIENCE: You said the address printed
out was [INAUDIBLE] x of the variable s
and--
DAVID MALAN: Sorry,
could you say that again?
AUDIENCE: You said the address
printed out on the screen was an x,
but x is [INAUDIBLE]
DAVID MALAN: Ah, I should've clarified.
0x, humans years ago decided
anytime you see anything
with 0x, that means whatever
comes next is hexadecimal.
Just the convention.
It's also common too if it starts with
a 0, it's an octal, which is base-8.
If you see a lowercase b at
the end, it means binary.
So humans have just
come up with symbology
as to kind of communicate
this to readers, that's all.
Not part of the value.
So turns out that we can
actually do this math ourselves.
And we won't really get
into the weeds of this
because it's not a
particularly useful life
skill, to be able to convert
to various base systems,
but let's just do one example
so that we've seen it.
Just to make clear that
there's no magic here,
it's just a different way of thinking
about numbers versus grade school.

Arabic: 
كان ذلك مجرد عنوان رقمي
لاسمي في السداسيّ العشريّ.
و0x0 هو العنوان
الفني المُستخدم من قبل فارغ.
أجل؟
الجمهور: لقد قلت أن العنوان المطبوع
كان [INAUDIBLE] x للمتغير s
و--
ديفيد مالان: عذرًا،
هل يمكنك قول ذلك مجددًا؟
الجمهور: لقد قلت أن العنوان
المطبوع على الشاشة كان x،
ولكن x هو [INAUDIBLE]
ديفيد مالان: آه، كان علي أن أوضح ذلك.
0x، قرر البشر منذ سنوات
في أي وقت تشاهد أي شيء
مع 0x، هذا يعني أن أيًا كان
يأتي بعد ذلك هو سداسيّ عشريّ.
التقليد فقط.
كما أنه من الشائع أيضًا إذا كان يبدأ بـ
0، فهو ثُماني، وهو base-8.
إذا رأيت حرف b صغير في
النهاية، فهذا يعني أنه ثنائي.
إذن توصل البشر
إلى الرموز
كنوع من توصيل
هذا إلى القرّاء، هذا كل شيء.
ليس جزءًا من القيمة.
إذن يتضح أنه بالفعل يمكننا القيام
بهذه الحسابات بأنفسنا.
ولا نريد حقًا أن
تسوء الأمور لهذا
لأنها بشكل خاص ليست
مهارة مفيدة
في الحياة، لتكون قادرًا على التحويل
إلى أنظمة أساسية متنوعة،
ولكن دعونا فقط نقدم مثالاً واحدًا
حتى نراه.
فقط لتوضيح أن
أنه لا يوجد سحر هنا،
إنها مجرد طريقة مختلفة للتفكير
حول الأرقام مقابل المرحلة الابتدائية.

English: 
So if back in the day we
had three decimal numbers--
255, 216, and then another
255, if we rewound to week 0,
we could go through the math
of converting that to binary.
And even if it might take you a little
while, this is the binary equivalent.
And frankly, the first
and last are kind of easy.
255 is kind of a special value
because with 8 bits, all of which
are 1, that's what gives you 255.
So the only hard one is actually this.
But who cares about the math today.
We know from weeks ago that we
can do this if we really tried.
But notice that bytes are eight bits,
and of course, eight is a pair of four,
if you will.
Well what's really nice about
hexadecimal is that it starts at 0
and ends at f.
And that's 0, 1, 2,
3, 4, 5, 6, 7, 8, 9--
wait-- yes, that's 10.
OK.
And then a, b, c, d, e, f.
I just held up 16 fingers in
total, hence, hexadecimal.

Arabic: 
إذن إذا رجعنا بذاكرتنا إلى اليوم
الذي كان لدينا فيه ثلاثة أرقام عشرية--
255، و216، ثم
255 آخر، إذا رجعنا إلى الأسبوع 0،
يمكننا الانتقال خلال حسابات
التحويل لذلك إلى النظام الثنائي.
وحتى إذا كان ذلك يستغرق وقتًا،
فهذا هو معادل النظام الثنائي.
وبصراحة، الرقم الأول
والأخير سهلين نوعًا ما.
255 هو قيمة خاصة نوعًا ما
لأنه مع 8 وحدات بت، كلهم
1، وهذا ما يمنحك 255.
إذن فإن الشيء الوحيد الصعب هو هذا في الواقع.
لكن مَن يهتم بالرياضيات اليوم.
ونحن نعلم منذ أسابيع أننا
يمكننا القيام بذلك إذا حاولنا حقًا.
ولكن لاحظوا أن وحدات البايت هي 8 وحدات بايت،
وبالطبع، ثمانية هي زوج من أربعة،
إذا صح التعبير.
حسنًا الشيء الجيد حقًا في
السداسيّ العشريّ هو أنه يبدأ في 0
وينتهي في f.
وهذا 0، 1، 2،
3، 4، 5، 6، 7، 8، 9--
انتظروا-- نعم، هذا هو 10.
حسنًا.
ثم a، b، c، d، e، f.
لقد عددت 16 إصبعًا في المجمل،
وبالتالي، السداسيّ العشريّ.

English: 
What's nice about base-16 is that how
many bits do I need to count from 0 up
to--
one, two, three, four--
15?
Just 4, right?
So if I have all 0 bits, that's 0.
And if I have 4 1-bits, that's--
let's see.
This is an 8 plus 4 plus
2 plus 1 gives me 15.
So long story short, hexadecimal's
super convenient because 0 through f
maps wonderfully cleanly to 4 bits.
So it's just a nice way of thinking
about the world not in units of 8
but in 4 instead.
So all I did here was I
took my values and I just
added a little bit of
whitespace to make clear
that 8 bits is like a pair of 4 bits.
It turns out now that 1 1 1 1 is f
for the reasons I enumerated earlier.
All 1's is f, otherwise known as 15.
All 1's is again f,
otherwise known as 15.
If we did the math, 1 1 0 1 is d, 1 0
0 0 is 8, and then all 1's is f and f.
So long story short, there is
a way to convert from decimal

Arabic: 
الشيء الجيد في base-16 هو كم عدد
وحدات البايت التي أحتاجها للعدّ من 0
إلى--
واحد، اثنان، ثلاثة، أربعة--
15؟
4 فقط، أليس كذلك؟
لذلك إذا كان لديّ جميع وحدات بايت 0، هذا 0.
وكان لديّ 1 4 وحدة بايت، وهو--
لنرى.
هذا هو 8 زائد 4 زائد
2 زائد 1 يعطيني 15.
إذن خلاصة القول، السداسيّ العشريّ
مناسب للغاية لأن 0 خلال f
يقترن بصورة رائعة بسيطة بـ 4 وحدات بايت.
إذن، إنها طريقة لطيفة للتفكير
حول العالم وليس بوحدات 8
ولكن في 4 بدلاً من ذلك.
إذن كل ما فعلته هنا أنني
أخذت قيمي وقمت فقط
بإضافة مسافة
للتوضيح
أن 8 وحدات بايت مثل زوج من 4 وحدات بايت.
يتضح الآن أن 1 1 1 1 هو f
للأسباب التي ذكرتها سابقًا.
كل الآحاد تكون f، والمعروف أيضًا بـ 15.
جميع الآحاد مجددًا تكون f،
والمعروف أيضًا بـ 15.
إذا قمنا بعملية حسابية، فإن 1 1 0 1 هو d،
و1 0 0 0 هو 8، ومن ثم جميع الآحاد هي f وf.
إذن خلاصة القول، توجد
طريقة للتحويل من الأرقام العشرية

English: 
to binary, to hexadecimal, to
any number of other base systems.
It all just boils down to
what digits you care about.
And the way you write this,
to your question earlier,
is by human convention.
Not just FFDAFF, but
0xFF0xD80xFF just because.
Then it's clear to the user what it is.
So a little levity now.
I'm sorry to do this to you,
but now you will all hopefully
understand this famous comic.
OK, welcome to that club of people
who understand things like this.
So let's now stumble upon
just one last problem,
and we'll take it home by
putting into the context
a very sexy field of forensics
where all of these building blocks
will come into play.
But first let's start with a problem.
Suppose I want to implement a function
here called swap whose purpose in life
is just to swap two values, a and b.
I just want to do a switcheroo.
Let's first do this with a sort
of mid-lecture snack for at least
one person.
Would anyone be up for--
OK, that was fast.

Arabic: 
إلى النظام الثنائي، إلى السداسيّ العشريّ، إلى
أي عدد من الأنظمة الأساسية الأخرى.
كل ذلك فقط يتلخص في
ما هي الأرقام التي تهتم بها.
والطريقة التي تكتب بها هذا،
لسؤالك في وقت سابق،
بالتقليد الإنساني.
ليس فقط FFDAFF، ولكن
0xFF0xD80xFF لسبب فقط.
ثم يتضح إلى المستخدم ماذا يكون ذلك.
إذن بعض المرح الآن.
أنا آسف لفعلي هذا بكم،
ولكن آمل من كل ذلك أن تفهموا
هذه الصورة الهزلية ​​الشهيرة.
حسنًا، مرحبًا بكم في هذا النادي الخاص بالأشخاص
الذين يفهمون أشياء من هذا القبيل.
لذا دعونا الآن نعثر على
مشكلة واحدة أخيرة فقط،
وسنتناولها في المنزل عن طريق
وضعها في السياق
مجالاً مثيرًا جدًا من الطب الشرعي
حيث جميع تلك العناصر الأساسية
ستدخل حيز التشغيل.
لكن دعونا نبدأ أولاً بمشكلة.
لنفترض أنني أريد تنفيذ دالة
هنا تسمّى swap غرضها في الحياة
هو فقط المبادلة بين قيمتين، a وb.
أريد فقط تبديل الصف.
دعونا أولاً نقوم بذلك كوجبة
خفيفة في منتصف المحاضرة على الأقل
شخص واحد.
هل يمكن أن يتطوّع شخص ما ويأتي إلى هنا--
حسنًا، كان ذلك سريعًا.

English: 
Volunteering, come on up.
What's your name?
Kelly, all right.
Thank you for volunteering so suddenly.
Kelly, David, nice to meet you.
OK, so very simple task at hand.
I have here two empty cups,
and we have some orange juice.
OK, put this in here.
And we've got some milk over here.
That should stand out,
very different colors.
OK, I would just like you, Kelly,
if you could, swap those two values.
Orange goes into milk, milk
goes into orange please.
That is cheating, OK?
No, I mean literally the cups.
I put them in the wrong
cup, I prefer my milk
in the other cup and my orange
juice in the other cup, I'm sorry.
AUDIENCE: Pour it back in.
DAVID MALAN: No, that is
not available to you, OK?
[LAUGHTER]
OK, so you're struggling.

Arabic: 
متطوعة، تعالي.
ما اسمك؟
كيلي، حسنًا.
شكرًا لتطوعك بشكل مفاجئ.
كيلي، ديفيد، سررت بلقائك.
حسنًا، مهمة بسيطة جدًا في متناول اليد.
لدي هنا كوبين فارغين،
ولدينا بعض من عصير البرتقال.
حسنًا، ضَعي هذا هنا.
ولدينا بعض الحليب هنا.
هذا يجب أن تظهر،
ألوان مختلفة للغاية.
حسنًا، أود فقط أن تقومي، كيلي،
إذا أمكنك ذلك، بتبديل تلك القيمتين.
البرتقال إلى حليب، والحليب
إلى برتقال، من فضلك.
هذا غش، حسنًا؟
لا، أعني حرفيًا الأكواب.
لقد وضعتهما في الكوب الخاطئ،
وأفضل أن يكون الحليب
في الكوب الآخر وعصير البرتقال
في الكوب الآخر، أنا آسف.
الجمهور: أسكبي من الزجاجة.
ديفيد مالان: لا، هذا
غير متاح لك، حسنًا؟
[LAUGHTER]
حسنًا، إذًا أنت تعانين.

Arabic: 
لماذا تعانين؟
كيلي: لأنني سأقوم بمزجهما.
ومن ثم لن يكون الأمر ذاته.
ديفيد مالان: حسنًا.
لذا من الواضح أنني أعني،
هذه مسألة خاسرة نوعًا ما.
أنه لا يمكنك القيام بذلك بالفعل.
فما الذي قد يجعل هذا الأمر أسهل بالنسبة لك
بجانب وضعهم مجددًا
في الزجاجات؟
كيلي: وجود كوب آخر.
ديفيد مالان: أجل.
لذا فأنتي بحاجة إلى ما يكون بمثابة
مساحة تخزين مؤقتة لهذا.
أنتم تعرفوا، دعوني--
تارا، هل يمكننا العثور على
بعض الأكواب الإضافية هنا؟
آه، هذا سيجعل الأمر أسهل.
حسنًا، إذا حصلتي على
مساحة تخزين مؤقتة--
ها هو-- هل يمكنك حل هذه
المشكلة الآن من فضلك؟
آه، جميل جدًا.
القليل من التلوث، لكن لا بأس.
لكن أحتاج إلى إعادة ذلك الكوب
المؤقت إلى تارا.
أجل، حسنًا.
شكرًا لكِ.
حسنًا، صفقوا بحرارة
رجاءً لكيلي هنا.
[APPLAUSE]
حسنًا، ها نحن ذا.
أعتقد أنك لا تريدين حليب دافئ،
لكن ما رأيك في عصير البرتقال؟
حسنًا.
شكرًا جزيلاً لكِ.
حسنًا، ما هو المغزى هنا؟
هذا سهل جدًا.
مثل عندما تكون لديك
مساحة تخزين
مؤقتة-- متغير، إذا صح التعبير، على سبيل المثال
لا توجد مشكلة لتبديل القيمتين.

English: 
Why are you struggling?
KELLY: Because I'm going to mix them.
And then it won't be the same.
DAVID MALAN: Right.
So I mean obviously, this is
kind of a losing proposition.
You can't really do this.
What would make this easier for
you besides putting them back
in the bottles?
KELLY: Having another container.
DAVID MALAN: Yeah.
So you need like a temporary
storage space for this.
You know, let me--
Tara, can we get some
more cups over here?
Ah, this will make it easier.
OK, so if I get you
some temporary space--
here you go-- could you
solve the problem now please?
Ah, very nice.
A little contamination, but that's OK.
But I need that temporary
cup back for Tara.
Yeah, OK.
Thank you.
All right, a round of applause
if we could for Kelly here.
[APPLAUSE]
Well here we go.
I'm guessing you don't want
warm milk, but orange juice?
OK.
Thank you so much.
All right, so what's the point here?
This is pretty easy.
Like once you have
some temporary storage
space-- a variable, if you will, like
it's no problem to swap two values.

Arabic: 
لذا دعوني أمضي قدمًا
وأقوم بذلك على النحو التالي.
سأمضي قدمًا وسأقوم
فقط بتنفيذ دالة التبديل هذه
وأرى بالضبط ما قامت
كيلي فقط بتنفيذه في النهاية.
إذا كان الهدف هو تبديل a وb، فلا يمكنني
فقط القيام بتبديل صف كامل،
كما يبدو.
أحتاج إلى وضع إحدى هذه القيم،
مثل الحليب، في كوب آخر،
ومن ثم تبديلها، ثم تبديلها.
لذا هي تتطلب ثلاث خطوات، وليست خطوة واحدة.
حسنًا، إذًا يمكنني تسمية
هذا كوب أو متغير إضافي
لقد قدّمت لنا تارا أي
شيء نريده-- tmp.
إذن سأقوم فقط بوضع a في tmp.
ثم سأقوم بوضع b في
a، لأن a فارغة الآن.
ثم سأقوم بوضع tmp في
b، ومن ثم لن أهتم حقًا
بما سيحدث لـ tmp-- في الواقع،
إنه ما زال في مكانه هنا،
لكن تمت المهمة الآن.
لذا دعوني أمضي قدمًا وأري هل
هذا البرنامج قيد التشغيل، لأن من الواضح يجب
أن يكون هذا مباشرًا للغاية.
لذلك دعوني أمضي قدمًا
وأشغّل البرنامج
في سياق دالة رئيسية
حيث يمكننا تشغيلها بالفعل.
في هذه التعليمة البرمجية،
سأقوم بشرحها على النحو التالي.
ها هي دالتي الرئيسية.
سأقوم بتسمية متغير x،
وأعطيه 1، وسأقوم بتسمية متغير y،
وأعطيه 2، وسأمضي قدمًا وسأقوم
بالطباعة فقط من أجل فحص السلامة السريع--

English: 
So let me go ahead and
do that as follows.
I'm going to go ahead and just
implement this swap function
and see exactly as Kelly
ultimately just implemented it.
If the goal is to swap a and b, I
can't just do a complete switcheroo,
it seems.
I need to put one of those values,
like the milk, in another container,
and then swap and then swap.
So it takes three steps, not just one.
All right, so I could call
this extra variable or cup
that Tara gave us
anything we want-- tmp.
So I'm just going to put a in tmp.
Then I'm going to put b in
a, because a is now empty.
Then I'm going to put tmp in
b, and then I don't really
care what happens to tmp-- indeed,
it's just still sitting there,
but the job is now done.
So let's go ahead and see this program
in action, because obviously this
should be pretty straightforward.
So let me go ahead and
open up this program
in the context of a main function
so we can actually run it.
In this code here, I'm going
to demonstrate it as follows.
Here's my main function.
I'm going to call variable x,
give it 1, call variable y,
give it 2, go ahead and just print
out just for a quick sanity check--

English: 
x is this, y is that.
Then I'm going to call this
super simple swap function, x, y.
Then I'm going to print the exact
same thing-- x is this, y is that,
just so I can see in those variables--
I could also use debug50, but this
is meant to be a complete solution,
I want to see it on the screen.
Here is swap.
I copy-pasted that from before.
This feels like a no-brainer,
super straightforward,
let's go into my directory and compile
this program, which, slight spoiler,
noswap is the name.
./noswap.
Oof.
Let's zoom in.
Nope, that is not what
I intended, right?
I really intended milk to
become OJ, OJ to become milk,
or x become y, y become x,
this doesn't seem to work.
And again, the only magic
is this one call to swap.
All right, maybe it just
works some of the time.
So nope, nope-- OK.
Now it's time for the debugger.
I don't understand what's
going on in my program,
printf is not really illuminating here.
So let me go ahead and
run debug50 ./noswap.

Arabic: 
x هو هذا، y هو ذاك.
ومن ثم سأقوم بتسمية دالة
المبادلة البسيطة الرائعة هذه، x، y.
ومن ثم سأقوم بطباعة نفس الشيء
بالضبط-- x هو هذا، y هو ذاك،
لذا يمكنني رؤية ذلك في تلك المتغيرات--
يمكنني أيضًا استخدام debug50، لكن من
المفترض أن يكون هذا حلاً كاملاً،
أريد أنا أراه على الشاشة.
ها هي المبادلة.
لقد نسخت ولصقت هذا من قبل.
يبدو أن هذا لا يتطلب التفكير،
فهو مباشر للغاية،
دعوني أنتقل إلى دليلي، وأقوم
بتحويل هذا البرنامج برمجيًا، وهو، مفسد قليلاً،
noswap هو اسمه.
./noswap.
أووف.
دعوني أقوم بالتكبير.
كلا، هذا ليس ما كنت
أعنيه، أليس كذلك؟
أنا أعني بالفعل أن يصبح الحليب عصير برتقال،
ويصبح عصير البرتقال حليبًا،
أو x تصبح y، وy تصبح x،
لا يبدو أن هذا يعمل.
ومجددًا، السحر الوحيد
هو أن هذا الشيء يدعو إلى المبادلة.
حسنًا، ربما قد يعمل
فقط لبعض الوقت.
إذن لا، كلا-- حسنًا.
الآن حان وقت مصحح الأخطاء.
أنا لا أفهم ما الذي
يجري في برنامجي،
لا يضيء printf بالفعل هنا.
لذا دعوني أمضي قدمًا
وأشغّل debug50 ./noswap.

Arabic: 
تم فتح لوحات تصحيح الأخطاء جانبًا،
لكن تمهلوا، أحتاج إلى نقطة توقف.
سأقوم ببدء نقطة توقف في الأعلى،
السطر الأول الذي أهتم به.
أنا حقًا لا أهتم بالأشياء الموجودة في الجزء العلوي.
الآن سأمضي قدمًا وأعيد تشغيل
debug50 ./noswap، أليس كذلك؟
أرى الآن هنا، أنه تم تمييز أول السطر 9.
لاحظوا في الجهة اليمنى،
قد تكون هذه هي الإجابة بمثال
على سؤالك السابق.
x وy بشكل مناسب، لكن
فقط لأننا انتقلنا إلى 0--
لم أقم بذلك، أنا لا يجب بالضرورة أن
أثق في هذا في جميع السياقات،
ولكن هذا هو سبب امتلاكهم قيم.
فهم بخلاف ذلك يتم تعريفهم بقيم
ضئيلة، لكنني محظوظ مع الأصفار هنا.
دعوني أمضي قدمًا وأنتقل إلى هذا السطر،
وإذا كنتم ترون ذلك، وإن كان صغيرًا،
في الجانب الأيمن، فيجب أن يأخذ x القيمة 1.
وإذا انتقلت إلى سطر واحد آخر،
فيجب أن يأخذ y القيمة 2.
حسنًا، إذن أنا واثق تمامًا أن
البرنامج حتى الآن صحيح.
سأمضي قدمًا وسأنتقل إلى printf.
ولاحظوا في النافذة الطرفية
الزرقاء، أنا أرى خرجًا واحدًا.
الآن تصبح الأشياء مثيرة للاهتمام.
إذا تابعت في الانتقال عبر السطور،
فسينهي ذلك التشغيل فقط
وهذا ليس كافيًا.

English: 
The little debugging panels
get opened on the side,
but wait, I need a breakpoint.
I'm going to start a breakpoint at the
very top, the first line I care about.
I don't really care about all
the stuff at the super top.
Now I'm going to go ahead and
rerun debug50 ./noswap, all right?
Now I see over here, the
first line 9 is highlighted.
Notice on the right-hand
side, and this perhaps
answers by example
your question earlier.
x and y conveniently, but just
because we're initialized to 0--
not by me, I shouldn't necessarily
trust this in all contexts,
but that's why they had values.
They're otherwise known as garbage
values, but I got lucky with 0's here.
Let me go ahead and step over that
line, and if you watch, albeit small,
on the right-hand side, x should
suddenly take on a value of 1.
And if I step over one more line,
y should take on a value of 2.
OK, so I'm pretty confident the
program is thus far correct.
I'm going to go ahead
and step over printf.
And notice the blue terminal
window, I see one output.
Now things get interesting.
If I continue stepping over lines,
it's just going to finish running
and that's not enough.

Arabic: 
لذا لاحظوا هذه المرة سأقوم بالتمرير
فوق الرمز الثالث هذا، Step Into.
الآن يمكنني نوعًا ما
النزول في جحر الأرنب،
إذا جاز التعبير،
والدخول إلى دالة المبادلة، ولاحظوا،
أن مصحح الأخطاء ينتقل
إلى الدالة الأخرى تلك.
إذن هنا الآن، تغيّر السياق.
متغيراتي المحلية الآن هي a، وb،
وtmp، وهذا حقًا أمر غريب.
A هو 1، b هو 2، كما هو متوقع،
لأنني تجاوزت x، y.
وفي سياق هذه الدالة
أطلق عليهما a، b فقط.
لكن لماذا tmp 32,767؟
فقط لأنه لا يمكن الوثوق به،
إنه قيمة ضئيلة.
إذا أعطيت نفسك قيمة مؤقتة،
مَن يدري ما الذي يوجد هناك؟
نحن محظوظون، وليس لدى تارا
أي شيء في هذا الكوب،
ولكن قد يكون له قيمة ضئيلة،
ربما يحتوي على بعض المياه الغازية،
ومن ثم كان يجب علينا استبدال
تلك القيمة بطريقة ما.
حتى نكون واضحين، عندما
تعلن عن متغيرات في برنامج،
كثيرًا ما تحتوي على قيم
ضئيلة، مجرد قيم وهمية--
فالأصفار والآحاد الموجودة هناك أسفل
الغطاء في هذه الشريحة،
ولكن لم تقم بتعيينها بنفسك.
ولكن لا بأس، لأنني صراحةً في إعداد
السطر التالي هذا حيث tmp يعادل a.

English: 
So notice this time I'm going to
hover over this third icon, Step Into.
Now I can kind of go
down the rabbit hole,
so to speak, and go into the
swap function, and notice,
the debugger jumps into
that other function.
So here now, the context changed.
My local variables are now a, b,
and tmp, and this is really weird.
A is 1, b is 2, as expected,
because I passed an x, y.
And in the context of this function
I'm just calling them a, b because.
But why is tmp 32,767?
It's just because it can't be
trusted, it's a garbage value.
If you just give yourself a temporary
value, who knows what's in there?
We got lucky and Tara did not
have anything in this cup,
but it could have had a garbage
value, maybe it had some Pepsi,
and then we would have had to
replace that value somehow.
So to be clear, when you
declare variables in a program,
quite often they have garbage
values, just bogus values--
the 0's and 1's that are there
underneath the hood in that chip,
but that you didn't set yourself.
But that's OK, because I'm explicitly in
this next line setting tmp equal to a.

English: 
So it doesn't matter what its original
weird value was, so if I click Next,
tmp is now 1, a.k.a.
a.
Now notice a is going to become b
if you watch the right-hand side.
Now I seem to have a is 2, b is 2, which
is a little worrisome but not as bad,
because I have that separate variable
tmp, so I still have the one around.
So now b is about to become 1,
and I've done the switcheroo.
OK, at this point in the story,
line 22, my code seems correct.
b has become a, a has become
b, and the values are swapped--
and the debugger is confirming
that for me visually.
So now, let's do a step and--
dammit.
Lost.
What is going on?
Intuitively?
Even if you've never seen or done this
before, like clearly there's a bug.
What is that bug?
What must be happening?
Yeah?

Arabic: 
لذا لا يهم ما كانت قيمته الغريبة
الأصلية، إذا قمت بالنقر على التالي،
tmp الآن يعادل 1، ويُعرف أيضًا بـ
a.
لاحظوا الآن أن a ستصبح b
إذا نظرتم إلى الجانب الأيمن.
الآن يبدو أن لدي a يعادل 2، b يعادل 2،
والذي يعد أمرًا مزعجًا قليلاً ولكنه ليس بهذا السوء،
لأن لدي المتغير المنفصل هذا tmp،
لذا ما زال لدي متغير في الجوار.
حتى الآن b على وشك أن تصبح 1،
وقمت بتنفيذ تبديل صف.
حسنًا، عند هذه النقطة في القصة،
السطر 22، تبدو التعليمة البرمجية صحيحة.
b أصبحت a، وa أصبحت b،
ويتم تبديل القيم--
ويؤكد لي مصحح الأخطاء هذا
ذلك بشكل مرئي.
إذن الآن، دعونا نقوم بخطوة و--
اللعنة.
لقد فقدته.
ما الذي يجري؟
بشكل حدسي؟
حتى ولو لم تروه أو تقوموا
به من قبل، من الواضح إنه خطأ.
ما هو هذا الخطأ؟
ماذا يجب أن يحدث؟
أجل؟

English: 
AUDIENCE: [INAUDIBLE]
a new value [INAUDIBLE]
doesn't have the same
address for the first one?
DAVID MALAN: Yeah.
What seems to be happening here
is yes, you're passing in x and y
and calling it a and b, but a and b
would seem to be copies of x and y.
And I am very successfully,
very correctly swapping a and b,
but because they're copies, it has
no effect on the original x and y.
So our metaphor here of
juice isn't quite apt
because I didn't pass Kelly
copies of the OJ and milk,
I handed her the actual OJ and milk
and she was able to change the values.
But in the context of C and code,
when you pass arguments to a function,
you're passing copies of those
arguments to the function.
So intuitively, what is the solution?
We clearly cannot pass from one function
to another copies of the values if we
expect the function swap, or a.k.a.
Kelly, to make some
useful change for us.
What do we have to pass to the
function or to Kelly instead?
The addresses of those values, right?
I told her where the milk and OJ were.

Arabic: 
الجمهور: [INAUDIBLE]
[INAUDIBLE] قيمة جديدة
ليس لها نفس عنوان القيمة الأولى؟
ديفيد مالان: أجل.
ما يبدو أنه سيحدث هنا هو أجل،
أنك تمر في x وy
وتطلق على ذلك a وb، لكن يبدو
أن a وb هي نسخ من x وy.
وأنني أقوم بتبديل a وb بشكل صحيح
وناجح جدًا،
ولكن نظرًا لأنها نُسخ، فليس لها
تأثير على x و y الأصليين.
لذا فإن استعارتنا هنا
للعصير ليست ملائمة تمامًا
لأنني لم أمرر نُسخ كيلي
من عصير البرتقال و الحليب،
لقد ناولتُها عصير البرتقال والحليب الفعليين
وتمكنت هي من تغيير القيم.
ولكن في سياق لغة C والتعليمة البرمجية،
عندما تقوم بتمرير الوسيطات إلى دالة،
فإنك تمرر نُسخًا من تلك
الوسيطات إلى الدالة.
إذن بديهيًا، ما هو الحل؟
لا يمكننا بالتأكيد المرور من دالة واحدة
لنُسخ أخرى من القيم إذا كنا
نتوقع مبادلة الدالة، أو المعروفة أيضًا باسم
كيلي، لإجراء بعض التغييرات المفيدة لنا.
ما الذي يجب علينا تمريره إلى الدالة
أو إلى كيلي بدلاً من ذلك؟
عناوين تلك القيم، أليس كذلك؟

Arabic: 
أخبرتُها بمكان الحليب وعصير البرتقال.
لم أعطها نُسخًا منها،
قلت لها، ها هو الحليب،
ها هو عصير البرتقال، استبدلي هذين.
في هذا الإصدار من التعليمة البرمجية،
لقد قلتُ للتو،
ها هي نسخة من x، وها هي نسخة من
y، يمكنك تسميتهما a وb-- نعم.
نحتاج الآن لاستخدام حرف العطف أو
شيء من هذا القبيل للتمرير في خريطة،
إن شئت.
خريطة الكنز لتلك القيم وبالتالي
المبادلة يمكنها تغيير القيم الأصلية.
والطريقة التي نفعل بها
هذا تبدو غريبة قليلاً،
لكن كل ما سيتوجب علينا
القيام به هو إجراء إضافة بسيطة هنا
والتي تبدو كما يلي.
يجب أن تبدو مثل هذا بدلاً من ذلك.
إذن هذا هو الإصدار المعطّل.
أو معطل بافتقاده للتأثير
الذي نقصده حتى بالرغم من عمله.
هذا هو ما نحتاج للقيام به بدلاً
من ذلك، وهو آخر جزء
من التعبير الجديد بالرموز في الوقت الحالي.
لقد رأينا نجمة في
مكانين مختلفين
من قبل، ونحن الآن نستخدمها
في سياق نهائي واحد.
عند تحديدك لنجمة هنا وهنا
في الوسيطات إلى دالة، فتلك
تحديدًا هي الطريقة التي
تقول بها للكمبيوتر، أنا
لا أتوقع عددًا صحيحًا int،
بل عنوان عدد صحيح int.

English: 
I didn't give her copies of them,
I told her, here's the milk,
here's the OJ, swap those.
In this version of the
code, I've just said,
here's a copy of x, here's a copy of
y, you can call them a and b-- um-mmm.
We need to now use the ampersand or
something like that to pass in a map,
if you will.
The treasure map to those values so that
swap can change the original values.
And the way we do this is
a little weird-looking,
but all we're going to have to
do is make a little addition here
that looks as follows.
It's got to look like this instead.
So this is the broken version.
Or broken in that it doesn't have the
effect we intend even though it works.
This is what we need to do
instead, and it's the last piece
of new symbology for today.
We've seen star in a
couple of different places
before, now we're using
it in one final context.
When you specify a star here and here
in the arguments to a function, that
is just the way you
tell the computer, I'm
expecting not an int, but
the address of an int.

Arabic: 
أنا لا أتوقع عددًا صحيحًا int هنا،
بل عنوان عدد صحيح int.
إذن مؤشران اثنان،
وعنوانان اثنان لأعداد صحيحة.
بالأسفل هنا، tmp هي ما زالت مجرد عدد صحيح int.
لستُ بحاجة لإمعان التفكير في
tmp، إنه مجرد كوب فارغ.
أعطني عددًا صحيحًا باسم tmp من الأسبوع الأول.
لكن، ما الذي أريد تخزينه في tmp؟
كل من a وb في هذا
الإصدار عبارة عن عنوانين.
هل أريد أن أتذكر
العنوان a والعنوان b؟
لا، بل أريد أن أتذكر
حجم عصير البرتقال، حجم الحليب،
أريد أن أتذكر 1 و2، لا أهتم
لمكان وجودهما في الذاكرة.
لذا فإن النجمة في هذا السياق،
عندما لا يوجد ذكر لنوع البيانات،
فهناك فقط نجمة واسم متغير.
ذلك المتغير هو مؤشر
وليس عملية ضرب،
فلا توجد هنا عمليات رياضية.
تلك النجمة هي عامل تشغيل الإسناد المؤشري
الذي يقول، انتقل إلى هذا العنوان
واحصل على القيمة هناك.
لذلك فإذا كان هذا العنوان a في الموقع،
فلا أعرف، 100 مثلما كان Brian،
وكان هذا العنوان b في
الموقع 900 مثلما كانت Veronica،

English: 
I'm expecting not an int here,
but the address of an int.
So two pointers, two
addresses of integers.
Down here, tmp is still just an int.
I don't need to over think
tmp, that's just an empty cup.
Give me an integer
called tmp from week 1.
But, what do I want to store in tmp?
Both a and b in this
version are addresses.
Do I want to remember the
address a and the address b?
No, I want to remember the
volume of OJ, the volume of milk,
I want to remember 1 and 2, I don't
care where in memory they are.
So star in this context, when
there's no mention of a data type,
there's just a star and a variable name.
That variable is a pointer
and it's not multiplication,
there's no math going on.
That star is the dereference operator
that says, go to this address
and get the value there.
So if this address a is at location,
I don't know, 100 like Brian was,
and this address b is at
location 900 like Veronica was,

Arabic: 
فإن *a تعني الانتقال إلى وحدة البايت صاحبة الترتيب رقم 100 في
الذاكرة وحصولي على تلك القيمة، وهي 1.
هذا يعني، بالأسفل هنا، الانتقال إلى العنوان
b، وحصولي على تلك القيمة في العنوان 900،
وهي 2.
والمضي قدمًا وتخرين 1 في tmp.
امضِ قدمًا وانتقل إلى ذلك
العنوان وضعه أيًا ما كان
في عنوان b-- إذن احصل على ذلك العنوان
وضَعه هناك-- واحصل على ذلك العنوان،
واحصل على القيمة، وضَعها هناك
في ذلك العنوان عن طريق الإسناد المؤشري.
وأخيرًا، انتقل إلى b في الذاكرة، كتلك
الموجودة هناك، وضَع قيمة tmp هناك.
لذا في حين أن علامة العطف في
المثال السابق لدينا تعني،
أخبرني ما هو عنوان متغير ما،
والنجمة هي العكس.
عندما يكون لديك عنوان،
فإنها تقول، انتقل إلى ذلك العنوان.
اتبع خريطة الكنز، حيث تحدد X
المكان في ذلك الموقع في الذاكرة،
واحصل عليه عند قيمته.
إذن ما هو التأثير الصافي هنا؟
إذا قمتُ الآن بالفعل بفتح
ليس هذا المثال، بل swap.c--
أداة التعطيل، فستعمل
هذه الأداة بالفعل.
إذا قمتُ الآن بفتح swap.c،
فسنرى الآن ما يلي بدلاً من ذلك.
التعليمة البرمجية هي نفسها تقريبًا،
باستثناء أني قمتُ بلصقها

English: 
*a means go to the 100th byte in memory
and get me that value, which is 1.
This means, down here, go to the address
b, get me that value at address 900,
which is 2.
And go ahead and store 1 in tmp.
Go ahead and go to that
address and put whatever's
at b's address-- so get that address
and put it over-- get that address,
get the value, and put it over
at that address by dereferencing.
And then lastly, go to b in memory, like
over there, put the tmp value there.
So whereas ampersand in
our previous example means,
tell me what the address is of a
variable, star is the opposite.
When you have an address,
it says, go to that address.
Follow the treasure map, X marks
the spot at that location in memory,
and get at its value.
So what is the net effect here?
If I actually now open up not
this example, but swap.c--
spoiler, this one is
going to actually work.
If I open up swap.c, we're going
to see now the following instead.
The code is almost the same,
except that I pasted it

English: 
in this new green
version of the function.
And notice here, this had a change.
Why am I typing in %x now and
%y instead of just x and y?
AUDIENCE: [INAUDIBLE] address
[INAUDIBLE] functions [INAUDIBLE]..
DAVID MALAN: Exactly.
The swap function now,
the new improved version
is expected two addresses-- stars.
Each star, a.k.a.
pointers, not just values.
So this means I know x and y are
actually integers from week 1.
Now I need the address
of x and the address of y
so that swap can follow
those treasure maps,
so to speak, and go to those addresses.
So now, when I run this program, this
is more like the metaphor with Kelly
where I told her where
the milk and OJ were.
Now swap and go to those
locations as follows. make swap.
Let me go ahead and
then do ./swap, Enter--
ah!
Now it seems to be working.
And we can see as much
even with the debugger.
Even though it doesn't seem to
be buggy, I can still use debug50

Arabic: 
في هذا الإصدار الأخضر
الجديد للدالة.
ولاحظوا هنا، أنه حدث تغيير لهذا.
لماذا أكتب الآن &x
و$y بدلاً من x وy فقط؟
الجمهور: [INAUDIBLE] عنوان
[INAUDIBLE] دوال [INAUDIBLE]..
ديفيد مالان: بالضبط.
دالة المبادلة الآن،
يُتوقّع للإصدار المحسن الجديد
عنوانان-- نجمتان.
كل نجمة، كما هي معروفة أيضًا باسم
المؤشرات، ليست مجرد قيم.
لذا فهذا يعني أنني أعرف أن x وy هما بالفعل
عددان صحيحان من الأسبوع الأول.
والآن أحتاج لعنوان
x وعنوان y
بحيث يمكن لهذه المبادلة اتباع
خرائط الكنز هذه،
إذا جاز التعبير، والانتقال إلى تلك العناوين.
لذا الآن، عندما أقوم بتشغيل هذا البرنامج، فهذا
يشبه إلى حد كبير الاستعارة المستخدمة مع كيلي
عندما أخبرتها بمكان
الحليب وعصير البرتقال.
الآن قم بالمبادلة وانتقل إلى تلك
المواقع على النحو التالي. make swap.
دعوني أمضي قدمًا
ثم أنفّذ ./swap، إدخال--
آه!
يبدو أنها تعمل الآن.
يمكننا مشاهدة ذلك
حتى باستخدام مصحح الأخطاء.
على الرغم من أنه لايبدو هناك خطأ،
فلا يزال بإمكاني استخدام debug50

Arabic: 
لرؤية برنامجي وفهمه،
إذا لم يكن واضحًا - أوه،
ما زلت بحاجة إلى نقطة توقف.
دعونا نعين نقطة توقف مثلما سبق.
دعونا نعيد تشغيل debug50.
ستفتح لي اللوحة
اليمنى بشكل تلقائي.
ودعونا نمضي قدمًا ونرى،
ما إذا كنتُ بدأت الانتقال بالتدرج عبر هذا،
الآن أرى أن x تساوي 1، y تساوي 2،
فتقوم الدالة printf بالطباعة بنفس القدر على الشاشة.
الآن سأمضي قدمًا
وأنتقل بالتدرج إلى المبادلة،
لاحظوا الآن،
إنها تبدو غريبة قليلاً،
لأن a الآن عبارة عن عنوان
وb عبارة عن عنوان،
ولكن لا يزال tmp عددًا صحيحًا int بقيمة
مهملة، ولكن يمكنني إصلاح ذلك.
الآن tmp يساوي 1، لكن لاحظوا،
أن قيم a وb لا تتغير،
ولكن ما هو التغيير الواضح
حسب التعليمة البرمجية؟
لذا لاحظوا، أن هذا غريب ومشفر.
a هي قيمة 0x هذه.
هذا عنوان سداسي عشري كبير،
مثل هذا الذي توجد فيه a في الذاكرة.
ولكن أتدرون ما الأمر؟
إذا قمتُ بالنقر فوق المثلث الصغير،
فيمكنني نوعًا ما متابعة ذلك المؤشر
والانتقال إليه.

English: 
to see and understand my
program, if not obvious-- oh,
I still need a breakpoint.
Let's set a breakpoint as before.
Let's rerun debug50.
The right-hand panel will
open automatically for me.
And let's go ahead and see,
if I start stepping over this,
now I see that x is 1, y is 2,
printf prints as much on the screen.
Now I'm going to go
ahead and step into swap,
and now notice, it's a
little weird-looking,
because now a is an address
and b is an address,
but tmp is still an int with a
garbage value, but I can fix that.
Now tmp is 1, but notice, a and
b's values are not changing,
but what is clearly
changing per the code?
So notice, this is weird and cryptic.
a is this 0x value.
That's a big hexadecimal address,
like that is where in memory a is.
But you know what?
If I click the little triangle,
I can kind of follow that pointer
and go to it.

English: 
The debugger is smart like that.
So *a, go to a is 2; and *b at the
moment is 2, but if I keep going,
now I've done a switcheroo, and you
can see that these values have changed.
And again, we don't care
what these addresses are,
I don't care what the
actual addresses are.
I do care that it gives me this
functionality, because now when
I return up here in print,
now the values have indeed
changed as I expected this whole time.
All right.
That was complex, but hopefully clear
as to why it now works even though we've
made this code look more cryptic.
If not, any questions are welcome.
Yeah?
AUDIENCE: Is that from
the spot where [INAUDIBLE]
DAVID MALAN: Uh huh.
AUDIENCE: [INAUDIBLE] the
star [INAUDIBLE] pointers?
DAVID MALAN: Good question.
Do we really need to have these
ampersands here because we already
have the stars here?
Short answer, yes, for symmetry.
This is telling the function
what to expect on the way in;

Arabic: 
يكون مصحح الأخطاء ذكيًا كذلك.
لذا *a، تنتقل إلى a تساوي 2؛ و*b في
هذه اللحظة هي 2، لكن إذا تابعتُ،
فأنا الآن قمتُ بتبديل مفاجئ، ويمكنكم
أن تروا أن هذه القيم قد تغيرت.
ومرة أخرى، نحن لا نهتم
بماهية هذه العناوين،
لا يهمني ما هي
العناوين الفعلية.
أنا أهتم بأن تمنحني
الدوال هذه، لأنني الآن عندما
أرجع هنا في الطباعة،
فإن القيم الآن بالفعل
قد تغيرت كما كنت أتوقع هذا طوال الوقت.
حسنًا.
كان ذلك معقدًا ، لكن نأمل أن يكون موضحًا
لسبب عملها الآن حتى رغم أننا قمنا
بجعل هذه التعليمة البرمجية تبدو أكثر تشفيرًا.
إن لم يكن ذلك، فأي أسئلة مرحب بها.
أجل؟
الجمهور: هل هذا من
المكان الذي [INAUDIBLE] فيه
ديفيد مالان: آه.
الجمهور: [INAUDIBLE]
النجمة [INAUDIBLE] مؤشرات؟
ديفيد مالان: سؤال جيد.
هل نحن حقًا بحاجة
لعلامات العطف هذه لأن لدينا بالفعل
هذه النجوم هنا؟
إجابة مختصرة، نعم، لأجل التماثل.
هذا يخبر الدالة
ما الذي يمكن توقعه خلال العملية؛

Arabic: 
وهذا ما يخبر جهاز الكمبيوتر
ما الذي سيرسله بالفعل.
إذن ما هي المدخلات الفعلية
لهذه الدالة؟
يجب أن تكون متناسقة.
أجل؟
الجمهور: تقوم قيمة [INAUDIBLE] بتبديل العناوين.
ديفيد مالان: نحن نقوم بتبديل ما هو موجود في العناوين.
الجمهور: إذن ماذا لو قمت بتغيير
عنوان [INAUDIBLE]
ديفيد مالان: حسنًا.
الجمهور: هل سنقوم بتبديل العناوين
بالقول أن 2 موجودة في 200 و1
موجود في [INAUDIBLE] والتي من الممكن أن تتغير.
ديفيد مالان: إجابة مختصرة، لا يمكنك
للسبب التالي.
من الناحية الفنية: عندما نقوم
بكتابة %x و%y، فسيتم تحويلهما إلى عنوان
x، وعنوان y.
فالتبديل من الناحية الفنية هو الحصول على نُسخ
من شيء ما، ولم تتغير C.
لكن تحصل C الآن على
نُسخ من عنوان
x، ونسخ من عنوان y
ويطلق عليهما a وb.
بالتأكيد، يمكنك تبديل العناوين،
ولكن للأسباب نفسها كما في السابق،
فلن يكون لها أي تأثير أساسي.

English: 
this is what's telling the
computer actually what to send in.
So what are the actual
inputs to that function?
It has to be symmetric.
Yeah?
AUDIENCE: [INAUDIBLE] value
is swapping addresses.
DAVID MALAN: We are swapping
what is at the addresses.
AUDIENCE: So what if you change
the address of [INAUDIBLE]
DAVID MALAN: OK.
AUDIENCE: And would we swap the
addresses saying 2 is at 200 and 1
is at [INAUDIBLE] that could change.
DAVID MALAN: Short answer, you
cannot for the following reason.
So technically, when you do %x and
%y, these are converted to the address
of x, the address of y.
Technically swap is getting copies
of something, C has not changed.
But C is now getting
copies of the address
of x, copies of the address
of y, calling them a and b.
So sure, you could swap the addresses,
but for the same reasons as before,
it's going to have no
fundamental effect.

Arabic: 
الاختلاف هنا هو لأنني أقوم بالتمرير
في الخريطة، إذا جاز التعبير،
إلى x وy، عنوانيهما.
ومرة أخرى، فإن العنوان مثل--
أعتقد أننا الآن في
45 Quincy Street--
Cambridge، Massachusetts 02138، USA.
هذا يميز المبنى بشكل فريد.
تحدد هذه الأرقام السداسية العشرية الخاصة بـ 0x
المواقع في الذاكرة بشكل فريد.
إذن هذا مثل القول الآن، أعطني
عنوان x، أعطني عنوان y،
وأنا أقوم من الناحية الفنية بالتمرير في نُسخ
هذه العناوين، ولكن لا يهم،
لأن القيام بتدوين النجمة الأن،
فأنا أقول الانتقال إلى تلك العناوين
وتبديل الشخص الموجود بشكل
مادي في هذا المبنى بشخص آخر.
حسنًا.
لذا دعونا فقط نضع هذا الآن
في سياق ما الذي
يشتمل عليه أيضًا
جهاز الكمبيوتر مجرد أنكم
شاهدتم بعض التسميات حول
ذاكرة جهاز الكمبيوتر هذا.
إذن هذه هي الشريحة التي تحتوي على شبكة
موضوع فوقها
فقط لتوصيل وجود وحدات
بايت هنا، ويمكننا ترقيمها.
ولكن دعونا نفكر بشأن
هذا الآن بطريقة تجريدية أكثر،
ودعوني أكشف أنه
سيتضح أن جهاز الكمبيوتر يعامل
وحدات البايت المختلفة، المربعات المختلفة
بطرق مختلفة فقط عن طريق التقليد.
من الواضح أنه في
ذاكرة جهاز الكمبيوتر الخاص بك--
وهذا كله مجرد تمثيل فني--

English: 
The difference here is because
I'm passing in a map, so to speak,
to x and y, their addresses.
And again, an address is like--
we are at 45 Quincy
Street I think right now--
Cambridge, Massachusetts 02138, USA.
That uniquely identifies the building.
These 0x hexadecimal numbers uniquely
identify locations in memory.
So this is like saying now, get me the
address of x, get me the address of y,
and I'm technically passing in copies of
those addresses, but it doesn't matter,
because now with the star notation,
I'm saying go to those addresses
and swap who is physically in
this building and some other.
All right.
So let's just put this now
into the context of what else
your computer actually
has just that you've
seen some nomenclature around
this computer's memory.
So this is the chip with a
grid laid out on top of it
just to communicate that there's
bytes here, and we could number them.
But let's think about
this now more abstractly,
and let me just reveal that it
turns out that the computer treats
different bytes, different squares
in different ways just by convention.
It turns out that in
your computer's memory--
and this is all just an
artist's representation--

Arabic: 
في الجزء العلوي من شريحة
الذاكرة تلك، إذا جاز التعبير،
وهو ما يسمى بنص برنامجك.
هذه طريقة رائعة وغير واضحة لقول
الأصفار والأحاد التي تم تحويلها برمجيًا
إلى تعليماتك البرمجية.
نص البرنامج هو التعليمات البرمجية
التي كتبتها في النظام الثنائي،
حيث تم تحميلها من الذاكرة.
لذا في macOS وWindows،
تقوم بالنقر المزدوج على رمز،
فيتم تحميل هذا البرنامج في
الذاكرة كما قلت الأسبوع الماضي.
يتم تحميله حرفيًا في الجزء العلوي من
ذاكرة الكمبيوتر الخاص بك من الناحية النظرية.
ماذا أيضًا؟
حسنًا، الكومة هي الاسم الوهمي الذي يتم منحه
لجزء الذاكرة الذي تأتي
الذاكرة منه عندما تقوم باستدعاء malloc.
لذا عندما قمتُ باستدعاء malloc في وقت سابق للحصول
على مساحة كبيرة لبعض الأحرف،
فإنها كانت تأتي فقط من هذه
المنطقة المفتوحة الكبيرة التي تسمى الكومة.
وهذا ما يستخدمه get_string
والوظائف الأخرى كذلك.
حسنًا، من الواضح أن سبب
المشكلة التي واجهناها للتو
هو أن الجزء السفلي من الذاكرة والذي يسمى المكدس.
والمكدس هو مساحة الذاكرة التي تستخدمها الوظائف
عندما يتم استدعاؤها.
وهذا بالفعل ذو صلة بمثال noswap
البسيط جدًا على النحو التالي.

English: 
at the top of that chip
of memory, so to speak,
is the so-called text of your program.
This is a fancy and
non-obvious way of saying
the 0's and 1's that your code
have has been compiled into.
The text of a program is the
code you wrote in binary,
that's where it's loaded from memory.
So in macOS and Windows,
you double-click an icon,
that program is loaded into
memory I said last week.
It's literally loaded into the top of
your computer's memory conceptually.
What else?
Well the heap is the fancy name given
to the chunk of memory in which memory
is coming from when you call malloc.
So when I called malloc earlier to get
a bunch of space for some characters,
it was just coming from this
big open area called the heap.
And that's what get_string is
using and other functions as well.
Well it turns out that the reason
for the problem we just ran into
is because the bottom part of
memory is what's called the stack.
The stack is the area of memory that
functions use when they are called.
And this is actually relevant to that
very simple noswap example as follows.

Arabic: 
لو افترضنا الآن أن في أي وقت تقوم
باستدعاء وظيفة، فإن الذاكرة التي تستخدمها
تأتي من أسفل
تلك الكتلة الكبيرة من الذاكرة،
التي يمكنك فيها رسم تلك الدالة، على سبيل المثال،
هنا على الشاشة،
لأنه يتضح أن في أي وقت تقوم فيه
باستدعاء دالة، فإن تلك الوظيفة
تحصل على شريحة من ذاكرتها الخاصة.
إذن على سبيل المثال، main تكون دائمًا
البرنامج الأول الذي تستدعيه وظيفة،
ولذلك تحصل على الشريحة الأولى من
الذاكرة في أسفل الشاشة هنا.
وبالتالي إذا كان هناك متغيران في main وهما
x وy، فهذا مثل قول،
حسنًا ، أعطني جزءًا من الذاكرة
يسمّى x وضع القيمة 1 فيه؛
أعطني جزءًا آخر من الذاكرة،
وأطلق عليه y، وضَع قيمة فيه هنا.
ولكن تذكّروا، من المثال noswap الأول،
أنه تم استدعاء وظيفة swap.
وهذا هو المكدس بالمعنى الحرفي.
أنتم تذهبون إلى قاعة طعام، مقهى،
صينية واحدة للطعام، وفوقها واحدة أخرى،
وفوقها واحدة أخرى، وفوقها واحدة أخرى،
بحيث يمكن للأشخاص أخذها
ووضع الطعام والأطباق عليها.
وبالمثل تمامًا في هذا النموذج،
عندما تستدعي وظيفة،
فإنها تحصل على شريحة الذاكرة الخاصة بها،
ولكن حرفيًا، من الناحية النظرية، أعلى
الإطار الموجود على المكدس.

English: 
If we now assume that anytime you
call a function, the memory it uses
comes from the bottom of
that big block of memory,
where you can draw that, for
instance, here on the screen,
because it turns out that anytime you
call a function, that function gets
a slice of its own memory.
So for instance, main is always
the first program a function calls,
and so it gets the first slice of
memory at the bottom of the screen here.
And so if main had two variables
x and y, that's like saying,
OK, give me a chunk of memory
called x and put the value 1 in it;
give me another chunk of memory,
call it y, put a value in it here.
But remember, from the first noswap
example, the swap function was called.
This is a stack in the literal sense.
You go into a dining hall, a cafeteria,
one tray for food, goes on another,
goes on another, goes on another
so that the humans can take it
and put food and plates on it.
Well similarly in this model,
when you call a function,
it gets its own slice of memory,
but literally above, conceptually,
the existing frame on the stack.

Arabic: 
إذن هذه هي قطعة الذاكرة
الخاصة بدالة swap لديك،
وهي تحصل، أيضًا، على بعض المساحة.
تحصل على بعض المساحة
لمتغير يسمّى a.
وتحصل على بعض المساحة
لمتغير يسمّى b.
وخمّنوا ما الذي يدخل إلى
هذين المتغيرين في المثال الأول هذا؟
نسخة من x ونسخة من y.
أتعلمون ما الأمر؟
كان بها متغير temp، لذلك تم الحصول
عليه لامتلاك بعض المساحة هنا.
إذن سأسمّي هذا tmp.
وتذكّروا أنني قمت بتعيين tmp
تساوي a، وبالتالي حصلت على 1.
وماذا حدث بعد؟
حسنًا وماذا فعلت بعد ذلك--
ماذا فعلت؟
دعوني أصل إلى هذا مباشرة.
كان لدينا a تحصل على b.
إذن ما الذي حدث هناك؟
إذن في هذا المثال هنا، تحصل a على
القيمة 2، لذا فقد تغيرت.
ثم ماذا حدث هنا، حصلت b
على القيمة 1، بالتالي فقد تغيرت.
لذا كانت swap تعمل بمعنى
أنه قام بتبديل القيم،
ولكن المشكلة هي، عند تعيد وظيفة،
فهذا الجزء من الذاكرة الذي
تم استخدامه سابقًا يتم استرداده
حتى يمكن لشخص آخر الآن استخدامه،

English: 
So this is the swap function's
own chunk of memory,
and it, too, gets some space.
It gets some space for
a variable called a.
It gets some space for
a variable called b.
And guess what goes inside
those of that first example?
A copy of x and a copy of y.
And you know what?
It had a temp variable, so that's
got to have some space here.
So I'll call this tmp.
And recall that I set tmp
equal to a, so that got 1.
And then what happened?
Well then I did what--
what did I?
Let me get this right.
We had a gets b.
So what happened there?
So in this example here, a gets
the value b, so that changed.
And then what happens here, b got
the value of 10, so that changed.
So swap was working in the sense
that it was swapping values,
but the problem is, when a function
returns, this chunk of memory that it
was previously using gets reclaimed
so that someone else can now use it,
another function.

English: 
So we did all that hard work and
no swap, and we did it correctly,
we just did it in the wrong place.
So by contrast, this next example
that we did, which was swap.c,
just treated the memory
a little bit differently.
Main this time still had two
variables called x, and this was a 1,
and then another one
called y, and this was a 2.
And then one swap was
called this time, it again
had a variable called
a and a variable called
b, but what was stored in a and b?
Well now they're addresses.
And I don't know what it is, but let
me just arbitrarily say that this
is location 100, this is location--
let's say 104.
But it could be anything, we
just don't care at this point,
it would have 0x technically if
the computer were showing us.
What's going in a here is 100,
what's going in b here is 104.
And those are the addresses
of x and y, and the code
we had using all of those
new stars was saying,

Arabic: 
كوظيفة أخرى.
إذن قمنا بكل ذلك العمل الشاق وبدون
إجراء تبديل، وقمنا بذلك بشكل صحيح،
لقد قمنا بذلك في المكان الخطأ فقط.
لذا على النقيض من ذلك، هذا المثال التالي
الذي قمنا به، والذي كان swap.c،
عامَل الذاكرة فقط
بطريقة مختلفة قليلاً.
ما يزال لدى Main هذه المرة متغيرين
يسمى x، وكان هذا a 1،
والآخر يسمّى
y، وكان هذا a 2.
ثم تمت تسمية مبادلة واحدة
هذه المرة، مجددًا
لديها متغير يسمّى
a ومتغير يسمّى
b، ولكن ما الذي تم تخزينه في a وb؟
حسنًا الآن هم عناوين.
وأنا لا أعرف ما هذا، ولكن دعوني
أقول ذلك بشكل اعتباطي أن هذا
هو الموقع 100، هذا الموقع--
دعونا نقول 104.
ولكن يمكنه أن يكون أي شيء،
ونحن لا نكترث لهذه النقطة،
قد يشتمل على 0x من الناحية الفنية إذا
كان الكمبيوتر يعرض لنا ذلك.
الذي يحدث في a هنا هو 100،
والذي يحدث في b هنا هو 104.
وتلك هي عناوين
x وy، وتقول التعليمات البرمجية حيث
كنا نستخدم جميع تلك
النجوم الجديدة،

English: 
go to address 100 and store
whatever is at address 100 in tmp.
Then go to the address
that's in b, or 104,
and store that at the location
int *a, whatever is there.
Then it was saying, go get
that 10th value, by the way,
and go ahead and put that
here, so that now we did
different work in a different place.
So now when swap is
done running, it doesn't
matter if its memory disappears
because it has now mutated or changed
the other memory.
That it was passed in just like
Kelly changed or mutated the cups
I actually pointed her at
rather than copies thereof.
Now as an aside, there's other chunks
of memory that are actually used.
If you have global
variables in a program,
turns out that in between
the text and the heap
memory are your global variables,
if they're initialized with values
or they're not initialized with values,
as would happen with the equal sign,
but we don't care too much
about that for today's purposes.
And if you've ever heard of
environment variables, which

Arabic: 
انتقل إلى عنوان 100 وخزِّن
أي شيء في العنوان 100 في tmp.
ثم انتقل إلى العنوان
الذي في b أو 104،
وخزِّن هذا في الموقع
int *a، أيًا كان هناك.
بعد ذلك تقول، احصل على
تلك القيمة 10، بالمناسبة،
وامضي قدمًا وضَع هذا
هنا، إذن الآن قمنا
بعمل مختلف في مكان مختلف.
إذن الآن عندما يكون تنفيذ
المبادلة قيد التشغيل، فلا يهم
إذا اختفت ذاكرتها
لأنها تحولت أو تغيرت الآن
إلى الذاكرة الأخرى.
التي تم تمريرها للتو مثلما
قامت كيلي بتغيير أو تحويل الأكواب
لقد أشرت إليها في الواقع بدلاً من نسخها.
وبعيدًا عن موضوعنا الآن، هناك أجزاء أخرى
من الذاكرة التي يتم استخدامها بالفعل.
إذا كانت لديك متغيرات
عالمية في أحد البرامج،
يتضح أنه يوجد بين
ذاكرة النص وذاكرة
الكومة متغيراتك العالمية،
إذا تمت تهيئتها باستخدام القيم
أو لم تتم تهيئتها بستخدام القيم،
كما سيحدث مع علامة يساوي،
لكننا لا نهتم كثيرًا
بذلك لأغراض اليوم.
وإذا كنت قد سمعت من قبل عن
متغيرات البيئة، والتي

Arabic: 
سنسمع عنها عندما نصل إلى
برمجة الويب، التي يتم أيضًا
تخزينها في مكان آخر في الذاكرة.
ولكن الجزئين الأكثر إثارة
للاهتمام من الذاكرة
هما المكدس والكومة،
كما في هذه الحالة هنا.
ولكن لسوء الحظ إنه لمن السهل
أن تنحرف الأشياء--
أعني، بعضكم جرّب
أخطاء التجزئة بالفعل،
ودعونا نفكر
لماذا قد يحدث ذلك.
إذن، هنا مثال مُستنبط
من التعليمات البرمجية بواسطة تصميم الخطأ،
ولكن دعونا نتحدث عنها فقط
باللغة الإنجليزية ما الذي تقوم به هذه السطور.
هذا السطر هنا، يقول،
int *x، مرحبًا، جهاز الكمبيوتر،
أعطني متغيرًا سيقوم
بتخزين عنوان عدد صحيح.
إذن أعطني مؤشرًا إلى عدد صحيح وهي
الطريقة الأكثر حداثة لقول ذلك.
مرحبًا جهاز الكمبيوتر، أعطني
متغيرًا آخر يقوم
بتخزين عنوان
عدد صحيح وأطلق عليه y.
إذن x وy، هذا كل شيء.
هذا السطر جديد.
مرحبًا جهاز الكمبيوتر، قم بتخصيص مساحة
كافية تناسب عددًا صحيحًا.
إذن sizeof int هي الصياغة الجديدة التي
رأيناها في وقت سابق لاكتشاف
عدد وحدات البايت في أي عدد صحيح فقط.
الاحتمالات هي أنه سيعود
كعدد 4 أو 32 وحدة بايت في معظم أجهزة الكمبيوتر.
إذن فهذا سيقول فقط، مرحبًا أيها المتصفح،
أعطني 4 وحدات بايت من الذاكرة

English: 
we will when we get to web
programming, they, too,
are stored elsewhere in memory.
But the most interesting
chunks of memory
are stack and heap,
as in this case here.
But unfortunately it's so
easy for things to go awry--
I mean, some of you experienced
segmentation faults already,
and let's consider
why that might happen.
So here's a contrived example
of code that is by design buggy,
but let's just talk it through in
English what these lines are doing.
This line here, int *x,
is saying, hey, computer,
give me a variable that will
store the address of an integer.
So give me a pointer to an int is
the more casual way of saying it.
Hey computer, give me
another variable that's
going to store the address
of an int and call it y.
So x and y, that's it.
This line is new-ish.
Hey computer, allocate enough
space that will fit an int.
So sizeof int is the new syntax we
saw earlier for just figuring out
how many bytes is an int.
Odds are this is going to come back
as 4 or 32 bits in most computers.
So this just says, hey browser,
give me 4 bytes of memory

Arabic: 
وقم بتخزينها في هذا الموقع.
أو بدلاً من ذلك، قم بتخزينها في هذا المتغير،
قم بتخزين هذا المتغير.
إذن ربما سيقول، حسنًا،
هنالك أربع وحدات بايت في الموقع 100،
أو توجد أربع وحدات بايت في الموقع 900.
أو في أي مكان، لا يهم، نحن
فقط نتذكر ذلك العنوان في x.
وتقول *x، انتقل إلى ذلك العنوان--
100 أو 900، أيًا كان،
وضَع الرقم 42 هناك.
يقول هذا السطر التالي، انتقل إلى العنوان
في y وضَع الرقم غير المحظوظ - المحوا،
المحوا--
13 هناك.
حسنًا ما هو العنوان في y؟
لم أقم بتخصيصه بعد.
ما هو العنوان في x؟
إنه حيث تخبرني malloc
باستخدام مساحة.
ذلك آمن، كان ذلك مثل 100،
900، أيًا كانت القيمة،
ولكن هل قمتُ بتخصيص مساحة لـ y؟
إذن ما نوع القيمة الذي
تحتوي عليه، إذا جاز التعبير؟
قيمة ضئيلة.
ربما تكون 0، ربما تكون
مثل 32000-- لا نعرف،
لأنك إذا لم تقم
بتحديد القيمة، فليس
من الآمن الوثوق بها
أو القيام بأي شيء باستخدامها.

English: 
and store that in this location.
Or rather, store that in this
variable, store that this variable.
So maybe it's going to say, OK,
here's four bytes at location 100,
or here's four bytes at location 900.
Or wherever, we don't care, we're
just remembering that address in x.
*x says, go to that address--
100 or 900, whatever it is,
put the number 42 there.
This next line says, go to the address
in y and put the unlucky number-- hint,
hint--
13 there.
Well what is the address in y?
I haven't allocated it yet.
What's the address in x?
It's wherever malloc
told me to use space.
That's safe, that was like 100,
900, whatever the value was,
but did I allocate space for y?
So what kind of value does
it contain, so to speak?
A garbage value.
Maybe it's 0, maybe it's
like 32,000-- we don't know,
because if you don't
specify the value, it
is not safe to trust it
or do anything with it.

Arabic: 
سيعطيني هذا على الأرجح
إحدى أخطاء التجزئة تلك.
وبالفعل، إذا قمتُ بتشغيل
برنامج مثل هذا،
فمن المحتمل جدًا أن أرى
بالضبط ذلك النوع من المشاكل.
ربما يكون من الأفضل، رغم ذلك،
رؤية هذا بالطريقة التي
سترسم صورة أكثر رسوخًا في الذاكرة،
ولهذا، أعتقد أننا سنتناول--
في الدقائق العشر المتبقية لدينا،
استخدام بعض من هذه الدقائق
لإلقاء نظرة على شيء
قام أصدقاؤنا في جامعة ستانفورد
بإعداده سويًا باستخدام بعض من الرسوم المتحركة الطينية.
إنه يستغرق حوالي ثلاث دقائق،
والأمر يستحق رسم
صورة للخطأ الذي
يحدث بالضبط
عندما لا تستخدم الذاكرة بشكل صحيح.
إذا كنت تستطيع تخفيف الأضواء.
[VIDEO PLAYBACK]
[MUSIC PLAYING]
- مرحبًا، بينكي.
استيقظي!
حان الوقت لمتعة المؤشر!
- ما هذا؟
التعرّف على المؤشرات؟
أوه رائع!
- بداية جيدة، أعتقد أننا
سنحتاج لمؤشرين اثنين.
- حسنًا.
تخصص التعليمات البرمجية تلك مؤشرين
يمكن أن يشيرا إلى الأعداد الصحيحة.
- حسنًا.
حسنًا رأيت المؤشرين، لكن
لا يبدو أنهما يشيران إلى أي شيء.
- هذا صحيح.
في البداية لا تشير المؤشرات
إلى أي شيء.
تسمّى الأشياء التي تُشار إليها
باسم pointees

English: 
This is going to give me probably
one of those segmentation faults.
And indeed, if I run
a program like this,
I'm quite likely going to see
exactly that kind of problem.
It's perhaps better, though,
to see this in a way that
will paint a more memorable picture,
and for that, thought we'd take--
in our 10 minutes remaining,
use a few of these minutes
to take a look at something
our friends at Stanford
put together with a bit of claymation.
It's about three minutes
long, well worth it
to paint a picture of
exactly what goes wrong
when you don't use memory correctly.
If you could dim the lights.
[VIDEO PLAYBACK]
[MUSIC PLAYING]
- Hey, Binky.
Wake up!
It's time for pointer fun!
- What's that?
Learn about pointers?
Oh goody!
- Well to get started, I guess we're
going to need a couple of pointers.
- OK.
This code allocates two pointers
which can point to integers.
- OK.
Well I see the two pointers, but they
don't seem to be pointing to anything.
- That's right.
Initially pointers
don't point to anything.
The things they point
to are called pointees,

Arabic: 
وإعدادهم لخطوة منفصلة.
- أوه، صحيح، صحيح.
علمت ذلك.
pointees منفصلة.
إذن كيف تخصص pointee؟
- حسنًا.
حسنًا تخصص تلك التعليمات
البرمجية pointee لعدد صحيح جديد،
ويقوم هذا الجزء بتعيين x للإشارة إليه.
- مهلاً، هذا يبدو أفضل.
إذن اجعله يفعل شيئًا.
- حسنًا.
كيف يمكنك الإشارة إلى المؤشر x
لتخزين الرقم 42 في pointee الخاص به؟
بالنسبة إلى تلك الخدعة، أحتاج
إلى عصاي السحرية الخاصة بالإسناد المؤشري.
- عصاك السحرية الخاصة بالإسناد المؤشري؟
هذا-- أمر رائع.
- هكذا تبدو التعليمات البرمجية.
سأقوم فقط بإعداد الرقم و--
[POP]
- انظر!
ها هو ينتقل.
إذن، يتبع القيام بالإسناد المؤشري على x
السهم للوصول إلى pointee الخاص به.
في هذه الحالة، لتخزين 42 هناك.
مهلاً، حاول استخدامه لتخزين الرقم
13 عبر المؤشر الآخر، y.
- حسنًا.
سأنتقل من هنا فقط إلى y
وأقوم بإعداد الرقم 13،
ثم آخذ عصا
الإسناد المؤشري وفقط--
[BUZZING] آه!

English: 
and setting them up to a separate step.
- Oh right, right.
I knew that.
The pointees are separate.
So how do you allocate a pointee?
- OK.
Well this code allocates
a new integer pointee,
and this part sets x to point to it.
- Hey, that looks better.
So make it do something.
- OK.
How do you reference the pointer x to
store the number 42 into its pointee?
For this trick, I'll need my
magic wand of dereferencing.
- Your magic wand of dereferencing?
That-- that's great.
- This is what the code looks like.
I'll just set up the number and--
[POP]
- Hey look!
There it goes.
So doing a dereference on x follows
the arrow to access its pointee.
In this case, to store 42 in there.
Hey, try using it to store the number
13 through the other pointer, y.
- OK.
I'll just go over here to y
and get the number 13 set up,
and then take the wand of
dereferencing and just--
[BUZZING] whoa!

Arabic: 
- أوه مهلاً، هذا لم ينجح.
أقول، يا بينكي، لا أعتقد
أن الإسناد المؤشري فكرة جيدة،
لأن إعداد
pointee هو خطوة منفصلة
ولا أعتقد أننا فعلنا ذلك من قبل.
- اممم، ملاحظة جيدة.
- أجل.
لقد قمنا بتخصيص مؤشر y، لكننا
لم نقم بتعيينها أبدًا لتشير إلى pointee.
- اممم، شديد الملاحظة.
-مهلاً، تبدو جيد هناك، يا بينكي.
هل يمكنك إصلاح ذلك بحيث يشير y
إلى pointee نفسه مثل x؟
- بالتأكيد.
سأستخدم عصاي السحرية
الخاصة بمهمة المؤشر.
- هل سيتسبب هذا في حدوث
مشكلة كالسابق؟
- لا، هذا لا يلمس pointees.
يقوم فقط بتغيير مؤشر واحد
للإشارة إلى الشيء نفسه كشيء آخر.
- أوه، أرى ذلك.
الآن يشير y إلى المكان نفسه مثل x.
إذن انتظروا، الآن تم إصلاح y.
لديه pointee.
إذن يمكنك تجريب عصا الإسناد
المؤشري مجددًا لإرسال 13 إلى هناك.
- حسنًا.
ها هو يذهب.
- مهلاً، انظر إلى هذا.
يعمل الآن الإسناد المؤشري على y.
ونظرًا لأن المؤشرات تتشارك في
pointee واحد، فإن كليهما يرى 13.
- نعم، مشاركة، أيًا كان.
إذن سنقوم بتبديل الأماكن الآن؟

English: 
- Oh hey, that didn't work.
Say, Binky, I don't think
dereferencing y is a good idea,
cause setting up the
pointee is a separate step
and I don't think we ever did it.
- Mmm, good point.
- Yeah.
We allocated the pointer y, but we
never set it to point to a pointee.
- Mmm, very observant.
- Hey, you're looking good there, Binky.
Can you fix it so that y points
to the same pointee as x?
- Sure.
I'll use my magic wand
of pointer assignment.
- Is that going to be
a problem like before?
- No, this doesn't touch the pointees.
It just changes one pointer to
point to the same thing as another.
- Oh, I see.
Now y points to the same place as x.
So wait, now y is fixed.
It has a pointee.
So you can try the wand of
dereferencing again to send the 13 over.
- OK.
Here goes.
- Hey, look at that.
Now dereferencing works on y.
And because the pointers are sharing
that one pointee, they both see the 13.
- Yeah, sharing, whatever.
So we going to switch places now?

English: 
- Oh look, we're out of time.
- But--
[END PLAYBACK]
DAVID MALAN: All right.
So hopefully that puts a little more
visual behind some of these ideas,
but let's now contextualize
this in a domain that's perhaps
more familiar in a couple of ways.
So one, some of you might
already know, especially
if you've had prior programming
experience, of a very popular website
called Stack Overflow
where lots of programmers
post questions and hopefully answers
to common technical problems.
If you ever wondered why
it's called Stack Overflow,
it turns out it reduces
to this picture here.
This was not a mistake that I drew
one arrow from the heap pointing down,
and one arrow from the stack growing up.
As you malloc, malloc,
malloc more and more space,
starts up here, so to speak, and
you just get more and more space
that's going this direction.
But the more functions you
call-- function after function
after function after a
function, each of them
gets its own slice or frame of
memory, that, too, is growing up.
So this feels like a pretty bad design,
but honestly, it's not really avoidable
because if you have a
finite amount of memory,
you can't avoid each other forever.

Arabic: 
- أوه لاحظ، الوقت ينفد.
- لكن--
[END PLAYBACK]
ديفيد مالان: حسنًا.
إذن آمل أن يرسخ هذا رؤية
بصرية أكثر حول بعض هذه الأفكار،
ولكن دعونا الآن نحدد سياقات
هذا في مجال من المحتمل أن يكون
أكثر إلمامًا بالطريقتين.
إذن الأولى، البعض منكم قد
يعرفه بالفعل، خصوصًا
إذا كانت لديكم خبرة سابقة في البرمجة،
من موقع ويب شائع جدًا
باسم Stack Overflow
حيث الكثير من المبرمجين
يقومون بنشر الأسئلة وأحيانًا الإجابات أيضًا
حول المشاكل الفنية الشائعة.
إذا تساءلت لماذا
يسمّى Stack Overflow،
يتضح أنه يختزل إلى
هذه الصورة هنا.
ولم يكن هذا خاطئًا أنني رسمت
سهمًا واحدًا من الكومة يشير إلى أسفل،
وسهمًا آخر من المكدس يشير للأعلى.
فكلما قمت بتنفيذ دالة malloc،
مرة تلو أخرى، تبدأ مساحات أكبر وأكبر،
بالظهور هنا، إذا جاز التعبير، و
ستحصل على المزيد والمزيد من المساحة
والتي تذهب إلى هذا الاتجاه.
لكن كلما زادت الدالات التي
تطلق عليها اسم-- دالة بعد دالة
بعد دالة بعد دالة،
كل واحدة منها
تحصل على شريحتها الخاصة أو إطار الذاكرة
هذا، أيضًا، الذي يرتفع لأعلى.
إذن هذا يبدو وكأنه تصميم سيئ للغاية،
ولكن بصراحة، ولا يمكن تجنبه حقًا
لأنه إذا كان لديك
مساحة محدودة من الذاكرة،
لا يمكنك تجنب بعضها البعض إلى الأبد.

English: 
And so there's this fundamental
risk of overflowing the stack,
or even overflowing the heap
in the reverse direction.
So Stack Overflow is an allusion
to, for instance, calling too
many-- many, many, many, many,
many, many, many, many functions,
so many so that it overlaps other
chunks or segments of memory,
thereby inducing a segmentation
fault, and buffer heap overflow
is in the reverse direction,
and these are more
generally known as buffer overflows,
and we'll see more of these in the weeks
to come.
But now that we have the
ability to discuss pointers,
let's introduce one final
feature and then a familiar face.
So it turns out that you can actually
come up with your own custom variables
kind of like we did with string, but
even more sophisticated than that.
For instance, if I wanted
to implement a program that
involves multiple students, I
might do something like this.
Ask the user what is the enrollment
in a class, then go ahead
and give myself an
array of strings, a.k.a.
char*s today of that size, and then I
could also have another array of dorms.

Arabic: 
ولذا يوجد خطر
أساسي متمثل في تجاوز المكدس،
أو حتى تجاوز الكومة
في الاتجاه المعاكس.
إذن موقع Stack Overflow هو إشارة
إلى، على سبيل المثال، تسمية
دالات-- كثيرة،كثيرة،كثيرة،كثيرة،
كثيرة،كثيرة،كثيرة،كثيرة،
كثيرة للغاية بحيث تتداخل مع أجزاء
أخرى أو أجزاء من الذاكرة،
وبالتالي بما في ذلك خطأ
التجزئة، وتجاوز سعة التخرين المؤقت للكومة
يكون في الاتجاه المعاكس،
ويعرف هذا كثيرًا
عمومًا باسم تجاوزات سعة التخزين المؤقت،
وسنرى المزيد من هذه في الأسابيع
المقبلة.
لكن الآن يمكننا
مناقشة أمر المؤشرات،
دعونا نقدم ميزة واحدة نهائية
ثم وجه مألوف.
إذن يتضح أنه يمكنك في الواقع
إنشاء متغيراتك المخصصة
مثلما فعلنا مع سلسلة، ولكن
أكثر تطورًا من ذلك.
على سبيل المثال، إذا رغبت في
تنفيذ برنامج
يحتوي على عدة طلاب،
قد أقوم بفعل شيء من هذا القبيل.
اسأل المستخدم ما هو
التسجيل في الصف، ثم امضِ قدمًا
وأعطني مصفوفة من
السلاسل، والمعروفة أيضًا باسم
char*s حاليًا بذلك الحجم، وبعد ذلك يمكنني
أيضًا الحصول على مصفوفة أخرى للمساكن.

Arabic: 
ويمكنني الحصول على مصفوفتين تحتوي
واحدة على أسماء الطلاب،
وأخرى على مساكن الطلاب،
ويمكنني تتبع أشياء أخرى.
مصفوفة أخرى لعناوين البريد الإلكتروني،
ومصفوفة أخرى لأرقام الهواتف--
ولكن هذا يصير فوضويًا بسرعة،
لأنه يمكنك أن تتخيل،
إذا كنتُ بحاجة إلى الأسماء والمساكن
وعناوين البريد الإلكتروني والهواتف،
فسيصبح هناك
الكثير من النسخ واللصق.
ولديّ فقط هذا التصميم الذي
توجد لديّ فيه الكثير والكثير من المصفوفات
حيث يشير كل موقع قوس--
مثل قوس 0، قوس 1
افتراضيًا إلى الطالب نفسه
عبر جميع تلك المصفوفات، مثل اممم!
تصميم فوضوي للغاية.
إذن، بتلويحة بيدي،
دعوني أقوم بالفعل
بإصلاح هذه المشكلة الفورية من البداية
بإدخال ميزة جديدة.
يمكنني اختراع أنواع البيانات الخاصة بي.
دعوني أمضي قدمًا
وأعلن عن مصفوفة
تسمّى students "الطلاب" بهذا العدد الكبير من
الطلاب، ولكن بطلاب بنوع البيانات.
تأتي لغة C بأنواع بيانات float، وbool، وchar، وint،
وليس بنوع string، وبالتأكيد ولا بنوع student.
إذن يمكنك إنشاء
أنواع بيانات مخصصة لك،
ويمكنك وضعها في ملفات الرؤوس
الخاصة بك، والتي لم ننتهِ من أي منها.

English: 
And I could have two arrays containing
one for the students' names,
one for the students' dorms, and
I can keep track of other things.
Another array for emails,
another array for phone numbers--
but this gets messy quickly,
because you can imagine,
if I need names and dorms
and emails and phones,
that starts to become
a lot of copy-paste.
And I just have this design where
I have lots and lots of arrays
where each bracket location--
like bracket 0, bracket 1
presumably refers to the same student
across all of these arrays, like mmm!
Messy, messy, messy design.
So with a wave of my
hand, let me actually
fix that immediate problem out of the
gate by introducing a new feature.
I can invent my own data types.
Let me just go ahead
and declare an array
called students with this many
students, but of data type student.
C comes with float, bool, char, int,
not string, and definitely not student.
So you can make your
own custom data types,
and you can put them in your own header
files, which we've not done either.

English: 
But I can look, and you'll see more
of this in the next problem set.
So not to worry if
this feels quite brief,
it's just meant to be a teaser here.
And struct.h is how you declare
or define your own type.
The keyword is literally typedef
struct for structure, or data structure
to be more complete.
The name of the data structure comes
at the end after some curly braces.
And then inside the curly
braces you just specify,
well what do you want a student to have?
I want them to have a name, a
dorm, maybe a phone number, maybe
an email address, anything I want.
I can just add here.
So that now in my actual code, I can
have an array of actual students,
and I can just access them with
this new notation like this.
You know that you can index into
an array with bracket notation.
What you didn't know until now,
perhaps, is that if at that location
is a structure, a.k.a.
struct, you can get at the name, the
dorm, or the phone, or the email,
or anything else there just by
using a dot-notation, which is
our last piece of new syntax for today.
Everything else is the same.

Arabic: 
ولكن يمكنني الاطلاع على، ويمكنكم مشاهدة المزيد من
هذا في مجموعة المسائل التالية.
لذلك لا داعي للقلق إذا
كان هذا يبدو مختصرًا إلى حد ما،
فإنه فقط مصمم لأن يكون إعلانًا تشويقيًا هنا.
ودالة struct.h هي الكيفية التي ستعلن
أو تحدد بها النوع الخاص بك.
وتكون الكلمة الأساسية حرفيًا هي typedef
struct لكي تكتمل البنية، أو بنية البيانات
على نحو أفضل.
ويأتي اسم بنية البيانات
في النهاية بعد بعض الأقواس المتعرجة.
ثم بداخل الأقواس
المتعرجة التي تقوم بتحديدها فقط،
حسنًا ماذا تريد أن يكون لدى الطالب؟
أرغب أن يكون لديه اسم،
ومسكن، وربما رقم هاتف، وربما
عنوان بريد إلكتروني، وأي شيء أريده.
يمكنني تحديدًا الإضافة هنا.
وبذلك الآن في التعليمة البرمجية الفعلية لديّ، يمكن
أن تكون لديّ مصفوفة من الطلاب الفعليين،
ويمكنني تحديدًا الوصول إليها باستخدام
تدوين العلامات الجديد هذا كهذا مثلاً.
تعرفون أنه يمكنكم الفهرسة بداخل
مصفوفة باستخدام تدوين علامة قوس.
ما لم تعرفوه حتى الآن،
ربما، أنه إذا كانت هناك في ذلك الموقع
بنية، والتي تعرف أيضًا باسم
struct، فيمكنكم الوصول إلى الاسم،
أو المسكن، أو الهاتف، أو البريد الإلكتروني،
أو أي شيء آخر هناك فقط من خلال
استخدام تدوين علامة نقطة، والتي تمثل
آخر جزء من بناء الجملة الجديد ليومنا هذا.
وأي شيء آخر على نفس الحال.

Arabic: 
يمكنني كتابة برنامج يقول
كذا وكذا في مسكن كذا وكذا
بأن أقول فقط احصل على اسم الطالب صاحب الترتيب رقم i
ومسكن الطالب صاحب الترتيب رقم i.
ويمكنني أن أكون أكثر براعة، وإذا كنت
لا أرغب في طباعة تلك القيم فقط،
فيمكنني تمامًا، الآن، وأنا لا
أرى أي مؤشرات فهم--
أو أني رأيتُ مؤشرات
وسنفهمها عما قريب
عن طريق مجموعات المسائل
والممارسة، يمكنني بالفعل القيام بذلك.
هذه مجرد معاينة خاطفة
لسطر في التعليمة البرمجية
والذي يستخدم دالة جديدة تسمّى fopen.
fopen بمعنى فتح هذا الملف، وهي تشتمل
على اسم الملف المطلوب فتحه.
ربما تعرفون عن ملفات CSV،
إنها مثل جداول بيانات بسيطة،
قيم مفصولة بفاصلة.
و"w" بين علامة الاقتباس وإنهاء الاقتباس تعني كتابة.
لذلك فهذه الدالة تقول افتح الملف الذي يسمى
students.csv في وضع الكتابة،
حتى أتمكن من الكتابة في هذا الملف.
لأنه في هذا المثال، كما
سترون في الأيام القادمة،
أريد أن أكتب كل شيء في ملف.
لكن من الواضح أنه لاستخدام ملفات،
نحتاج لمعرفة ما هو المؤشر،
ومن الغريب إلى حد ما
أنها كلها بأحرف كبيرة،
ولكن هناك نوع بيانات في لغة C
يسمى "file"، وهو مؤشر.
لاختصار القصة الطويلة، ما
سترونه في مجموعة المسائل التالية
ونحن نستكشف عالم
التحليلات الجنائية هو القدرة

English: 
I can write a program that says so
and so is in such and such a dorm
by just saying get the i-th student's
name and the i-th student's dorm.
And I can be even fancier, and if I
don't want to just print those values,
I can even, now, that I see
no understand pointers--
or I've seen pointers and
we'll soon understand them
by way of problem sets and
practice, I can actually do this.
This is just a little sneak
preview of a line of code
that uses a new function called fopen.
fopen this file open, and it takes
in the name of the file to open.
You might know of CSV files,
they're like simple spreadsheets,
comma separated values.
And quote-unquote "w" means write.
So this says open the file called
students.csv in write mode,
so I can write to this file.
Because in this example, as
you'll see in the days to come,
I want to write out to a file.
But it turns out to use files, I
need to know what a pointer is,
and it's a little weird
that it's all caps,
but there is a data type in C
called "file," and it's a pointer.
So long story short, what you're
going to see in the next problem set
as we explore the world of
forensics is the ability

English: 
using pointers and a few new
functions to open files and get back
the address of that file in memory
so that you can go to that address,
change the contents of a
file, and save it back out.
All of us take for granted these days
that you can go to File, Open and File,
Save, but what's actually
happening, pointers are involved,
stuff's getting loaded into
memory, and the computer
is dereferencing or
going to those addresses
and changing what's at
those locations in memory.
Now why might you want to do this?
Well here, of course,
is Zamila-- you might
recall from some of the problem
sets and the walkthroughs.
Turns out we could try to enhance
this picture of her by zooming in,
and here's about as much
fidelity as it is in her eyes.
Like I do not see the glint
of any criminal's logo
on his or her jacket in
the glint of Zamila's eyes.
If you zoom in on an image, and
an image, recall, from week 0
is just a grid of pixels or
dots, that's all you get.
And you can maybe smooth it out a
little bit or clean up the colors,
but you can't just
"enhance," quote-unquote,
and see more of the
glint in Zamila's eye,
because an image at the end of
the day is just a bitmap, a map--

Arabic: 
على استخدام المؤشرات وعدد قليل من
الدوال الجديدة لفتح الملفات واستعادة
عنوان ذلك الملف في الذاكرة
حتى يمكنك الانتقال إلى ذلك العنوان،
وتغيير محتويات ملف،
وإعادة حفظه.
كل منّا يُسَلِّم بأنك يمكنك الانتقال حاليًا إلى
File "ملف"، Open "فتح" وFile "ملف"،
Save "حفظ"، لكن ما يحدث في الواقع،
هو أن المؤشرات متضمنة،
وأنه يتم تحميل البرامج في
الذاكرة، وأن الكمبيوتر
يقوم بالإسناد المؤشري أو
ينتقل الى تلك العناوين
ويغيّر ما هو موجود في
تلك المواقع في الذاكرة.
الآن لماذا قد ترغب في القيام بهذا؟
حسنًا إليكم هنا، بالطبع،
زاميلا-- ربما
تذكرونها من بعض مجموعات المسائل
والتعليمات المساعدة.
من الواضح أنه يمكننا محاولة تحسين
صورتها هذه من خلال التكبير،
ويوجد هنا تقريبًا نفس
الدقة الموجودة في عينيها.
يبدو أني لا أرى بريق
أي شعار جنائي
على سترته أو سترتها كبريق
عيني زاميلا.
إذا قمتَ بتكبير صورة، والصورة،
لو تذكرون، من الأسبوع 0
هي مجرد شبكة من وحدات البكسل أو النقاط،
وهذا كل ما توصلتم إليه.
وربما يمكنكم جعلها متجانسة قليلاً
أو منسقة الألوان،
لكن لا يمكنكم تحديدًا إجراء تحسين
"enhance،" علامة اقتباس-علامة إنهاء الاقتباس،
ورؤية المزيد من
البريق في عين زاميلا،
لأن الصورة في نهاية المطاف
هي مجرد bitmap "صورة نقطية"، خريطة من وحدات البكسل--

English: 
top-down, left-right-- of pixels.
For instance, here's a smiley face.
If you kind of take a look back and
you can kind of see a black smiley
face against a white backdrop.
And if we just decide as humans,
let's represent white dots
with 1's and black dots with 0's,
this might be what's in the file,
this is what the human sees.
So if we have the ability to open
that from a file, store it in memory,
and then using pointers go
to those locations in memory,
we can even change the smiley face to an
unhappy face, for instance, or color it
or do any number of things to it.
Now at quick glance, there's
a lot going on in files,
because what a file is is a set
of conventions that humans decided
on where humans years ago
just decided in a bitmap file,
BMP file-- so an older but still
popular file format for images, humans
just decided that, like, we're going
to put a bunch of special values
at the first bytes of
the file, then some more
special values than the actual RGB
pixels in the rest of the file.
So this is meant to look
cryptic at first glance,

Arabic: 
من أعلى لأسفل، من اليسار لليمين.
على سبيل المثال، إليكم وجه مبتسم.
إذا ألقيتم نوعًا ما نظرةً إلى الوراء،
فيمكنكم نوعًا ما رؤية وجه مبتسم باللون الأسود
على خلفية بيضاء.
وإذا قررنا للتوّ كأشخاص،
فدعونا نمثل النقاط البيضاء
بالواحدات والنقاط السوداء بالأصفار،
فقد يكون هذا هو الموجود في الملف،
وهذا ما يراه الشخص.
لذا إذا كانت لدينا القدرة على فتح
ذلك من ملف، فقم بتخزينه في الذاكرة،
ومن ثم انتقل باستخدام المؤشرات
إلى تلك المواقع في الذاكرة،
فيمكننا حتى تغيير الوجه المبتسم إلى
وجه غير سعيد، على سبيل المثال، أو تلوينه
أو القيام بأي عدد من الأشياء له.
الآن بنظرة سريعة، هناك
الكثير الذي يحدث في الملفات،
لأن ماهية الملف عبارة عن مجموعة
من القواعد التي قررها البشر
حيث إن البشر منذ سنوات
أقروا في ملف bitmap "الصورة النقطية"،
ملف BMP-- بأن تنسيق ملفات أقدم كثيرًا
لكنه ما يزال شائعًا للصور، أقر البشر
تحديدًا، بأننا كأننا سنضع
مجموعة من القيم الخاصة
في وحدات البايت الأولى
للملف، ثم بعض القيم الخاصة
أكثر من وحدات بكسل
RGB الفعلية في بقية الملف.
إذن فهذا مصمم ليبدو
مشفرًا للوهلة الأولى،

English: 
and the next homework assignment
will walk you through this,
but all it is is a convention
of what the 0's and 1's mean
in these different locations.
And indeed, the challenge ahead is
going to be to do a number of things.
One is to first and
foremost figure out--
who done it?
A sort of murder mystery in which
there's a clue hidden in an image,
but an image that's a
little noisy and you're
going to have to figure out what
secret messages in the image
by loading that image in, tweaking
it, putting a sort of red filter
on top of it and seeing the secret
message, but all digitally; two,
actually resizing images and
taking this many pixels in this big
of a smiley face or something
else and making it bigger,
or if more comfortable,
making it even smaller
and figuring out how
to make that workout;
and then lastly, we've been taking
some photographs of all CS50 staff
in Cambridge and New Haven.
Unfortunately we accidentally
corrupted or lost the memory card,
but we made a forensic image of it, a
copy of all of the 0's and 1's with all
of the staff photos,
and we're going to need
you to write code that actually
recovers all of the JPEGs
or photographs from that
digital card by opening a file,

Arabic: 
وواجبكم المنزلي التالي سيكون
استكشاف هذا،
ولكن كل ماهيته عبارة عن
قاعدة لما تعنيه الأصفار والواحدات
في هذه المواقع المختلفة.
وبالفعل، فإن التحدي الذي أمامنا
سيكون القيام بعدد من الأشياء.
أولاً وقبل كل شيء توضيح--
من فعلها؟
إنه نوع من لغز جريمة قتل
يوجد فيه دليل مخفي في صورة،
ولكنها صورة مشوشة
قليلاً وسيتعين عليك
اكتشاف الرسائل
السرية في الصورة
عن طريق تحميل تلك الصورة فيها، وتعديلها،
ووضع نوع من عامل تصفية أحمر اللون
بأعلاها ورؤية الرسالة
السرية، لكن سيتم كل ذلك رقميًا؛ ثانيًا،
في الواقع تغيير حجم الصور وأخذ هذا العدد
الكبير من وحدات البكسل في هذا الوجه المبتسم
الكبير أو شيء آخر وجعله أكبر،
أو إذا كان واسعًا بدرجة أكبر، فبجعله أصغر
ومعرفة كيفية القيام بذلك التمرين؛
وأخيرًا، لقد قمنا بالتقاط
بعض الصور الفوتوغرافية لجميع طاقم العاملين في CS50
في كامبريدج ونيو هافن.
لسوء الحظ لقد أتلفنا
بطاقة الذاكرة أو ضيّعناها دون قصد،
لكننا قمنا بصورة تحليلية كبحث جنائي لها، نسخة
من جميع الأصفار والواحدات باستخدام جميع
صور طاقم العاملين، وسنحتاج
لكتابة التعليمة البرمجية التي تسترد
في الواقع كل ملفات JPEG
أو الصور الفوتوغرافية من تلك
البطاقة الرقمية بفتح ملف،

English: 
reading in those 0's and 1's,
understanding what they are
and where they are,
and just writing them
back out to disk using functions
we'll introduce you to in the problem
set itself.
But of course, all of this takes
for granted that we can do this,
and you can only do so much.
And indeed, this week is as much
about solving those problems
as it is realizing the
limitations of computers,
and so we thought we'd end with
the final few seconds of this very
real example from Futurama.
[VIDEO PLAYBACK]
- Magnify that death sphere.
Why is it still blurry?
- That's all the resolution we have.
Making it bigger
doesn't make it clearer.
- It does on CSI Miami.
- Ugh.
[END PLAYBACK]
DAVID MALAN: And that's it for
CS50, we'll see you next time.
[APPLAUSE]

Arabic: 
وقراءة ماهيتها ومكانها
في تلك الأصفار والواحدات،
وفهمهما،
وإعادة كتابتهما تحديدًا
للقرص باستخدام الدوالّ
التي سنقدمها لكم في مجموعة
المسائل نفسها.
ولكن بالطبع، إمكانية قيامنا بهذا
هو أمر مفروغ منه،
ويمكنكم فقط القيام بأكثر من ذلك بكثير.
وفي الحقيقة، هذا الأسبوع
يتمحور حول حل تلك المسائل
لأنها تتعرف على قيود
أجهزة الكمبيوتر،
لذلك فكرنا أننا سنختم
في الثواني الأخيرة بهذا
المثال الواقعي جدًا من مسلسل فيوتشوراما.
[VIDEO PLAYBACK]
- قم بتكبير كرة الموت هذه.
لماذا ما تزال غير واضحة؟
- هذا كل ما باستطاعتنا من دقة.
فجعلها أكبر
لا يجعلها أوضح.
- يفعل ذلك على CSI Miami.
-أُف.
[END PLAYBACK]
ديفيد مالان: وهذا كل شيء بالنسبة
إلى CS50، سأراكم المرة القادمة.
[APPLAUSE]
