>> [Chơi nhạc]
>> DAVID J. Malan: Tất cả quyền này là CS50 và điều này là sự bắt đầu của tuần năm.
Vì vậy, ngày hôm nay, bên dưới ghế ngồi của bạn, bạn sẽ không tìm thấy bất cứ điều gì.
Nhưng ở trên, bạn nên tìm những, một ít dấu hiệu của sự đánh giá cao của chúng tôi cho
tất cả các công việc mà bạn đặt vào các trò chơi của Mười lăm.
Đơn giản chỉ cần loại bỏ các vòng tròn nhỏ trên phía dưới để bắt đầu chơi cho
còn lại của lớp.
>> Vì vậy, nhớ lại rằng, hoặc biết rằng vấn đề đặt bốn, mà đi ra ngoài vào cuối tuần này,
liên quan đến văn bản trò chơi khác.
Nhưng lần này nó liên quan đến cách sử dụng một thực tế giao diện người dùng đồ họa, không phải là một
giao diện văn bản như Trò chơi của Mười lăm là.
Và các trò chơi ở phía trước của bạn, nếu bạn đã chưa nhìn thấy điều này tiếp theo,
trông một chút gì đó như thế này.
Tôi sẽ đi vào thiết bị đầu cuối của tôi cửa sổ ở đây trong GDB.
Và tôi sẽ đi trước và chạy giải pháp nhân viên, mà bạn có thể truy cập
sau khi chạy cập nhật 50 như bình thường.
>> Nhưng tôi sẽ đặt nó vào một chút chế độ bí mật, một chút trứng Phục Sinh,
cái gọi là chế độ của Thiên Chúa, bởi Thiên Chúa đặt trong argv1.
Và tôi phải làm theo hướng dẫn của riêng tôi, chạy nó trong của riêng tôi
vấn đề thiết lập thư mục.
Vì vậy, bây giờ bạn nhìn thấy một phiên bản hoàn chỉnh các trò chơi của breakout.
Trong thực tế, đây là chế độ không-tay.
Vì vậy, nó thực sự -
gây ấn tượng mạnh mặc dù bạn có thể có -
khá tầm thường để thực hiện chế độ Thiên Chúa trong Đột phá, không giống như trò chơi của mười lăm,
mà một số bạn có thể đã giải quyết cho phiên bản hacker.
>> Trong Breakout nó cũng đủ trong Thiên Chúa chế độ chỉ đơn giản là làm những gì,
trực giác với mái chèo?
Chỉ cần làm cho nó bằng bất cứ điều gì vị trí ngang của quả bóng.
Và miễn là bạn làm điều này theo sát bước chân với quả bóng di chuyển trò chơi này sẽ
không bao giờ, bao giờ, bao giờ bỏ lỡ bóng và bạn sẽ giành chiến thắng tất cả các thời gian.
>> Nhưng trong phiên bản của hacker trong tuần này có nhiều hơn là chỉ Thiên Chúa chế độ.
Có một số tính năng khác.
Trong số đó, laser.
Vì vậy, nếu bạn thực sự mất kiên nhẫn bạn có thể bắt đầu bắn hạ những viên gạch
và một vài người khác.
Và đối với những người bạn của những người muốn hiệu chỉnh tiêu chuẩn so với tin tặc
phiên bản, tôi có thể thấy rằng trong tuần này phiên bản của hacker cố tình là một
ít khả thi hơn, nói rằng, hơn Thiên Chúa chế độ là với trò chơi của Mười lăm.
>> Vì vậy, nếu bạn đang tìm kiếm một đoạn và bạn đang tìm kiếm một số vui vẻ thêm
tính năng làm lặn trong nếu quan tâm.
Bây giờ thực tế hơn, hãy để tôi chỉ ra một điều là tốt.
GDB, mà một số bạn có thể không có nhưng chạm cá nhân, đó là tốt.
Nhưng bây giờ thực sự là thời gian để làm quen này và thoải mái với công cụ này
bởi vì nó sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều, thực sự.
>> Mỗi bài giảng của Rob trên GDB một vài tuần trước, nhớ lại
GDB là một trình gỡ lỗi.
Đó là một công cụ cho phép bạn chạy của bạn chương trình nhưng chạy nó từng bước, dòng
Dòng, do đó bạn có thể poke xung quanh, để các bạn thấy những điều xảy ra, vì vậy
mà bạn có thể in ra giá trị của biến.
Trong ngắn hạn, nó sẽ cho bạn nhiều hơn nữa sức mạnh hơn printDef không.
>> Bây giờ phải thừa nhận rằng, giao diện là khá phức tạp.
Màu đen và màu trắng giao diện văn bản cho hầu hết các phần.
Các lệnh được phần nào khó khăn nhớ lần đầu tiên.
Nhưng ngay cả khi nó có thể đưa bạn một nửa một giờ, một giờ, để đưa trả trước đó
đầu tư thời gian vào nó, tôi tin tưởng.
Chắc chắn vào cuối học kỳ của nó sẽ tiết kiệm cho bạn một thứ tự cường độ hơn
thời gian hơn thế.
>> Vì vậy, vào đầu tuần lặn nhập
Và trong các điều khoản của breakout, biết rằng bạn có thể làm được điều này, miễn là bạn có
mã phân phối hoặc mã riêng của bạn trong tiến bộ trong thư mục Pst4 của bạn.
Biết rằng bạn có thể chạy gdb. / Đột phá.
>> Điều này sẽ mở ra một cửa sổ như thế này.
Hãy để tôi cung cấp cho bản thân mình hơn của một cửa sổ thiết bị đầu cuối.
Và sau đó những gì tôi sẽ đi trước và làm, nó không chỉ cần chạy nó.
Tôi sẽ lần đầu tiên thiết lập một điểm break thu hồi, cho phép bạn tạm dừng
thực hiện tại một địa điểm cụ thể.
>> Chỉ để giữ cho mọi thứ đơn giản, tôi sẽ để phá vỡ tại dòng một chỉ bằng cách gõ
số một.
Hãy để tôi thực sự mở lại cửa sổ này bởi vì nó nhận được một
nhỏ nhỏ đó.
Vì vậy, những gì bây giờ tôi sẽ làm ở đây là nếu tôi mở cửa sổ thiết bị đầu cuối của tôi.
Thôi nào, có chúng tôi đi.
>> Vì vậy, bây giờ nếu tôi quay trở lại Dropbox, Pst4 và chạy gdb. / đột phá nhập, thông báo
Tôi sẽ phá vỡ một thiết lập một điểm break ở dòng thứ nhất.
Và bây giờ tôi sẽ đi và loại chạy về phía trước.
Và khi tôi làm, nhận thấy không có gì có thể xảy ra.
>> Không có cửa sổ pop up.
Không có đồ họa giao diện người dùng được nêu ra.
Nhưng đó là dễ hiểu bởi vì tôi nghĩa tại dòng trong một chương trình của tôi.
Và nhận thấy rằng tôi đã chuyển tiếp nhanh, đặc biệt bây giờ đến 62, bởi vì tất cả
các công cụ ở trên cùng của tập tin này là những thứ như ý kiến ​​và hằng số và
không hấp dẫn các công cụ cho bây giờ.
>> Vì vậy, bây giờ tôi bên trong của chính, có vẻ như, tại dòng 62.
Và đây là sự phân phối mã, thu hồi.
Nếu tôi mở này lên bằng cách đi, tương tự, vào thư mục hộp thả tôi vào Pst4,
vào breakout.c.
Và nếu tôi di chuyển xuống và xuống và xuống, và để cho tôi đi trước và bật
số dòng của tôi.
>> Những gì tôi sẽ thấy, nếu tôi di chuyển xuống đường 62, chính xác là dòng
chúng tôi đã tạm dừng trên.
Vì vậy, dòng này đây, 62 tuổi, là nơi chúng tôi sắp sửa được.
Vì vậy, bây giờ trong GDB, nếu tôi đi trước và gõ giờ tiếp theo, nhập nó sẽ
thực hiện dòng đó.
Và thì đấy, chúng tôi có cái gọi là cửa sổ g.
Nếu không quen thuộc với những gì một GWindow là, không phải lo lắng.
Spec sẽ giới thiệu bạn với nó, như cũng như một số video hương
nhúng trong spec.
>> Nhưng bây giờ chúng ta hãy làm điều này một ít thú vị hơn.
Hãy để tôi di chuyển cửa sổ này hơn sang một bên một chút.
Hãy để tôi làm cho cửa sổ một chút lớn hơn để tôi có thể nhìn thấy hơn.
>> Và bây giờ hãy để tôi đi trước và làm gì tiếp theo nữa.
Và có những viên gạch của tôi.
Nếu tôi gõ tiếp theo lại bây giờ tôi thấy bóng.
Và nếu tôi gõ tiếp theo lại bây giờ tôi thấy mái chèo.
>> Và may mắn thay gedit đây không phải là thực sự hợp tác bằng cách cho tôi
tất cả mọi thứ tôi muốn.
Nhưng bây giờ nếu tôi làm gì tiếp theo một lần nữa, tiếp theo một lần nữa, tôi chỉ
khai báo một số biến.
Và tôi có thể in bất kỳ một của những kẻ ra.
Gạch in, bản in cuộc sống.
>> Và bây giờ nếu tôi tiếp tục làm tiếp theo, thông báo rằng tôi sẽ có
trong vòng lặp đó.
Nhưng mã này sẽ thực hiện chính xác như tôi mong đợi.
Vì vậy, khi tôi nhấn chức năng này, Chờ cho Click, nó sẽ làm
nó theo nghĩa đen đó.
Vì vậy, tôi dường như đã mất quyền kiểm soát trong chương trình.
>> GDB không đem lại cho tôi một dấu nhắc.
Nhưng không phải lo lắng.
Hãy vào trò chơi của tôi, nhấp vào một nơi nào đó.
>> Và thì đấy, bây giờ nó đi vào dòng 86.
Vì vậy, một lần nữa, nó là vô giá, cuối cùng, cho các vấn đề gỡ lỗi.
Bởi vì bạn có nghĩa là có thể bước qua mã của bạn, in những điều trên và nhiều,
nhiều, nhiều hơn nữa.
Nhưng hiện nay, những công cụ một mình sẽ giúp bạn khá xa.
>> Vì vậy, chúng tôi, tất nhiên, lấy một cái nhìn ở đồ họa bây giờ, tất cả của một đột ngột.
Và bây giờ thế giới của chúng tôi được một chút thú vị hơn.
Và bạn biết, có lẽ, từ một số các video trực tuyến mà chúng ta có những
quần short mà bạn đã xem như là một phần của bài tập.
>> Và họ đã bị bắn, cố tình, chống lại một nền màu trắng.
Và một số người trong số họ có giảng dạy Nghiên cứu sinh vẽ một số văn bản trên
màn hình đó là phủ về phía họ.
Nhưng tất nhiên, đây không phải là tất cả những gì thú vị trong thế giới thực.
Đây chỉ là một giảng đường với một màn hình lớn màu trắng và bối cảnh.
Và đội ngũ sản xuất tuyệt vời của chúng tôi loại của làm cho mọi thứ trông đẹp
sau khi thực tế bằng cách cắt ra hoặc đè bất cứ điều gì
chúng ta làm hoặc không muốn.
>> Bây giờ chỉ cần để thúc đẩy tuần này và thực sự, nơi bạn có thể đi, cuối cùng,
với khoa học máy tính.
Không chỉ là vấn đề sau khi thiết lập bốn.
Nhưng sau một khóa học hoặc một toàn bộ chương trình giảng dạy đó là những gì tuyệt vời bạn có thể
làm những ngày về đồ họa nói riêng.
>> Một số bạn có thể đã nhìn thấy điều này chảy xung quanh trực tuyến.
Nhưng tôi nghĩ rằng tôi muốn cho bạn thấy, chỉ một vài phút, một cái nhìn thoáng qua về những gì
công nghệ máy tính và những gì CGI, đồ họa máy tính có thể làm những ngày này
với một bài hát quen thuộc và có lẽ phim.
>> [MUSIC - LANA DEL RAY, "TRẺ ĐẸP VÀ]
>> SPEAKER 1: Nó chỉ là một chút tuyệt vời, có lẽ, như thế nào
mặt ở khắp nơi -
>> [Vỗ tay]
>> SPEAKER 1: Tôi chỉ cần tải về nó.
Nhưng nó thực sự tuyệt vời, tôi nghĩ rằng, chỉ cần cách mặt ở khắp nơi và phần mềm mã và
các công cụ như thế này thực sự là.
Vì vậy, đó là một hương vị của hướng trong đó bạn có thể đi.
Oh, không gia dụng ngày hôm nay.
Vâng, đó là thời gian thực sự bi thảm cho điểm tôi chỉ cố gắng để thực hiện.
>> Được rồi, vì vậy hãy khởi động Kết hợp một lần nữa.
Nhắc nhở tôi sau này.
Tất cả các bên phải, và bạn nên đã có một email như một sang một bên nếu bạn đã có được một
nhận thấy như thế.
Được rồi, nhớ lại rằng tuần trước chúng tôi bắt đầu bóc này
sau đó được gọi là chuỗi.
>> chuỗi nhớ lại một kiểu dữ liệu đó là khai báo trong thư viện CS50.
Và nó là một phần của các bánh xe đào tạo mà bây giờ sẽ bắt đầu cất cánh.
Đó là một khái niệm hữu ích sớm.
Nhưng bây giờ nó sẽ nhận được nhiều hơn thú vị và mạnh mẽ hơn để
thực sự thấy rằng bên dưới mui xe, một chuỗi chỉ là những gì, đã làm chúng tôi nói gì không?
>> Yeah, vì vậy đó là một cái gọi là char *.
Và * có biểu thị rằng có một số loại địa chỉ có liên quan.
Và vì vậy khi bạn nói char * Bạn chỉ có nghĩa là một biến có kiểu dữ liệu là một
con trỏ bây giờ.
Thực tế là có những ngôi sao có chỉ có nghĩa là bạn đang khai báo một
cái gọi là con trỏ.
Và con trỏ có nghĩa là sẽ rõ ràng lưu trữ các địa chỉ của, của
Tất nhiên, một char.
>> Bây giờ tại sao điều này có ý nghĩa?
Vâng, một chuỗi là những gì bên dưới mui xe?
Vâng, trong một thời gian chúng tôi đã nói rằng một chuỗi bên dưới mui xe là
chỉ h-e-l-l-o, ví dụ.
>> Nhưng chúng tôi đã nói về điều này như là, về cơ bản, một mảng.
Và một mảng sau đó sẽ xem xét một chút hơn như thế này, với mỗi
chiếm một vết cắn.
Và sau đó chúng tôi đã nói rằng có một cái gì đó đặc biệt trở lại đây, các
dấu gạch chéo ngược 0, hoặc null terminator.
>> Vì vậy, tất cả các thời gian này, này đây đã được một chuỗi.
Nhưng thực sự, một chuỗi thực sự là một địa chỉ.
Và địa chỉ, như chúng ta sẽ thấy, thường bắt đầu với 0x theo quy ước.
0x gì biểu thị?
Không ai biết?
>> Vì vậy, nó chỉ có nghĩa là hệ thập lục phân.
Vì vậy, bạn có thể nhớ lại, trên thực tế, từ PST 1, tôi tin rằng, một trong những khởi động
câu hỏi thực sự được hỏi về ký hiệu thập lục phân ngoài
nhị phân và thập phân.
Và động lực ở đây là với hệ thập lục phân bạn có 16
chữ số theo ý của bạn.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, tiếp theo bởi a, b, c, d, đ, e.
>> Và nếu tính tất cả những người lên, bạn nhận được tổng số 16.
Vì vậy, điều này trái ngược với số thập phân, nơi chúng tôi có 10
chữ số, 0 đến chín.
Nó trái ngược với nhị phân nơi chúng tôi chỉ có 0 và 1.
>> Nhưng vào cuối ngày, bạn có thể chỉ cần đại diện cho các con số tương tự, nhưng
hơi khác nhau.
Và hệ thập lục phân là phổ biến vì như nó quay ra - và chúng ta sẽ thấy điều này
sau trong khóa học - ngay cả khi chúng ta có được để lập trình web trong bối cảnh
HTML và mã màu, hệ thập lục phân là tốt đẹp.
Bởi vì mỗi chữ số, quay ra, đại diện cho bốn bit hoàn hảo.
Vì vậy, nó chỉ là loại đường lên độc đáo như chúng tôi cuối cùng sẽ thấy.
Vì vậy, đây có thể là một cái gì đó hoặc Ox123 như thế, biểu thị địa chỉ 123
ở đâu đó bên trong của tôi bộ nhớ của máy tính.
>> Nhưng tất nhiên, một số vấn đề phát sinh vì cơ bản này
thực hiện.
Và nhớ lại rằng tôi đã lấy một đâm vào thực hiện một chức năng như thế này -
so sánh dấu gạch ngang 0 dot c tuần trước, mà mặc dù nó trông giống như nó là
đúng, nó chỉ đơn giản là không so sánh hai dây một cách chính xác.
>> Tôi đã vứt bỏ chính, và tôi đã ném đi những ý kiến ​​chỉ để tập trung vào
các mã đó là quan tâm ở đây.
Và đó là màu đỏ vì đó là lỗi.
Vì lý do gì?
>> Vâng, ở trên cùng có khi tôi tuyên bố một chuỗi, những gì đã thực sự xảy ra
bên dưới mui xe?
Vâng, hãy để tôi đi về phía sàng lọc ở đây và rút ra rằng.
Vì vậy, tôi tuyên bố, một lần nữa, string s GetString.
>> Vì vậy, tôi sẽ đi trước và bây giờ vẽ s cho những gì nó thực sự là.
Nó sẽ là một hình vuông đây.
Và tôi sẽ yêu cầu bồi thường mà đó là 32 bit.
Ít nhất nó thường là, ít nhất là trên CS50
thiết bị trong rất nhiều máy tính.
Tôi sẽ gọi nó là s.
>> Nhưng bây giờ nhớ lại rằng chúng tôi gọi là GetString.
Vì vậy, lợi nhuận GetString, tất nhiên, một chuỗi.
Nếu sử dụng các loại trong h-e-l-l-o nhập chuỗi hello được trả lại.
Và chuỗi đó, như chúng tôi vừa nói, kết thúc ở đâu đó trong bộ nhớ máy tính của bạn
với một dấu gạch chéo ngược 0 ở cuối.
Tôi sẽ vẽ này như mảng - hoặc khối liên tục của các nhân vật -
nó thực sự là.
>> Và bây giờ, những gì đang GetString thực sự trở lại?
Những gì đã GetString được trở về tất cả thời gian này?
Vâng, chúng ta nói, trong tuần trước, nó trả về một chuỗi.
Nhưng về mặt kỹ thuật hơn, những gì hiện GetString trở lại rõ ràng?
>> ĐỐI TƯỢNG: Một địa chỉ.
>> SPEAKER 1: Một địa chỉ.
Cụ thể nó sẽ trả về địa chỉ của vết cắn đầu tiên, bất cứ điều gì.
Tôi chỉ tiếp tục sử dụng một, hai, ba bởi vì nó thuận tiện.
>> Nó sẽ trả về địa chỉ của các đầu tiên nhân vật trong chuỗi.
Và chúng tôi cho biết tuần trước rằng đó là đủ.
Bởi vì chúng ta luôn luôn có thể tìm ra nơi kết thúc chuỗi chỉ bằng cách
duyệt qua nó, có lẽ, với một cho vòng lặp hoặc một vòng lặp trong khi hoặc một cái gì đó như
đó, chỉ cần tìm kiếm "dấu gạch chéo ngược 0", các nhân vật trọng điểm đặc biệt.
>> Và sau đó chúng ta biết rằng chuỗi sẽ xảy ra là chiều dài -
trong trường hợp này -
năm.
Vì vậy, về mặt kỹ thuật những gì GetString không là nó trả về Ox123 trong trường hợp này.
Và về mặt kỹ thuật những gì xảy ra sau đó là mà chúng tôi lưu trữ, bên trong s, Ox123.
Vào cuối ngày, mặc dù điều này là khái niệm mới, con trỏ, họ
chỉ biến.
Nhưng chúng xảy ra để lưu trữ các bit mà tập thể đại diện cho một địa chỉ.
Vì vậy, về mặt kỹ thuật tất cả họ được được lưu trữ trong s là Ox123.
>> Nhưng chúng tôi như con người -
bao gồm cả hôm nay trở đi -
đang thực sự sẽ không quan tâm, thông thường, những địa chỉ thực tế
một số đoạn bộ nhớ.
Nó chỉ là mức thấp của chi tiết để có trí tuệ thú vị.
Vì vậy, tôi sẽ lùi lại này.
Và thay vào đó, mức độ cao hơn, chỉ cần nói rằng khi chúng ta đang nói về con trỏ
Tôi sẽ chỉ thu hút nhiều hơn mũi tên sử dụng mà chuyển tải
cùng ý tưởng và tóm tắt đi cụ thể về những gì thực tế
địa chỉ cơ bản là.
>> Bây giờ nếu chúng ta quay trở lại các mã, những gì xảy ra trong tuần cuối cùng nếu chúng ta có chuỗi t
bằng GetString?
Vâng, nếu tôi một lần nữa, gõ vào xin chào thời gian này tôi sẽ nhận được
một đoạn bộ nhớ.
h-e-l-l-o dấu chéo ngược 0.
>> Nhưng vì tôi gọi là getString lần thứ hai -
và tôi biết điều này từ nhìn vào mã nguồn cho GetString - thậm chí
mặc dù nó trùng hợp ngẫu nhiên mà là xin chào gõ vào hai lần, GetString không phải là
sẽ cố gắng để tối ưu hóa và được thông minh.
Nó chỉ sẽ nhận được một đoạn bộ nhớ từ máy tính, mà là
sẽ có mặt tại một địa chỉ khác.
Chúng ta hãy tự ý chỉ nói 456.
>> Và sau đó những gì là nó sẽ trở lại?
Nó sẽ trở lại 456 và lưu trữ nó trong t.
Vì vậy, những gì đang thực sự xảy ra, trên bên trái là tôi có đoạn khác
bộ nhớ, 32 bit thường.
Và trong đó sẽ đi Ox456.
Nhưng một lần nữa, tôi không quan tâm đến các số cụ thể nữa.
Tôi chỉ cần đi đến trừu tượng vẽ nó như một mũi tên.
>> Vì vậy, đây bây giờ là một lời giải thích mới.
Nhưng đó là ý tưởng chính xác đó là đã xảy ra suốt thời gian qua.
Và do đó, lý do đó, điều này đầu tiên phiên bản của so sánh là lỗi
tuần trước là lý do tại sao?
Khi bạn làm gì nếu s tương đương với bằng t bạn là những gì thật sự
bên dưới mui xe so sánh?
>> Bạn đang so sánh các địa chỉ.
Và chỉ trực quan, rõ ràng, Ox123 sẽ không bằng Ox456.
Những con số, những bit chỉ khác nhau.
>> Và do đó một cách nhất quán, tuần trước cho biết bạn gõ những thứ khác nhau, ngay cả khi
lời là đúng nguyên văn như vậy.
Vì vậy, chúng tôi sửa lỗi này.
Trong điều khoản của layman, việc sửa chữa là gì?
>> ĐỐI TƯỢNG: Sử dụng chức năng.
>> SPEAKER 1: Sử dụng chức năng.
Hoặc sao chắc chắn có liên quan, nhưng sử dụng một chức năng để làm những gì?
>> ĐỐI TƯỢNG: Để so sánh chuỗi.
>> SPEAKER 1: Để so sánh chuỗi.
Vì vậy, các vấn đề cơ bản ở đây là rằng tôi chỉ xem xét
chất lượng của chuỗi được xác định bằng so sánh địa chỉ của họ.
Và rõ ràng đó chỉ là câm giờ một lần bạn hiểu những gì đang xảy ra
bên dưới mui xe.
Để thực sự so sánh chuỗi để xem họ bằng trong cách mà một con người
sẽ xem xét hai dây được bình đẳng chúng ta cần phải so sánh chúng nhân vật cho
nhân vật cho nhân vật.
>> Bây giờ tôi có thể có thực hiện này rất tediously.
Nhưng thân thiết, chúng tôi sử dụng một vòng lặp.
Và chỉ cần so sánh s khung tôi chống lại t khung tôi.
s khung tôi cộng với 1 đối với t khung tôi cộng với 1, vv, trong
một số loại vòng lặp.
Và nếu tôi phát hiện bất kỳ hai ký tự khác nhau, hoặc nếu tôi nhận ra rằng ooh, s là
ngắn hơn hoặc dài hơn t t Tôi ngay lập tức có thể nói sai,
họ không giống nhau.
>> Nhưng nếu tôi nhận được thông qua s và t và nói , cùng, cùng, cùng, cùng, kết thúc
cả hai chuỗi, tôi có thể nói đúng, chúng bằng nhau.
Vâng, may mắn thay, năm trước một người nào đó đã viết mã cho chúng tôi.
>> Và họ gọi nó là StrComp cho chuỗi so sánh.
Và mặc dù nó là một chút truy cập trực quan, StrComp trả về 0 nếu những
hai dây, s và t là như nhau.
Nhưng nó trả về giá trị âm nếu s nên đến trước khi t theo thứ tự abc hoặc
giá trị tích cực nếu cần đến sau khi t theo bảng chữ cái.
>> Vì vậy, nếu bạn muốn sắp xếp một cái gì đó, nó quay ra rằng StrComp là hữu ích.
Bởi vì nó không chỉ nói có hay không, bằng hoặc không.
Nó mang lại cho bạn một cảm giác đặt hàng như một từ điển sức.
Vì vậy, StrComp, s dấu phẩy t bằng bằng 0 có nghĩa là
dây thật sự bình đẳng.
Bởi vì bất cứ ai đã viết chức năng này năm trước đây có lẽ là sử dụng một vòng lặp for
hoặc một vòng lặp trong khi hay tin như thế để tích hợp trên các nhân vật một lần nữa
và một lần nữa và một lần nữa.
>> Nhưng hai vấn đề nảy sinh ở đây.
Đây là copy0.c.
Và hai màu đỏ là bởi vì đó là sai lầm.
Và chúng tôi đã làm gì ở đây?
Vâng, đầu tiên tôi gọi là getString.
Và tôi lưu trữ các giá trị trả về trong s.
Vì vậy, đó là khá nhiều giống như này là một phần trên của hình ảnh.
>> Nhưng điều gì sẽ đến sau đó?
Vâng, hãy để tôi đi trước để loại bỏ của một bó toàn bộ này.
Chúng tôi sẽ quay lại trong thời gian đến nơi chúng tôi chỉ có s, mà bây giờ phù hợp với
đường lên đó.
>> Tôi kiểm tra.
Nếu s bằng bằng 0.
Bây giờ, một mặt lưu ý nhanh chóng, khi có thể GetString trở về 0?
Không có đủ bộ nhớ.
Phải không?
>> Nó hiếm hoi rằng điều này sẽ xảy ra, chắc chắn trên một máy tính đó là
có hàng trăm megs hoặc thậm chí hợp đồng biểu diễn của bộ nhớ RAM.
Nhưng nó có thể, trong lý thuyết, trở về 0, đặc biệt là nếu
người sử dụng không hợp tác.
Có cách để giả vờ như bạn chưa bất cứ điều gì nhập và lừa
GetString vào trở lại 0 có hiệu quả.
>> Vì vậy, nó sẽ kiểm tra cho điều đó.
Bởi vì nếu bất kỳ của bạn đã bắt đầu nhận được, đã có, lỗi phân khúc -
trong đó đã có thể là một nguồn của một số thất vọng -
đó là hầu như luôn luôn kết quả bộ nhớ liên quan đến lỗi.
Bằng cách nào đó bạn sai lầm liên quan với một con trỏ, thậm chí nếu bạn đã không nhận ra
có một con trỏ.
Vì vậy, bạn có thể đã gây ra chia nhỏ gói lỗi càng sớm càng một tuần sử dụng
một cái gì đó giống như một vòng lặp hoặc một thời gian vòng lặp và một mảng bằng cách đi quá xa
qua ranh giới của một số mảng bạn tuyên bố, trong tuần hai trong
cụ thể.
>> Bạn có thể thực hiện nó ngay cả trong vấn đề thiết lập bốn với Breakout.
Mặc dù có thể bạn không nhìn thấy bất kỳ ngôi sao trong mã phân phối
Đột phá, nó chỉ ra rằng những GRect và những thứ đó GOval và khác,
những người thực sự con trỏ bên dưới mui xe.
>> Nhưng Stanford, như chúng tôi, loại da rằng chi tiết ít nhất là cho các thư viện
mục đích, giống như chúng ta làm cho chuỗi và char *.
Nhưng GRect và GOval và tất cả những điều các bạn đang hoặc sẽ được sử dụng
tuần này là cuối cùng địa chỉ bộ nhớ.
Bạn chỉ không biết nó.
>> Vì vậy, nó không phải là đáng ngạc nhiên sau đó, có lẽ, mà bạn có thể đi qua một số
lỗi phân khúc.
Nhưng điều thú vị ở đây bây giờ, nếu sau khi chúng tôi kiểm tra số 0 chúng tôi
chuỗi t được s.
Vâng, hãy để tôi tuyên bố t.
Tôi sẽ vẽ nó như một hình vuông, 32 bit, gọi nó là t.
Và sau đó tôi sẽ làm được s.
>> Vâng, điều đó không có nghĩa là gì?
Vâng, đó là một chút khó khăn để nghĩ về nó hình khôn ngoan.
Nhưng chúng ta hãy suy nghĩ về những gì bên trong của x?
Những gì là nghĩa đen bên trong biến này?
Các Ox123 giá trị.
>> Vì vậy, khi tôi nói chuỗi t được s, mà chỉ có nghĩa là có số lượng
trong, mà là Ox123 và đặt nó Ox123.
Hoặc những bức tranh, nếu tôi loại trừu tượng đi từ chi tiết mà nó có
hiệu lực của nghĩa đen làm này là tốt.
>> Vì vậy, bây giờ, nghĩ lại tuần trước khi chúng tôi tiến hành tư T. tôi
T đã làm khung 0.
Vâng, T khung 0, mặc dù đó là một con trỏ, bạn có thể đối xử với nó như thể
nó là một mảng, với một hình vuông khung ký hiệu.
>> Vì vậy, nơi là T khung 0?
Vâng, đó là h.
Và khi chúng tôi sử dụng dòng mã, hai phía trên, đó là trong đó c type.h
tập tin tiêu đề, đó là nơi nó tuyên bố.
Bạn đang tận H. này Nhưng Tất nhiên, đó là h chính xác đó là
bên trong, do đó, để nói chuyện.
Và vì vậy bây giờ bạn đã thay đổi hoặc vốn đầu tư cả hai bản gốc và
cái gọi là bản sao.
Bởi vì bạn đã không tạo một bản sao trong cách mà một con người sẽ muốn nó được.
>> Vì vậy, những gì đã được sửa chữa ở đây, trong copy1.c tuần trước?
Chức năng, vì vậy chúng tôi có thể thực sự sao chép chuỗi.
Và về cơ bản, những gì chúng ta cần phải làm để sao chép chuỗi?
>> Vâng, trong phiên bản này màu xanh lá cây ở đây tôi sẽ làm điều đó ở mức khá thấp.
Thực tế, có chức năng họ có thể giúp đỡ với điều này.
Nhưng một trong những cơ bản nhất, và nhiều nhất một quen thuộc, ít nhất, sẽ sớm được
quen thuộc với chúng ta, là như sau -
do đó, một trên dòng đầu tiên mã trong xanh bây giờ.
>> Tôi chỉ viết lại như là char *.
Không có chức năng sự khác biệt đó.
Tôi chỉ ném đi những thư viện và CS50 Tôi gọi nó là gì, một *.
>> Bây giờ dấu chấm, dấu chấm, dấu chấm, bởi vì có một số kiểm tra lỗi đó không phải là
thú vị để nói về một lần nữa.
Vì vậy, bây giờ t được khai báo.
Nó cũng là một char *.
Vì vậy, tôi đã vẽ một hình vuông nhỏ trên màn hình như trước.
>> Nhưng ở phía bên phải, malloc, chúng tôi đã nói là bộ nhớ phân bổ.
Vì vậy, phân bổ một số đoạn bộ nhớ.
Và bao nhiêu byte làm chúng tôi thực sự muốn phân bổ, nó có vẻ?
>> Vâng, chiều dài chuỗi s.
Vì vậy nếu nó xin chào đó là sẽ là năm.
Chúng tôi sẽ nói h-e-l-l-o.
Vì vậy, năm byte.
>> Nhưng sau đó cộng thêm 1, tại sao 1?
Nhân vật 0.
Nếu chúng ta không cho phép những anh chàng này, chúng tôi có thể vô tình tạo ra một tình huống
nơi chuỗi là h-e-l-l-o.
Và sau đó là thời gian GetString tiếp theo là gọi và tôi gõ vào, ví dụ,
David, D-một-v-i-d, máy tính sẽ nghĩ rằng s thực sự là
h-e-l-l-o-d-một-v-i-d bởi vì có không phá vỡ ở giữa những từ đó.
>> Vì vậy, chúng ta cần phá vỡ đó.
Vì vậy, chúng tôi không muốn năm.
Chúng tôi muốn sáu byte.
>> Và byte tôi nói.
Nhưng nó thực sự thời gian kích thước của char.
Về mặt kỹ thuật char gần như luôn luôn là một byte.
>> Nhưng chỉ để làm cho mã của chúng tôi cầm tay, vậy để nói chuyện, để nó hoạt động trên
máy tính khác nhau ngay cả khi họ có thể thể hơi khác nhau bên dưới
mui xe, tôi sẽ tổng quát nói rằng kích thước của char để
mã của tôi luôn luôn làm việc.
Và tôi không cần phải biên dịch lại nó chỉ bởi vì tôi nâng cấp máy tính của tôi hay sử dụng
một số nền tảng khác nhau.
>> Vì vậy, tôi đã có 6 lần kích thước của một char, mà sẽ xảy ra là 1.
Vì vậy, đó có nghĩa là có thể malloc cung cấp cho tôi sáu byte.
Là những gì mà thực sự đang làm gì?
Vâng, hãy để tôi quay trở lại trong thời gian ở đây nơi chúng ta đang ở trong câu chuyện.
>> Vì vậy, nếu tôi quay trở lại đây, tôi đã tuyên bố một * char gọi là t.
Bây giờ tôi đã gọi là malloc trong sáu byte.
Và bây giờ tôi sẽ rút ra những sáu byte giống như mảng trước đó.
Nhưng tôi thực sự không biết điều gì trong mảng này.
>> Nếu bạn cấp phát bộ nhớ nó chỉ ra rằng bạn không thể tin tưởng rằng có một số
giá trị đã biết đó.
Nó có thể được sử dụng bởi một cái gì đó khác, một số chức năng khác, một số khác
dòng mã mà bạn đã viết.
Vì vậy, chúng ta thường gọi là các rác thải giá trị và vẽ chúng, có lẽ, như
dấu hỏi, chỉ cho thấy rằng chúng tôi không biết những gì thực sự ở đó.
Và đó là không có việc lớn, miễn là chúng tôi có đủ thông minh để ghi đè lên những
giá trị rác với số lượng hoặc ký tự mà chúng tôi quan tâm.
>> Vì vậy, trong trường hợp này những gì tôi sẽ làm gì?
Vâng, dòng của tôi về code tiếp theo, tôi có bốn.
int tôi nhận được 0, n nhận được chiều dài chuỗi s.
Vì vậy, một quen thuộc cho vòng lặp.
Tôi là nhỏ hơn hoặc bằng n, mà thường là ở trên.
>> Nhưng lần này là có chủ ý.
I + +, và sau đó tôi chỉ đơn giản là làm t khung tôi được s.
Bởi vì hình ảnh của tôi trông như thế này tại thời điểm này, được lưu trữ trong t là
địa chỉ của người đoạn ngẫu nhiên của bộ nhớ giá trị mà chưa được biết.
Nhưng ngay sau khi tôi làm t khung 0 mà đặt tôi ở đây.
>> Và những gì kết thúc lên nhận rút ra có?
Chúng tôi sẽ đặt h.
Bởi vì đó là những gì tại s khung 0.
Và sau đó điều tương tự cho điện tử, và tôi, và tôi, và o.
>> n, tại sao tôi đi lên thông qua một bằng n?
Vì nhân vật 0.
Vì vậy, chỉ cần được rõ ràng, sau đó, nếu tôi thực sự xóa bất cứ điều gì những rác
giá trị này và sau đó thực sự thu hút những gì tôi mong đợi, đây là s khung 1, 2,
3, 4, cộng với đó là theo sau nhân vật mới.
>> Và vì vậy bây giờ nếu chúng tôi tiếp tục qua các dấu chấm, dấu chấm, dấu chấm trong phiên bản chính xác này
và hoa t khung 0 Tôi sẽ, của Tất nhiên, được tận dụng chỉ này
chàng trai ở đây, mà khái niệm, là mục tiêu cuối cùng.
Vì vậy, đó là tất cả các con trỏ.
>> Và bạn đã sử dụng chúng trong nhiều tuần bây giờ trong bối cảnh của chuỗi.
Nhưng bên dưới mui xe chúng một chút phức tạp hơn.
Nhưng nếu bạn nghĩ về họ trong này dưới dạng ảnh tôi đề nghị rằng họ đang
có lẽ không phải tất cả mà đáng sợ như họ đầu tiên có vẻ ở cái nhìn đầu tiên,
đặc biệt là với cú pháp mới như vậy.
Bất kỳ câu hỏi về con trỏ, chuỗi, hoặc ký tự?
Yeah?
>> ĐỐI TƯỢNG: bạn có thể quay trở lại đến [nghe được]?
>> SPEAKER 1: Chắc chắn.
>> ĐỐI TƯỢNG: Vậy làm thế nào đến trong của bạn cuối cùng dòng, bạn không có một * t dòng
và một * s trong dòng?
Bạn không có tham chiếu đến -
>> SPEAKER 1: Ah, một câu hỏi thực sự tốt.
Tại sao tôi không có một * t và * s?
Bởi vì một thời gian ngắn, tuần trước, như trong của chúng tôi chức năng trao đổi, tôi đã nói rằng khi
bạn đã có một con trỏ phương tiện mà bạn đi đến đó như chúng tôi đã làm
vật lý trên sân khấu, là để thực sự sử dụng các nhà điều hành sao.
>> Nó chỉ ra rằng điều này vuông-khung ký hiệu là những gì chúng tôi sẽ gọi cú pháp
đường, mà chỉ là một cách gợi cảm của nói rằng đó là viết tắt ký hiệu cho
chính xác những gì bạn đang mô tả.
Nhưng đó là một ít trực quan hơn.
Và có nguy cơ làm cho điều này có vẻ hơn phức tạp hơn nó cần phải được,
những gì đang thực sự xảy ra ở đây như sau -
Nếu tôi nói * t đó có nghĩa là đi đến địa chỉ được lưu trữ trong t.
>> Vì vậy, theo nghĩa đen, nếu t được lưu trữ các địa chỉ của người h
ban đầu, * t phương tiện đi đây.
Bây giờ, những gì t khung 0 nghĩa là gì?
Cùng một điều chính xác.
Nó chỉ là một ít người sử dụng hơn thân thiện với người viết.
>> Nhưng tôi không thực hiện được nêu ra.
Tôi không thể chỉ nói * t được * s.
Bởi vì những gì tôi sẽ làm sau đó?
Tôi muốn được đặt h, h, h, h, h trong suốt toàn bộ điều.
Phải không?
>> Vì * t là đi đến các địa chỉ trong t.
Nhưng chúng ta đang ở trong một vòng lặp.
Và những gì giá trị tôi incrementing, tất nhiên, trên mỗi lần lặp?
i.
>> Nhưng có một cơ hội ở đây, phải không?
Mặc dù điều này cảm thấy như nó nhận được nhiều hơn một chút tinh vi
hơn các ký hiệu vuông-khung chúng tôi đã sử dụng một thời gian -
cho tôi lùi lại thay đổi giờ của tôi có -
mặc dù điều này bây giờ là nhận được một chút fancier, ý tưởng cơ bản, nếu * t
có nghĩa là ở đây và * t chỉ là đi đến địa chỉ trong t.
>> Nhưng những gì đã được địa chỉ trong t?
Số lượng, chúng tôi tiếp tục sử dụng?
Như Ox456, chúng ta hãy mang lại cho rằng trở lại chỉ vì lợi ích của cuộc thảo luận.
Vâng, nếu tôi muốn có được ở các điện tử trong t chuỗi, tôi chỉ muốn đi đến,
về cơ bản, 456.
>> Hay đúng hơn, 457.
Tôi chỉ cần thêm một.
Nhưng tôi có thể làm điều đó, phải không?
Vì t, mặc dù tôi giữ cho bản vẽ nó bây giờ như một mũi tên, nó chỉ là một
số, Ox456.
Và nếu tôi thêm một đến đó, hoặc hơn nói chung, nếu tôi thêm tôi để tôi có thể
thực sự có được chính xác nơi mà tôi muốn.
Vì vậy, nếu tôi thực sự làm được điều này -
và đây là những gì bây giờ được gọi là con trỏ số học -
Tôi có thể loại bỏ dòng này.
Đó là, thẳng thắn mà nói, tôi nghĩ rằng rõ ràng hơn và một ít người sử dụng thân thiện hơn để đọc.
Nhưng điều này là không ít chính xác.
>> Dòng mã này hiện đang sử dụng con trỏ số học.
Nó nói đến địa chỉ sau đây -
bất cứ điều gì khi bắt đầu t là, mà là t cộng với tôi, ban đầu
là 0, đó là rất tốt.
Bởi vì đó có nghĩa là sự khởi đầu của t cộng với 1, cộng với 2, và 3, và vv.
Và cùng đối phó với s.
>> Vì vậy, đường cú pháp cho việc này.
Nhưng sự hiểu biết những gì đang thực sự xảy ra bên dưới mui xe, tôi sẽ tranh luận,
là thực sự hữu ích trong và của chính nó.
Bởi vì nó có nghĩa là bây giờ có không ma thuật nhiều hơn nữa xảy ra
bên dưới mui xe.
Có sẽ không có nhiều hơn lớp chúng ta có thể gọt vỏ sao cho bạn.
Đây là c.
Và điều này được lập trình.
Thực sự tốt câu hỏi.
>> Được rồi, vì vậy đây là lỗi mà chương trình tôi đã đề cập đến trước đó.
trao đổi là sai lầm.
Nếu không có vẻ làm việc.
Nhớ lại rằng giống như với sữa và nước cam - mà tôi bắt đầu
uống cuộc biểu tình ngày hôm nay.
Vì vậy, cũng giống như với các nước cam và sữa, chúng tôi đã phải sử dụng một
biến tạm thời, tmp, để tổ chức một tạm thời để chúng tôi có thể sau đó
thay đổi giá trị của nó và sau đó cập nhật b.
>> Nhưng chức năng này, chúng tôi đã nói, hoặc này chương trình trong chức năng này là
viết là sai và thiếu sót, tại sao?
Có?
>> ĐỐI TƯỢNG: [nghe được].
>> SPEAKER 1: Chính xác, khi bạn gọi swap -
hay rộng hơn, khi bạn gọi hầu hết mọi chức năng -
nếu các đối số chức năng mà nguyên thủy, có thể nói, số nguyên và ký tự
và tăng gấp đôi và phao nổi, điều mà không sao, bạn đang đi qua trong một bản sao của
các đối số.
Vì vậy, nếu x là 1 và y là 2, sẽ là 1 và b là có được 2.
Nhưng họ sẽ có những phần khác nhau bit, khối khác nhau
bộ nhớ điều đó xảy ra được lưu trữ giá trị giống nhau.
>> Vì vậy, mã này là siêu hoàn hảo tại trao đổi a và b.
Đó là không tốt trao đổi -
Ví dụ trong tuần trước -
x và y.
Bởi vì một lần nữa, họ trong phạm vi sai.
>> Bây giờ, làm thế nào chúng tôi đi về sửa chữa này?
Chúng tôi phải làm cho chức năng trông xấu hơn chút.
Nhưng một lần nữa, hãy xem xét những gì điều này chỉ có nghĩa là.
>> Và trên thực tế, cho tôi, cho nhất quán, thay đổi một điều để nó giống y hệt
những gì chúng ta đã làm.
Như tôi đã đề cập tuần trước, nó không quan trọng, nơi nó đi.
Trong thực tế, thường bạn sẽ đặt các ngôi sao bên cạnh tên biến.
Nhưng tôi nghĩ rằng nó sẽ là một chút dễ dàng hơn để xem xét * bên cạnh
kiểu dữ liệu như có nghĩa là nó là một con trỏ đến một int trong trường hợp này.
>> Vì vậy, những gì tôi làm ở đây?
Tôi nói không cho tôi một int tiếp theo int khác,
gọi họ là a và b.
Cung cấp cho tôi địa chỉ của một int.
Cho tôi địa chỉ của int khác.
Gọi những địa chỉ a và b.
>> Và sau đó sử dụng các kí hiệu * xuống dưới đây, đi với nhau của những địa chỉ
khi cần thiết hoặc là có được hoặc thiết lập giá trị của nó.
Nhưng có một ngoại lệ ở đây.
Tại sao tôi không có * bên cạnh tmp?
Tại sao tôi không làm điều này, chẳng hạn?
Nó cảm thấy như tôi chỉ nên đi tất cả ra và sửa chữa toàn bộ điều.
Yeah?
>> ĐỐI TƯỢNG: [nghe được].
>> SPEAKER 1: Tôi đã không tuyên bố tmp như một chuỗi.
Vì vậy, đây sẽ tuyên bố, trong trường hợp này, một tmp là địa chỉ của một int.
Nhưng đó không phải là hoàn toàn những gì tôi muốn, cho một vài lý do.
>> ĐỐI TƯỢNG: Bạn không muốn trao đổi chúng.
>> SPEAKER 1: Chính xác, tôi không muốn trao đổi bất cứ điều gì với tmp. tmp chỉ là
tuần-một công cụ.
Tất cả tôi muốn là một biến để lưu trữ một số lượng.
Tôi thậm chí không quan tâm đến địa chỉ tại thời điểm này.
>> Tôi chỉ cần 32 bit hoặc do đó, để lưu trữ một số nguyên.
Và tôi muốn để đưa vào những 32 bit bất cứ điều gì không phải là trong một, có thể nói, nhưng
những gì đang có một, chỉ để được chính xác hơn.
Bởi vì nếu một là một địa chỉ, một phương tiện * đến đó và nhận được giá trị 1.
Ví dụ, trong ví dụ tuần trước hoặc trong trường hợp b, có được giá trị của 2.
>> Vì vậy, những gì đang thực sự xảy ra?
Hãy để tôi vẽ một bức tranh ở đây là sẽ chỉ trêu chọc nhau một phần của ngày hôm nay.
Nhưng điều này sẽ tiếp tục xuất hiện trong một thời gian.
>> Này, tôi khẳng định, là những gì máy tính của bạn bộ nhớ trông giống như khi bạn chạy một
chương trình, bất kỳ chương trình.
Khi bạn chạy một chương trình ở đầu RAM máy tính của bạn - vì vậy suy nghĩ của
hình chữ nhật này, thực sự, như của bạn RAM hoặc bộ nhớ máy tính, tất cả 101
tỷ byte của nó, tất cả hai tỷ byte, tất cả hai gigabyte của nó,
bất kể số lượng bạn có được, hãy vẽ nó như một hình chữ nhật.
Và tôi cho rằng khi bạn chạy một chương trình như Microsoft Word hoặc Chrome
hoặc bất cứ điều gì như thế, các bit Microsoft hoặc Google viết -
trong các trường hợp của các chương trình này -
được nạp vào bộ nhớ máy tính của bạn nơi họ có thể được thực thi hơn
nhanh chóng và đưa vào các CPU, là bộ não của máy tính.
>> Và trong TAM chúng được lưu trữ ở rất đầu chương trình của bạn, do đó, để nói chuyện.
Nói cách khác, nếu điều này là một đoạn bộ nhớ, khi bạn kích đúp vào
Microsoft Word, các bit đến ra khỏi ổ đĩa cứng.
Họ có được nạp vào bộ nhớ RAM.
Và chúng tôi sẽ xô chúng ở đầu của hình chữ nhật này khái niệm.
>> Vâng, phần còn lại của bộ nhớ của bạn sử dụng cho những thứ khác nhau.
Ở phía trên bạn sẽ thấy khởi tạo dữ liệu và uninitialize dữ liệu.
Điều này đã làm cho hầu hết các phần, với hằng hoặc biến toàn cầu
có giá trị.
Nhưng nhiều hơn về những thời điểm khác.
>> Sau đó, bạn có đống, mà chúng tôi sẽ quay trở lại.
Nhưng ở phía dưới là phần đó là đặc biệt là Gecman ngay bây giờ.
Đó là cái gọi là chồng.
Vì vậy, giống như trong hầu hết mọi trường D đây trên khuôn viên trường, bạn có những khay đó
chỉ chồng lên nhau mà bạn có thể đặt thức ăn và những thứ linh tinh.
Ngăn xếp trong một hệ thống máy tính là rất giống nhau.
Ngoại trừ trong khi khay, như chúng tôi sử dụng trong phòng ăn, tất nhiên, có nghĩa là
để mang đồ vật các khay hoặc khung -
như chúng tôi sẽ gọi cho họ - trong một máy tính bộ nhớ được sử dụng để giữ
biến và giá trị.
>> Vì vậy, những gì thực sự diễn ra bên dưới mui xe?
Vâng, hãy để tôi lật qua để màn hình ở đây.
Và chúng ta hãy chỉ tập trung vào các phần dưới cùng một lúc.
Nếu điều này là phần dưới của tôi bộ nhớ máy tính của nó quay ra khi tôi
gọi chức năng chính - trong đó xảy ra, thẳng thắn,
tự động cho tôi -
Tôi nhận được một đoạn bộ nhớ tại dưới cùng của bộ nhớ RAM của tôi có thể nói.
Và đây là nơi mà chính là các biến địa phương đi.
Đó là nơi argc và argv có thể đi, và bất kỳ biến tôi
tuyên bố bên trong chính.
Họ kết thúc ở phía dưới RAM máy tính của tôi.
>> Bây giờ giả sử rằng các cuộc gọi một chức năng chính như trao đổi, giống như nó đã làm tuần trước?
Vâng, chúng tôi chủ yếu đặt một khay mới, một khung mới, lên đoạn của tôi về bộ nhớ.
Và tôi sẽ mô tả điều này như thuộc chức năng trao đổi.
>> Bây giờ bên trong trao đổi là gì?
Vâng, dựa trên chương trình tuần trước và mà chúng ta chỉ thấy một đoạn trích từ,
bên trong khung trao đổi, hoặc trên trao đổi của khay, những gì đang có biến?
Vâng, a và b.
Bởi vì đó là những đối số địa phương, cộng với một phần ba, tmp.
Vì vậy, thực sự, tôi có thể vẽ này một chút sạch hơn.
Hãy để tôi đi về phía trước và quay lại nhãn.
Và cho tôi cho rằng bạn biết những gì?
>> một có lẽ sẽ kết thúc ở đây.
B sẽ kết thúc ở đây.
Tmp và sẽ kết thúc ở đây.
Bây giờ, đặt hàng might là một chút khác nhau.
Nhưng khái niệm này là ý tưởng.
>> Và chỉ chung, đây là những gì chúng tôi sẽ gọi cho khung trao đổi, hoặc
khay ăn uống, hội họp.
Và cùng thỏa thuận với chính.
Nhưng tôi sẽ không vẽ lại đó.
Nhưng đó là nơi argc và argv và bất kỳ các biến địa phương như x và y
có thể là tốt.
>> Vì vậy, bây giờ xem xét những gì đang thực sự xảy ra khi bạn gọi trao đổi.
Khi bạn gọi điện trao đổi, thực thi mã như này, bạn đang đi qua trong, trong
lỗi phiên bản, a và b như bản sao của x và y.
Vì vậy, nếu tôi làm bây giờ vẽ này trên màn hình -
có để có được tốt hơn lúc này -
để những câu chuyện tôi đã nói với bản thân mình là trong phiên bản lỗi này, khi chúng tôi
gọi trao đổi đi qua trong nghĩa đen a và b là số nguyên, những gì đang thực sự xảy ra?
>> Vâng, những gì thực sự xảy ra này là.
Hãy để tôi đi về phía trước và quay lại chỉ để làm sáng tỏ một số không gian ở đây.
Vì vậy, đây là bộ nhớ máy tính của tôi.
>> Vì vậy, nếu tôi có, ví dụ -
thực sự chúng ta hãy làm theo cách này -
nếu tôi cho rằng đây là x, lưu trữ giá trị 1 chỉ như tuần trước.
Và điều này là y, lưu trữ các giá trị 2 giống như tuần trước.
Và điều này là chính, khi tôi gọi trao đổi, do đó cho bản thân mình truy cập vào một và
b và tmp, tôi sẽ cho rằng đây là một và đây là 1.
>> Đây là b.
Đây là 2.
Điều này được gọi là tmp.
>> Và ban đầu, nó có một số giá trị rác cho đến khi tôi thực sự lưu trữ trong nó một,
đó là 1.
Sau đó, tôi đi trước và thay đổi một là những gì?
Giá trị của B.
>> Và vì vậy bây giờ tôi có hai đây.
Và sau đó chúng tôi đã nói b được tmp.
Một lần nữa, giống như kiểm tra một sự tỉnh táo, thứ ba dòng mã ở đây chỉ đơn giản là này
một, b được tmp.
>> Và vì vậy cuối cùng, tôi phải làm gì?
Tôi đi trước và thay đổi b được bất cứ điều gì giá trị của tmp là, đó là 1.
Tôi không liên lạc tmp một lần nữa.
>> Nhưng bây giờ, vấn đề là ngay khi trao đổi lợi nhuận, bởi vì nó không bàn giao
sao một số giá trị, không có trở lại tuyên bố một cách rõ ràng trong đó.
Có gì thực sự xảy ra?
Vâng, về cơ bản tất cả các bộ nhớ này -
OK, rõ ràng tẩy thích chỉ có một ngón tay tại một thời điểm -
chỉ biến mất.
>> Bây giờ trong thực tế nó không đi bất cứ nơi nào.
Nhưng bạn có thể nghĩ về nó bây giờ là dấu hỏi.
Bởi vì nó không còn thực tế sử dụng.
Và không có gì được thực hiện với những giá trị.
>> Vì vậy, trong trường hợp của phiên bản màu xanh lá cây của mã này, thay vì những gì đang được
thông qua vào trao đổi?
Vì vậy, giải quyết.
Vì vậy, địa chỉ của x và địa chỉ của y.
Vì vậy, nếu chúng tôi lại kể câu chuyện này cuối cùng thời gian, và tôi thực sự rút ra trao đổi một lần nữa,
nhưng với con trỏ, đây là một, điều này là b, và là tmp này, những gì là
thực sự được lưu trữ trong một màu xanh lá cây này phiên bản của mã của tôi, nơi tôi đang đi qua
trong địa chỉ?
>> Nó sẽ là một con trỏ đến x.
Vì vậy, tôi có thể rút ra một mũi tên.
Nhưng chúng ta hãy sử dụng cùng một tùy ý Ví dụ như trước đây.
Chúng ta hãy nói rằng đây là một cái gì đó như Ox123.
Và điều này là có được Ox127 vì đó là bốn byte đi bởi vì nó là một
int, vì vậy Ox127.
>> Và một lần nữa, tôi sẽ lấy một số quyền tự do với các con số.
Chúng nhỏ hơn là họ sẽ nhiều thực sự được và theo một thứ tự khác nhau.
Nhưng đó là cách hình ảnh bây giờ khác nhau.
>> Nhưng khi tôi sử dụng mã màu xanh lá cây này và tôi int tmp được * a.
* Một phương tiện để làm như sau, đi giải quyết đó là trong một và đi với nó,
đó là 1.
Và đó là những gì tôi sau đó đặt trong tmp.
Trong khi đó, các dòng tiếp theo của mã đây, được một * b, điều đó không có nghĩa là gì?
>> Vâng, * a, để đi đây được * b, có nghĩa là đi đến đó.
Và đó có nghĩa là đưa giá trị đó.
Cuối cùng, dòng cuối cùng của mã chỉ đơn giản là nói * b được tmp.
>> Vì vậy, b nói đến đó và ghi đè lên nó với tmp, trong trường hợp này, sẽ
là, một lần nữa, 1.
Và đây là lý do tại sao các phiên bản màu xanh lá cây của công trình mã của chúng tôi, trong khi màu đỏ
phiên bản không bao giờ làm.
Tất cả chỉ là để nắm như thế nào bộ nhớ được quản lý và nơi mà nó
thực sự được đặt trong của bạn RAM của máy tính.
Và bây giờ, đó là một trong những điều rằng ngăn xếp được sử dụng cho.
>> Các câu hỏi về bố trí không?
Trên con trỏ?
Hoặc trao đổi?
>> Được rồi, vậy malloc, thu hồi, đã làm một cái gì đó như thế này.
Đây là một ví dụ siêu đơn giản.
Và đây là một trong những Binky giới thiệu chúng tôi, mặc dù khá
nhanh chóng, ở cuối lớp.
Chết tiệt, có chúng tôi đi một lần nữa.
>> Vì vậy, nhớ lại rằng đây là ví dụ về một Binky giới thiệu chúng tôi, mặc dù
phần nào một cách nhanh chóng vào cuối lớp.
Và ở đây chúng tôi sử dụng malloc thực sự lần thứ hai.
Bởi vì lần đầu tiên chúng tôi sử dụng nó để tạo ra đủ RAM, bố trí đủ RAM
để lưu trữ một chuỗi.
>> Thời gian này Binky giữ nó đơn giản.
Vì vậy, nó để lưu trữ chỉ một int, rõ ràng.
Và đó là hoàn toàn tốt.
Đó là một chút lạ, thẳng thắn, để sử dụng malloc để cấp phát một int.
Nhưng điểm claymation của Nick là thực sự chỉ kể lại câu chuyện về những gì
xảy ra hoặc không xảy ra khi bạn ngược đãi bộ nhớ.
>> Vì vậy, trong trường hợp này, chương trình này đã làm một vài điều.
Trong trường hợp đầu tiên ở đây, nó tuyên bố một con trỏ được gọi là x đến một int.
Sau đó nó tuyên bố một con trỏ gọi y đến một int.
Sau đó nó lưu trong x, những gì?
Người khác bây giờ.
Những gì được lưu trữ trong x theo dòng thứ ba của chương trình này?
>> ĐỐI TƯỢNG: [nghe được].
>> SPEAKER 1: Vâng, không khá byte, mỗi nói.
Được chính xác hơn bây giờ.
Những gì được lưu trữ trong x?
Một địa chỉ, tôi nghĩ rằng tôi nghe nó.
>> Vì vậy, những gì malloc trở lại?
malloc đến hành vi phân bổ một đoạn bộ nhớ.
Nhưng làm thế nào nó cung cấp cho bạn truy cập vào nó?
Nó sẽ trả về những gì?
Địa chỉ của byte đầu tiên trong các đoạn bộ nhớ.
>> Bây giờ, đây là siêu đơn giản.
Nó chỉ là một byte, có nghĩa là giải quyết chúng tôi nhận được trở lại là
địa chỉ của toàn bộ điều.
Vì vậy, được lưu trữ trong x sau đó, là địa chỉ trong đó đoạn bộ nhớ.
Trong khi đó, những gì xảy ra tiếp theo?
Vì vậy, trên thực tế, chúng ta hãy đi trước và rút ra nhanh chóng ra khỏi thực này.
>> Vì vậy, nếu chúng ta đi qua màn hình ở đây và chúng tôi chơi này ra int * x, int * y
sẽ làm những gì cho tôi?
Tôi cho rằng nó chỉ cần đi làm một cái gì đó như thế này và gọi nó là x, và
và điều này gọi là y.
Trong khi đó, dòng thứ ba của mã là sẽ phân bổ kích thước của một int,
mà sẽ xảy ra là - xin lỗi nếu tôi nói một trước khi tôi có nghĩa là một int -
bốn byte trên một máy tính điển hình.
Ít nhất là với các thiết bị CS50.
>> Vì vậy, điều này sẽ phân bổ nó, ai biết được?
Một nơi nào đó ở đây.
Và điều này được lưu trữ tại một số địa chỉ Sửu, ai biết được?
Nhưng những gì sẽ được trả lại là địa chỉ đó.
Nhưng chúng tôi sẽ vẽ những bức tranh này như chỉ là một mũi tên như thế.
>> Bây giờ các dòng tiếp theo * x được 42.
Không * x có ý nghĩa gì trong cách hiểu thông thường?
Chỉ cần đến đó.
Đi đến địa chỉ đó.
Hay nói cách khác, hãy làm theo các mũi tên và đặt 42 có.
Nhưng sau đó một cái gì đó không hay xảy ra để Binky, phải không?
>> Nhớ lại dòng năm ở đây, * y được 13, thực sự là một con số không may mắn,
đã làm những gì cho chúng ta?
Vâng, * y phương tiện đến đó.
Vâng, điều này đã không được trao một giá trị nào, phải không?
Các mã không có y là khởi tạo để bất cứ điều gì.
Chúng tôi đã x được khởi tạo đến một địa chỉ.
Nhưng y đã được tuyên bố lên hàng đầu.
Nhưng sau đó một dấu chấm phẩy, không có giá trị đã thực sự đặt vào nó.
Vì vậy, nó là công bằng để gọi đây một giá trị rác.
Ai biết được những gì đang có?
Đó là dấu tích còn lại của các bit đã được sử dụng bởi một số dòng trước mã trong
chương trình của tôi.
>> Vì vậy, nếu tôi nói đến đó, điều này là như thế, Tôi không có ý tưởng mũi tên này là
sẽ kết thúc.
Và đó là khi bạn thường nhận được một lỗi phân khúc.
Nếu bạn vô tình tới đích, vì vậy để nói chuyện, hoặc đi đến một địa chỉ đó là không
thực sự là một địa chỉ hợp pháp, điều xấu xảy ra.
>> Và đó là chính xác những gì đã xảy ra suy nghĩ Binky.
Vì vậy, nhớ lại rằng những câu chuyện đó Nick nói đây là ý tưởng giống như những gì
Tôi đã rút ra một sự ảo tưởng của phấn trên bảng đó.
X và y được khai báo.
>> Sau đó chúng tôi phân bổ kích thước của một int và lưu trữ nó trong x.
Sau đó, các dòng tiếp theo chúng tôi đã làm * x.
Đây là cây đũa thần của Nick của dereferencing.
Khiến 42 trong bộ nhớ chỉ ra bởi x.
>> Nhưng đây là nơi mà mọi thứ đi sai lầm khủng khiếp.
Phải không?
Chúng tôi đã cố gắng để tới đích của y.
Nhưng y đã có một số giá trị không có thật, phải không?
>> Mà mũi tên ở dưới cùng bên trái góc, không phải là
thực sự chỉ vào bất cứ điều gì.
Đó là loại làm những gì tôi đã làm ở đây trên diễn đàn.
Vì vậy, những điều xấu xảy ra, phân khúc lỗi, hoặc Binky lỗi, trong trường hợp này.
>> Nhưng nếu chúng ta sau đó sửa chữa rằng bằng cách làm x được y như thế nào thay đổi câu chuyện?
Vâng, nếu tôi làm được x y, đó là hiệu quả giống như nói
đây là bất cứ điều gì, Sửu-một cái gì đó là có được như vậy ở đây,
Bò một cái gì đó.
Hoặc những bức tranh chúng ta sẽ vẽ một mũi tên.
>> Vì vậy, ở đây trên diễn đàn với Binky, với các dòng tiếp theo của
mã, * y có nghĩa là đi đến đó.
Ở đâu có?
Nó có nghĩa là ở đây.
>> Và khi chúng tôi cập nhật đó là 13 nó chỉ liên quan đến việc đi và
viết 13 ở đây bây giờ.
Vì vậy, có lẽ không hoàn toàn đơn giản ở cái nhìn đầu tiên.
Nhưng tóm lại và sử dụng các thuật ngữ tương tự mà Binky đã được sử dụng ở đây, vì vậy
lần đầu tiên hai bố con trỏ, x và y, nhưng không phải là pointees.
Và pointees không phải là một thường được sử dụng hạn.
Nhưng con trỏ hoàn toàn.
Nhưng đó là những gì đang được chỉ tại trong danh mục Binky của.
>> Này dòng tiếp theo, tất nhiên, phân bổ một pointee int.
Vì vậy, một đoạn bộ nhớ - như tôi đã thu hút hơn trên các bên phải có - và thiết lập
x bằng trỏ đến nó.
Này dereferences x để lưu trữ 42 bộ nhớ rằng nó chỉ vào.
Và sau đó điều này, tất nhiên, là một điều xấu.
Bởi vì y không chỉ tại bất cứ điều gì được nêu ra.
Điều này sửa chữa nó.
Vì vậy, đây vẫn là chương trình lỗi.
Chỉ vì chúng ta đang thổi qua dòng code của dòng và nói, ồ được thôi,
để cho nó sụp đổ đó.
Đó là một điều xấu.
Tỷ lệ cược là chương trình chỉ là sẽ hủy bỏ hoàn toàn tại dòng đó.
Nhưng nếu bạn đã gỡ bỏ rơi xếp hàng và thay thế nó bằng cuối cùng hai
dòng có bạn chỉ định -
sử dụng giao con trỏ - y để trỏ đến x là điểm t.
Và sau đó bạn tới đích y một cách rất an toàn.
>> Vì vậy, nơi vấn đề này thì chúng ta?
Vâng, chỉ ra rằng bên dưới mui xe trong thư viện CS50, con trỏ
sử dụng trong suốt.
Và chúng tôi sẽ thực sự bắt đầu vỏ lại rằng lớp trước khi dài.
Nhưng nó quay quá, một biểu thức một số bạn có thể quen thuộc với,
đặc biệt là thoải mái hơn, thực sự là của một rất phổ biến
trang web, hoặc ngăn xếp tràn, những ngày này.
>> Nhưng điều này thực sự có rất ý nghĩa kỹ thuật.
Bây giờ chúng tôi biết những gì một chồng là.
Nó giống như một chồng khay bên trong một phòng ăn.
>> Hoặc bên trong máy tính của bạn bộ nhớ của nó những khung hình
được sử dụng bởi các chức năng.
Vâng, nó quay ra rằng vì lý do đó thực hiện rất đơn giản
bộ nhớ và các khung hình trên cái gọi là ngăn xếp, bạn thực sự có thể kiểm soát
của một hệ thống máy tính một cách dễ dàng.
Bạn có thể hack vào một hệ thống nếu người như chúng tôi đã không viết mã của chúng tôi
đặc biệt tốt.
>> Nếu những người như chúng ta sử dụng khối bộ nhớ hoặc sử dụng mảng -
thậm chí còn phổ biến hơn -
nhưng đôi khi quên kiểm tra ranh giới mảng của chúng tôi như bạn có thể
có cho mình đôi khi, và lặp cách quá xa quá khứ kết thúc một mảng.
Trong trường hợp tốt nhất, chương trình của bạn chỉ có thể sụp đổ.
Lỗi phân khúc, loại xấu hổ.
Không lớn, nhưng nó không nhất thiết một điều cực kỳ xấu.
>> Nhưng nếu chương trình của bạn thực sự là trên thực tế máy tính của người sử dụng, nếu nó đang chạy
trên một trang web mà mọi người ngẫu nhiên thực tế trên internet đang đánh, cho phép
người gây ra những điều xấu trên mã của bạn nói chung không phải là một điều tốt vì
nó có nghĩa là một cơ hội để có kiểm soát của máy tính.
Và điều này sẽ xem xét một chút khó hiểu.
Nhưng tôi nghĩ rằng tôi muốn scare bạn với ví dụ này cuối cùng ở đây.
>> Dưới đây là một ví dụ về mã.
Và có một Wikipedia tốt bài viết đó đi qua
này chi tiết hơn.
Tôi có chính trên gọi dưới foo, đi qua trong argv của 1.
Và đó chỉ là để bạn có thể chạy chương trình và vượt qua
một đầu vào tùy ý.
>> Và sau đó foo được tuyên bố lên hàng đầu như chấp nhận một chuỗi, hoặc nhiều hơn
chính xác, một *.
Sau đó nó tuyên bố một loạt các ký tự.
Gọi nó là một bộ đệm, nói chung, kích thước 12.
Vì vậy, 12 ký tự có thể phù hợp trong của mảng được gọi là c.
>> Và sau đó nó sử dụng chức năng mới này, đó là mới nhưng không khó
hiểu, bản sao bộ nhớ.
Nó sao chép các bộ nhớ từ thanh, đó là n qua biến, bất cứ điều gì
người sử dụng gõ vào argv 1 vào c.
Bao nhiêu byte?
Chiều dài chuỗi các quán bar.
>> Vì vậy, nói cách khác, nếu loại người sử dụng trong h-e-l-l-o enter, chiều dài chuỗi
của hello là năm.
Vì vậy, năm trong số những byte là sẽ nhận được sao chép vào mảng gọi là c, mà
có kích thước 12.
Nhưng những gì loại người sử dụng trong một lâu hơn nữa từ đó là 13 ký tự hoặc 14
ký tự hoặc 100 ký tự hoặc nhiều hơn?
>> Mà là họ sẽ đi đâu?
Vâng, khung, mà khay trong ăn uống, hội họp chồng,
họ sẽ đến đó.
Và nó chỉ sẽ bắt đầu ghi đè lên công cụ khác đó là đã có
trên ngăn xếp, tràn ngăn xếp, vậy để nói chuyện.
>> Vì vậy, những bức tranh, nghĩ về nó theo cách này.
Đây chỉ là một phiên bản đầy màu sắc của hình ảnh chúng tôi đã được vẽ.
Ở phía dưới, chúng ta hãy nói, là chính.
Và trên đầu, những gì bạn đang thấy bây giờ là khung hình, màu sắc mã hóa bây giờ, cho một
chức năng gọi là foo.
Nhưng điều thú vị ở đây về foo là đây là khung của nó.
Vì vậy, nó được vẽ giống như tôi đã làm nhưng trong ánh sáng màu xanh.
Và bây giờ đây là nơi mà c khung 0 đi.
Và đây là nơi mà c khung 11 sẽ kết thúc.
>> Nói cách khác, nó sẽ xảy ra được biểu diễn như là một hình vuông.
Nhưng nếu bạn chỉ cần giữ nhúng cả byte xuống - hoặc ký tự - họ sẽ kết thúc
tại vị trí 0 tất cả các con đường lên đến 11 bởi vì nó 0 lập chỉ mục.
>> Nhưng mà là nhân vật thứ 13 sẽ kết thúc?
Trường hợp của 14?
Đâu là nhân vật thứ 50 sẽ kết thúc?
>> Nó sẽ tiếp tục đi xuống.
Bởi vì mặc dù chúng tôi đã thu hút được sự hình ảnh với chồng ngày càng tăng lên,
địa chỉ, nó quay ra, đi từ địa chỉ nhỏ, nhỏ
con trỏ, đến các địa chỉ lớn.
Vì vậy, nó chỉ tiếp tục đi lên và lên.
>> Vì vậy, nếu loại người sử dụng trong xin chào, đó là tuyệt vời.
Không có lỗi, không có vấn đề, an toàn của tất cả mọi người.
Nhưng nếu loại người sử dụng trong những gì chúng tôi sẽ gọi mã đối lập, đại diện
quát như một, tấn công, tấn công, tấn công, tấn công, những gì có thể xảy ra?
>> Vâng, nếu tất cả các đầu vào mà người sử dụng gõ vào là không chỉ là một số thân thiện
hoặc chuỗi tấn công của nhân vật.
Nó thực sự là một chuỗi các ký tự rằng nếu bạn biên dịch nó,
nó thực sự là mã.
Có thể đó là mã xóa tất cả các các tập tin trên ổ đĩa cứng của bạn hoặc gửi thư rác
hoặc một cái gì đó như thế.
Chú ý rằng chính là những gì ở đây là nếu kẻ xấu có đủ may mắn để
ghi đè lên các đoạn màu đỏ của bộ nhớ -
mà tôi đã không vẽ trên hình ảnh của tôi, nhưng này hình ảnh Wikipedia đây có -
cái gọi là địa chỉ trở lại của mình.
>> Khi trở về thực phẩm, khi trở về trao đổi, làm thế nào để máy tính biết đi từ
lên đây để xuống đây?
Hoặc trong phân khúc công nghệ cao lên trên, làm thế nào nó biết đi từ trao đổi
mã - 0 và 1 của mà soạn trao đổi -
trở lại chính?
Có một địa chỉ trả lại cái gọi là được lưu trữ trong cùng một khung ngăn xếp, trên
các khay ăn cùng.
>> Vì vậy, nếu kẻ xấu là đủ thông minh để đặt mã tấn công, mã tấn công, tấn công
mã, và có đủ may mắn -
thường là thông qua thử và sai - để ghi đè lên địa chỉ trả lại màu đỏ,
với địa chỉ và thông báo phần trên.
Chú ý 0835C080.
Nó được viết ngược lên hàng đầu cho lý do chúng tôi sẽ có thể xem lại.
Đây là con số đó.
>> Vì vậy, nếu kẻ xấu được may mắn hoặc là đủ thông minh để ghi đè lên các màu đỏ
dải bộ nhớ với địa chỉ của mã mà người đó có bằng cách nào đó
tiêm vào máy tính của bạn, đoán có mã được sẽ được trả lại cho
ngay sau khi foo được thực hiện thực hiện?
>> Mã của kẻ xấu.
Vì vậy, mã tấn công này, AAA, một lần nữa, năng gửi thư rác, có thể xóa tất cả các file
trên ổ cứng của bạn.
Nhưng đó là những gì thực sự là một chồng tràn là, hoặc tràn bộ đệm, hoặc một
đệm tấn công tràn.
>> Và nó vô cùng, vô cùng phổ biến cho đến ngày nay với các chương trình viết bằng
C, C + +, và thậm chí một số ngôn ngữ khác.
Trên đó ghi chú đáng sợ, chúng tôi sẽ kết thúc với một trò đùa.
>> [Cười]
>> Hẹn gặp lại vào thứ Tư.
Ở bên cạnh CS50 -
Vì vậy, tôi là tất cả ra khỏi đèn đĩa nhưng hôm nay chờ đợi, không có chất béo sữa, một nửa điện thoại
cuốn sách, các nước cam mà tôi uống hôm nay.
Cáp USB, một chìa khoá.
>> [Chơi nhạc]