Placeholder Image

字幕列表 影片播放

  • [MUSIC PLAYING]

    [音樂播放]

  • >> DAVID J. MALAN: All right.

    >> 戴維·J·馬蘭:好吧。

  • This is CS50.

    這是CS50。

  • And this is the start of week 5.

    這是5週的開始。

  • And as you may have noticed, some of the material

    正如你可能已經注意到, 一些材料

  • is getting a little more complex, the little denser.

    越來越多一點 複雜,小更密。

  • >> And it's very easy, especially if you've been in the habit for some time,

    >> 而且它是很容易的,尤其是當 你已經在習慣了一段時間,

  • to be trying to scribble down most anything we do, we're saying in class.

    是為了要塗下最 什麼我們做什麼,我們說在課堂上。

  • But realize, that is not perhaps the ideal pedagogical approach

    但要意識到,這也許不是 理想的教學方法

  • to learning this kind of material, and material more generally.

    學習這種物質, 而材料更普遍。

  • And so we are pleased to announce that CS50's own Gheng

    因此,我們很高興 宣布,CS50自己Gheng

  • Gong has begun to prepare a canonical set of notes

    龔已開始準備 一個規範的集合票據

  • for the course, the hope of which is that, one, these

    用於操作過程中,希望 其是,一個,這些

  • not only serve as a reference and a resource

    不僅作為 參考和資源

  • for reviewing material and going back through material that might have

    審查材料中去 回通過材料可能具有的

  • escaped you the first time around, but also so that your heads can be more

    逃脫你在第一時間左右,但 也讓你的頭可以更

  • up than down, when it comes time to lecture,

    向上比下降,當它 談到時間來講課,

  • so that you might engage more thoughtfully, as

    所以,你可能搞 更周到,為

  • opposed to more scribbly.

    相對於更雜亂。

  • >> With that said, what you'll find on the website is such documents as this.

    >> 雖這麼說,你會發現 該網站是這樣的文件,因為這。

  • And notice, at top left, there's not only a table of contents,

    並請注意,在左上角,有 不僅表的內容,

  • but also time codes that will immediately jump you

    而且時間碼的 會立即跳到你

  • to the appropriate part in the video online.

    到相應的部分 在視頻網上。

  • And what Chang here has done is, essentially, documented

    什麼常在這裡做了 在本質上,記載

  • what happened in this particular lecture.

    發生了什麼事在這 特別講座。

  • And many of the lectures are already online now with this URL.

    和許多的講座是 已經在線使用這個網址。

  • And we'll continue to post the remainder of those by the end of this week,

    我們將繼續張貼其餘 那些在本週末結束,

  • so do take advantage of that resource.

    所以不要採取資源優勢。

  • >> So without further ado, we started to peel back

    >> 因此,事不宜遲, 我們開始剝離回

  • the layer that has been string for some time.

    已經作為層 串持續一段時間。

  • And what did we say a string actually is last week?

    並沒有說什麼一個字符串 上週居然是?

  • So char star.

    因此,焦炭的明星。

  • And char star, well, what did that really mean?

    和CHAR星,那麼, 這樣做究竟意味著什麼?

  • Well, all this time, if we've been calling a function,

    那麼,這一切的時候,如果我們已經 被調用的函數,

  • like getString, and storing the so-called return

    喜歡的getString和存儲 所謂返回

  • value of getString in a variable-- it's called

    的getString的價值 變量 - 這就是所謂的

  • s type string-- we've been writing the line of code up there above.

    S型string--我們已經寫 這行代碼在那裡上面。

  • And it's only when I see my handwriting magnified here

    而且它是只有當我看到我的 在這裡手寫放大

  • do I realize just how atrocious this is.

    我意識到多麼惡劣,這是。

  • >> However, let's assume that, on the right-hand side

    >> 但是,讓我們假設, 在右手側

  • is, nonetheless, a reasonable depiction of what's

    是,但是,合理的 一個什麼樣的描述

  • been going on all this time with getString.

    一直在進行這一切 時間的getString。

  • getString, of course, gets a string.

    的getString,當然,得到​​的字符串。

  • But what does that really mean?

    但是,這究竟意味著什麼?

  • It means it gets a chunk of memory from the operating system

    這意味著它得到了一大塊 來自操作系統的內存

  • by calling a function, called malloc.

    通過調用一個函數,稱為malloc的。

  • But more on that later.

    但後​​來更多。

  • And then it populates that chunk of memory

    然後填充 該內存塊

  • with the letters the user has typed in, followed by, of course,

    以字母的用戶具有 當然鍵入,緊接著,,

  • a null character, or backslash zero at the very end.

    一個空字符或反斜杠 零在最後。

  • >> Meanwhile, on the left-hand side of this story, all this time,

    >> 同時,在左手側 這個故事,這一切的時候,

  • we've been declaring a variable, like s.

    我們已經聲明了一個變量,如第

  • And that variable is what now will start calling a pointer.

    而這個變量就是現在 將開始調用的指針。

  • It's not a box inside of which we put the string, Daven, per se,

    這不是這裡面一箱 我們把串,Daven,本身

  • but rather we put in that square box on the left what exactly?

    而是我們把在這方 箱體左側究竟是什麼?

  • Yeah?

    是嗎?

  • >> AUDIENCE: The address of where it's located in memory.

    >> 聽眾:的地址 它位於內存中。

  • >> DAVID J. MALAN: Exactly.

    >> 戴維·J·馬蘭:沒錯。

  • The address of where Daven is located in memory.

    Daven的所在地址 位於存儲器。

  • And not where all of Daven is located, per se, but specifically the address

    不,所有Daven的所在, 本身,而是專門的地址

  • of what?

    什麼?

  • Yeah?

    是嗎?

  • >> AUDIENCE: First character.

    >> 聽眾:第一個字符。

  • >> DAVID J. MALAN: The first character in Daven, which, in this case,

    >> 戴維·J·馬蘭:第一個字符 在Daven,其中,在這種情況下,

  • I proposed was arbitrarily and unrealistically 1, Ox1,

    我提出了任意 和不切實際1,OX1,

  • which just means the hexadecimal number of 1.

    它的意思是, 1的十六進制數。

  • But it's probably going to be a much bigger number

    但是,它可能會 是一個更大的數字

  • that we might draw with a 0x as a prefix,

    我們可能會得出 以0X作為前綴,

  • representing a hexadecimal character.

    代表一個十六進制字符。

  • And because we don't need to know where the rest of the characters of Daven

    而且,由於我們並不需要知道在哪裡 Daven的字符的其餘部分

  • are, because of what simple design decision that was made many years ago?

    是因為,有什麼簡單的設計 決定這是多年前?

  • Yeah?

    是嗎?

  • >> AUDIENCE: Backslash 0.

    >> 聽眾:反斜杠0。

  • DAVID J. MALAN: Yeah, exactly.

    戴維·J·馬蘭:是的,沒錯。

  • The backslash 0 allows you, albeit in linear time, to traverse the string,

    反斜線0可以讓你,儘管在 線性時間,來遍歷字符串

  • walk from left to right, with a for loop, or a while

    由左到右行走, 用for循環,或同時

  • loop, or something like that, and determine, oh, here

    環或類似的東西 這一點,決定了哦,這裡

  • is the end of this particular string.

    是這個特定字符串的結尾。

  • So with just the address at the beginning of a string,

    所以只用在地址 字符串的開始,

  • we can access the entirety of it, because all this while,

    我們可以訪問的全部 它,因為這一切的同時,

  • a string has just been a char star.

    一個字符串,剛剛一個char明星。

  • >> So it's certainly fine to continue using the CS50 library and this abstraction,

    >> 因此,這的確精緻繼續使用 在CS50庫,而且這樣的抽象,

  • so to speak, but we'll begin to see exactly

    可以這麼說,但我們會 首先,看看到底

  • what's been going on underneath this whole time.

    什麼是怎麼回事 下面這整個時間。

  • So you may recall this example, too, from last time, compare 0,

    所以,你可能還記得這個例子中, 同樣,從去年的時候,比較0,

  • which didn't actually compare.

    這實際上並沒有進行比較。

  • But we began to solve this.

    但是,我們開始解決這個問題。

  • >> But as perhaps a refresher, might I interest someone

    >> 但是作為也許是複習, 我可能感興趣的人

  • in a pink elephant today, also made by Chang?

    粉紅色的大象的今天, 還長呢?

  • How about you in front? [INAUDIBLE].

    怎麼樣,你在前面? [聽不清]。

  • Come on up.

    上來吧。

  • >> And in the meantime, as you come up, let's

    >> 並且在此期間, 你上來,讓我們

  • consider for just a moment what this code was actually doing.

    考慮了一會兒就好了什麼 這段代碼實際上做的事情。

  • It's declaring two variables up top, s and t, and calling getString.

    它聲明兩個變量了 頂,S和T,並調用的getString。

  • This isn't a very user-friendly program, because it doesn't tell you what to do.

    這不是一個非常用戶友好的程序, 因為它不會告訴你的事。

  • But let's just assume we're focusing on the juicy part.

    但是,讓我們姑且我們 重點是多汁的一部分。

  • And then we do, if s equals equals t, it should say printf,

    然後我們做的,如果s等於 等於T,應該說printf的,

  • you typed the same thing.

    您鍵入同樣的事情。

  • Hello.

    你好。

  • What's your name?

    你叫什麼名字?

  • >> JANELLE: Janelle.

    >> 詹妮爾:詹妮爾。

  • DAVID J. MALAN: Janelle, nice to meet you.

    戴維·J·馬蘭:詹妮爾, 很高興認識你。

  • So your challenge at hand for this elephant

    所以,你在挑戰 手這頭大象

  • is to first draw us a picture of what's being represented in those first two

    是第一個吸引我們的是什麼圖片 被代表的前兩個

  • lines.

    線。

  • So s and t might be represented how on the screen?

    因此,S和T可能是 顯示在畫面上如何?

  • And you can just draw it with your finger on this big screen.

    而且你可以繪製與 將手指放在這個大屏幕上。

  • >> So there's two halves to each side of that equation.

    >> 因此,有兩部分,以 該方程的每一側。

  • So there's s on the left, and then getString on the right.

    所以有S上的左側,並且 然後GetString的右邊。

  • And then there's t on the left, and then getString on the right.

    再有就是噸左邊, 然後GetString的右邊。

  • So how might we begin drawing a picture that

    那麼我們如何開始 繪製的畫面,

  • represents what's going on here in memory, would you say?

    表示這是怎麼回事 這裡的記憶,你會說什麼?

  • And let me let you explain what you're doing as you go.

    讓我讓你解釋 你在做什麼,當您去。

  • >> JANELLE: OK.

    >> 詹妮爾:好的。

  • Well, first, it would be asking you to get the input string.

    嗯,首先,它會問 你得到輸入字符串。

  • And it would store-- oh, sorry.

    它會store--哦,對不起。

  • DAVID J. MALAN: OK.

    戴維·J·馬蘭:確定。

  • Good.

    好。

  • And this is called what?

    而這個叫什麼?

  • Oh, OK.

    哦,好吧。

  • Keep going.

    繼續前進。

  • I didn't mean to interrupt.

    我不是故意要打斷。

  • JANELLE: Sorry.

    詹妮爾:對不起。

  • So it would input it into the address of-- not sure.

    因此,將其輸入到 地址of--不能確定。

  • I can't exactly remember the number, but I believe it was starting with 0.

    我不記得確切的數字, 但我相信這是從0開始。

  • >> DAVID J. MALAN: That's all right, because I made the numbers up,

    >> 戴維·J·馬蘭:沒關係, 因為我做的數字了,

  • so there's no right answer.

    所以沒有正確的答案。

  • >> JANELLE: Starting with the 0 arc.

    >> 詹妮爾:用0起弧。

  • >> DAVID J. MALAN: OK, so element 0.

    >> 戴維·J·馬蘭:好了,元素0。

  • Sure.

    當然。

  • >> JANELLE: And then if was like just a two-letter--

    >> 詹妮爾:然後如果是 像剛才兩個letter--

  • >> DAVID J. MALAN: OK, back to you.

    >> 戴維·J·馬蘭:好了,還給你。

  • >> JANELLE: So element 0, and then element 1 or element 2.

    >> 詹妮爾:所以元素0, 然後元件1或元件2。

  • DAVID J. MALAN: And which piece of the picture are you drawing right now?

    戴維·J·馬蘭:而且這一塊 圖片是你畫的權利嗎?

  • The call to getString?

    給GetString的調用?

  • Or the declaration of s?

    或s的聲明?

  • >> JANELLE: The declaration of s, I believe.

    >> 詹妮爾:報關 的S,我相信。

  • Oh, the getString, because it would be inputted into each [? area. ?]

    哦,對的getString,因為它會 被輸入到每一個[?區。 ?]

  • >> DAVID J. MALAN: Good.

    >> 戴維·J·馬蘭:好。

  • Exactly.

    沒錯。

  • Even though this effectively returns an array, recall,

    儘管這有效地 返回一個數組,調用,

  • when we get back a string, we can index into that string using 01 and 2.

    當我們回到一個字符串,我們可以 索引使用01和2的字符串。

  • Technically, these are probably represented by individual addresses,

    從技術上講,這很可能是 個別地址表示,

  • but that's fine.

    但是這很好。

  • >> So suppose, if I can just fast forward to where we left off

    >> 於是想,如果我可以快 轉發給我們留下了

  • last time, if one of the strings was g a b e,

    最後時刻,如果一個 字符串是克A B E,

  • backslash 0, thereby representing gabe's input, how might we represent s now?

    反斜杠0,從而表示Gabe的 輸入,怎麼可能,我們代表就談到?

  • If this is the memory that's been returned by getString?

    如果是這樣的存儲器那 被送回了的getString?

  • >> JANELLE: Would it be represented by an arc?

    >> 詹妮爾:這將是 由電弧所表示?

  • >> DAVID J. MALAN: By an arc?

    >> 戴維·J·馬蘭:通過電弧?

  • Well, no.

    哦,不。

  • Let's just say, pictorially, let me just go ahead

    遠的不說,形象地, 讓我繼續前進

  • and propose that, if this is s, this is the return value of getString.

    和建議,如果這是秒,這 是的getString的返回值。

  • And you've drawn this as 0, 1, 2, which is perfectly reasonable, because we

    而你畫這是0,1,2,其中 是完全合理的,因為我們

  • can index into the string, as such.

    可以索引到字符串,作為這樣。

  • But just to be consistent with last time, let me go ahead

    但剛需一致 最後一次,讓我先走

  • and arbitrarily propose that this is address 1, this is address 2,

    並隨意提出這 是地址1,這是地址2,

  • this is address 3, and so forth.

    這是地址3,依此類推。

  • And so, just to be super clear, what's going

    因此,剛需超 顯然,這是怎麼回事

  • to go in s as a result of that first line of code, would you say?

    s中去,作為一個結果, 代碼的第一行,你會說什麼?

  • >> JANELLE: Address 1?

    >> 詹妮爾:地址1?

  • >> DAVID J. MALAN: Exactly.

    >> 戴維·J·馬蘭:沒錯。

  • So address 0x1.

    因此,解決為0x1。

  • And meanwhile, let me go ahead and duplicate much of what you've done

    而與此同時,讓我繼續前進, 重複的很多東西,你做

  • and add my own t here.

    在這裡添加自己噸。

  • If I were to type in gabe again, a second time,

    如果我要在加布型 再一次,第二次,

  • when prompted with getString, where, of course, is gabe going to go?

    當用的getString提示,其中, 當然,被加布要去?

  • Well, presumably--

    那麼,presumably--

  • >> JANELLE: Like on here?

    >> 詹妮爾:像在這裡?

  • DAVID J. MALAN: Yeah.

    戴維·J·馬蘭:是的。

  • JANELLE: Or it's also in the same boxes?

    詹妮爾:或者它也是在同一個箱子?

  • DAVID J. MALAN: Let me propose, yeah, exactly, so in these additional boxes.

    戴維·J·馬蘭:我建議,是啊, 準確,因此,在這些附加的盒子。

  • But what's key now is that, even though I've drawn these pretty close

    但是,什麼是現在的關鍵是,即使 雖然我畫這些八九不離十

  • together-- 0x1, this is 0x2-- in reality,

    together--為0x1,這 被0x2--在現實中,

  • this now might be address 0x10, for instance, and 0x11, and 0x12,

    這個現在可能是地址為0x10, 例如,和為0x11,以及0x12的

  • and so forth.

    等等。

  • And so, if that's the case, what's going to end up here in t?

    因此,如果是這樣的話, 這是怎麼回事結束了在這裡噸?

  • >> JANELLE: 0x10?

    >> 詹妮爾:為0x10?

  • DAVID J. MALAN: Exactly.

    戴維·J·馬蘭:沒錯。

  • So 0x10.

    因此,為0x10。

  • And so now, final question.

    所以現在,最後一個問題。

  • You have, by far, had to work the hardest for an elephant thus far.

    你有,到目前為止,已經工作了 最難的大象迄今。

  • By now, if I pull up the code again, when I do, in line three,

    事到如今,如果我拉起碼 再次,當我這樣做,在三線,

  • if s equals equals t, what am I actually comparing that we've drawn here?

    如果s等於等於T,我算什麼實際 相比較,我們在這裡畫?

  • >> JANELLE: The two addresses?

    >> 詹妮爾:這兩個地址?

  • DAVID J. MALAN: Exactly.

    戴維·J·馬蘭:沒錯。

  • So I'm saying is s equal equal to t?

    所以,我要說的是S等於等於t?

  • In other words, is 1 equal equal to 10?

    換句話說,是1等於等於10?

  • And of course, the obvious answer now is, no.

    並且,當然,在 答案很明顯,現在是,沒有。

  • And so this program is ultimately going to print what, would you say?

    所以這個方案最終是 要打印的內容,你會說什麼?

  • >> JANELLE: Would it be, you typed the same thing?

    >> 詹妮爾:它會是這樣, 您鍵入同樣的事情?

  • >> DAVID J. MALAN: So if s is 1 and t is 10?

    >> 戴維·J·馬蘭:所以,如果 s是1和t是10?

  • >> JANELLE: You typed different things.

    >> 詹妮爾:輸入不同的事情。

  • >> DAVID J. MALAN: Exactly.

    >> 戴維·J·馬蘭:沒錯。

  • You typed different things.

    你輸入不同的事情。

  • All right.

    好吧。

  • So a round of applause, if we could, here.

    所以,掌聲雷動, 如果我們能在這裡。

  • [APPLAUSE]

    [掌聲]

  • That was painful.

    這是痛苦的。

  • I know.

    我知道。

  • Nicely done.

    很好地完成。

  • So now let's see if we can't tease apart what the fix was.

    所以,現在讓我們來看看,如果我們不能 梳理出什麼樣的修復程序。

  • And of course, when we fixed this-- which I'll now represent in green--

    當然,當我們固定this-- 現在我將代表green--

  • we did a couple of enhancements here.

    我們做了幾個增強功能在這裡。

  • First, just as a sanity check, I'm first checking

    首先,正如一個理智 檢查一下,我先檢查

  • if s equals null and t equals null.

    如果s等於null和T等於null。

  • And just to be clear, when might s or t be null in code like this?

    而只是要清楚,如果可能 s或t為null,在這樣的代碼?

  • When might s or t be null.

    當可能s或t為null。

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • >> DAVID J. MALAN: Exactly.

    >> 戴維·J·馬蘭:沒錯。

  • If the string that the user typed in is way too long

    如果字符串用戶 鍵入的是太長時間

  • to fit into memory, or some weird corner case like that,

    要裝入內存,或者一些 奇怪的角落情況下那樣,

  • getString, as we'll see, literally today, in its documentation,

    GetString的,正如我們所看到的,從字面上 今天,它的文檔中,

  • says it will return null as a special sentinel value,

    表示將返回null作為 一個特殊的標記值,

  • or just sort of a special symbol that means something went wrong.

    或者只是有點特殊符號 這意味著出事了。

  • So we want to check for that, because it turns out

    因此,我們要檢查 是,因為事實證明

  • that null is a very dangerous value.

    那空是一個非常危險的價值。

  • >> Often, if you try to do something with null involving a function-- passing it

    >> 通常情況下,如果你嘗試做一些與 空涉及函數 - 它傳遞

  • as input, for instance-- that function might very will crash and, with it,

    作為輸入,對instance--該功能 很可能會崩潰,並用它,

  • take down your whole program.

    記下你的整個程序。

  • So this third line now is just a sanity check, error checking, if you will.

    因此,這第三條線,現在僅僅是一個理智 檢查,檢查錯誤,如果你願意。

  • That's a good habit now for us to get into any time we

    這是一個好習慣,現在的 我們進入任何時候我們

  • try to use a value that could, potentially, be null.

    嘗試使用一個值, 可能,可能,是空的。

  • >> Now, in the fourth line here, "if strcmp(s, t)," well,

    >> 現在,在第四行此處, “如果STRCMP(S,T),”好了,

  • what's that referring to?

    那是什麼指?

  • Well, we said this was a very succinctly named function for string comparison.

    好吧,我們說這是一個非常簡潔 命名函數的字符串比較。

  • And its purpose in life is to compare its first argument against it second,

    及其在生命的目的是比較 其反對的第一個參數第二,

  • but not in terms of their addresses, as we did unintentionally a moment

    但不是在它們的地址而言, 因為我們沒有無意中片刻

  • ago with the red code, but rather to compare those two

    以前的紅色代碼,但 而比較這兩個

  • strings in the humanly intuitive way by comparing this, against this,

    在力所能及直觀的字符串 通過比較這一點,對這種方式,

  • against this, against this, and then stopping if and when one

    針對這一點,針對這一點,並 然後停止,如果和當一個

  • or both of my fingers hits a backslash 0.

    還是我的兩個手指 打一個反斜杠0。

  • So someone years ago implemented strcmp to implement for us the functionality

    因此,有人年前實施的strcmp 實現我們的功能

  • that we hoped we would have gotten by just comparing two simple values.

    我們希望我們會得到 僅通過比較兩個簡單的值。

  • >> Now frankly, I keep drawing all of these various numbers.

    >> 現在,坦率地說,我把圖紙 所有這些不同的數字。

  • But the reality is, I've been making these up the whole time.

    但現實是,我已經 製備這些向上的全部時間。

  • And so let me just go ahead and scribble these out

    因此,讓我乾脆去 而這些亂塗出來

  • to make a point that, at the end of the day and moving forward,

    做一個點,在結束 這一天,並向前走,

  • we're not really going to care about what addresses things are actually

    我們不是真的要關心 有什麼解決的事情,其實

  • in memory.

    在存儲器中。

  • So I'm not going to draw these kinds of numbers so much anymore,

    所以,我不會畫這些 種數的那麼多了,

  • I'm just an abstract this away a little more friendly with just arrows.

    我只是一個抽象的這個客場 小只箭更友好。

  • >> In other words, if s is a pointer, well, let's just draw it, literally,

    >> 換言之,如果s是一個指針, 好了,讓我們只繪製它,從字面上看,

  • as a pointer, an arrow pointing from itself to something else,

    作為一個指針箭頭指向 從自身到別的東西,

  • and not worry too much more about the minutia of these addresses

    而不用太擔心更多 這些地址的細節

  • which, again, I made up anyway.

    其中,再次,我反正做了。

  • But we'll see those addresses, sometimes, when debugging code.

    但是,我們可以看到這些地址, 有時,調試代碼的時候。

  • >> Now meanwhile, this program up here fixes, of course,

    >> 現在,同時,該計劃 當然,在這裡的修復,

  • that problem by comparing those two strings.

    通過比較該問題 這兩個字符串。

  • But we ran into another problem.

    但是,我們遇到了另一個問題。

  • This was from the copy program last time,

    這是從複製 節目最後一次,

  • whereby, I was trying to capitalize just the first character in a string.

    因此,我試圖利用 在一個字符串僅僅是第一個字符。

  • But what was the symptom we saw last time when

    但究竟是什麼症狀 我們看到最後的時候

  • a user typed in a value, like gabe in lowercase, for s,

    用戶鍵入一個值,如 加布於小寫的S,

  • then we assigned s into t, as in the third line there,

    那麼我們分配s轉換T, 如第三行那裡,

  • and then I tried to capitalize t bracket 0?

    然後我試圖 資本噸支架0?

  • What was the effect of changing t bracket 0 here?

    什麼效果 改變噸支架0嗎?

  • >> AUDIENCE: It changed s.

    >> 聽眾:它改變了第

  • >> DAVID J. MALAN: Yeah, I changed s, as well.

    >> 戴維·J·馬蘭:是啊, 我換了S,以及。

  • Because what was really going on?

    因為什麼怎麼回事?

  • Well, let me see if I can clean up this picture, as follows.

    好吧,讓我看看,如果我能清潔 這幅畫,如下所示。

  • >> If s is, again, the word g, a, b, e, backslash, 0, and s

    >> 如果S是再次,字克, A,B,E,反斜杠,0和s

  • we'll continue drawing as a box here, but no more addresses.

    我們將繼續繪製一個框 在這裡,但沒有更多的地址。

  • Let's stop making things up.

    讓我們停止做的事情了。

  • Let's just draw a picture to simplify the world.

    讓我們只畫一幅畫 簡化了世界。

  • >> When I declare t with string t, that creates that chunk of memory.

    >> 當我宣布噸,串T, 創建的內存塊。

  • Square happens to be 32 bits in most computers.

    方碰巧是32 位在大多數計算機上。

  • In fact, if you've ever heard of a computer having a 32-bit architecture,

    事實上,如果你曾經聽說過的 具有32位體系結構的計算機,

  • really fancy-speak, that just means it uses 32-bit addresses.

    真正看中的,說話,只是 意味著它採用32位地址。

  • And as a technical aside, if you've ever wondered

    而作為一個技術不談, 如果你曾經想知道

  • why older computers, if you actually tried to soup them up with lots of RAM,

    為什麼舊的電腦,如果你真的 想喝湯起來,有很多的RAM,

  • could only have a maximum of four gigabytes of RAM,

    只能有一個最大 四個千兆字節的RAM,

  • well that's because, literally, your old computer could only

    好,這是因為,從字面上看, 您的舊電腦只能

  • count as high as 4 billion, 4 billion bytes,

    計高達4 十億,4個十億字節,

  • because it was using 32-bit numbers for addresses.

    因為它是使用32位 號碼的地址。

  • >> But in any case, in this example, story's much simpler.

    >> 但在任何情況下,在該 比如,故事中的要簡單得多。

  • t is just another pointer, or really a char star, aka string.

    t是只是一個指針,或 真是一個char星,又名字符串。

  • And how do I want to update this picture now with that second line of code,

    怎麼辦我想更新這幅畫 現在的代碼,第二行,

  • after the dot, dot, dot?

    點後,點,點?

  • When I do string t equals s semicolon, how does this picture change?

    當我做串T等於Š分號, 請問這張照片改變?

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • >> DAVID J. MALAN: Yeah.

    >> 戴維·J·馬蘭:是的。

  • Exactly.

    沒錯。

  • I just put an arrow from the t box to the same address,

    我只是把一個箭頭從 噸方塊以相同的地址,

  • the same first letter in gave.

    在相同的第一個字母給了。

  • Or technically, if this guy were still at 0x1,

    或在技術上,如果這 男人仍然在為0x1,

  • it's as though I had 0x1 here and 0x1 here.

    這是因為雖然我有 這裡為0x1和0x1這裡。

  • But again, who cares about the addresses?

    但同樣,誰在乎 關於地址?

  • It's just the idea that now matters.

    只是,現在最重要的想法。

  • So this is what's happening here.

    因此,這是這裡發生了什麼。

  • So of course, if you do t bracket 0, which is array notation,

    所以,當然,如果你做T支架 0,這是數組符號,

  • of course-- and frankly, it looks like there's an array over here,

    的course--坦率地說,它看起來 像有一個數組在這裡,

  • but now there's this weird thing.

    但現在有這樣奇怪的事情。

  • Know that the programming language, C, offers you this feature,

    要知道,編程語言, C,為您提供此功能,

  • whereby, even if t is a pointer, or s is a pointer,

    由此,即使t是 指針,或s是一個指針,

  • you can still use that familiar, comfortable square bracket

    您還可以使用熟悉的, 舒適的括號

  • notation to go to the first element, or the second element, or any element

    符號去的第一要素, 或所述第二元件,或任何元件

  • that that pointer is pointing to because, presumably, it

    在該指針指向 到,因為,據推測,它

  • is, as in this case, pointing at some array.

    是,因為在這種情況下, 指著一些數組。

  • >> So how do we fix this?

    >> 那麼,我們如何解決這個問題?

  • Frankly, this is where it got a little overwhelming at first glance.

    坦率地說,這是它得到了 有點麻煩第一眼。

  • But here is a new and improved version.

    但這裡是一個新的和改進的版本。

  • >> So first, I'm getting rid of the CS50 library,

    >> 因此,首先,我越來越 擺脫CS50庫,

  • just to expose that s is indeed a char star, just a synonym.

    只是揭露S是真的 一個char明星,只是一個代名詞。

  • And t is also a char star.

    和T也是一個char明星。

  • But what is going on on the right-hand side of that line

    但對到底是怎麼回事 該行的右手側

  • where t is assigned a value?

    其中T是賦值?

  • >> What is malloc?

    >> 什麼是malloc的?

  • What it's strlen?

    什麼是strlen的?

  • What is sizeof(char)?

    什麼是的sizeof(char)的?

  • Why the heck does this line look so complex?

    為什麼非得這樣做 線看起來那麼複雜嗎?

  • What's it doing at a high level?

    它是什麼做在一個較高的水平?

  • What's it storing in t?

    什麼是存儲在T?

  • Yeah?

    是嗎?

  • AUDIENCE: It's allocating a certain amount of memory space.

    聽眾:它的分配 一定量的存儲空間。

  • It's to store, I guess, letters [INAUDIBLE].

    它的存儲,我想, 信[聽不清]。

  • >> DAVID J. MALAN: Perfect.

    >> 戴維·J·馬蘭:完美。

  • Perfect.

    完美的。

  • It's allocating a certain amount of memory space

    它分配一個特定的 存儲空間量

  • to store, presumably, future letters.

    存儲,據推測,未來的信件。

  • And in particular, malloc is therefore returning what?

    並且特別地,malloc的 因此,返回什麼?

  • >> AUDIENCE: Returning the [INAUDIBLE]?

    >> 聽眾:返回的[聽不清]?

  • DAVID J. MALAN: Exactly.

    戴維·J·馬蘭:沒錯。

  • Returning the address of that memory, which is a fancy way of saying,

    返回的內存地址, 這只不過是一個奇特的方式,

  • returns the address of the first byte of that memory.

    返回的地址 該內存的第一個字節。

  • The onus is on me to remember how much memory I actually

    的責任是我記住 實際上有多少內存I

  • allocated or asked malloc for.

    分配或要求的malloc的。

  • >> Now how much is that?

    >> 現在是多少呢?

  • Well, even though there's a lot of parentheses here,

    好吧,即使有 很多括號在這裡,

  • malloc takes just a single argument.

    malloc的只需要一個參數。

  • And I'm specifying strlen of s, so give me as many bytes as there are in s,

    和我指定的字符strlen,所以給 我盡可能多的字節,因為在S,

  • but add one.

    但新增一個。

  • Why?

    為什麼呢?

  • Yeah?

    是嗎?

  • >> AUDIENCE: The backslash 0.

    >> 聽眾:反斜杠0。

  • DAVID J. MALAN: Exactly.

    戴維·J·馬蘭:沒錯。

  • We've got to do a little housekeeping.

    我們必須做一點家務。

  • So because there's a backslash 0, we'd better remember that.

    所以,因為有一個反斜杠 0,我們最好記住這一點。

  • Otherwise, we're going to create a string that

    否則,我們將 創建一個字符串,

  • doesn't have that special terminator.

    沒有特別的終結者。

  • >> Meanwhile, just to be super anal, I have sizeof(char),

    >> 同時,剛需超 肛門,我的sizeof(char)的,

  • just in case someone runs my code not on the CS50 appliance,

    萬一有人跑我 不上CS50設備代碼,

  • but maybe a different computer altogether where chars

    但也許在不同的計算機 乾脆在那裡字符

  • are one byte, by convention, but two bytes, or something bigger than that.

    是一個字節,按照慣例,但有兩個 字節或更大的東西不止這些。

  • It's just to be super, super averse to errors.

    這是剛需超, 超級反感的錯誤。

  • Even though, in reality, it's most likely going to be a 1.

    儘管,在現實中,這是 最有可能將是一個1。

  • >> Now, meanwhile, I go ahead and copy the string, t bracket i equals t bracket s.

    >> 現在,同時,我繼續和複製 字符串,T支架i等於噸支架第

  • And I will defer to last week's source code to see what's going on.

    我將按照上週的 源代碼,看看是怎麼回事。

  • But the key takeaway, and the reason I put the code now in green,

    但關鍵的外賣,以及 我之所以把代碼現在綠,

  • is because that very last line, t bracket 0 equals toupper,

    是因為很最後一行 噸支架0等於TOUPPER,

  • has the effect of capitalizing which string?

    具有的效果 轉增股本的字符串?

  • t and/or s?

    T和/或S?

  • That last line of code.

    最後一行代碼。

  • >> Just t, because what's happened this time,

    >> 只是T,是因為什麼 最少此時,

  • if I slightly undo that last step, what's happened is, when I call malloc,

    如果我稍微撤消最後一步, 什麼情況是,當我調用malloc,

  • I essentially get a chunk of memory that is the same size as the original,

    í基本上得到一個內存塊 這是相同的尺寸,原來,

  • because that's the arithmetic I did.

    因為這是算術我做到了。

  • I'm storing in t the address of that chunk of memory.

    我存儲在T地址 的內存塊。

  • Even though this looks nice and pretty, nice and blank,

    儘管這看起來不錯 漂亮,漂亮,一片空白,

  • the reality is there's, what we'll keep calling, garbage values in here.

    實際情況是有,我們會 保持通話,在這裡的垃圾值。

  • That chunk of memory might very well have been used before,

    該內存塊可能很 也有之前被使用,

  • a few seconds, a few minutes ago.

    幾秒鐘,幾分鐘前。

  • So there could absolutely be numbers or letters there, just by accident.

    因此,有可能完全是數字 或字母那裡,只是偶然。

  • But they're not valid, until I myself populate this chunk of memory

    但他們不是有效的,直到我 我自己填充此塊內存

  • with actual chars, as I do in that for loop there.

    與實際的字符,如我 做在for循環出現。

  • All right?

    好吧?

  • >> So now, the climax of these three examples

    >> 所以,現在的高潮 這三個例子

  • that were seemingly broken last time, this Swap example, this function

    那名看似打破最後一次, 這個互換的例子,這個功能

  • worked in the sense that it swapped a and b.

    在這個意義上製作 它交換a和b。

  • But it didn't work in what other sense?

    但它並沒有什麼其他意義的工作?

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • >> DAVID J. MALAN: Exactly.

    >> 戴維·J·馬蘭:沒錯。

  • If I were to call this function from another-- for instance,

    如果我要調用這個函數 從another--例如

  • from a function like main, where I have a variable, x and y, as I

    從主一樣,在功能 我有一個變量,x和y,當我

  • did last week, same code, and I pass in x and y

    上星期,同樣的代碼, 而我通過在X和Y

  • to Swap, and then call Swap-- this, of course, is the correct version

    以交換,然後調用Swap--這一點, 當然是正確的版本

  • is what we're about to see-- it did not work.

    就是我們即將 see--沒有奏效。

  • So what is the fix?

    那麼,什麼是定位?

  • >> Well, so just to be clear, let me go ahead

    >> 好了,所以才要 顯然,讓我先走

  • and-- give me one second here, and see if I can show you the last one, which

    還有 - 給我1秒在這裡,看 如果我能告訴你的最後一個,這

  • will be in-- let's see if I can find this real fast-- OK, [INAUDIBLE].

    將in--讓我們來看看,如果我能找到 這種真正的fast--確定,[聽不清]。

  • OK, there it is.

    好了,它就在那裡。

  • So ignore the commands I'm just typing.

    所以忽略我只是鍵入命令。

  • I want it to retrieve at the last minute an example

    我希望它在檢索 最後一分鐘的一例

  • from last time, which is now called no Swap.

    從去年的時間,這 現在所謂的無交換。

  • >> So no Swap is where we left off last time,

    >> 因此,沒有交換的地方 我們離開的最後一次,

  • whereby, I initialized x to 1 and y to 2.

    因此,我初始化 X要1和y 2。

  • I then call Swap, passing in 1 and 2.

    後來我打電話交換,傳遞1和2。

  • And then this function worked in some sense,

    然後這個函數 在某種意義上工作,

  • but it had no permanent effect on x and y.

    但它沒有永久的 在x和y的影響。

  • So the question at hand is, how now do we actually fix this problem?

    因此,目前的問題是,怎麼現在 我們其實解決這個問題?

  • What is the solution at hand?

    如何解決在眼前?

  • >> Well, in swap.c, which is new today, notice a couple of differences.

    >> 那麼,在swap.c,今天是新的, 看到一對夫婦的差異。

  • x and y are the same.

    x和y是相同的。

  • But what is clearly different about line 25?

    但顯然 約25行有什麼不同?

  • What's new there, if you remember what it looked like a second ago?

    最新消息那裡,如果你還記得 它看起來像一秒鐘前?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • >> DAVID J. MALAN: Yeah.

    >> 戴維·J·馬蘭:是的。

  • So the ampersands are a new piece of syntax not only in this program,

    所以連字號是一個新的作品 語法不僅這個程序中,

  • but also more generally in CS50.

    而且更普遍的CS50。

  • To date, I don't think we've seen any examples

    到目前為止,我不認為 我們見過的任何實例

  • or really talked about them in any detail, other than, maybe, preemptively

    還是真的在任何談論他們 細節,不是,也許,搶先其他

  • in section, an ampersand like this.

    在節中,像這樣的符號。

  • Well, it turns out ampersand is one of the last pieces of new syntax

    嗯,原來符號是 最後張新語法

  • we're going to learn.

    我們要學習的。

  • All it means is the address of some variable.

    它的意思是在 一些變量的地址。

  • At what address does x live?

    請問您的地址並點¯x住在哪裡?

  • But what address does y live?

    但ÿ住什麼地址?

  • Because if the fundamental problem before

    因為如果 之前根本問題

  • was that x and y were being passed as copies, what we really want to do

    在x和y分別被傳遞 作為副本,我們真正想做的事

  • is provide Swap with like a treasure map that leads to where x and y actually

    是提供交換與像寶貝一樣 地圖,導致其中x和y實際上

  • are in RAM, so that Swap can follow that map

    在RAM中,從而使 交換可以按照該圖

  • and go to wherever x or y marks the spot and change the actual values 1 and 2

    和去哪裡x或y標誌的地方 和改變實際值1和2

  • there.

    那裡。

  • >> So Swap needs to change slightly too.

    >> 所以交換需要稍微改變了。

  • And at first glance, this might seem a little similar to char star.

    乍看之下,這可能 似乎有點類似於字符的明星。

  • And indeed it is.

    的確是。

  • So a is a pointer to what type of data, based on this highlighted portion?

    所以a是一個指向什麼類型的數據, 在此基礎上突出部分?

  • So it's an int.

    所以這是一個int。

  • >> So a is no longer an int, it's the address of an int.

    >> 所以不再是一個int, 這是一個int的地址。

  • And similarly, b is now going to be the address of an int.

    同樣,B現在準備 是一個int的地址。

  • So when I now call Swap from Main, I'm not going to give Swap 1 and 2.

    所以,當我現在請交換從主, 我不會給交換1和2。

  • I'm going to give it like Ox-something and Ox-something,

    我要去給它像 牛的東西,黃牛的東西,

  • two addresses that will lead Swap to their actual locations

    兩個地址,這將導致 交換自己的實際位置

  • in my computer's memory.

    在我的電腦的內存中。

  • >> So now, my remaining implementation needs to change a tad.

    >> 所以,現在,我剩下的落實 需要改變一點點。

  • What's obviously different now in these three lines of code?

    有什麼明顯的不同,現在 在這三行代碼?

  • There's these damn stars all over the place, all right?

    有這些該死的明星都 過的地方,好嗎?

  • So what's going on here?

    所以,這是怎麼回事嗎?

  • Yeah?

    是嗎?

  • >> AUDIENCE: It's obviously [INAUDIBLE].

    >> 聽眾:這是很明顯[聽不清]。

  • >> DAVID J. MALAN: Exactly.

    >> 戴維·J·馬蘭:沒錯。

  • So in this context-- and this was not the best design decision, admittedly,

    所以在此context--,這是不 最好的設計決定,無可否認,

  • years ago.

    幾年前。

  • In this context, where you just have a star,

    在這種情況下,其中 你只需要一個明星,

  • and you don't have a data type, like int, immediately to the left,

    而你沒有的數據類型, 如int,立即到左邊,

  • instead you have an equal sign, clearly, in this context, when you say star a,

    而不是你有一個等號,顯然, 在這種情況下,當你說星A,

  • that means go to the address that's in a.

    這意味著去 地址是在一個。

  • Follow the treasure map, so to speak.

    按照藏寶圖,可以這麼說。

  • >> And meanwhile, in line 37, it means the same thing.

    >> 並且同時,在第37行, 這意味著同樣的事情。

  • Go to the address a, and put what there?

    去的地址,並把什麼呢?

  • Whatever is at the location that b specifies.

    不管是在 地理位置使得b指定。

  • In other words, go to b.

    換句話說,去到b。

  • Get that value.

    獲得該值。

  • Go to a and, per the equal sign, the assignment operator,

    去和每平等 簽署,賦值運算符,

  • put that value there.

    把該值存在。

  • >> Similarly, int temp is just an int.

    >> 同樣,INT溫度僅僅是一個int。

  • Nothing needs to change about temp.

    沒有什麼需要改一下溫度。

  • It's just a spare glass from Annenberg for some milk or orange juice.

    這只是一個備用的玻璃從安嫩伯格 對於一些牛奶或橙汁。

  • But I do need to say, go to b.

    但我需要說的,去到B。

  • Go to that destination and put the value in temp there.

    去那個目的地, 放在那裡的溫度值。

  • So what's happening then?

    因此,發生了什麼呢?

  • When I actually call Swap this time, if this first tray here represents Main,

    當我真正稱之為交換這個時候,如果 這第一盤在這裡代表主,

  • this second tray represents Swap, when I pass ampersand x and ampersand y

    當第二盤代表交換, 我通過符號x和符號ÿ

  • from Main to Swap, just to be clear, what is this stack frame receiving?

    從主來交換,只是要清楚, 這是什麼堆棧幀接收?

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • DAVID J. MALAN: Exactly.

    戴維·J·馬蘭:沒錯。

  • The address of x and the address of y.

    x的地址和y的地址。

  • And you can think of these like postal addresses.

    而你能想到的這些 如郵寄地址。

  • 33 Oxford Street and 35 Oxford Street, and you

    33牛津街和35 牛津街和你

  • want to move the two buildings that are at those locations.

    要移動的兩棟樓 這是在這些地方。

  • >> It's sort of a ridiculous idea, but that's all we mean by address.

    >> 這有點荒謬的想法, 但是這就是我們所說的地址。

  • Where in the world can you find those two ints?

    凡在世界上可以 你會發現這兩個整數?

  • Where in the world can you find those two buildings?

    凡在世界上你 找到這兩個建築物?

  • So if finally, after all this time I go into today's source code and compile

    因此,如果最後,畢竟這個時候我 進入今天的源代碼和編譯

  • Swap and run ./swap, finally, for the first time do we actually see that

    交換和運行./swap,最後,為 第一次,我們確實看到,

  • my values have indeed been swapped successfully.

    我的價值觀的確有 已成功交換。

  • And now, we can even take note of this in, say, gdb.

    而現在,我們甚至可以把 請注意這一點,比如,廣發銀行。

  • >> So let me go into the same file.

    >> 所以,讓我去到同一個文件中。

  • Let me go ahead and run gdb of ./swap.

    讓我繼續運行./swap的GDB。

  • And now, in Swap, I'm going to go ahead and set a break point in Main.

    而現在,在交換,我會去 未來,並設置一個斷點在主。

  • And now I'm going to go ahead and run the program.

    現在我要去 繼續運行該程序。

  • And now we see my code paused at that line.

    現在我們看到我的代碼 停在該行。

  • >> If I go ahead and print x, what should I see here?

    >> 如果我繼續和打印 X,我應該在這裡看到的?

  • It's a question.

    這是一個問題。

  • Say again?

    再說一遍?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • >> DAVID J. MALAN: So random numbers, maybe.

    >> 戴維·J·馬蘭:所以 隨機數,也許。

  • Maybe I get lucky, and it's nice and simple, like 0.

    也許我很幸運,它的 優雅而簡單,如0。

  • But maybe it's some random number.

    但也許這是一些隨機數。

  • In this case, I got lucky.

    在這種情況下,我真的很幸運。

  • It just happens to be 0.

    這恰好是0。

  • But it is indeed luck, because not until I

    但它確實是運氣, 因為直到我

  • type next and then print x has that line of code, line 19, been executed.

    輸入下一個,然後打印x的那 代碼行,19行,被執行死刑。

  • >> Meanwhile, if I type next again, and now print out y, I'm going to see 2.

    >> 同時,如果我輸入下一一遍, 現在打印出Y,我要見2。

  • Now, if I type next, it's going to get a little confusing, because now,

    現在,如果我輸入下一個,它要 變得有點混亂,因為現在,

  • the printf is going to appear on the screen, as it did. x is 1.

    中的printf會出現在 在屏幕上,因為它沒有。 x是1。

  • >> Let's do this again.

    >> 讓我們再次做到這一點。

  • And now, here's where things get interesting.

    而現在,這裡的地方 事情變得有趣。

  • Before I call Swap or even step into it, let's take a little peek.

    在我打電話交換,甚至一步 進去,讓我們一點點偷看。

  • x is, again, 1.

    x是,再次,1。

  • Y is, of course, quick sanity check, 2, so not hard there.

    Y是當然,快清醒 檢查,2,所以並不難有。

  • But what is ampersand x?

    但是,什麼是符號X你是否

  • Answer, it's kind of funky looking.

    答案,它是一種時髦好看。

  • But the int star in parentheses is just gdp's way of saying this is an address.

    但INT明星在括號只是 對這種說法GDP的方式是一個地址。

  • It's not an int, it's a pointer to an int, or otherwise known as an address.

    它不是一個整數,它是一個指向 int或以其他方式被稱為一個地址。

  • >> What is this crazy thing?

    >> 這是什麼瘋狂的事?

  • We've never seen something quite like that before.

    我們從來沒有見過的東西 很喜歡之前。

  • So this is the address in my computer's memory of where x happens to live.

    因此,這是在我的電腦的地址 內存,其中x恰好住。

  • It's Ox-something.

    這是黃牛的東西。

  • And this is, frankly, why I've started drawing arrows,

    這是坦率地說,為什麼 我開始畫箭頭,

  • instead of numbers, because who really cares

    不是數字的, 因為誰真正關心

  • that your int is at a particular address that's that big.

    您的int是在一個特定的 地址是那麼大。

  • But bffff0c4, these are all indeed hexadecimal digits,

    但bffff0c4,這些都是 的確十六進制數字,

  • which are 0 through f.

    這是0到f。

  • >> So we're not going to dwell too long on what those things are.

    >> 因此,我們不會過多糾纏 長在什麼地方的東西。

  • But if I print out y, of course, I see 2.

    但是,如果我打印出Y, 當然,我看到2。

  • But ampersand y, I see this address.

    但符號Y,我看這個地址。

  • And notice, for the curious, how far apart are x and y?

    並請注意,為好奇, 相距多遠是x和y?

  • You can ignore most of the address.

    您可以忽略大部分的地址。

  • Four bytes.

    四個字節。

  • And that's consistent with our earlier claim that how big is an int?

    而這與我們的一致 早前聲稱有多大是一個int?

  • Four bytes.

    四個字節。

  • So it looks like everything's lining up nicely, as you might hope, in memory.

    所以看起來一切都排隊 很好,你可能希望,在內存中。

  • >> So now, let's just fast forward to the end of this story.

    >> 所以,現在,讓我們快進 這個故事的結尾。

  • Let's go ahead and type step, to dive into the Swap function.

    讓我們繼續前進,步型, 潛入交換功能。

  • Now notice, if I type a, it's identical to the address of x.

    現在發現,如果我輸入一個,它的 相同,x的地址。

  • If I type b, it's identical to the address of y.

    如果我B型是相同的 到y的地址。

  • So what should I see if I say, go to the address a?

    所以,我應該怎樣,如果我看到 說,進入地址的?

  • So print star a.

    因此,打印星號標示。

  • So star means go there, in this context.

    所以,明星意味著去那裡,在這種情況下。

  • Ampersand means what's the address of.

    &符號意味著什麼的地址。

  • So star a means 1.

    所以,明星的手段1。

  • And print star b gives me 2.

    並打印星級的住宿給我2。

  • >> And let me assume, for the moment, that at least the code that

    >> 讓我假設,就目前而言, 至少所述代碼

  • proceeds to execute now can be reasoned through in that way.

    現在進入執行即可 通過這種方式的理由。

  • But we'll revisit this idea before long.

    但我們會在不久重新討論這個想法。

  • So this version of Swap is now correct and allows

    所以這個版本的互換 現在是正確的,並且允許

  • us to swap this particular data type.

    我們來交換該特定數據類型。

  • >> So any questions then on Swap?

    >> 所以任何疑問然後交換?

  • On star?

    在星?

  • On address of?

    對地址?

  • And you'll see, with problem set 4, sort of,

    你會看到,有 問題集4,排序,

  • but problem set 5, definitely, how these things are useful and get much more

    但問題集5,絕對,如何將這些 東西是有用的,並得到更多的

  • comfortable with them, as a result.

    熟悉他們,作為一個結果。

  • Anything at all?

    什麼呢?

  • All right.

    好吧。

  • So malloc is, again, this function that just allocates memory, memory

    所以malloc的是,再次,此功能 剛剛分配內存,內存

  • allocation.

    分配。

  • And why is this useful?

    以及為什麼是這樣有用嗎?

  • Well, all this time, you've been using malloc.

    那麼,這一切的時候, 你一直在使用malloc。

  • If you consider now how getString works, presumably, it's

    如果你現在怎麼考慮的 GetString的作品,據推測,這是

  • been asking someone for a chunk of memory, anytime the user types a string

    被問的人一大塊 記憶,隨時在用戶鍵入字符串

  • in, because we certainly didn't know, as CS50 staff,

    在,因為我們肯定 不知道,因為CS50的工作人員,

  • how big those strings that humans are going to type might be.

    有多大的字符串,人類 要鍵入可能。

  • >> So let's, for the first time, start to peel back how the CS50 library works,

    >> 因此,讓我們,第一次,開始 剝開如何CS50庫工程,

  • by way of a couple of examples that will lead us there.

    通過幾個實例來 這將導致我們的。

  • So if I open up gedit and open up scanf 0,

    所以,如果我打開gedit的 開拓scanf函數0,

  • we're going to see the following code.

    我們將看到下面的代碼。

  • Scanf 0, available on the website for today, has relatively few lines of code

    scanf函數0,可以在網站上 今天,有代碼相對較少的行

  • here, 14 through 20.

    在這裡,14至20。

  • And let's see what it's doing.

    讓我們來看看它在做什麼。

  • It declares an int, called x.

    它聲明為int,名為x。

  • It says something like, number please.

    它說像,數請。

  • And now it says, scanf %i, &x.

    而現在它說,scanf函數%I,&X。

  • So there's a bunch of new stuff there.

    因此,有一堆新的東西出現。

  • >> But scanf, you can kind of think of as the opposite of printf.

    >> 但是scanf函數,你可以種思考 作為printf的相反。

  • printf, of course, prints to the screen.

    printf的,當然,打印到屏幕上。

  • scanf sort of scans from the user's keyboard something he or she has typed.

    scanf的排序從用戶的掃描 鍵盤的東西,他或她已經打出來。

  • >> %i is just like printf.

    >> %i是一樣的printf。

  • This means expect the user to type an int.

    這意味著預期 用戶鍵入一個int。

  • And now, why do you think I might be passing scanf &x?

    而現在,你為什麼認為我 可能是通過scanf函數&X?

  • If the purpose in life of scanf is to get something from the user,

    如果目的在scanf生活 是得到的東西從用戶

  • what is the meaning of passing it, &x, now?

    是什麼意思 通過它,與X,現在呢?

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • DAVID J. MALAN: Exactly.

    戴維·J·馬蘭:沒錯。

  • Whatever I, the human, type in, my input is going to be saved at that location.

    無論我,人,請在我的輸入 將被保存在該位置。

  • It's not sufficient, recall, to just pass in x, because we've seen already,

    這是不夠的,還記得,剛 通過在X,因為我們已經看到,

  • any time you pass just a raw variable, like an int, to some other function,

    任何時候,你只需通過一個原始變量, 就像一個int,一些其他的功能,

  • sure, it can change that variable, but not permanently.

    當然,它可以改變 可變的,但不會永久。

  • It can't have an effect on Main.

    它不能對主要的效果。

  • It can only change its own local copy.

    它只能改變自己的本地副本。

  • But if, instead, you don't give me the actual int,

    但相反,如果你不這樣做 給我實際的詮釋,

  • but you give me directions to that int, I now, being scanf,

    但你給我方向 在INT,我現在,是scanf函數,

  • surely, I can follow that address and put a number there

    當然,我可以按照這 解決並把一些有

  • so you have access to it as well.

    所以你可以訪問它。

  • >> So when I run this program, let's see.

    >> 所以,當我運行這個程序,讓我們來看看。

  • Make scanf 0 dot slash, scanf 0.

    使scanf函數0點斜線,scanf函數0。

  • And if I now type a number like 50, thanks for the 50.

    如果我現在鍵入數字 像50,感謝50。

  • If I now type a number like negative 1, for the negative 1.

    如果我現在鍵入數字一樣 負1,為負1。

  • I now type a number like 1.5, hm.

    我現在鍵入數字如1.5,HM。

  • Why did my program ignore me?

    為什麼我的程序不理我了?

  • Well, because simply, I told it to expect an int only.

    嗯,因為簡單地說,我告訴 只期待一個int。

  • All right.

    好吧。

  • So that's one version of this.

    所以這是其中的一個版本。

  • Let's take things up a notch and propose that this is not good.

    讓我們拿東西了一個缺口, 提出,這是不好的。

  • And herein lies a very simple example of how we can start writing code

    而就在這裡一個很簡單的例子, 怎麼我們就可以開始編寫代碼

  • that other people can exploit or compromise by doing bad things.

    其他人可以利用或 做不好的事情妥協。

  • So line 16, so similar in spirit to before,

    所以第16行,如此相似 在精神之前,

  • but I'm not declaring it int this time.

    但我不會宣布它詮釋這個時候。

  • I'm declaring it char star, aka string.

    我宣布它炭星,又名字符串。

  • >> But what does that really mean?

    >> 但是,這究竟意味著什麼?

  • So if I don't specify an address-- and I'm calling it arbitrarily, buffer,

    所以,如果我不指定address--和 我打電話是隨意,緩衝,

  • but I could call it s, to be simple-- and then I do this, explain to me,

    但我可以把它稱為為s,是simple-- 然後我做到這一點,給我解釋一下,

  • if you could, based on the previous logic, what is scanf doing in line 18,

    如果可以的話,基於先前 邏輯是什麼scanf函數在做線18,

  • if pass %s and buffer, which is an address?

    如果傳%s和緩衝區, 這是一個地址?

  • What is scanf, if you apply the exact same logic as version 0,

    什麼是scanf函數,如果你申請的 完全相同的邏輯版本0,

  • going to try to do here, when the user types something in?

    當將試圖在這裡做, 在用戶類型的東西嗎?

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • >> DAVID J. MALAN: Exactly.

    >> 戴維·J·馬蘭:沒錯。

  • Scanf, by the logic earlier, is going to take the string

    scanf函數,通過邏輯較早, 將要採取的串

  • that the human typed in-- it's now a string,

    該人的類型化 in--它現在是一個字符串,

  • it's not a number, presumably, if he or she cooperates--

    它不是一個數,據推測, 如果他或她cooperates--

  • and it's going to try to put that string in memory at whatever address

    並且它會試圖把那 字符串在內存中的任何地址

  • buffer specifies.

    緩衝區指定。

  • And this is great, because buffer is indeed meant to be an address.

    這是偉大的,因為緩衝 的確意味著是一個地址。

  • >> But I claim this program is buggy in a very serious way, because what value is

    >> 但我要求這個節目是越野車的 很嚴肅的方式,因為價值是什麼

  • buffer by default?

    默認情況下緩衝區?

  • What have I initialized into?

    我有什麼初始化為?

  • What chunk of memory?

    什麼的內存塊?

  • I haven't, right?

    我沒有,對不對?

  • >> So even though I've allocated a char star that's no longer called s,

    >> 所以,即使我已經分配了 焦恆星的不再叫S,

  • it's instead called, buffer-- so let's draw the variable's name

    它不是所謂的,buffer--所以 讓我們來繪製變量名

  • now as buffer-- if I haven't called getString or malloc here,

    現在的buffer--如果我沒有 所謂的getString或malloc的位置,

  • that effectively means that buffer is just some garbage value.

    這實際上意味著, 緩衝區只是一些垃圾值。

  • >> Now what does that mean?

    >> 現在是什麼意思?

  • It means that I have told scanf to expect a string from the user.

    這意味著,我已經告訴scanf函數 期望從用戶的字符串。

  • And you know what?

    而且你知道嗎?

  • Whatever this thing is pointing to-- and I draw question mark,

    不管這件事情是指向 to--和我畫問號,

  • but in reality, it's going to be something like Ox1, 2, 3, right?

    但在現實中,這將是 像OX1,2,3,對不對?

  • It's some bogus value that just happens to be there from before.

    這是一些虛假的價值,僅僅 恰好從之前在那裡。

  • So put another way, it's as though buffer is just

    所以,換句話說,它是 彷彿緩衝只是

  • pointing to something in memory.

    指著東西在內存中。

  • I have no idea what.

    我不知道是什麼。

  • >> So if I type in gabe now, it's going to try to put g-a-b-e /0 there.

    >> 所以,如果我輸入加布現在,這是怎麼回事 嘗試把G-A-B-E / 0出現。

  • But who knows what that is?

    但誰知道這是什麼嗎?

  • And in the past, any time we've tried to touch

    和過去一樣,任何 我們試圖去觸摸時間

  • memory that doesn't belong to us, what has happened?

    不屬於存儲器 對我們來說,發生了什麼事?

  • Or almost every time.

    或幾乎所有的時間。

  • Segmentation fault, right?

    分段錯誤,對吧?

  • >> This arrow, I have no idea where it's pointing. it's just some random value.

    >> 這個箭頭,我不知道它是 指點。它只是一些隨機值。

  • And of course, if you interpret a random value as an address,

    當然,如果你解釋 一個隨機值作為地址,

  • you're going to go to some random destination.

    你會去 一些隨機的目的地。

  • So gabe might indeed crash my program in this case here.

    所以加布可能確實崩潰 我在這裡這種情況下程序。

  • >> So what can we do that's almost as bad?

    >> 所以,我們可以做到這一點幾乎是壞?

  • Consider this third and final example of scanf.

    考慮這個第三和 scanf函數的最後一個例子。

  • This version is better in what sense?

    這個版本是在何種意義上比較好?

  • If you are comfortable with the previous problem, this is better.

    如果你是舒服了 以前的問題,這是更好的。

  • Why?

    為什麼呢?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • DAVID J. MALAN: Good.

    戴維·J·馬蘭:好。

  • So this case of line 16 is better, in the sense

    線16,以便該情況下 較好,在這個意義上

  • that we're explicitly allocating some memory.

    我們是明確的 分配一些內存。

  • We're not using malloc, we're using the week 2

    我們不使用malloc, 我們使用了2週

  • approach of just declaring an array.

    只是聲明數組的方法。

  • And we've said before that a string is just an array of characters,

    而我們在此之前一個字符串說過 是一個字符只是一個數組,

  • so this is totally legitimate.

    所以這是完全合法的。

  • But it's, of course, as you note, fixed size, 16.

    但它的,當然,如 您注意,固定的大小,16。

  • >> So this program is totally safe, if I type

    >> 因此,這個計劃是 完全安全的,如果我輸入

  • in one character strings, two character strings, 15 character strings.

    在一個文字串,兩個字符的 串,15字符的字符串。

  • But as soon as I start typing 16, 17, 18, 1,000 character strings,

    但是當我開始打字16, 17,第18,千字符串,

  • where is that string going to end up?

    這裡是該字符串將要結束?

  • It's going to end up partly here.

    這將結束部分在這裡。

  • But then who knows what else is beyond the boundaries

    但誰知道還有什麼 超出了界限

  • of this particular array?

    這個陣列呢?

  • >> It's as though I've declared 16 boxes here.

    >> 這是因為雖然我 在這裡宣布16箱。

  • So rather than draw out all 16, we'll just pretend that I've drawn 16.

    因此,而不是畫出來的所有16中,我們將 只是假裝我畫16。

  • But if I then try to read a string that's much longer, like 50 characters,

    但是,如果我再嘗試讀取字符串 這是更長的時間,如50個字符,

  • I'm going to start putting a, b, c, d, x, y, z.

    我要開始把 A,B,C,D,X,Y,Z。

  • And this is presumably some other memory segment

    這大概是 其它一些內存段

  • that, again, might cause my program to crash,

    即,再次,可能會導致 我的程序崩潰,

  • because I've not asked for anything more than just 16 bytes.

    因為我沒有要求 事情不止16個字節。

  • >> So who cares?

    >> 那麼,誰在乎呢?

  • Well, here's the CS50 library.

    好了,這裡的CS50庫。

  • And most of this is just like instructions up top.

    而且大部分這只是 類似的指令往上頂。

  • The CS50 library, all this time, has had this line in line 52.

    該CS50庫,這一切的時候, 已經有這一行52行。

  • We've seen typedef, or you will see typedef

    我們已經看到的typedef,或 你會看到的typedef

  • in pset 4, which just creates a synonym whereby char star can be more

    在PSET 4,剛剛創建了一個 同義詞其中焦炭明星可以更

  • simply referred to as string.

    簡稱為字符串。

  • So this is one of the few training wheels

    因此,這是一個 數輪培訓

  • we've used secretly underneath the hood.

    我們已經偷偷使用了引擎蓋下方。

  • >> Meanwhile, here's the function, getchar.

    >> 同時,這裡的函數,getchar函數。

  • Now apparently, there's no body to it.

    現在很明顯,沒有身體吧。

  • And in fact, if I keep scrolling, I don't actually

    而事實上,如果我繼續 滾動,我實際上並不

  • see any implementations of these functions.

    看不到任何的實現 這些功能。

  • As a sanity check, why is that?

    作為一個全面的檢查,這是為什麼?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • DAVID J. MALAN: Yeah.

    戴維·J·馬蘭:是的。

  • So this is the header file.

    因此,這是頭文件。

  • And header files contain prototypes, plus some other stuff, it seems,

    和頭文件包含原型, 再加上一些其他的東西,現在看來,

  • like typedefs.

    喜歡的類型定義。

  • But in CS50.c, which we've never given you outright,

    但在CS50.c,我們已經 從來沒有給你顧左右而言他,

  • but has been in the CS50 appliance all this time, deep inside of its folders,

    但一直在CS50所有家電 這個時候,內心深處的文件夾,

  • notice that there's a whole bunch of functions in here.

    注意到有一個整體 在這裡一堆功能。

  • >> In fact, let's scroll down.

    >> 事實上,我們向下滾動。

  • Let's ignore most of them, for now.

    讓我們忽略了他們中的大多數現在。

  • But scroll down to getInt and see how getInt works.

    但是,向下滾動到調用getInt 看看調用getInt是如何工作的。

  • So here is getInt.

    因此,這裡是調用getInt。

  • And if you ever really cared how get int works, here is its documentation.

    如果你真的關心如何獲得 INT作品,這裡是它的文檔。

  • And among the things it says is it tells you

    而當中的事 它說的是它告訴你

  • what the ranges of values it can return.

    什麼值的範圍就可以返回。

  • It's essentially negative 2 billion to positive 2 billion, give or take.

    它本質上是負面的2十億 以正面的2十億,給予或採取。

  • >> And it turns out, all this time, even though we've never

    >> 而事實證明,這一切 時間,即使我們從來沒有

  • had you check for it, if something goes wrong,

    有了你檢查它, 如果出現錯誤,

  • it turns out that all this time, getInt has

    事實證明,所有的 此時,調用getInt有

  • been returning a special constant, not null,

    已返回一個特殊的 常量,不為空,

  • but rather int_max, which is just a programmer's convention.

    而是INT_MAX,這是 只是一個程序員的約定。

  • It means here is a special value.

    這意味著這裡是一個特殊的值。

  • Make sure to check for this, just in case something goes wrong.

    請一定要檢查這一點,只是 在出錯的時候。

  • But we've never bothered with that to date,

    但是,我們從來沒有困擾 同的是,到目前為止,

  • because again, this is meant to simplify.

    因為再次,這 是為了簡化。

  • >> But how does getInt get implemented?

    >> 但如何調用getInt得到實施?

  • Well, one, it takes no arguments.

    嗯,一,它不帶任何參數。

  • We know that.

    我們知道這一點。

  • It returns an int.

    它返回一個int。

  • We know that.

    我們知道這一點。

  • So how does it work underneath the hood?

    那麼它是怎樣的引擎蓋底下工作?

  • >> So there's apparently an infinite loop, at least the appearance of one.

    >> 所以這是很明顯的無限 環,其中一個至少外觀。

  • Notice that we're using getString.

    請注意,我們使用的getString。

  • So that's interesting. getInt calls our own function, getString.

    所以這很有趣。調用getInt 調用我們自己的函數,的getString。

  • And now why might this be the case?

    現在為什麼會變成這樣?

  • Why am I being defensive here in line 165?

    為什麼我會被防守 在這裡行165?

  • What could happen in line 164, just to be clear?

    哪些本著可能發生 164,只是要清楚嗎?

  • It's the same answer as before.

    這是同樣的答案和以前一樣。

  • Might just be out of memory.

    可能僅僅是內存不足。

  • Something goes wrong with getString, we've got to be able to handle that.

    不順心的事了的getString, 我們必須能夠處理的。

  • And the reason I don't return null is that, technically, null is a pointer.

    而我之所以不返回null是 即,在技術上,空是一個指針。

  • getInt has to return an int.

    調用getInt必須返回一個int。

  • So I've arbitrarily decided, essentially,

    所以我隨意 決定,從本質上講,

  • that 2 billion, give or take, is going to be a special value that I can never

    有2十億,而奮鬥,是怎麼回事 是一種特殊的價值,我永遠不可能

  • actually get from the user.

    其實獲取用戶。

  • It's just the one value I'm going to waste to represent an error code.

    這只是一個價值我要去 浪費,代表一個錯誤代碼。

  • >> So now, things get a little fancy.

    >> 所以,現在,事情變得有點奇特。

  • And it's not quite the same function as before, but it's very similar.

    它不是完全一樣的功能 和以前一樣,但它是非常相似的。

  • So notice, I declare here, in line 172, both an int n and a char c.

    所以請注意,我在這裡聲明,符合 172,無論是一個int n和一個char℃。

  • And then I use this funky line, sscanf, which it turns out

    然後我用這個時髦的路線, sscanf的,它原來

  • doesn't scan a string from the keyboard.

    不掃描從鍵盤輸入的字符串。

  • It stands an existing string that the user has already typed in.

    它代表著現有的字符串 用戶已經鍵入英寸

  • So I already called getString, which means I have a string in memory.

    所以,我已經叫的getString,這 意味著我有一個字符串在內存中。

  • sscanf is what you'd call a parsing function.

    sscanf的是什麼,你會 調用解析函數。

  • It looks at the string I've typed in, character by character,

    它著眼於我有串 鍵入,字符一個字符,

  • and does something useful.

    並做一些有用的東西。

  • That string is stored in line.

    該字符串被存儲在一行。

  • And I know that only by going back up here and saying, oh, OK,

    我知道,只有通過去 備份在這裡,說,哦,好吧,

  • I called it not s this time, but line.

    我把它叫做不發這個時間,但行。

  • >> And now this is a little different.

    >> 而現在,這是一個有點不同。

  • But this effectively means, for reasons we'll somewhat wave our hands at today,

    但是這實際上意味著,其原因 我們會有點潮手在今天,

  • that we are checking to see if the user typed in

    我們正在檢查 查看該用戶鍵入

  • and int and maybe another character.

    與詮釋,也許另一個字符。

  • If the user typed in an int, it's going to be stored in n, because I'm

    如果用戶輸入了一個int,它的 將要被存儲在正,因為我

  • passing this by address, the new trick we've seen today.

    按地址傳遞這一點, 今天我們看到的新把戲。

  • If the user also typed in like 123x, that x

    如果用戶還輸入 像123x,使得x

  • is going to end up a letter in character c.

    將要結束了 字母字符c。

  • >> Now it turns out that sscanf will tell me, intelligently,

    >> 現在事實證明,sscanf的 告訴我,智能化,

  • how many variables was sscanf successfully able to fill.

    多少個變量是sscanf的 能夠成功地填補。

  • So by this logic, if the function I'm implementing is getInt,

    所以通過這種邏輯,如果該函數 我實施的調用getInt,

  • but I'm checking, potentially, for the user

    但我檢查, 潛在地,對於用戶

  • to have typed in an int followed by something else,

    已經輸入了一個int 其次是別的東西,

  • what do I want sscanf's return value truly to be?

    什麼才是我想要的sscanf的 返回值真的是?

  • If the purpose is to get just an int from the user?

    如果目的是要獲得 只是從用戶的詮釋?

  • >> So if sscanf returns 2, what does that mean?

    >> 所以,如果sscanf的回報 2,是什麼意思呢?

  • The user typed in something like, literally,

    用戶鍵入 是這樣,從字面上看,

  • 123x, which is just nonsense.

    123x,這只是無稽之談。

  • It's an error condition, and I want to check for that.

    這是一個錯誤,並 我要檢查的。

  • >> So if the user types this in, by this logic, what does sscanf return,

    >> 因此,如果這在用戶的類型,由 這個邏輯有哪些呢sscanf的回報,

  • would you say?

    你會說什麼?

  • So it's going to return 2, because the 123 is going to go in here,

    所以它會返回2,因為 123是要去這裡,

  • and the x is going to end up in here.

    而X是要結束在這裡。

  • But I don't want the x to get filled.

    但我不想在x得到填補。

  • I want to sscanf to only succeed in filling the first of its variables.

    我想,sscanf會只成功 灌裝頭的變量。

  • And so that's why I want sscanf to return 1.

    所以這就是為什麼我 想sscanf會返回1。

  • >> And if this is a bit over the head for the moment, that's totally fine.

    >> 如果這是有點在頭上 就目前而言,這是完全正常。

  • Realize though, that one of the values of getInt and getString

    意識到雖然,其中一個 調用getInt和GetString值

  • is that we're doing a heck of a lot of error checking like this so

    就是我們正在做的啦! 很多錯誤檢查這樣使

  • that, to date, you can pretty much type anything at your keyboard,

    是,到今天為止,你幾乎可以 在你的鍵盤輸入任何東西,

  • and we will catch it.

    我們會抓住它。

  • And we certainly, the staff, will definitely not

    我們肯定的是, 工作人員,肯定不會

  • be the source of a bug in your program, because we're defensively

    在一個錯誤的來源你 計劃,因為我們的防守

  • checking for all of the stupid things that a user might do,

    檢查所有的愚蠢的 的東西,用戶可能會做,

  • like typing a string, when you really wanted int.

    如輸入一個字符串,當 你真的想要詮釋。

  • So for now-- we'll come back to this before long--

    因此,對於now--我們就來 回此之前long--

  • but all this time, getString and getInt have

    但是這一切的時候, 的getString和調用getInt有

  • been underneath the hood using this basic idea of addresses of memory.

    在使用這種發動機罩下方 內存地址的基本思路。

  • >> So now, let's make things a little more user-friendly.

    >> 所以,現在,讓我們把事情 對用戶來說更加友好。

  • As you may recall, from Binky last time-- if my mouse will cooperate-- so

    您可能還記得,從去年賓基 時間 - 如果我的鼠標會cooperate--所以

  • we had this code, which frankly, is fairly nonsensical.

    我們有這個代碼,這 坦率地說,是相當荒謬的。

  • This code achieves nothing useful, but it was the example

    此代碼實現了什麼 有用的,但它是例子

  • that professor Parlante used in order to represent

    該教授Parlante 為了表示用於

  • what was going on in a program involving memory.

    什麼樣的是怎麼回事 項目涉及內存。

  • >> So let's retell this story super briefly.

    >> 因此,讓我們複述這 故事超簡要介紹。

  • These first two lines, in English, do what, would you say?

    這些前兩行,在 英語,做什麼,會說什麼?

  • Just in reasonably human, but slightly technical terms, take a stab.

    就在合理的人,但 稍微專業術語,取刺。

  • AUDIENCE: [INAUDIBLE].

    聽眾:[聽不清]。

  • >> DAVID J. MALAN: OK, you're establishing addresses for your x and y variables.

    >> 戴維·J·馬蘭:好,你確定 地址為你的x和y變量。

  • Not quite, because x and y are not variables in the traditional sense.

    不大,因為x和y是未 變量在傳統意義上的。

  • x and y are addresses or will store address.

    x和y是地址 或者將存儲地址。

  • So let's try this once more.

    因此,讓我們試試這個一次。

  • Not a bad start, though.

    不是一個糟糕的開局,但。

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • DAVID J. MALAN: Good.

    戴維·J·馬蘭:好。

  • I think that's a little cleaner.

    我認為這是一個小清潔。

  • Declaring two pointers, two integers.

    聲明兩個三分球,兩個整數。

  • And we're calling them x and y.

    而我們稱他們為x和y。

  • Or if we were to draw this as a picture, again,

    或者,如果我們畫 此為圖片,再

  • recall quite simply that all we're doing with that first line

    記得很簡單,所有 我們正在做的與第一線

  • is drawing a box like this, with some garbage value in it,

    正在制定一個盒子這樣的, 在它的一些垃圾的價值,

  • and calling it x, and then another box like this,

    並調用它的X,然後 另一個盒子這樣的,

  • with some garbage value in it, calling it y.

    與一些垃圾值 它,叫它年。

  • We've declared two pointers that ultimately

    我們已經聲明了兩個 三分球,最終

  • will store the address of an int.

    將存儲一個int的地址。

  • So that's all there.

    所以這一切都在那裡。

  • >> So when Binky did this, the clay just looked like this.

    >> 所以當賓基這樣做,則 粘土只是看著這樣的。

  • And Nick just kind of wrapped up the arrows,

    和尼克剛種 包裹起來的箭,

  • as though they're not pointing anywhere in particular, because they're just

    彷彿他們不是指向任何地方 特別是,因為他們只是

  • garbage values.

    垃圾值。

  • They're not explicitly initialized anywhere in particular.

    他們沒有明確的初始化 任何地方尤其如此。

  • >> Now the next line of code, recall, was this.

    >> 現在的下一行 代碼,召回,是這樣的。

  • So in reasonably user-friendly, but somewhat technical English,

    因此,在合理的人性化, 但有些技術英語,

  • what is this line of code doing?

    什麼是這行代碼在做什麼?

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE].

    >> 聽眾:[聽不清]。

  • >> DAVID J. MALAN: Perfect.

    >> 戴維·J·馬蘭:完美。

  • It's allocating the chunk of the memory that's the size of an int.

    它分配的大塊 內存是一個int的大小。

  • And that's half the answer.

    而這一半的答案。

  • You answered the right half of the expression.

    你回答正確 一半的表情。

  • What is happening on the left-hand side of the equal sign?

    什麼是發生在 等號左邊?

  • Yeah?

    是嗎?

  • AUDIENCE: And assigns it to the variable x?

    聽眾:和受讓人 它給變量x?

  • >> DAVID J. MALAN: And assigns it to the variable x.

    >> 戴維·J·馬蘭:和受讓人 它給變量x。

  • So to recap, right-hand side allocates enough memory to store an int.

    總括來說,右側會分配 足夠的內存來存儲一個int。

  • But malloc specifically returns the address

    但具體的malloc 返回地址

  • of that chunk of memory, which you've just proposed gets stored in x.

    這大塊的內存,您已中 只是建議被存放在X。

  • >> So what Nick did last time with Binky is he dragged that pointer out, the clay,

    >> 那麼,尼克做了最後一次帶賓基是 他拖著那指針移出,粘土,

  • to point now at a white chunk of memory that is equal to the size of an int.

    現在指向一個內存塊白 等於一個int的大小。

  • And indeed, that's meant to represent four bytes.

    事實上,這意味著 來表示四個字節。

  • >> Now, the next line of code did this, star x gets 42.

    >> 現在,代碼的下一行 這樣做,星x被42。

  • So 42 is straightforward on the right-hand side, meaning of life.

    所以42是簡單的 右手側,生活的含義。

  • Left-hand side, star x means what?

    左側,星x表示什麼?

  • That too might have gone-- that's OK.

    這也可能gone--沒關係。

  • OK.

    行。

  • >> AUDIENCE: Basically, go to the [INAUDIBLE]

    >> 聽眾:基本上, 進入[聽不清]

  • DAVID J. MALAN: Good.

    戴維·J·馬蘭:好。

  • AUDIENCE: [INAUDIBLE].

    聽眾:[聽不清]。

  • DAVID J. MALAN: Exactly.

    戴維·J·馬蘭:沒錯。

  • Left-hand side means go to x.

    左手邊是指去為x。

  • x is address.

    x是地址。

  • It's like 33 Oxford Street, or Ox1.

    這就像33牛津街,或OX1。

  • And star x means go to that address and put what there?

    和星x表示去那家 解決和放什麼呢?

  • 42.

    42。

  • >> So indeed, that's exactly what Nick did.

    >> 所以,事實上,這正是尼克做了。

  • He started with by, essentially, mentally

    他開始用, 本質上,精神上

  • pointing a finger at x, following the arrow

    用手指指著 的x,下面的箭頭

  • to the white box on the right-hand side, and putting the number 42 there.

    到右側的白框 側,並且把數42那裡。

  • But then things got a little dangerous, right?

    但後​​來事情得到了 有點危險吧?

  • Binky's about to lose his head.

    賓基的即將失去他的頭。

  • >> Star y equals 13, bad luck, means what?

    >> 星y等於13,運氣不好,意味著什麼?

  • So star y means go to the address in y.

    所以,明星y表示去的地址y中。

  • But what is the address in y?

    但是,什麼是Y中的地址?

  • All right, it's garbage value, right?

    好吧,這是垃圾的價值,對不對?

  • I drew it as a question mark.

    我畫它作為一個問號。

  • Nick drew it as a curled up arrow.

    尼克畫了它作為一個蜷縮箭頭。

  • And as soon as you try to do star y, saying go there,

    而且只要你嘗試 做明星Y,說去那裡,

  • but there is not a legitimate address, it's some bogus location,

    但沒有一個合法的 地址,它的一些虛假的位置,

  • the program's going to crash.

    該計劃的要崩潰。

  • And Binky's head is going to fly off here, as it did.

    和賓基的頭部會 飛了出去,在這裡,因為它沒有。

  • >> So in the end, this program was just flat out flaw.

    >> 所以,最後,這個方案 只是平了破綻。

  • It was a buggy program.

    這是一個錯誤的程序。

  • And it needed to be fixed.

    它需要加以固定。

  • And the only way, really, to fix it would be, for instance, this line,

    而唯一的辦法,真的,要解決它 將是,舉例來說,這條線,

  • which we didn't even get to, because the program crashed too soon.

    我們甚至沒有去,因為 程序崩潰得太快。

  • But if we were to fix this, what effect does doing y equal x have?

    但是,如果我們要解決這個問題,有什麼 效果確實做Ÿ等於x具有?

  • Well, it essentially points y at whatever value x is pointing at.

    那麼,它基本上是在點ÿ 任何值x指向。

  • >> So in Nick's story, or Binky's story, both

    >> 因此,在尼克的故事, 或賓基的故事,無論是

  • x and y were pointing at the white chunk of memory,

    x和y分別為指向 白色塊的存儲器,

  • so that, finally, when you do star y equals 13 again,

    這樣一來,最終,當 做明星Ÿ再次等於13,

  • you end up putting 13 in the appropriate location.

    你最終將在13 適當的位置。

  • So all of these lines are perfectly legitimate, except for this one,

    因此,所有這些線路都完美 合法的,除了這一個,

  • when it happened before you actually assigned y some value.

    之前,當它發生 實際分配Ÿ一定的價值。

  • >> Now thankfully, you don't have to reason through all

    >> 現在值得慶幸的是,你不 要通過推理全部

  • of these kinds of issues on your own.

    這些類型的問題你自己。

  • Let me go ahead and open up a terminal window here

    讓我繼續前進,開 在這裡一個終端窗口

  • and open up, for just a moment, a super short program that

    與開拓,就一下, 超級短節目的

  • also is sort of pointless.

    也就是那種毫無意義的。

  • It's ugly.

    這是醜陋的。

  • It doesn't achieve anything useful.

    它沒有實現任何用處。

  • But it does demonstrate issues of memory, so let's take a look.

    但它確實證明問題 記憶,讓我們一起來看看。

  • >> Main, super simple.

    >> 主要的,超級簡單。

  • It apparently calls a function, f, and then returns 0.

    這顯然是調用一個函數, F,然後返回0。

  • It's kind of hard to mess this up.

    這是一種很難搞砸。

  • So Main is pretty good, so far.

    所以,主要是相當不錯的,到目前為止。

  • >> So f is problematic.

    >> 所以f是有問題的。

  • And just didn't put much effort into naming it

    只是沒放多少 努力為它命名

  • here, to keep the focus on the code.

    在這裡,以保持重心的代碼。

  • f has two lines.

    f有兩行。

  • And let's see what's now going on.

    讓我們看看現在怎麼回事。

  • So on the one hand here-- and let me make

    這樣一方面 這裡 - 並讓我

  • this consistent with the previous example-- on the one hand,

    與前此一致 example--一方面,

  • the left-hand side is doing what, in English?

    左手側是 做什麼,用英語?

  • It is--

    它is--

  • AUDIENCE: Creating a pointer.

    聽眾:創建一個指針。

  • DAVID J. MALAN: Creating a pointer to an int and calling it x.

    戴維·J·馬蘭:創建一個指針 為int,把它x即可。

  • So it's creating one of those boxes I keep drawing on the touch screen.

    因此,它的創造者一個箱子 我一直畫在觸摸屏上。

  • And now, on the right-hand side, malloc, of course,

    現在,對右手 當然一面,malloc的,

  • is allocating a chunk of memory.

    被分配的內存塊。

  • And just to be clear, how much memory is it apparently

    而只是要清楚,怎麼 多少內存是它明顯

  • allocating, if you just kind of do the math here?

    分配,如果你只是 種做數學題嗎?

  • >> So it's 40 bytes.

    >> 因此,它是40個字節。

  • And I know that only because I know an int, on the CS50 appliance, at least,

    我知道,只是因為我知道的 整數,在CS50器具,至少

  • is four bytes.

    是四個字節。

  • So 10 times 4 is 40.

    所以,10次4 40。

  • So this is storing an x, the address of the first out of 40 ints that

    所以這是存儲一個x,地址 第一次出40的整數

  • have been allocated space back, to back, to back, to back.

    已分配的空間回來了, 背,背,背來。

  • >> And that's what's key about malloc.

    >> 而這正是重點對malloc的。

  • It doesn't take a little memory here, a little here, a little here.

    它並不需要一點點內存 在這裡,有一點在這裡,在這裡一點點。

  • It gives you one chunk of memory, contiguously, from the operating

    它為您提供了一個內存塊, 連續地,從操作

  • system.

    系統。

  • >> Now what about this, x bracket 10 equals 0?

    >> 現在來談談這個, 點¯x支架10等於0?

  • Arbitrary line of code.

    獨斷專行的代碼。

  • It doesn't achieve anything useful.

    它沒有實現任何用處。

  • But it is interesting, because x bracket 10--?

    但有意思的是, 因為變量x支架10--?

  • Yeah?

    是嗎?

  • >> AUDIENCE: [INAUDIBLE]?

    >> 聽眾:[聽不清]?

  • >> DAVID J. MALAN: x bracket 10 doesn't have to be null.

    >> 戴維·J·馬蘭:X支架 10不必是空的。

  • The null detail only comes into play with strings, at the end of a string.

    空的細節只有進場 用字符串,在字符串的結尾。

  • But a good thought.

    但一個好的想法。

  • >> How big is this array, even though I've allocated 40 bytes?

    >> 有多大這個數組,甚至 雖然我已經分配40個字節?

  • It's 0 through nine, right?

    這是從0到9,對不對?

  • It's 10 ints, total.

    這10個整數,總。

  • 40 bytes, but 10 ints, indexed 0 through 0.

    40個字節,但是10個整數, 索引0到0。

  • >> So what is that x bracket 10?

    >> 那麼,什麼是是X支架10?

  • It's actually some unknown garbage value.

    它實際上是一些 未知的垃圾值。

  • It's memory that doesn't belong to me.

    這是一個不屬於我的記憶。

  • I should not be touching that byte number 41, 42, 43, 44.

    我不應該碰的 字節數41,42,43,44。

  • I'm going slightly too far.

    我會稍微有點遠。

  • >> And indeed, if I run this program, it might very well crash.

    >> 事實上,如果我運行這個 程序時,它很可能會崩潰。

  • But sometimes, we'll get lucky.

    但有時,我們會得到幸運。

  • And so just to demonstrate this-- and frankly,

    所以,只是為了演示 this--坦率地說,

  • you never know before you do it-- let's run this.

    你永遠不知道你之前 做它 - 讓我們來運行的。

  • It didn't actually crash.

    它實際上並沒有崩潰。

  • >> But if I change this, for instance, to be like 1,000,

    >> 但是,如果我改變這一狀況,為 例如,要像千,

  • to make this really deliberate, let's see

    使這真的 故意的,讓我們來看看

  • if we can get it to crash this time.

    如果我們可以得到它的崩潰這個時候。

  • OK, it didn't crash.

    好吧,它沒有崩潰。

  • How about 100,000?

    如何約10萬?

  • Let's remake it, and now rerun it.

    讓我們來改造它,現在重新運行它。

  • OK.

    行。

  • Phew.

    唷。

  • All right.

    好吧。

  • So apparently, again, these segments of memory, so to speak,

    因此很明顯,同樣,這些 內存段,可以這麼說,

  • are reasonably big, so we can get lucky again and again.

    是相當大的,所以我們可以 一次又一次得到幸運。

  • But eventually, once you get ridiculous and really go far out on the screen,

    但最終,一旦你得到可笑 真正炎等在屏幕上,

  • you touch memory that really, really doesn't belong to you.

    你觸摸記憶真的, 真的不屬於你。

  • >> But frankly, these kinds of bugs are going

    >> 但坦率地說,這些 種蟲子會

  • to be harder and harder to figure out on your own.

    是難當 找出你自己的。

  • But thankfully, as programmers, we have tools that allow us to do this for us.

    不過,值得慶幸的是,作為程序員,我們有 工具,使我們能夠做到這一點的我們。

  • So this is, perhaps, one of the ugliest programs,

    因此,這是,也許是一 最醜的節目,

  • even uglier than gdb's output.

    比gdb的輸出,甚至醜陋。

  • But it always has a line or two that are super useful.

    但它總有一條線或 2是超級有用。

  • >> Valgrind is a program that helps you not debug a program, per se,

    >> Valgrind是一個程序,可以幫助 你沒有調試一個程序,本身

  • but find memory-related problems, specifically.

    但是發現內存相關 的問題,特別是。

  • It will automatically run your code for you and look for at least two things.

    它會自動運行您的代碼 你看,至少兩件事情。

  • One, did you do something accidental like touch memory

    一,你做了什麼 偶然像觸摸記憶

  • that didn't belong to you?

    那不屬於你?

  • It will help you find those cases.

    這將幫助你找到這些情況。

  • >> And two, it will help you find something called

    >> 其二,它會幫助 你發現了一種叫做

  • memory leaks, which we have completely ignored, naively,

    內存洩露,我們有 全然不顧,天真,

  • for some time and blissfully.

    一段時間和幸福地。

  • But it turns out, all this time, whenever

    但事實證明,所有的 此時,每當

  • you've called getString in so many of our programs,

    你所謂的getString在 我們這麼多的節目,

  • you're asking the operating system for memory,

    你問工作 系統記憶體,

  • but you have any recollection of ever giving it

    但你有什麼回憶 有史以來給它

  • back, doing unalloc, or free, as it's called.

    回來了,做unalloc,或 免費的,因為它的調用。

  • No, because we've never asked you to do so.

    沒有,因為我們從來沒有 要求你這樣做。

  • >> But all this time, the programs you've been writing in C

    >> 但所有這一次,程序 你一直在寫C語言

  • have been leaking memory, asking the operating

    已經洩漏內存, 要求經營

  • system for more and more memory for strings and whatnot,

    系統越來越 存儲字符串和諸如此類的東西,

  • but never handing it back.

    但從來沒有遞了回去。

  • And now this is a bit of a oversimplification,

    而現在,這是一個有點 à簡單化的,

  • but if you've ever run your Mac or your PC for quite some time, opening

    但如果你曾經運行在Mac或 你的電腦很長一段時間,開

  • lots of programs, maybe closing programs,

    大量的節目, 也許關閉程序,

  • and even though your computer hasn't crashed,

    而即使你的 電腦沒有死機,

  • it's getting so much slower, as though it's really

    它變得這麼慢得多, 好像真的

  • using a lot of memory or resources, even though,

    使用大量的內存或 資源,即使,

  • if you're not even touching the keyboard,

    如果你不連 觸摸鍵盤,

  • that could be-- but not always-- could be that the programs you're running

    可能be--但不always--能 是因為你正在運行的程序

  • have themselves memory leaks.

    有自己的內存洩漏。

  • And they keep asking the OS for more and more memory, but forgetting about it,

    他們不斷地問操作系統的更多, 更多的內存,但忘記了它,

  • not actually using it, but therefore taking memory away

    實際上並不使用它,但 因此,服用內存離開

  • from other programs that might want it.

    從可能希望它的其他程序。

  • So that's a common explanation.

    所以這是一個常見的解釋。

  • Now here's where Valgrind's output is completely

    現在,這裡的地方Valgrind的公司 輸出是完全

  • atrocious to those less and more comfortable alike.

    殘暴的那些少 更舒適的一致好評。

  • But the interesting stuff is right up here.

    但有趣 東西是正確的在這裡。

  • It is telling me an invalid write of size four happens in this program,

    它告訴我一個無效的寫 大小4發生這個程序中,

  • in particular, at line 21 of memory.c.

    特別是,在memory.c的第21行。

  • >> If I go to line 21, hm, there indeed is an invalid write of size four.

    >> 如果我去到第21行,嗯,的確有 是大小為4的無效寫。

  • Why size four?

    為什麼大小4?

  • Well, this number-- and it could be anything-- is an int.

    那麼,這number--它 可能是anything--是一個int。

  • So it's four bytes.

    因此,這四個字節。

  • So I'm putting four bytes where they don't belong.

    所以,我把四個字節 他們不屬於。

  • That's what Valgrind is actually telling me.

    這就是Valgrind的 實際上是告訴我。

  • Moreover, it will also tell me, as we'll see,

    此外,它也將 告訴我,因為我們將看到,

  • as you run this in a future pset, if and when you've leaked memory, which indeed

    當你運行這個在未來的PSET,如果和 當你的內存洩漏,這確實是

  • I have, because I've called malloc, but I haven't actually

    我有,因為我打過電話 malloc的,但我並沒有實際

  • called, in this case, free, which we'll eventually see

    叫,在這種情況下,自由 我們最終會看到

  • is the opposite of malloc.

    是的malloc相反。

  • >> So now, I think, a final example.

    >> 所以,現在,我認為,最後一個例子。

  • So this one's a little more arcane, but it's perhaps

    所以這一塊是一個有點多 晦澀難懂,但它也許是

  • the biggest reason to be careful with memory,

    最大的原因 小心內存,

  • and the reason that many programs and/or web servers, even to this day,

    究其原因,很多節目 和/或Web服務器,甚至到今天,

  • are taken over by bad guys somewhere on the internet who are somehow

    被接管壞人的地方 在互聯網上誰是莫名其妙

  • sending bogus packets to your server trying to compromise your accounts,

    發送偽造的數據包到服務器 試圖破壞您的賬戶,

  • or take your data, or just generally take over a machine.

    或者把你的數據,或只是 一般拿過來一台機器。

  • Buffer overflow, as the name suggests, means

    緩衝區溢出,隨著 顧名思義,手段

  • overflowing not an int, but a buffer.

    不溢出為int,而是一個緩衝區。

  • And a buffer is just a fancy way of saying it's a bunch of memory.

    和緩衝僅僅是一個奇特的方式 的說這是一串記憶。

  • >> And indeed, I called a string before buffer, instead of s.

    >> 事實上,我叫一個字符串 前緩衝區,而不​​是S,。

  • Because if it's a buffer, like in the YouTube sense,

    因為如果它是一個緩衝, 像在YouTube的意義,

  • or any time you're watching a video, you might have seen the word buffering,

    或者您正在觀看的視頻的任何時間, 你可能已經看到這個詞的緩衝,

  • dot, dot, dot.

    點,點,點。

  • It's incredibly annoying.

    這是令人難以置信的煩人。

  • And that just means that your video player

    而這僅僅意味著 您的視頻播放器

  • is trying to download lots of bytes, lots of bytes

    試圖下載大量 字節,大量的字節

  • from a video from the internet.

    從網上的視頻。

  • But it's slow, so it's trying to download a bunch of them

    但它是緩慢的,所以它的嘗試 下載了一堆人

  • to fill a buffer, a container, so that you have enough bytes that it can then

    填充緩衝器,一個容器,從而使 你有足夠的字節,它可以再

  • show you the video, without pausing constantly.

    告訴你的視頻, 不停頓不斷。

  • But it turns out, you can have a buffer to this big.

    但事實證明,你可以 有一個緩衝,以這個大。

  • But try to put this much data in it, and very bad things can happen.

    但盡量把這麼多數據 微博,很糟糕的事情可能發生。

  • So for instance, let's look at this final teaser of an example.

    因此,例如,讓我們來看看 一個例子的這個最終預告片。

  • This is another program that, at first glance,

    這是另一種方案 即,乍一看,

  • doesn't do anything super useful.

    什麼都不做超級有用。

  • It's got a Main function that calls that function, f.

    它有一個主要功能 調用該函數f。

  • And that function, f, up here, has a char array, called c, of size 12.

    而且函數f,在這裡,有 一個char數組,稱為大小12℃,。

  • And then it's using this new function called strncpy.

    然後它用這個 新的函數調用strncpy()函數。

  • >> It turns out that, with this simple, simple line of code, just two lines,

    >> 事實證明,這種簡單 代碼簡單的線條,只是兩條線,

  • we have made my entire program, and therefore, my entire computer,

    我們已經做了我的整個程序, 因此,我的整個電腦,

  • and my user account, and my hard drive potentially vulnerable to anyone

    我的用戶帳戶,我的硬盤 開車可能受到任何人

  • who knows and is good enough to run this program with a certain command line

    誰知道,是不夠好,運行 這個節目帶有一定的命令行

  • argument.

    的說法。

  • In other words, if this bad guy puts inside of argvargv[1] by typing

    換句話說,如果這個壞傢伙 通過鍵入把argvargv [1]內

  • at the keyboard a very specially crafted string, not abc, 123, but essentially,

    在鍵盤非常特製 字符串,而不是ABC,123,但本質上,

  • binary symbols that represent executable code, a program that he or she wrote,

    代表可執行的二進制符號 代碼,一個程序,他或她寫道:

  • with this simple program, which is representative of thousands of programs

    用這種簡單的方案,這是 代表的數以千計的節目

  • that are similarly vulnerable, daresay, he or she can ultimately delete all

    這同樣是脆弱的,敢說, 他或她可以最終刪除所有

  • the files on my hard drive, get a blinking prompt so that he or she can

    在我的硬盤驅動器中的文件,得到了 閃爍提示,以便他或她可以

  • type commands on their own, email all files to myself.

    自己輸入命令, 電子郵件中的所有文件到自己。

  • Anything that I can do, he or she can do with this code.

    什麼我可以做的,他 或她可以使用此代碼做。

  • >> We won't quite solve this yet.

    >> 我們不太解決這事。

  • And in fact, it's going to involve a little picture

    而事實上,這將 涉及小圖片

  • like this, which we'll soon come to understand all the better.

    這樣,我們將很快到來 理解就更好了。

  • But for today, let's end on what's, hopefully, a slightly more

    但是今天,讓我們結束 什麼是有希望稍微

  • understandable XKCD joke, until we resume next time.

    可以理解的XKCD笑話, 直到我們重新開始下一次。

  • All right.

    好吧。

  • See you on Wednesday.

    星期三見。

  • >> [MUSIC PLAYING]

    >> [音樂播放]

  • >> SPEAKER: And now, deep thoughts, by Daven Farnham.

    >> 演講嘉賓:現在,深 思想,通過Daven法納姆。

  • Memory is like jumping into a pile of golden leaves on a Sunday afternoon.

    記憶就像是跳進了一堆 金黃的樹葉在週日下午。

  • Wind blowing, tossing your hair-- oh, I miss the days when--

    風拂過,你折騰 hair--哦,我懷念的日子when--

  • >> [LAUGHTER]

    >> [笑]

[MUSIC PLAYING]

[音樂播放]

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋