1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [제 4 - 더 편안한] 2 00:00:02,520 --> 00:00:04,850 [롭 보덴 - 하버드 대학교 (Harvard University)] 3 00:00:04,850 --> 00:00:07,370 [이 CS50입니다. - CS50.TV] 4 00:00:08,920 --> 00:00:13,350 너희가 알지 못 경우에 우리는 퀴즈 내일을 갖추고 있습니다. 5 00:00:14,810 --> 00:00:20,970 당신이 수업 시간에 본거나 수업 시간에 본 것 모두에 기본적으로 있습니다. 6 00:00:20,970 --> 00:00:26,360 그게 그들이 아주 최근의 주제에 있는데도 포인터가 포함되어 있습니다. 7 00:00:26,360 --> 00:00:29,860 당신이 적어도 그 중 높은 수준을 이해해야합니다. 8 00:00:29,860 --> 00:00:34,760 당신이 퀴즈에 대해 이해하고 있어야합니다 수업 시간에 늦었습니다 아무거나. 9 00:00:34,760 --> 00:00:37,320 당신이 그들에 대한 질문이있는 경우 그래서, 지금을 요청할 수 있습니다. 10 00:00:37,320 --> 00:00:43,280 너희들이 질문을하지만 어디이, 학생 주도의 매우 세션이 될 것입니다 11 00:00:43,280 --> 00:00:45,060 그래서 잘하면 사람들은 질문이 있습니다. 12 00:00:45,060 --> 00:00:48,020 사람이 질문이 있습니까? 13 00:00:49,770 --> 00:00:52,090 예. >> [학생]는 포인터를 통해 다시 갈 수 있나요? 14 00:00:52,090 --> 00:00:54,350 나는 포인터를 통해 갈거야. 15 00:00:54,350 --> 00:00:59,180 귀하의 모든 변수는 반드시 메모리에 살고 16 00:00:59,180 --> 00:01:04,450 하지만 보통은 걱정하지 않습니다 그리고 당신은 X + 2와 y + 3 말 17 00:01:04,450 --> 00:01:07,080 그리고 컴파일러는 것을 당신을 위해 살고있는 곳을 알아내는 것입니다. 18 00:01:07,080 --> 00:01:12,990 일단 지금은 명시 적으로 해당 메모리 주소를 사용하고, 포인터를 다루고 있습니다. 19 00:01:12,990 --> 00:01:19,800 따라서 하나의 변수는 과거의 어떤 주어진 시간에 하나의 주소에 살 것이다. 20 00:01:19,800 --> 00:01:24,040 우리가 포인터를 선언하려면, 어떤 유형처럼 보이도록 무슨 일이야? 21 00:01:24,040 --> 00:01:26,210 >> 나는 포인터 p를 선언하고 싶습니다. 유형 어떻게 생겼는데? 22 00:01:26,210 --> 00:01:33,530 [학생] INT * P. >> 그래. 따라서 정수 * P. 23 00:01:33,530 --> 00:01:38,030 그리고 어떻게 그것이 X로 연결하려면 어떻게해야합니까? >> [학생] 앰퍼샌드. 24 00:01:40,540 --> 00:01:45,300 [보덴] 지금 앰퍼샌드는 그대로 연산자의 주소라고합니다. 25 00:01:45,300 --> 00:01:50,460 그래서 내가 말 & 때 x는 그 변수 x의 메모리 주소를지고있어. 26 00:01:50,460 --> 00:01:56,790 그래서 지금은 포인터 P를 가지고 있고, 어디서든 내 코드에서 나는 * P를 사용할 수 있습니다 27 00:01:56,790 --> 00:02:02,960 아니면 X를 사용할 수 있으며 동일한 일이 될 것입니다. 28 00:02:02,960 --> 00:02:09,520 (* P)​​. 이것은 무엇을하는거야? 그 별은 무엇을 의미합니까? 29 00:02:09,520 --> 00:02:13,120 [학생]이 그 시점에서의 값을 의미합니다. >> 그래. 30 00:02:13,120 --> 00:02:17,590 우리가 보면 그래서, 다이어그램을 그리는 것은 매우 유용 할 수 있습니다 31 00:02:17,590 --> 00:02:22,230 이 값을 4 가지고 있었던 X 용 메모리의 작은 상자,입니다 32 00:02:22,230 --> 00:02:25,980 그러면 우리는, P에 대한 메모리의 작은 상자가 33 00:02:25,980 --> 00:02:31,590 그래서 X에 P 점은, 우리는 P에서 x로 화살표를 그립니다. 34 00:02:31,590 --> 00:02:40,270 그래서 우리가 말을 할 때 * P 우리는 P입니다 상자로 이동 말이야. 35 00:02:40,270 --> 00:02:46,480 스타는 화살표를 따라하고 다음 바로 그 상자 원하는 건 뭐든지. 36 00:02:46,480 --> 00:03:01,090 그래서 * P = 7 말할 수있는, 그리고 그 x와 그 7 변화의 상자로 이동합니다. 37 00:03:01,090 --> 00:03:13,540 아니면 내가 말할 수 정수 Z = * P * 2, 혼란 그건 별, 스타 때문입니다. 38 00:03:13,540 --> 00:03:19,230 한 별이 P를 dereferencing되어, 다른 스타 2로 곱한 수 있습니다. 39 00:03:19,230 --> 00:03:26,780 난 그냥뿐만 아니라 X와 *의 P를 교체 할 수 확인할 수 있습니다. 40 00:03:26,780 --> 00:03:29,430 당신은 같은 방법으로 사용할 수 있습니다. 41 00:03:29,430 --> 00:03:38,000 그리고 나중에에 완전히 새로운 이야기로 P 지점을 가질 수 있습니다. 42 00:03:38,000 --> 00:03:42,190 난 그냥 말할 수있는 P = &z; 43 00:03:42,190 --> 00:03:44,940 이제 X를 더 이상 포인트를 주실없고, 그 z로 가리 킵니다. 44 00:03:44,940 --> 00:03:50,510 그리고 * p를 수행하는 시간은 z를하고 같은입니다. 45 00:03:50,510 --> 00:03:56,170 우리가 함수로 받고 시작하면 그래서이에 대한 유용한입니다. 46 00:03:56,170 --> 00:03:59,790 >> 그것은 뭔가 그 점 포인터를 선언하는 쓸모의 일종 이죠 47 00:03:59,790 --> 00:04:03,140 그리고 당신은 그걸 그냥 dereferencing하는 48 00:04:03,140 --> 00:04:06,060 당신은 처음부터 원래 변수를 사용하여이 있었을 때. 49 00:04:06,060 --> 00:04:18,190 하지만 당신이 함수로 때 - 자, 우리가 어떤 기능 INT foo는이 말을 듣지 50 00:04:18,190 --> 00:04:32,810 그 포인터를 소요 단 * P에게 = 6을 수행; 51 00:04:32,810 --> 00:04:39,990 우리가 스왑과 전에 본과 마찬가지로, 당신은 효과적으로 스왑, 별도의 기능을 할 수 없어 52 00:04:39,990 --> 00:04:45,180 C의 모든은 항상 값으로 전달되기 때문에 단지 정수를 전달하여. 53 00:04:45,180 --> 00:04:48,360 이 포인터를 전달하는 경우에도이 값에 의해 전달하고 있습니다. 54 00:04:48,360 --> 00:04:51,940 그건 아주 해당 값이 메모리 주소임을 발생합니다. 55 00:04:51,940 --> 00:05:00,770 그래서 언제 내가 말할 foo는 (P), I는 함수 foo는에 포인터를 지나고 있는데 56 00:05:00,770 --> 00:05:03,910 그리고 foo는 * P = 6을 다하고 있습니다; 57 00:05:03,910 --> 00:05:08,600 내부의 그 기능이 너무, * P는 아직 X와 동일합니다 58 00:05:08,600 --> 00:05:12,720 그렇게 함수 내에서 범위를 지정하지 않기하지만 그 함수의 내부에 x를 사용할 수 없습니다. 59 00:05:12,720 --> 00:05:19,510 따라서 * P = 6는 내가 다른 함수에서 로컬 변수를 액세스 할 수있는 유일한 방법입니다. 60 00:05:19,510 --> 00:05:23,600 또는, 음, 포인터는 내가 다른 함수에서 로컬 변수를 액세스 할 수있는 유일한 방법입니다. 61 00:05:23,600 --> 00:05:31,600 [학생] 가자 당신은 포인터를 반환하고 싶어 말한다. 어떻게 그걸 하죠? 62 00:05:31,600 --> 00:05:44,270 [보덴]는 정수 y를 = 3 같은 같이 포인터를 반환, 반품 및 Y? >> [학생] 그래. 63 00:05:44,270 --> 00:05:48,480 [보덴] 좋아. 당신은이 작업을 수행하지 않습니다. 이 나쁜 것입니다. 64 00:05:48,480 --> 00:05:59,480 내가이 강의 슬라이드에서 본 것 같아 당신은 메모리의 전체 그림을보고 시작 65 00:05:59,480 --> 00:06:02,880 곳에서 당신은 여기 메모리 주소 0 명있어 66 00:06:02,880 --> 00:06:09,550 아래로 당신은 여기 32의 메모리 주소 4 기가 또는 2가 있습니다. 67 00:06:09,550 --> 00:06:15,120 그럼 당신은 어떤 짐이 좀 있어서요 그리고 당신은 당신의 스택이 68 00:06:15,120 --> 00:06:21,780 당신은 당신이 방금 성장에 대해 공부를 시작하여 힙을,있어. 69 00:06:21,780 --> 00:06:24,390 [학생]는 스택 위의 힙 아닌가? 70 00:06:24,390 --> 00:06:27,760 >> 그래. 힙은 상단에, 안 그래? >> [학생] 글쎄, 그가 정상에 0을 넣어. 71 00:06:27,760 --> 00:06:30,320 [학생] 오, 그 위에 0을 넣어. >> [학생] 아, 그래요. 72 00:06:30,320 --> 00:06:36,060 면책 조항 : 아무 데나 CS50으로 당신이 이런 식으로 만날 수있을 거예요. >> [학생] 좋아요. 73 00:06:36,060 --> 00:06:40,290 그건 단지 먼저, 스택을 표시 할 때 74 00:06:40,290 --> 00:06:45,000 당신은 서로의 위에 물건을 쌓아 생각 스택을 생각하면 좋아요. 75 00:06:45,000 --> 00:06:50,810 그래서 우리는 스택 스택은 평소처럼 성장 될 수 있도록 주위에 뒤집기를하는 경향이 76 00:06:50,810 --> 00:06:55,940 대신 스택의 무기력. >> [학생]지라도 힙이 기술적으로도 성장하나요? 77 00:06:55,940 --> 00:07:01,100 그것은 성장에 의해 당신이 무슨 말을하는지에 따라 달라집니다. 78 00:07:01,100 --> 00:07:04,010 스택과 힙은 항상 반대 방향으로 성장합니다. 79 00:07:04,010 --> 00:07:09,420 스택은 항상 성장한다는 의미에서 성장 80 00:07:09,420 --> 00:07:12,940 높은 메모리 주소 및 힙은 아래 성장을 향해 81 00:07:12,940 --> 00:07:17,260 점에서 낮은 메모리 주소를 향해 성장하고있어. 82 00:07:17,260 --> 00:07:20,250 그래서 상단은 0이며, 하단은 높은 메모리 주소입니다. 83 00:07:20,250 --> 00:07:26,390 그들은 단지 방향을 반대에서 성장하고있어 두. 84 00:07:26,390 --> 00:07:29,230 [학생]는 당신이 바닥에 스택을 넣어 말 때문에 난 그냥 그렇게 의미 85 00:07:29,230 --> 00:07:33,640 그것은 스택에 대한 힙의 상단에 시작하기 때문에보다 직관적 인 것, 때문에 86 00:07:33,640 --> 00:07:37,520 힙이 너무 자체의 상단에 있으므로 렸는데이야 - >> 그래. 87 00:07:37,520 --> 00:07:44,960 당신은 또한 스택 이상도 성장하고 더 큰로 힙 생각하지만. 88 00:07:44,960 --> 00:07:50,280 따라서 스택은 우리가 가지 성장 표시 할 것입니다. 89 00:07:50,280 --> 00:07:55,390 그러나 사방이 달리 보이는이 상단에 주소 0을 표시 할 것이다 90 00:07:55,390 --> 00:07:59,590 그리고 하단에 가장 높은 메모리 주소는,이 메모리의 일반적인 전망이다. 91 00:07:59,590 --> 00:08:02,100 >> 당신은 질문이 있습니까? 92 00:08:02,100 --> 00:08:04,270 [학생]는 당신이 우리에게 힙에 대해 좀 더 자세히 설명해 주실 수 있습니까? 93 00:08:04,270 --> 00:08:06,180 그래. 나는 두 번째에 해당로 연결됩니다. 94 00:08:06,180 --> 00:08:12,220 첫째, & y를 반환 이유로 돌아 가면 나쁜 짓이야, 95 00:08:12,220 --> 00:08:18,470 스택에 당신은 모든 기능을 나타내는 스택 프레임의 무리가 96 00:08:18,470 --> 00:08:20,460 어느가 호출되었습니다. 97 00:08:20,460 --> 00:08:27,990 이전 일을 무시 그래서, 당신 스택의 최상위 (top)는 항상 main () 함수가 될거야 98 00:08:27,990 --> 00:08:33,090 그 호출되고있어 첫 번째 기능입니다 때문입니다. 99 00:08:33,090 --> 00:08:37,130 그리고 나서 다른 함수를 호출 할 때 스택은 아래로 성장할 것이다. 100 00:08:37,130 --> 00:08:41,640 좀 기능, 푸 전화하고 자신의 스택 프레임을 도착하면, 101 00:08:41,640 --> 00:08:47,280 그 일부 기능 바를 호출 할 수 있습니다, 그것은 자신의 스택 프레임을 가져옵니다. 102 00:08:47,280 --> 00:08:49,840 그리고 바 재귀있을 수 있으며 그 자체를 호출 할 수 103 00:08:49,840 --> 00:08:54,150 그리고 바의 두번째 호출은 자체 스택 프레임을 얻을 수 있다는. 104 00:08:54,150 --> 00:08:58,880 그리고 이러한 스택 프레임에 무슨 일이 있었는지는 지역 변수 모두 105 00:08:58,880 --> 00:09:03,450 그 함수의 인자의 모든 - 106 00:09:03,450 --> 00:09:08,730 이 기능에 로컬로 범위를 지정하는 모든 일이 스택 프레임에서 이동합니다. 107 00:09:08,730 --> 00:09:21,520 그래서 내가 바 같은 것이 기능입니다 말했을 때 의미 108 00:09:21,520 --> 00:09:29,270 난 그냥 정수를 선언하고 해당 정수에 대한 포인터를 반환거야. 109 00:09:29,270 --> 00:09:33,790 그럼 y는 어디 살아? 110 00:09:33,790 --> 00:09:36,900 [학생] y는 바에서 살고있다. >> [보덴] 그래. 111 00:09:36,900 --> 00:09:45,010 어딘가 메모리의 작은 광장에서에서 Y가 littler 광장입니다. 112 00:09:45,010 --> 00:09:53,370 내가 돌아올 & Y 때, 메모리의이 작은 블록에 대한 포인터를 반환거야. 113 00:09:53,370 --> 00:09:58,400 하지만 때 함수가 반환, 그 스택 프레임은 스택을 쐈됩니다. 114 00:10:01,050 --> 00:10:03,530 이 스택이라는 이유입니다. 115 00:10:03,530 --> 00:10:06,570 당신은 그게 뭔지 알고있는 경우는, 스택 데이터 구조 같은거야. 116 00:10:06,570 --> 00:10:11,580 또는 트레이 스택처럼, 항상 예입니다 117 00:10:11,580 --> 00:10:16,060 메인은 ​​하단에 갈 것입니다, 다음 전화를 첫 번째 기능은, 그 꼭대기에 갈까요 118 00:10:16,060 --> 00:10:20,400 당신이 전화 된 모든 함수에서 돌아올 때까지 당신은 주로 돌아갈 수도 없어 119 00:10:20,400 --> 00:10:22,340 그는 그것의 상단에 배치되어 있습니다. 120 00:10:22,340 --> 00:10:28,650 >> 당신이 그랬다면 [학생] 지금 & Y, 그 가치는 사전 통보없이 변경 될 수 있습니다를 반환합니다. 121 00:10:28,650 --> 00:10:31,290 예, 괘 - >> 그것은 덮어 될 수 [학생]. >> 그래. 122 00:10:31,290 --> 00:10:34,660 당신이 시도 할 경우와 - 그건 완전히이에요 - 123 00:10:34,660 --> 00:10:38,040 그 포인터를 반환하기 때문에이 또한 정수 * 바 것 124 00:10:38,040 --> 00:10:41,310 그래서 그 반환 유형은 정수 *입니다. 125 00:10:41,310 --> 00:10:46,500 이 함수의 반환 값을 사용하려고하면 정의되지 않은 행동입니다 126 00:10:46,500 --> 00:10:51,770 그 포인터가 나쁜 기억을 지적 때문이다. >> [학생] 좋아요. 127 00:10:51,770 --> 00:11:01,250 그래서 경우, 예를 들어, 선언 INT * Y = malloc (sizeof (int는))? 128 00:11:01,250 --> 00:11:03,740 이게 더 낫다. 예. 129 00:11:03,740 --> 00:11:07,730 [학생] 우리는 휴지통으로 물건을 드래그 할 때 우리는하는 방법에 대해 이야기 130 00:11:07,730 --> 00:11:11,750 그들은 실제로 삭제하지, 우리는 자신의 포인터를 잃게됩니다. 131 00:11:11,750 --> 00:11:15,550 따라서이 경우에는 우리는 실제로 메모리에 여전히 값을 삭제하거나이 어떻게해야합니까? 132 00:11:15,550 --> 00:11:19,130 대부분의 경우, 그것은 여전히​​거야. 133 00:11:19,130 --> 00:11:24,220 하지만 그건 우리가 다른 기능 Baz도 전화를 어떻게 말한다. 134 00:11:24,220 --> 00:11:28,990 Baz도 여기에 자신의 스택 프레임을 얻을 수 있습니다. 135 00:11:28,990 --> 00:11:31,470 그것은이 물건을 모두 덮어 쓰기 할거야 136 00:11:31,470 --> 00:11:34,180 그리고 나중에, 이전에 가지고있는 포인터를 시도하고 사용하는 경우 137 00:11:34,180 --> 00:11:35,570 이 같은 값 않을거야. 138 00:11:35,570 --> 00:11:38,150 당신이 함수 Baz도라고하기 때문에 단지 변경거야. 139 00:11:38,150 --> 00:11:43,080 [학생] 그러나 우리는, 우리는 여전히 3 얻을 수 없겠죠 했을까? 140 00:11:43,080 --> 00:11:44,990 [보덴] 십중팔구, 당신은 겠지. 141 00:11:44,990 --> 00:11:49,670 하지만 당신은에 의존 수 없습니다. C는 정의되지 않은 행동을 말합니다. 142 00:11:49,670 --> 00:11:51,920 >> [학생] 아, 그건 않습니다. 좋아요. 143 00:11:51,920 --> 00:11:58,190 malloc를 사용 유래 그래서 당신은 포인터를 반환 할 때이입니다. 144 00:12:00,930 --> 00:12:15,960 난 사실드립니다 만 malloc을 반환 (3 * sizeof (int는)). 145 00:12:17,360 --> 00:12:24,050 두번째로 우리는 더 많은 malloc으로 갈거야,하지만 malloc의 아이디어는 지역 변수의 모든 146 00:12:24,050 --> 00:12:26,760 항상 스택에 이동합니다. 147 00:12:26,760 --> 00:12:31,570 malloced 아무는 힙에 간다, 그리고 영원히 항상 힙 될 것입니다 148 00:12:31,570 --> 00:12:34,490 당신은 명시 적으로 해방 때까지. 149 00:12:34,490 --> 00:12:42,130 그래서이 때 malloc 무언가를,이 함수를 반환 한 후 살아남을거야 것을 의미합니다. 150 00:12:42,130 --> 00:12:46,800 프로그램이 실행을 중지 한 후 [학생]은 생존됩니까? >> 번호 151 00:12:46,800 --> 00:12:53,180 좋아 그럼 그 프로그램이 모든 방법은 실행이 끝날 때까지있을거야. >> 예. 152 00:12:53,180 --> 00:12:57,510 우리는 프로그램이 실행을 중지하면 어떻게됩니까 일의 세부 사항을 갈 수 있습니다. 153 00:12:57,510 --> 00:13:02,150 당신은 날 기억해야 할 수도 있습니다,하지만 그건 완전히 별도의 문제입니다. 154 00:13:02,150 --> 00:13:04,190 [학생] 지금 malloc은 포인터를 만들어? >> 그래. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [학생] 내가 malloc는 포인터가 사용할 수있는 메모리의 블록을 지정합니다 생각합니다. 156 00:13:15,400 --> 00:13:19,610 [보덴]는 다시 그 다이어그램을 싶습니다. >> [학생] 그럼이 함수는하지만, 작품? 157 00:13:19,610 --> 00:13:26,430 [학생] 네, malloc 당신이 사용할 수있는 메모리 블록을 지정, 158 00:13:26,430 --> 00:13:30,470 다음은 메모리의 첫 번째 블록의 주소를 반환합니다. 159 00:13:30,470 --> 00:13:36,750 >> [보덴] 그래. 그래서 언제이 malloc, 당신은 메모리의 일부 블록이 있대 160 00:13:36,750 --> 00:13:38,260 그 힙 현재입니다. 161 00:13:38,260 --> 00:13:43,040 힙이 너무 작은 경우, 힙은 증가 할 것이다 있으며,이 방향으로 자랍니다. 162 00:13:43,040 --> 00:13:44,650 그러니 힙이 너무 작은한다고 가정 해 봅시다. 163 00:13:44,650 --> 00:13:49,960 그럼 조금 성장하고 단지 성장이 블록에 대한 포인터를 반환 할 참이야. 164 00:13:49,960 --> 00:13:55,130 당신이 무료로 콘텐츠, 당신은 힙에 더 많은 공간을 때, 165 00:13:55,130 --> 00:14:00,030 그럼 나중에 malloc에​​ 전화하면 이전에 해제했던 그 메모리를 재사용 할 수 있습니다. 166 00:14:00,030 --> 00:14:09,950 malloc과 무료에 대한 중요한 점은 당신에게 완벽하게 제어 할 수 있다는 것입니다 167 00:14:09,950 --> 00:14:12,700 이러한 메모리 블록의 수명 이상. 168 00:14:12,700 --> 00:14:15,420 전역 변수는 항상 살아 있습니다. 169 00:14:15,420 --> 00:14:18,500 지역 변수는 범위 내에 살아 있습니다. 170 00:14:18,500 --> 00:14:22,140 가능한 빨리 곱슬 괄호를지나 이동으로 지역 변수는 죽었어요. 171 00:14:22,140 --> 00:14:28,890 당신이 살아 할 때 Malloced 메모리 살아 172 00:14:28,890 --> 00:14:33,480 당신이 발표 될 할 이야기를하고 출시하고 있습니다. 173 00:14:33,480 --> 00:14:38,420 그 정말 실제로 메모리의 불과 3 종류입니다. 174 00:14:38,420 --> 00:14:41,840 스택이 자동 메모리 관리가 있어요. 175 00:14:41,840 --> 00:14:43,840 일이 자동으로 발생합니다. 176 00:14:43,840 --> 00:14:46,910 당신은 INT X를 말할 때, 메모리가 정수 x는 할당됩니다. 177 00:14:46,910 --> 00:14:51,630 x는 범위를 나가면 메모리가 x는 복원됩니다. 178 00:14:51,630 --> 00:14:54,790 그런 다음 동적 메모리 관리, malloc은 무엇일까요이있어 179 00:14:54,790 --> 00:14:56,740 당신이 제어 할 수있을 때하는 것입니다. 180 00:14:56,740 --> 00:15:01,290 당신은 동적으로 메모리와 할당하지 말아야 할 때를 결정합니다. 181 00:15:01,290 --> 00:15:05,050 그리고 정적이, 그 아저씨가 영원히 살아 있다는 것을 의미 182 00:15:05,050 --> 00:15:06,610 이는 전역 변수가 무엇인지입니다. 183 00:15:06,610 --> 00:15:10,240 그들은 메모리에 항상하고 있습니다. 184 00:15:10,960 --> 00:15:12,760 >> 질문이 있으십니까? 185 00:15:14,490 --> 00:15:17,230 [학생] 당신은 중괄호를 사용하여 블록을 정의 할 수 있습니다 186 00:15:17,230 --> 00:15:21,220 하지만이 필요하지 진술 또는 그런 식으로 잠시 문이나 어떤 경우? 187 00:15:21,220 --> 00:15:29,130 당신은 함수에서 같은 블록을 정의 할 수 있지만, 너무 중괄호가 있습니다. 188 00:15:29,130 --> 00:15:32,100 [학생] 그래서 당신은 당신의 코드에서 중괄호 임의의 한 쌍처럼 할 수 없습니다 189 00:15:32,100 --> 00:15:35,680 지역 변수이 있다는 말? >> 예, 할 수 있습니다. 190 00:15:35,680 --> 00:15:45,900 INT 바 내부 우리는 {int는 Y = 3;} 만들 수 있습니다. 191 00:15:45,900 --> 00:15:48,440 그이 바로 여기에 있어야있어. 192 00:15:48,440 --> 00:15:52,450 하지만 그건 완전히 정수 y의 범위를 정의합니다. 193 00:15:52,450 --> 00:15:57,320 그 순간 곱슬 괄호 후, y는 더 이상 사용할 수 없습니다. 194 00:15:57,910 --> 00:16:00,630 그래도, 그렇게하지 ​​거의 없어요. 195 00:16:02,940 --> 00:16:07,370 , 프로그램이 끝날 때 무슨 일이로 다시 돌아가 196 00:16:07,370 --> 00:16:18,760 우리가 일을 더 쉽게하기 위해 제공하는 오해 / 이분의 일 거짓말의 종류가 있습니다. 197 00:16:18,760 --> 00:16:24,410 우리는 당신을 말해 당신의 메모리를 할당 할 때 198 00:16:24,410 --> 00:16:29,860 그 변수 RAM의 일부 덩어리를 할당하고 있습니다. 199 00:16:29,860 --> 00:16:34,190 하지만 당신이 정말로 직접 프로그램에 어느 RAM를 건 드리면 안돼. 200 00:16:34,190 --> 00:16:37,490 당신이 생각하는 경우, 어떻게 그린 - 201 00:16:37,490 --> 00:16:44,330 당신은 GDB에 통과한다면 실제로, 당신은 같은 일을 볼 수 있습니다. 202 00:16:51,120 --> 00:16:57,590 에 관계없이 당신이 프로그램이나 실행중인 어떤 프로그램을 실행 얼마나 많은 시간 203 00:16:57,590 --> 00:16:59,950 스택은 항상 시작하는거야 - 204 00:16:59,950 --> 00:17:06,510 항상 주소 oxbffff 뭔가 주위에 변수를 만나러가는 중이 야. 205 00:17:06,510 --> 00:17:09,470 그것은 그 지역 어딘가에 보통입니다. 206 00:17:09,470 --> 00:17:18,760 하지만 어떻게이 프로그램은 아마도 동일한 메모리에 대한 포인터를 가질 수? 207 00:17:20,640 --> 00:17:27,650 [학생] oxbfff가 RAM에 있어야 할 곳의 일부 임의의 지정이 208 00:17:27,650 --> 00:17:31,320 그 사실은 함수가 호출되었을 때에 따라 다른 장소에있을 수 있습니다. 209 00:17:31,320 --> 00:17:35,920 그래. 용어는 가상 메모리입니다. 210 00:17:35,920 --> 00:17:42,250 아이디어는 모든 단일 프로세스, 컴퓨터에서 실행중인 모든 단일 프로그램입니다 211 00:17:42,250 --> 00:17:49,450 자체가 - 완전히 독립적 인 주소 공간 - 가자의 32 비트를 가정합니다. 212 00:17:49,450 --> 00:17:51,590 이 주소 공간입니다. 213 00:17:51,590 --> 00:17:56,220 그것은 사용하기 위해 자신의 완전히 독립적 4기가바이트 있습니다. 214 00:17:56,220 --> 00:18:02,220 >> 당신은 동시에 두 프로그램을 실행하는 경우 그래서,이 프로그램은 자체에 4기가바이트를 볼 수 215 00:18:02,220 --> 00:18:04,870 이 프로그램은, 자신에게 4기가바이트를 볼 수 216 00:18:04,870 --> 00:18:07,720 그리고이 프로그램에 대한 역 참조에 대한 포인터 불가능 217 00:18:07,720 --> 00:18:10,920 이 프로그램에서 메모리에서 소개합니다. 218 00:18:10,920 --> 00:18:18,200 그리고 가상 메모리는 것은 프로세스 주소 공간에서 매핑입니다 219 00:18:18,200 --> 00:18:20,470 RAM에 실제 물건 있습니다. 220 00:18:20,470 --> 00:18:22,940 그래서 그걸 알고 운영 체제까지 것은, 221 00:18:22,940 --> 00:18:28,080 이봐 요, 때이 남자가 dereferences 포인터 oxbfff, 그 진정한 의미를 222 00:18:28,080 --> 00:18:31,040 그는 RAM 바이트 1000, 원하는 223 00:18:31,040 --> 00:18:38,150 반면에이 프로그램 dereferences의 oxbfff 경우, 그는 정말 RAM 바이트 만를 원합니다. 224 00:18:38,150 --> 00:18:41,590 그들은 임의로 멀리 떨어져 할 수 있습니다. 225 00:18:41,590 --> 00:18:48,730 이 하나의 프로세스 주소 공간 내에서 일들도 마찬가지입니다. 226 00:18:48,730 --> 00:18:54,770 그래서 어떤 그 자체로 모든 4 기가 바이트 볼 수 있지만, 말합시다 - 227 00:18:54,770 --> 00:18:57,290 [학생] 모든 프로세스 하나를합니까 - 228 00:18:57,290 --> 00:19:01,350 자, 당신은 RAM 만 4기가바이트있는 컴퓨터가 있다고 가정 해 봅시다. 229 00:19:01,350 --> 00:19:06,430 모든 단일 프로세스는 전체 4기가바이트를 참조합니까? >> 예. 230 00:19:06,430 --> 00:19:13,060 하지만 그것은 보는 4기가바이트은 거짓입니다. 231 00:19:13,060 --> 00:19:20,460 단지 그것이 다른 프로세스가 존재하는지하지 않기 때문에 그 모든 기억이 생각있어. 232 00:19:20,460 --> 00:19:28,140 실제로 필요로하는 단지 많은 메모리를 사용합니다. 233 00:19:28,140 --> 00:19:32,340 운영 체제는이 과정에 RAM을 제공 할 수 없습니다 234 00:19:32,340 --> 00:19:35,750 이 파일은 전체 지역의 모든 메모리를 사용하지 이죠. 235 00:19:35,750 --> 00:19:39,300 그것은 그 지역에 대한 메모리를 포기하지 않을거야. 236 00:19:39,300 --> 00:19:54,780 그러나 생각은 - 내가 생각하는거야 - 나는 비유 생각 할 수 없습니다. 237 00:19:54,780 --> 00:19:56,780 유추는 하드입니다. 238 00:19:57,740 --> 00:20:02,700 가상 메모리의 문제 중 하나가 해결 것 중 하나 239 00:20:02,700 --> 00:20:06,810 프로세스가 서로를 전혀 모르고 있어야한다는 것입니다. 240 00:20:06,810 --> 00:20:12,140 그리고 당신은 어떤 프로그램을 쓸 수는 dereferences 모든 포인터를, 241 00:20:12,140 --> 00:20:19,340 단, * (ox1234)라는 프로그램을 작성 좋아 242 00:20:19,340 --> 00:20:22,890 그리고 그건 dereferencing 메모리 주소 1234. 243 00:20:22,890 --> 00:20:28,870 >> 그러나 다음에 어떻게 1234 수단을 번역하기 위해 운영 체제에게 달려 있습니다. 244 00:20:28,870 --> 00:20:33,960 그래서, 만약 1234이 과정의 유효한 메모리 주소로 갈거야 245 00:20:33,960 --> 00:20:38,800 이 스택 또는 무언가있는 것, 다음이 해당 메모리 주소의 값을 반환한다 246 00:20:38,800 --> 00:20:41,960 지금까지의 과정을 알고 있습니다. 247 00:20:41,960 --> 00:20:47,520 육지에서 일어나는처럼 그러나 만약 1234이 올바른 주소가 아닙니다 248 00:20:47,520 --> 00:20:52,910 스택 넘어 여기를 메모리의 일부 조각과 힙 이외의 249 00:20:52,910 --> 00:20:57,200 당신은 정말 segfaults 등을 그때 다음, 바로이 사용하지 않은 250 00:20:57,200 --> 00:21:00,260 당신이 만지는해서는 안된다는 메모리를 만지고 때문입니다. 251 00:21:07,180 --> 00:21:09,340 이것은 또한 사실입니다 - 252 00:21:09,340 --> 00:21:15,440 32 비트 시스템은 32 비트는 메모리 주소를 정의하는 32 비트를 의미합니다. 253 00:21:15,440 --> 00:21:22,970 또는 4 바이트 - 포인터는 8 바이트 이유 32 비트 8 바이트 때문입니다. 254 00:21:22,970 --> 00:21:25,250 포인터는 4 바이트입니다. 255 00:21:25,250 --> 00:21:33,680 그래서 oxbfffff 같은 포인터를 볼 때, 그입니다 - 256 00:21:33,680 --> 00:21:40,080 특정 프로그램 내에서 당신은 어떤 임의의 포인터를 만들 수 있습니다 257 00:21:40,080 --> 00:21:46,330 어디서든 ox0에서 소 8 f's에 - ffffffff. 258 00:21:46,330 --> 00:21:49,180 [학생]이 (가) 당신이 사람들이 4 바이트하다고하지 않았나요? >> 그래. 259 00:21:49,180 --> 00:21:52,730 [학생] 다음 각 바이트해야합니다 - >> [보덴] 16. 260 00:21:52,730 --> 00:21:59,360 진수 - 5, 6, 7, 8. 포인터 그래서 항상 16 진수 만날 수있을 거예요. 261 00:21:59,360 --> 00:22:01,710 우리가 포인터를 분류하는 방법 뿐이야. 262 00:22:01,710 --> 00:22:05,240 진수의 모든 2 자리는 1 바이트입니다. 263 00:22:05,240 --> 00:22:09,600 따라서 4 바이트 8 자리 16 진수가있을거야. 264 00:22:09,600 --> 00:22:14,190 따라서 32 비트 시스템에있는 모든 싱글 포인터가 4 바이트가 될거야 265 00:22:14,190 --> 00:22:18,550 어떤이 과정에서 어떤 임의의 4 바이트를 만들 수 있다는 것을 의미 266 00:22:18,550 --> 00:22:20,550 그리고, 그것의 포인터를 만들 267 00:22:20,550 --> 00:22:32,730 이는까지가 아는대로,이 메모리의 32 바이트에 전체 2를 해결할 수 있다는 것을 의미합니다. 268 00:22:32,730 --> 00:22:34,760 정말 그에 액세스 할 수 없습니다하더라도하면, 269 00:22:34,760 --> 00:22:40,190 컴퓨터 만 512메가바이트이​​있는 경우에도, 그것은 그렇게 많은 메모리를 가지고 생각한다. 270 00:22:40,190 --> 00:22:44,930 그리고 운영 체제는 실제로 필요한 할당 될만큼 지능적입니다. 271 00:22:44,930 --> 00:22:49,630 4 기가 : 단지, 오, 새로운 프로세스를 이동하지 않습니다. 272 00:22:49,630 --> 00:22:51,930 >> 그래. >> [학생] 소는 무엇을 의미합니까? 왜 당신은 그걸 작성하려면 어떻게해야합니까? 273 00:22:51,930 --> 00:22:54,980 그냥 16 진수의 상징입니다. 274 00:22:54,980 --> 00:22:59,590 당신은 소와 숫자 시작을 볼 때, 연속 일 16 진수입니다. 275 00:23:01,930 --> 00:23:05,760 [학생] 당신은 프로그램이 끝날 때 무슨 일에 대해 설명했다. >> 예. 276 00:23:05,760 --> 00:23:09,480 어떤 프로그램이 끝날 때 발생하면 운영 체제입니다 277 00:23:09,480 --> 00:23:13,600 그냥 지우가이 주소에 있고, 그것 뿐이야 매핑합니다. 278 00:23:13,600 --> 00:23:17,770 운영 체제는 이제 막 사용하는 다른 프로그램이 메모리를 제공 할 수 있습니다. 279 00:23:17,770 --> 00:23:19,490 [학생] 좋아. 280 00:23:19,490 --> 00:23:24,800 그래서 당신은 힙 또는 스택 또는 전역 변수 또는 뭔가에 무언가를 할당 할 때 281 00:23:24,800 --> 00:23:27,010 모두 자마자 프로그램이 종료로 사라 282 00:23:27,010 --> 00:23:32,120 운영 시스템이 다른 프로세스에 해당 메모리를 줄 무료이기 때문이다. 283 00:23:32,120 --> 00:23:35,150 [학생]로 작성된 값은 여전히​​있을 거예요도? >> 그래. 284 00:23:35,150 --> 00:23:37,740 값은 여전히​​ 가능성이 있습니다. 285 00:23:37,740 --> 00:23:41,570 단지는 그들을 얻을 힘들 것 같아. 286 00:23:41,570 --> 00:23:45,230 그 삭제 된 파일에 얻을 것보다 그것은 그들을 얻을 훨씬 더 어렵습니다 287 00:23:45,230 --> 00:23:51,450 의 삭제 된 파일 종류 오랫동안 앉아서 하드 드라이브는 많은 큰 때문입니다. 288 00:23:51,450 --> 00:23:54,120 그래서 메모리의 다른 부분을 덮어거야 289 00:23:54,120 --> 00:23:58,640 그렇게 파일에있을하는 데 사용되는 메모리의 덩어리를 덮어 발생하기 전에. 290 00:23:58,640 --> 00:24:04,520 그러나 메인 메모리, 더 빠른 많은을 통해 당신은 사이클 RAM, 291 00:24:04,520 --> 00:24:08,040 그래서 매우 빠르게 덮어거야. 292 00:24:10,300 --> 00:24:13,340 이 또는 다른 어떤 것도 질문이 있으십니까? 293 00:24:13,340 --> 00:24:16,130 [학생] 내가 다른 주제에 대한 질문이 있습니다. 좋아요 >>. 294 00:24:16,130 --> 00:24:19,060 사람이에 대해 질문이 있습니까? 295 00:24:20,170 --> 00:24:23,120 >> 좋아요. 다른 항목을 참조하십시오. >> [학생] 좋아요. 296 00:24:23,120 --> 00:24:26,550 나는 연습 시험의 일부를가는 297 00:24:26,550 --> 00:24:30,480 그 중 하나는 sizeof에 대해 얘기하고 있었어요 298 00:24:30,480 --> 00:24:35,630 그리고 값을 그 반환 또는 다른 변수 유형 것으로. >> 예. 299 00:24:35,630 --> 00:24:45,060 그리고 정수 및 긴 모두 반환 네 모두, 그래서 그들은 모두 4 바이트 길이 있다고 말했다. 300 00:24:45,060 --> 00:24:48,070 정수와 긴 사이에 차이가, 또는 같은 일입니까? 301 00:24:48,070 --> 00:24:50,380 예, 차이가 있습니다. 302 00:24:50,380 --> 00:24:52,960 C 표준 - 303 00:24:52,960 --> 00:24:54,950 아마 엉망까지 갈거야. 304 00:24:54,950 --> 00:24:58,800 C 표준은 C는 C.의 공식 문서입니다 맘에 수 있습니다 305 00:24:58,800 --> 00:25:00,340 이렇게 말씀입니다. 306 00:25:00,340 --> 00:25:08,650 그래서 C 표준은 숯불 영원히 항상 1 바이트가 될 것이라고 말했다. 307 00:25:10,470 --> 00:25:19,040 그 후 모든 - 짧은이 항상보다 크거나 문자와 동일한 것으로 정의됩니다. 308 00:25:19,040 --> 00:25:23,010 이 엄격히보다 더 있지만, 긍정적하지 수 있습니다. 309 00:25:23,010 --> 00:25:31,940 INT는 단지보다 크거나 짧은 동일하다고 정의됩니다. 310 00:25:31,940 --> 00:25:36,210 그리고 긴 단보다 크거나 INT와 동일한 것으로 정의됩니다. 311 00:25:36,210 --> 00:25:41,600 그리고 긴 긴은 이상 긴 같습니다. 312 00:25:41,600 --> 00:25:46,610 따라서 C 표준 정의 유일한 모든의 상대적 순서입니다. 313 00:25:46,610 --> 00:25:54,880 일이 소요될하는 메모리의 실제 금액은 최대 구현에 일반적으로 314 00:25:54,880 --> 00:25:57,640 하지만 꽤 잘이 시점에서 정의있어. >> [학생] 좋아요. 315 00:25:57,640 --> 00:26:02,490 그럼 반바지는 거의 항상 2 바이트가 될 것이다. 316 00:26:04,920 --> 00:26:09,950 Ints은 거의 항상 4 바이트가 될 것이다. 317 00:26:12,070 --> 00:26:15,340 긴 longs는 거의 항상 8 바이트가 될 것이다. 318 00:26:17,990 --> 00:26:23,160 그리고 당신이 32 비트 또는 64 비트 시스템을 사용하는지 여부에 따라 다릅니다, longs. 319 00:26:23,160 --> 00:26:27,450 그래서 긴 시스템의 유형에 해당하는 것입니다. 320 00:26:27,450 --> 00:26:31,920 이 어플라이언스와 같은 32 비트 시스템을 사용하는 경우는 4 바이트거야. 321 00:26:34,530 --> 00:26:42,570 당신은 최근 컴퓨터의 많은 같은 64 비트를 사용하는 경우는 8 바이트거야. 322 00:26:42,570 --> 00:26:45,230 >> Ints는 거의 항상이 시점에서 4 바이트입니다. 323 00:26:45,230 --> 00:26:47,140 긴 longs는 거의 항상 8 바이트입니다. 324 00:26:47,140 --> 00:26:50,300 과거에는 ints는 2 바이트로 사용됩니다. 325 00:26:50,300 --> 00:26:56,840 그러나이 완전히보다 크고 같 이러한 관계를 모두 만족 확인합니다. 326 00:26:56,840 --> 00:27:01,280 너무 오랫동안 완벽하게 정수와 같은 크기로 허용하는 것은, 327 00:27:01,280 --> 00:27:04,030 하고도 긴 긴와 같은 크기가 될 수있어. 328 00:27:04,030 --> 00:27:11,070 그리고 그냥 시스템의 99.999 %에 그와 동등해질 거에요 저건 무슨 일이 329 00:27:11,070 --> 00:27:15,800 정수 또는 긴 긴 하나. 단지 32 비트 또는 64 비트에 따라 달라집니다. >> [학생] 좋아요. 330 00:27:15,800 --> 00:27:24,600 수레에서 비트의 관점에서 지정한 소수점은 어때요? 331 00:27:24,600 --> 00:27:27,160 바이너리로 쓰시 려고요? >> 그래. 332 00:27:27,160 --> 00:27:30,570 당신은 CS50 그 방법을 알 필요가 없습니다. 333 00:27:30,570 --> 00:27:32,960 당신은 61에있는 내용을하지 않습니다. 334 00:27:32,960 --> 00:27:37,350 귀하는 과정에서 정말로 배울하지 않습니다. 335 00:27:37,350 --> 00:27:42,740 단지 표현입니다. 336 00:27:42,740 --> 00:27:45,440 나는 정확한 비트 할당 받죠 잊어 버려. 337 00:27:45,440 --> 00:27:53,380 부동 소수점의 아이디어는 표시하는 비트의 특정 번호를 할당 있다는 것입니다 - 338 00:27:53,380 --> 00:27:56,550 기본적으로, 모든 과학적 표기법입니다. 339 00:27:56,550 --> 00:28:05,600 그럼 당신은 1.2345과 같은 숫자 자체를 나타내는 비트의 특정 번호를 할당합니다. 340 00:28:05,600 --> 00:28:10,200 나는 5 이상 자리로 수를 나타냅니다 않을 수 있습니다. 341 00:28:12,200 --> 00:28:26,300 이 같은 경향이 있도록 그리고 당신은 또한 비트 특정 번호를 할당 342 00:28:26,300 --> 00:28:32,810 그게 당신이 할 수 가장 큰 지수처럼 만, 특정 번호에 올라가 수 343 00:28:32,810 --> 00:28:36,190 그리고 당신은, 특정 지수에 가도 되요 344 00:28:36,190 --> 00:28:38,770 당신이 할 수있는 가장 작은 지수 야 좋아요. 345 00:28:38,770 --> 00:28:44,410 >> 나는 정확한 방법 비트가 이러한 모든 값에 할당 기억이 안나요 346 00:28:44,410 --> 00:28:47,940 하지만 비트의 특정 번호가 1.2345 위해 최선을 다하고 있습니다 347 00:28:47,940 --> 00:28:50,930 비트의 또 다른 특정 번호가 지수 위해 최선을 다하고 있습니다 348 00:28:50,930 --> 00:28:55,670 그리고 특정 크기의 지수를 나타냅니다 만 가능합니다. 349 00:28:55,670 --> 00:29:01,100 [학생] 그리고 두 번? 그 여분의 긴 부동처럼입니까? >> 그래. 350 00:29:01,100 --> 00:29:07,940 지금은 대신 4 바이트의 8 바이트를 사용하고 제외 부동과 같은 일이야. 351 00:29:07,940 --> 00:29:11,960 이제, 9 자리 또는 10 자리 숫자를 사용할 수 있습니다 352 00:29:11,960 --> 00:29:16,630 이 300 대신 100까지 갈 수있을 것입니다. >> [학생] 좋아요. 353 00:29:16,630 --> 00:29:21,550 그리고 수레는 4 바이트입니다. >> 예. 354 00:29:21,550 --> 00:29:27,520 음, 다시, 아마, 일반 구현에 전체 따라 달라집니다 355 00:29:27,520 --> 00:29:30,610 하지만 수레는 4 바이트이며, 더 블룸은 8입니다. 356 00:29:30,610 --> 00:29:33,440 그들은 두 수레의 크기이기 때문에 더블이 더블이라고합니다. 357 00:29:33,440 --> 00:29:38,380 [학생] 좋아. 그리고 더블 배가거야? >>가 없습니다. 358 00:29:38,380 --> 00:29:43,660 내 생각 엔 - 긴 longs처럼 >> [학생]? >> 그래. 그렇게 생각하지 않아요. 예. 359 00:29:43,660 --> 00:29:45,950 작년 시험에서 [학생] main () 함수에 대한 질문이있었습니다 360 00:29:45,950 --> 00:29:49,490 프로그램의 일부가 될 필요. 361 00:29:49,490 --> 00:29:52,310 답은 여러분의 프로그램의 일부가 될 필요가 없습니다 것이 었습니다. 362 00:29:52,310 --> 00:29:55,100 어떤 상황에서? 그게 내가 본 것이죠. 363 00:29:55,100 --> 00:29:59,090 [보덴] 그것은 보인다 - >> [학생] 어떤 상황? 364 00:29:59,090 --> 00:30:02,880 당신은 문제가 있습니까? >> [학생] 그래, 나도 확실히 끌어 수 있습니다. 365 00:30:02,880 --> 00:30:07,910 그것은 기술적으로 할 필요는 없지만, 기본적으로는거야. 366 00:30:07,910 --> 00:30:10,030 [학생] 난 다른 년에 하나를 보았다. 367 00:30:10,030 --> 00:30:16,220 그것은 참 또는 거짓 같았어요 : A 유효 기간 - >> 아, C 파일입니다.? 368 00:30:16,220 --> 00:30:18,790 . [학생] 모든 C 파일이 있어야합니다 - 한 번에 두 권 - 불륜의 현장을! 369 00:30:18,790 --> 00:30:21,120 좋아요. 그래서 별도의입니다. 370 00:30:21,120 --> 00:30:26,800 >> . C 파일은 기능을 포함해야합니다. 371 00:30:26,800 --> 00:30:32,400 당신은 기계 코드로 파일, 이진, 뭐든지을 컴파일 할 수 372 00:30:32,400 --> 00:30:36,620 없이 아직 실행된다. 373 00:30:36,620 --> 00:30:39,420 유효한 실행 파일은 main () 함수가 있어야합니다. 374 00:30:39,420 --> 00:30:45,460 당신은 100 1 개의 파일에있는 함수를 있지만 기본을 작성할 수 있습니다 375 00:30:45,460 --> 00:30:48,800 그리고, 이진로 내려 컴파일 376 00:30:48,800 --> 00:30:54,460 다음은 주요가 다른 파일을 작성하지만이 기능의 무리 호출 377 00:30:54,460 --> 00:30:56,720 여기이 이진 파일 인치 378 00:30:56,720 --> 00:31:01,240 그리고 당신은 실행을 할 때, 그날은 링커가 무슨 상관이야 379 00:31:01,240 --> 00:31:05,960 그것은이 두 이진 파일 실행에 조화를 이루고 있습니다. 380 00:31:05,960 --> 00:31:11,400 그럼. C 파일은 전혀 main () 함수가 필요하지 않습니다. 381 00:31:11,400 --> 00:31:19,220 그리고 큰 코드베이스에이. C 파일 1 주 파일의 수천을 확인할 수 있습니다. 382 00:31:23,960 --> 00:31:26,110 더 질문? 383 00:31:29,310 --> 00:31:31,940 [학생] 또 다른 질문이 발생했습니다. 384 00:31:31,940 --> 00:31:36,710 이 확인은 컴파일러라고 말했다. 참 또는 거짓? 385 00:31:36,710 --> 00:31:42,030 그리고 답은 거짓이었고, 그 꽝이 아니야 왜 이해. 386 00:31:42,030 --> 00:31:44,770 하지만 우리는 사실이 아니라면 확인 뭐라고 부릅니까? 387 00:31:44,770 --> 00:31:49,990 확인은 기본적으로 것입니다 - 난이 전화를 정확히 확인할 수 있습니다. 388 00:31:49,990 --> 00:31:52,410 하지만 그냥 명령을 실행합니다. 389 00:31:53,650 --> 00:31:55,650 합니다. 390 00:31:58,240 --> 00:32:00,870 나는이 일을 당겨 수 있습니다. 그래. 391 00:32:10,110 --> 00:32:13,180 오, 그래. 확인은 또한을 수행합니다. 392 00:32:13,180 --> 00:32:17,170 이것은 제조업체 유틸리티의 목적은 자동으로 결정하는 것입니다라고 393 00:32:17,170 --> 00:32:19,610 큰 프로그램의 조각은 다시 컴파일 할 필요가있는 394 00:32:19,610 --> 00:32:22,350 그리고 그것들을 다시 컴파일하는 명령을 발행. 395 00:32:22,350 --> 00:32:27,690 당신은 절대적으로 큰 않은 파일을 만들 수 있습니다. 396 00:32:27,690 --> 00:32:33,210 확인은 우리가 전에 말했듯이, 파일의 시간 스탬프에보고 397 00:32:33,210 --> 00:32:36,930 당신은 개별 파일을 컴파일 할 수 있습니다, 그리고 링커에 도착 할 때까지 그렇지 않아 398 00:32:36,930 --> 00:32:39,270 그들은 실행에 조립하고 있는지. 399 00:32:39,270 --> 00:32:43,810 당신은 10 다른 파일을 가지고 있고, 그들 중 하나를 변경한다면 400 00:32:43,810 --> 00:32:47,870 그리고 어떤 제조업체가하려는 것은 단지 재 컴파일입니다 파일 1 401 00:32:47,870 --> 00:32:50,640 그리고 함께 모든 relink. 402 00:32:50,640 --> 00:32:53,020 그러나 그것보다 더 멍청한입니다. 403 00:32:53,020 --> 00:32:55,690 완전히 그 얘기가 할 일이 있다는 정의의 몫입니다. 404 00:32:55,690 --> 00:32:59,560 그것은 기본적으로이 타임 스탬프 물건을 인식 할 수있는 능력을 가지고 405 00:32:59,560 --> 00:33:03,220 하지만 당신은 아무것도 할 제조업체 파일을 쓸 수 있습니다. 406 00:33:03,220 --> 00:33:09,150 당신은 쓸 수있는 파일을 만들 때문에 당신이 그냥 CD를 다른 디렉토리에 만들어 입력 할 때.에게 407 00:33:09,150 --> 00:33:15,560 나는 좌절하게 만들었 어 I 뾰족한 모든 내 어플라이언스의 내부 때문에 408 00:33:15,560 --> 00:33:21,740 그럼 내가 Mac에서 PDF를 볼 수 있습니다. 409 00:33:21,740 --> 00:33:30,720 >> 그래서 파인더로 가서 내가 이동 할 수 Server에 연결 410 00:33:30,720 --> 00:33:36,950 내가 연결 서버 내 어플라이언스이며, 그런 다음 PDF를 엽니 다 411 00:33:36,950 --> 00:33:40,190 그는 LaTeX에 의해 컴파일됩니다. 412 00:33:40,190 --> 00:33:49,320 그러나 내가 좌절하게 만들었 어 제가 PDF를 새로 고치는 데 필요한 매번 때문에, 413 00:33:49,320 --> 00:33:53,900 나는 액세스 할 수있는 특정 디렉토리에 복사했다 414 00:33:53,900 --> 00:33:57,710 그리고 짜증나는 점점되었다. 415 00:33:57,710 --> 00:34:02,650 대신에 당신이이 일을하게하는 방법을 정의해야 제조업체 파일을 썼다. 416 00:34:02,650 --> 00:34:06,130 귀하가 만드는 방법이 PDF LaTeX이 있습니다. 417 00:34:06,130 --> 00:34:10,090 그냥 다른 제조업체 파일과 같은 - 또는 당신이 제조업체 파일을 보지 못했다 것, 418 00:34:10,090 --> 00:34:13,510 하지만 우리는 어플라이언스에 불과라는 글로벌 제조업체 파일이 419 00:34:13,510 --> 00:34:16,679 당신은 C 파일을 컴파일하는 경우, 꽝을 사용합니다. 420 00:34:16,679 --> 00:34:20,960 그리고 여기 내 제조업체 파일에서 내가 말을 만드는 것이, 421 00:34:20,960 --> 00:34:25,020 이 파일은 PDF LaTeX이 컴파일하려는거야. 422 00:34:25,020 --> 00:34:27,889 그리고 이제 컴파일을하고 PDF LaTeX이 있습니다. 423 00:34:27,889 --> 00:34:31,880 확인이 컴파일되지 않습니다. 그것은 내가 지정한 순서대로 이들 명령을 실행있어. 424 00:34:31,880 --> 00:34:36,110 그래서이 PDF의 LaTeX이를 운영하고, 이건 제가 일이 잘 복사 할 디렉토리로 복사 425 00:34:36,110 --> 00:34:38,270 이 CD의 디렉토리와 다른 일들을, 426 00:34:38,270 --> 00:34:42,380 하지만, 그런 일이 모든 때, 파일 변경 사항을 인식하고 있습니다 427 00:34:42,380 --> 00:34:45,489 가 변경되면, 그것은 실행해야하는 명령을 실행합니다 428 00:34:45,489 --> 00:34:48,760 때 파일 변경됩니다. >> [학생] 좋아요. 429 00:34:50,510 --> 00:34:54,420 나는 글로벌 제조업체 파일은 내가 그것을 확인하기 위해 어디 있는지 어떻게 알아요. 430 00:34:57,210 --> 00:35:04,290 다른 질문? 과거의 일이 퀴즈? 모든 포인터 일? 431 00:35:06,200 --> 00:35:08,730 같은 포인터와 미묘한 가지가 있습니다 - 432 00:35:08,730 --> 00:35:10,220 나는 그곳에서 퀴즈 질문을 찾을 수 않을거야 - 433 00:35:10,220 --> 00:35:16,250 하지만 단지 이런 걸처럼. 434 00:35:19,680 --> 00:35:24,060 내가 무슨 말을 할 때 당신이 그렇게 이해를해야합니다 정수 * X * Y - 435 00:35:24,890 --> 00:35:28,130 이 정확히 여기 건지 아닌지는 것 같아요. 436 00:35:28,130 --> 00:35:32,140 그러나 같은 * X * Y, 그는 스택에있는 두 변수입니다. 437 00:35:32,140 --> 00:35:37,220 나는 말을 할 때 X = malloc (sizeof (int는)), x는 여전히 스택에 변수 438 00:35:37,220 --> 00:35:41,180 malloc은 힙 분쟁 블록이며, 우리는 힙 X 포인트가 있어요. 439 00:35:41,180 --> 00:35:43,900 >> 힙에 스택 점에서 뭔가 그럼. 440 00:35:43,900 --> 00:35:48,100 때마다 malloc 아무것도, 당신은 불가피하게 그 포인터의 내부를 저장하고 있습니다. 441 00:35:48,100 --> 00:35:55,940 그 포인터가 스택에 그래서 malloced 블록은 힙에 있습니다. 442 00:35:55,940 --> 00:36:01,240 많은 사람들이 혼란스러워하고 말 INT * X = malloc, x는 힙에 있습니다. 443 00:36:01,240 --> 00:36:04,100 X가 가리키는 어떤 번호는 힙에 있습니다. 444 00:36:04,100 --> 00:36:08,540 어떤 이유로 당신이 x는 전역 변수가 될하지 않는 X 자체는, 스택에 445 00:36:08,540 --> 00:36:11,960 이 경우에 메모리의 다른 영역에 있어야 발생합니다. 446 00:36:13,450 --> 00:36:20,820 트랙을 유지 그래서,이 상자 화살표 다이어그램은 퀴즈에 대한 아주 흔한 일입니다. 447 00:36:20,820 --> 00:36:25,740 이 퀴즈를 0에이 아니라면 아니면, 퀴즈 1 될 것입니다. 448 00:36:27,570 --> 00:36:31,940 당신은 컴파일의 단계를이 모든 걸 알 수 있어야 449 00:36:31,940 --> 00:36:35,740 당신이 저에 대한 질문에 대답했다 때문입니다. 예. 450 00:36:35,740 --> 00:36:38,940 [학생] 우리가 그 단계에 가서 할 수 없습니다 - >> 그래. 451 00:36:48,340 --> 00:36:58,640 단계 및 컴파일하기 전에 우리는 전처리가 452 00:36:58,640 --> 00:37:16,750 컴파일 조립 및 연결. 453 00:37:16,750 --> 00:37:21,480 전처리. 그 용도는 무엇입니까? 454 00:37:29,720 --> 00:37:32,290 그것은에있는 가장 쉬운 단계 - 글쎄, 그런 식으로 - 455 00:37:32,290 --> 00:37:35,770 그 방법은 우리가 분명해야 의미하지는 않습니다,하지만 가장 쉬운 단계입니다. 456 00:37:35,770 --> 00:37:38,410 당신들은 그것을 자신을 구현 수 있습니다. 그래. 457 00:37:38,410 --> 00:37:43,410 [학생] 무엇 당신이하고있는 것은 다음과 같이 포함 해하고 복사하고도 정의합니다. 458 00:37:43,410 --> 00:37:49,250 그것은, # 등의 존재를보고 # 정의 459 00:37:49,250 --> 00:37:53,800 하고 그냥 복사하여 페이스트 사람들은 실제로 무슨 뜻인지. 460 00:37:53,800 --> 00:37:59,240 그래서 당신은 # cs50.h을 포함 말은, 전처리가 복사 cs50.h 붙여 넣기합니다 461 00:37:59,240 --> 00:38:01,030 그 줄에. 462 00:38:01,030 --> 00:38:06,640 당신은 # 4로 x를 정의 말은, 전처리는 전체 프로그램을 통해 간다 463 00:38:06,640 --> 00:38:10,400 그리고 4 X의 모든 인스턴스를 대체합니다. 464 00:38:10,400 --> 00:38:17,530 따라서 전처리은 (는) 유효한 C 파일을 소요하고 유효한 C 파일을 출력 465 00:38:17,530 --> 00:38:20,300 있는 물건은 복사 및 붙여 넣기되었습니다. 466 00:38:20,300 --> 00:38:24,230 이제 컴파일. 그 용도는 무엇입니까? 467 00:38:25,940 --> 00:38:28,210 [학생]는 C에서 이진로 이동합니다. 468 00:38:28,210 --> 00:38:30,970 >> [보덴] 그것은 바이너리로 모든 길을 갈수하지 않습니다. 469 00:38:30,970 --> 00:38:34,220 [학생] 기계 코드 그럼? >> 그것은 기계 코드 없습니다. 470 00:38:34,220 --> 00:38:35,700 [학생] 국회? >> 조립. 471 00:38:35,700 --> 00:38:38,890 이 C 코드로 모든 길을 들어가기 전에이 국회에 가서, 472 00:38:38,890 --> 00:38:45,010 대부분의 언어는 이런 일을 할. 473 00:38:47,740 --> 00:38:50,590 어떤 높은 수준의 언어를 선택하고 그것을 컴파일 할 경우, 474 00:38:50,590 --> 00:38:52,390 이 단계에서 컴파일 할 것입니다. 475 00:38:52,390 --> 00:38:58,140 첫 번째는 C로 파이썬을 컴파일거야, 다음은 조립 C를 컴파일거야 476 00:38:58,140 --> 00:39:01,600 그리고 조립 바이너리로 번역 할 거에요. 477 00:39:01,600 --> 00:39:07,800 따라서 컴파일은 C에서 어셈블리로 가져 것이다. 478 00:39:07,800 --> 00:39:12,130 컴파일 단어는 일반적으로 높은 수준에서 가져 의미 479 00:39:12,130 --> 00:39:14,340 낮은 수준의 프로그래밍 언어. 480 00:39:14,340 --> 00:39:19,190 그래서이 집이 당신이 높은 수준의 언어로 시작하는 컴파일에있는 유일한 단계입니다 481 00:39:19,190 --> 00:39:23,270 과 낮은 수준의 언어로 끝나, 그리고 단계가 컴파일이라고하는 이유입니다. 482 00:39:25,280 --> 00:39:33,370 컴파일시 [학생], 귀하가 # 포함 한 그렇게 말하지 cs50.h. 483 00:39:33,370 --> 00:39:42,190 컴파일러 컴파일 cs50.h 윌, 거기에있는 기능과 같은, 484 00:39:42,190 --> 00:39:45,280 그리고,뿐만 아니라 그 어셈블리 코드로 번역 485 00:39:45,280 --> 00:39:50,830 또는 사전 조립 된 뭔가를 복사하여 붙여 넣기 것인가? 486 00:39:50,830 --> 00:39:56,910 cs50.h이 정말 국회에서 생을 마감하지 않습니다. 487 00:39:59,740 --> 00:40:03,680 함수 프로토 타입과 물건 같은 콘텐츠는 조심 만위한 것입니다. 488 00:40:03,680 --> 00:40:09,270 당신이 함수를 호출하는 것 컴파일러가 일을 확인할 수 있도록 보장 489 00:40:09,270 --> 00:40:12,910 오른쪽 반환 형식과 오른쪽 인수하고 뭐 다른 것들. 490 00:40:12,910 --> 00:40:18,350 >> 이 컴파일 될 때 그럼 cs50.h는 다음 파일로 preprocessed, 그리고 될 것입니다 491 00:40:18,350 --> 00:40:22,310 이 모든 것이 제대로 호출되고 있는지 확인합니다 후에는 기본적으로 버려진있어. 492 00:40:22,310 --> 00:40:29,410 그러나 CS50 라이브러리에 정의 된 함수, cs50.h 분리되어있는 493 00:40:29,410 --> 00:40:33,610 그는 별도로 컴파일되지 않습니다. 494 00:40:33,610 --> 00:40:37,270 실제로 연결 단계에서 내려 와서됩니다, 그래서 우리는 두 번째에 해당로 연결됩니다. 495 00:40:37,270 --> 00:40:40,100 그러나 먼저, 어떻게 조립입니까? 496 00:40:41,850 --> 00:40:44,500 진에 [학생] 국회? >> 그래. 497 00:40:46,300 --> 00:40:48,190 조립. 498 00:40:48,190 --> 00:40:54,710 총회는 거의 이진의 순수한 번역이기 때문에 우리는 컴파일 연락하지 않습니다. 499 00:40:54,710 --> 00:41:00,230 총회에서 이진에가는 매우 작은 논리가 있습니다. 500 00:41:00,230 --> 00:41:03,180 그냥 테이블에 찾는 사람이야 오, 우리는이 명령을 가지고있다 501 00:41:03,180 --> 00:41:06,290 그 바이너리 01110에 해당합니다. 502 00:41:10,200 --> 00:41:15,230 그리고 파일이 출력은 일반적으로 조립. O 파일이. 503 00:41:15,230 --> 00:41:19,020 그리고. O 파일은 우리가 전에 말을했던 있으며, 504 00:41:19,020 --> 00:41:21,570 어떻게 파일은 main () 함수가 필요하지 않습니다. 505 00:41:21,570 --> 00:41:27,640 모든 파일은 유효한 C 파일의만큼. O 파일로 다운 컴파일 할 수 있습니다. 506 00:41:27,640 --> 00:41:30,300 이. O으로 컴파일 할 수 있습니다. 507 00:41:30,300 --> 00:41:43,030 이제 연결이 있습니다. 실제로 잔뜩 무슨 일로 오 파일이며 실행에을 제공합니다. 508 00:41:43,030 --> 00:41:51,110 그리고 어떤 연결이 수행하면. O 파일로 CS50 라이브러리를 생각할 수 있습니다. 509 00:41:51,110 --> 00:41:56,980 그것은 이미 컴파일 된 바이너리 파일입니다. 510 00:41:56,980 --> 00:42:03,530 그리고 당신은 GetString 호출 파일, 당신 hello.c를 컴파일 할 때 511 00:42:03,530 --> 00:42:06,360 hello.c는 hello.o으로 컴파일됩니다 512 00:42:06,360 --> 00:42:08,910 hello.o는 바이너리 중이다. 513 00:42:08,910 --> 00:42:12,830 , 그것은 GetString 사용하기 때문에 cs50.o에 갈 필요가 514 00:42:12,830 --> 00:42:16,390 그리고 링커가 함께 그들을 smooshes이 파일에 GetString를 복사합니다 515 00:42:16,390 --> 00:42:20,640 하고 필요로하는 모든 기능을 가지고 실행으로 나온다. 516 00:42:20,640 --> 00:42:32,620 그럼 cs50.o은 실제로 O 파일입니다,하지만 더 근본적인 차이가 없다는 것을 충분히 있습니다. 517 00:42:32,620 --> 00:42:36,880 그냥을 연결하면 함께 파일의 무리를 제공합니다 518 00:42:36,880 --> 00:42:41,390 개별적으로 모든 기능을 포함하고 제가 사용해야합니다 519 00:42:41,390 --> 00:42:46,120 실제로 실행되는 실행 파일을 만듭니다. 520 00:42:48,420 --> 00:42:50,780 >> 그리고 우리가 전에 말을했던 것이기도 521 00:42:50,780 --> 00:42:55,970 당신은 1000가 할 수있는. C 파일을, 당신은 모두를 컴파일합니다. O 파일, 522 00:42:55,970 --> 00:43:00,040 아마 시간이 걸릴됩니다, 다음 1을 변경할 수 있습니다. C 파일은. 523 00:43:00,040 --> 00:43:05,480 귀하는 그 1. C 파일 및 다음 다른 relink 모든을 다시 컴파일 할 필요가 524 00:43:05,480 --> 00:43:07,690 다시 함께 모든 연결합니다. 525 00:43:09,580 --> 00:43:11,430 [학생] 우리가 lcs50를 작성 연결 할 때? 526 00:43:11,430 --> 00:43:20,510 그래,-lcs50. 해당 라이브러리에 연결되어야 링커에게 깃발 신호. 527 00:43:26,680 --> 00:43:28,910 질문이 있으십니까? 528 00:43:41,310 --> 00:43:46,860 우리는 첫 번째 강의에서 해당 오초 이외의 바이너리왔다? 529 00:43:50,130 --> 00:43:53,010 그렇게 생각하지 않아요. 530 00:43:55,530 --> 00:43:58,820 당신은 우리가 늦었가 큰 OS의 모든 사항을 알아 두어야 531 00:43:58,820 --> 00:44:02,670 우리가 당신에게 기능을 해준다면 당신은, 할 수 있어야합니다 532 00:44:02,670 --> 00:44:09,410 그게 약, 큰 O 있다고도 할 수 있어야합니다. 또는 잘, 큰 O는 거친 것입니다. 533 00:44:09,410 --> 00:44:15,300 당신이 일의 동일한 수를 통해 반복 루프에 대한 중첩 참조하면, 534 00:44:15,300 --> 00:44:22,260 >> [학생] N 제곱 - INT J, J >는 제곱 N 경향이있다. 535 00:44:22,260 --> 00:44:25,280 당신은 트리플 중첩 한 경우, n은 cubed 될 경향이있다. 536 00:44:25,280 --> 00:44:29,330 그래서 그런 일이 바로 지적 할 수 있어야합니다. 537 00:44:29,330 --> 00:44:33,890 당신은 삽입 정렬과 버블 정렬을 알고 종류와 그의를 병합해야합니다. 538 00:44:33,890 --> 00:44:41,420 그들은 그 N 제곱과 n 로그 N 그 모든 이유가 이해하기 쉽게 539 00:44:41,420 --> 00:44:47,810 난 우리가 기본적으로 준 1 년 퀴즈 거기에 생각하기 때문에 540 00:44:47,810 --> 00:44:55,050 버블 정렬의 구현 및 "이 함수의 실행 시간은 무엇입니까?"라고 541 00:44:55,050 --> 00:45:01,020 당신은 거품 정렬로 인식하면, 다음 즉시 n은 제곱 말할 수 있습니다. 542 00:45:01,020 --> 00:45:05,470 네가 그냥 보면하지만, 당신도 그게 거품 정렬을 실현 할 필요가 없습니다; 543 00:45:05,470 --> 00:45:08,990 당신은 본이를하고있다 말할 수 있습니다. 이것은 제곱 습니됩니다. 544 00:45:12,350 --> 00:45:14,710 [학생]이 (가) 당신이 가지고 올 수있는 어려운 사례가 있습니까, 545 00:45:14,710 --> 00:45:20,370 알아 냈어과 비슷한 생각처럼? 546 00:45:20,370 --> 00:45:24,450 >> 나는 우리가 당신에게 어떤 힘든 예를 포기할 거라 생각하지 않습니다. 547 00:45:24,450 --> 00:45:30,180 버블 정렬 건, 우리가 갈거야 최대한 어렵다 548 00:45:30,180 --> 00:45:36,280 그리고 오래 당신이 이해로는 배열을 통해 반복하고 있다는 것을 549 00:45:36,280 --> 00:45:41,670 배열의 각 요소에 대해, 어느 제곱 습니 뭔가 될 것입니다. 550 00:45:45,370 --> 00:45:49,940 우리가 여기에 같은 일반적인 질문이 있습니다 - 오. 551 00:45:55,290 --> 00:45:58,530 그냥 어느 날, 더그 주장, "나는 배열을 정렬 할 수 있습니다 알고리즘을 발명했습니다 552 00:45:58,530 --> 00:46:01,780 "O (로그 n)이 시간!의 N 숫자의" 553 00:46:01,780 --> 00:46:04,900 그럼 어떻게 우리가 그렇게는 불가능 알 수 있습니까? 554 00:46:04,900 --> 00:46:08,850 [안 들리게 학생 응답] >> 그래. 555 00:46:08,850 --> 00:46:13,710 최소한, 당신은 배열의 각 요소를 터치해야 556 00:46:13,710 --> 00:46:16,210 그래서 배열을 정렬 할 수가 없어 - 557 00:46:16,210 --> 00:46:20,850 모든 정렬되지 않은 순서로되어있는 경우, 다음은 배열에 모든 것을 만지고 있어야 할거야 558 00:46:20,850 --> 00:46:25,320 그래서 N의 O 이내에 작업을 수행하는 것은 불가능입니다. 559 00:46:27,430 --> 00:46:30,340 [학생] 당신이 우리에게 n의 O에서 할 수있는의 예를 보여 560 00:46:30,340 --> 00:46:33,920 당신은 많은 메모리를 사용하는 경우. >> 그래. 561 00:46:33,920 --> 00:46:37,970 그리고 전 ... - 내가 그정도 잊지 - 이건 일종의 계산 있습니까? 562 00:46:47,360 --> 00:46:51,330 음. 그 정수 정렬 알고리즘입니다. 563 00:46:59,850 --> 00:47:05,100 제가 지난 주에 기억 할 수없는이를위한 특별한 이름을 찾고있었습니다. 564 00:47:05,100 --> 00:47:13,000 그래. 다음은 n의 큰 O의 일을 수행 할 수 종류의 유형입니다. 565 00:47:13,000 --> 00:47:18,430 만 특정 번호로 정수를 사용할 수 있습니다 것 같지만 한계가 있습니다. 566 00:47:20,870 --> 00:47:24,560 또한 당신이 뭔가를 렸는데을 정렬하려는 경우 - 567 00:47:24,560 --> 00:47:30,750 당신의 배열은 012, -12, 151, 4 만 경우 568 00:47:30,750 --> 00:47:35,120 해당 단일 요소는 완전히 전체 정렬을 망칠 것입니다. 569 00:47:42,060 --> 00:47:44,030 >> 질문이 있으십니까? 570 00:47:49,480 --> 00:47:58,870 [학생] 당신은 재귀 함수가 있고 그냥 재귀 호출을하는 경우 571 00:47:58,870 --> 00:48:02,230 return 문에서, 그, 꼬리 재귀입니다 572 00:48:02,230 --> 00:48:07,360 그리고 그 실행 기간 동안 더 많은 메모리를 사용하지 않을 573 00:48:07,360 --> 00:48:12,550 이 솔루션을 반복적으로하거나 최소한 유사한 메모리를 사용해야합니까? 574 00:48:12,550 --> 00:48:14,530 [보덴] 예. 575 00:48:14,530 --> 00:48:19,840 그것은 가능성이 다소 느려질 수 있지만 정말로. 것 576 00:48:19,840 --> 00:48:23,290 재귀 꼬리가 아주 좋은 것입니다. 577 00:48:23,290 --> 00:48:32,640 스택 프레임에서 다시 찾고, 우리는 주요 있다고 가정 해 봅시다 578 00:48:32,640 --> 00:48:42,920 우리는 INT 바 (INT X) 또는 게있어. 579 00:48:42,920 --> 00:48:52,310 이건 완벽한 재귀 함수가 아니라 수익 바 (X - 1). 580 00:48:52,310 --> 00:48:57,620 그러니 확실히,이 썼어. 당신은 기본 케이스와 재료가 필요합니다. 581 00:48:57,620 --> 00:49:00,360 하지만, 여기에 아이디어는,이 재귀 꼬리 때문입니다 582 00:49:00,360 --> 00:49:06,020 어떤은의 스택 프레임을 얻을 수있을 때 주요 통화 표시 줄을 의미합니다. 583 00:49:09,550 --> 00:49:12,440 이 스택 프레임에 메모리의 작은 블록이있을거야 584 00:49:12,440 --> 00:49:17,490 그는 인수 x에 해당합니다. 585 00:49:17,490 --> 00:49:25,840 그리고 보자는 메인이 바 (100) 전화 댔어; 586 00:49:25,840 --> 00:49:30,050 따라서 x는 100로에서 시작 예정이다. 587 00:49:30,050 --> 00:49:35,660 컴파일러는이, 꼬리 재귀 함수입니다 인식하는 경우 588 00:49:35,660 --> 00:49:38,540 바, 그 재귀 호출이 금지 할 수 있습니다 땐 589 00:49:38,540 --> 00:49:45,490 대신 스택이 크게 성장 시작 어디에 새로운 스택 프레임을 만드는, 590 00:49:45,490 --> 00:49:48,220 결국 힙으로 실행됩니다 그리고 당신은 segfaults을 591 00:49:48,220 --> 00:49:51,590 메모리 충돌 시작 때문입니다. 592 00:49:51,590 --> 00:49:54,830 >> 대신 자신의 스택 프레임을 너무, 이건 실현할 수 593 00:49:54,830 --> 00:49:59,080 이봐 요, 난 정말이 스택 프레임에 다시 할 필요가 없습니다 594 00:49:59,080 --> 00:50:08,040 대신에 그냥 99로이 인수를 대체하고 줄을 모두 다시 시작합니다. 595 00:50:08,040 --> 00:50:11,810 - (1 개) 그리고 다시 그렇게하고는 반품 바 도달 할 596 00:50:11,810 --> 00:50:17,320 대신 새로운 스택 프레임을의, 단지 98 현재 인수를 교체합니다 597 00:50:17,320 --> 00:50:20,740 다음 줄의 처음으로 돌아 이동합니다. 598 00:50:23,860 --> 00:50:30,430 이러한 운영 스택에 그 한 가치를 교체하고 처음부터 다시 점프, 599 00:50:30,430 --> 00:50:32,430 매우 효율적이다. 600 00:50:32,430 --> 00:50:41,500 그래서 ..이 반복되는 별도의 함수와 같은 메모리 사용량 is 601 00:50:41,500 --> 00:50:45,390 만 1 스택 프레임을 사용하고 있지만, 단점을 겪고있는 것이 아니기 때문 602 00:50:45,390 --> 00:50:47,240 함수를 호출해야하는. 603 00:50:47,240 --> 00:50:50,240 이 모든 설정을 할 있기 때문에 전화 기능은 다소 비쌀 수 있습니다 604 00:50:50,240 --> 00:50:52,470 및 teardown이 모든 것들. 605 00:50:52,470 --> 00:50:58,160 그래서 꼬리 재귀이 양호합니다. 606 00:50:58,160 --> 00:51:01,170 [학생] 왜 새로운 단계를 생성하지 않습니다? 607 00:51:01,170 --> 00:51:02,980 그 실현 때문 필요하지 않습니다. 608 00:51:02,980 --> 00:51:07,800 바 호출은 재귀 호출을 반환합니다. 609 00:51:07,800 --> 00:51:12,220 그럼 리턴 값으로 아무것도 할 필요가 없습니다. 610 00:51:12,220 --> 00:51:15,120 단지 즉시 반환하는거야. 611 00:51:15,120 --> 00:51:20,530 그럼 그냥 자신의 주장을 교체하고 다시 시작 할거야. 612 00:51:20,530 --> 00:51:25,780 또한, 당신은 꼬리 재귀 버전이없는 경우, 613 00:51:25,780 --> 00:51:31,460 다음은이 줄이 반환이 모든 막대를 얻을 614 00:51:31,460 --> 00:51:36,010 이 막대가 즉시 반환 한 후,이 하나의 값을 반환한다 615 00:51:36,010 --> 00:51:39,620 그리고이 하나의 값을 반환 한 후 그냥 바로 돌아거야 616 00:51:39,620 --> 00:51:41,350 이 하나의 값을 반환합니다. 617 00:51:41,350 --> 00:51:45,350 그럼 당신은 스택의이 모든 일을 터지는이 절감 618 00:51:45,350 --> 00:51:48,730 반환 값은 어쨌든 다시 모든 방법을 전달하려고 때문입니다. 619 00:51:48,730 --> 00:51:55,400 왜 그냥 업데이트 된 인수와의 논쟁을 교체하고 다시 시작하지? 620 00:51:57,460 --> 00:52:01,150 - 당신이 그런 짓을하면 기능은 꼬리 재귀가 아닌 경우 621 00:52:01,150 --> 00:52:07,530 [학생] 경우 바 (X + 1). >> 그래. 622 00:52:07,530 --> 00:52:11,770 >> 이 상태로 넣어면, 다음의 리턴 값에 뭔가 의미있는 일을하고 있어요. 623 00:52:11,770 --> 00:52:16,260 아니면 그냥 반환이 작업을 수행하는 경우에도 * 바 (X - 1). 624 00:52:16,260 --> 00:52:23,560 이제 바 -가 2 배 그 값을 계산하기 위해 (X 1) 순서로 반환해야합니다 625 00:52:23,560 --> 00:52:26,140 이제야는 별도의 스택 프레임이 필요 없습니다 626 00:52:26,140 --> 00:52:31,180 지금, 당신이 아무리, 당신은 필요 할 건 - 627 00:52:31,180 --> 00:52:34,410 이 재귀 꼬리 없습니다. 628 00:52:34,410 --> 00:52:37,590 [학생] 나는 꼬리 재귀을 목표로하는 재귀을 가져보십시오시겠습니까 - 629 00:52:37,590 --> 00:52:41,450 [보덴]는 이상적인 세계에서하지만, CS50에 필요하지 않습니다. 630 00:52:43,780 --> 00:52:49,280 꼬리 재귀를 위해 일반적으로, 당신은 추가 인수를 설정 631 00:52:49,280 --> 00:52:53,550 바 Y에 정수 x를 취할 것입니다 곳 632 00:52:53,550 --> 00:52:56,990 와 y는 반환 할 궁극적 인 문제에 해당합니다. 633 00:52:56,990 --> 00:53:03,650 (- 1 개), 2 * y를 그럼 이건 당신이 줄을 반환 할거야. 634 00:53:03,650 --> 00:53:09,810 단지 있도록 높은 수준의 당신이 일이 꼬리 재귀로 변환하는 방법. 635 00:53:09,810 --> 00:53:13,790 그러나 추가 인수 - 636 00:53:13,790 --> 00:53:17,410 그리고 결국에는 당신의 기본 케이스에 도달 할 때, 당신은 y를 반환 637 00:53:17,410 --> 00:53:22,740 당신은 전체 시간을 당신이 원하는 반환 값을 축적 해왔거든요. 638 00:53:22,740 --> 00:53:27,280 의 당신 종류 선언을하고 있지만, 재귀 호출을 사용하고 있습니다. 639 00:53:32,510 --> 00:53:34,900 질문이 있으십니까? 640 00:53:34,900 --> 00:53:39,890 문자열을 사용할 때와 같은 아마 포인터 산술에 대한 [학생]. >> 물론이지. 641 00:53:39,890 --> 00:53:43,610 포인터 산술. 642 00:53:43,610 --> 00:53:48,440 문자열이 문자 별이기 때문에 문자열을 사용하는 경우는, 쉽게 643 00:53:48,440 --> 00:53:51,860 문자는 영원히 항상 단일 바이트 아르 644 00:53:51,860 --> 00:53:57,540 그래서 포인터 연산은 문자열을 상대하는 일반 산술 동일합니다. 645 00:53:57,540 --> 00:54:08,790 우선은 숯불 * S = "안녕하세요"라고. 646 00:54:08,790 --> 00:54:11,430 그래서 우리는 메모리에 블록이 있습니다. 647 00:54:19,490 --> 00:54:22,380 항상 널 종료가 필요하기 때문에 6 바이트가 필요합니다. 648 00:54:22,380 --> 00:54:28,620 그리고 숯불 * s은 (는)이 배열의 시작 부분을 가리 키도록 것이다. 649 00:54:28,620 --> 00:54:32,830 따라서 S가 지적했다. 650 00:54:32,830 --> 00:54:36,710 자,이, 기본적으로 모든 배열 방법은 다음과 651 00:54:36,710 --> 00:54:40,780 상관없이 malloc으로하거나 스택에 있어요 여부를 반환했습니다 여부. 652 00:54:40,780 --> 00:54:47,110 모든 배열은 기본적으로 배열의 시작에 대한 포인터입니다 653 00:54:47,110 --> 00:54:53,640 다음 일련의 작업을 모든 색인을 생성, 그냥 특정 오프셋 그 배열로 갈 수 있습니다. 654 00:54:53,640 --> 00:55:05,360 >> 그래서 님의 [3] 같은 말을 할 때,이 S로 이동 인치 세 문자를 주시 655 00:55:05,360 --> 00:55:12,490 그럼 님의 [3], 우리는 0이, 1, 2, 3, 기건 [3]이 리터를 참조 예정이다. 656 00:55:12,490 --> 00:55:20,460 [학생] 그리고 우리는 S + 3 일 후 괄호 스타 같은 값에 도달 할 수? 657 00:55:20,460 --> 00:55:22,570 예. 658 00:55:22,570 --> 00:55:26,010 이 * (S + 3)에 해당합니다; 659 00:55:26,010 --> 00:55:31,240 그리고 영원히 항상 동등한 당신이 무슨 짓을하든 없습니다. 660 00:55:31,240 --> 00:55:34,070 당신은 브라켓 구문을 사용 할 필요가 없습니다. 661 00:55:34,070 --> 00:55:37,770 당신은 언제나 (들 + 3) 문법 *를 사용할 수 있습니다. 662 00:55:37,770 --> 00:55:40,180 사람들은하지만 브라켓 구문을 좋아하는 경향이 있습니다. 663 00:55:40,180 --> 00:55:43,860 [학생] 지금 모든 배열은 실제로 포인터입니다. 664 00:55:43,860 --> 00:55:53,630 내가 무슨 말을 할 때 약간의 차이가 있습니다 INT X [4]; >> [학생] 그 메모리를 만들 수 있습니까? 665 00:55:53,630 --> 00:56:03,320 [보덴 그건 정말 16 바이트 전체, 스택에 4 ints를 만드는 것이다. 666 00:56:03,320 --> 00:56:05,700 이 스택에 16 바이트를 만들거야. 667 00:56:05,700 --> 00:56:09,190 x는 저장되지 않습니다. 668 00:56:09,190 --> 00:56:13,420 단지 일을 시작을 참조 상징입니다. 669 00:56:13,420 --> 00:56:17,680 당신은이 함수의 안쪽에 배열을 선언하기 때문에 670 00:56:17,680 --> 00:56:22,340 컴파일러가 무슨 짓을할지 그냥 변수 x의 모든 인스턴스를 바뀝니다 671 00:56:22,340 --> 00:56:26,400 그 다음 16 바이트를 넣어 선택이 있었던 곳으로. 672 00:56:26,400 --> 00:56:30,040 s이 (가) 실제 포인터이기 때문에이 숯불 * s와 (과) 그런 짓을 할 수 없습니다. 673 00:56:30,040 --> 00:56:32,380 그런 다음 다른 일을 가리 할 수​​있다. 674 00:56:32,380 --> 00:56:36,140 x는 상수입니다. 당신은 다른 배열이 지점 수 없습니다. >> [학생] 좋아요. 675 00:56:36,140 --> 00:56:43,420 그러나이 아이디어에,이 색인을 생성, 그건 기존의 배열 여부와 상관없이 동일합니다 676 00:56:43,420 --> 00:56:48,230 그건 뭔가 또는 경우에 대한 포인터인지 아니면 malloced 배열에 대한 포인터입니다. 677 00:56:48,230 --> 00:56:59,770 그리고 사실, 또한 같은입니다 너무 동일합니다. 678 00:56:59,770 --> 00:57:05,440 그것은 실제로 괄호의 내부에 어떤 번역과는 괄호 남은 679 00:57:05,440 --> 00:57:07,970 을 함께 추가하고, dereferences. 680 00:57:07,970 --> 00:57:14,710 따라서이만큼 유효합니다 * (S + 3) 또는 S [3]. 681 00:57:16,210 --> 00:57:22,090 [학생] 당신은 2 차원 배열을 가리키는 포인터를 할 수 있습니까? 682 00:57:22,090 --> 00:57:27,380 >> 이 힘듭니다. 전통적으로, 안돼. 683 00:57:27,380 --> 00:57:34,720 2 차원 배열은 단지 편리한 구문과 1 차원 배열입니다 684 00:57:34,720 --> 00:57:54,110 때문에 내가 말할 때 INT X [3] [3]이 정말 아홉 값으로 단 1 배열입니다. 685 00:57:55,500 --> 00:58:03,000 그리고 그래서 지수는, 컴파일러가 무슨 뜻인지 알고 때. 686 00:58:03,000 --> 00:58:13,090 나는 X [1] [2], 그건 내가 두 번째 행에 가고 싶어 알고 있으므로 처음 3를 건너 뛰거야,라고하면 687 00:58:13,090 --> 00:58:17,460 다음, 아마 이걸 가져 오지 점에서 두 번째 일을하려고합니다. 688 00:58:17,460 --> 00:58:20,480 하지만 여전히 단지 하나의 차원 배열입니다. 689 00:58:20,480 --> 00:58:23,660 그래서 난, 그 배열에 대한 포인터를 할당하고자 할 경우 690 00:58:23,660 --> 00:58:29,770 그러니까 ... 그게 정수 * P = X; 691 00:58:29,770 --> 00:58:33,220 X의 유형은 단지입니다 - 692 00:58:33,220 --> 00:58:38,280 , 그냥 상징이기 때문에 그것은 X의 거친 말하는 타입이고 실제 변수 아닙니다 693 00:58:38,280 --> 00:58:40,140 하지만 그냥 정수 *입니다. 694 00:58:40,140 --> 00:58:44,840 x는 그냥이의 시작에 대한 포인터입니다. >> [학생] 좋아요. 695 00:58:44,840 --> 00:58:52,560 그래서 난 [1] [2]을 (를) 액세스 할 수 없습니다. 696 00:58:52,560 --> 00:58:58,370 나는 특별한 문법은 포인터를 선언 거기에 생각 697 00:58:58,370 --> 00:59:12,480 INT 같은 터무니없는 일이 (* P [-. 말도 안돼 무언가조차 모르겠어요. 698 00:59:12,480 --> 00:59:17,090 그러나 괄호 내고, 물건 같은 포인터를 선언을위한 구문이 있습니다. 699 00:59:17,090 --> 00:59:22,960 심지어 당신이 그렇게하지 ​​못하게 할 수 있습니다. 700 00:59:22,960 --> 00:59:26,640 나는 내게 진실을 말해 줄 수 무언가를 다시 확인 수 있습니다. 701 00:59:26,640 --> 00:59:34,160 포인트 구문이있을 경우, 나중에 찾습니다. 하지만, 당신이 그걸 표시되지 않습니다. 702 00:59:34,160 --> 00:59:39,670 그리고 문법은 당신이 그것을 사용하는 경우, 사람들이 당황 될 정도로 오래된 것입니다. 703 00:59:39,670 --> 00:59:43,540 객관적으로 다차원 배열은 매우 드문 있습니다. 704 00:59:43,540 --> 00:59:44,630 꽤 많이 당신 - 705 00:59:44,630 --> 00:59:48,490 당신은 매트릭스 일을하는 경우 음, 희귀 않을거야 706 00:59:48,490 --> 00:59:56,730 하지만 C에서 당신은 거의 다차원 배열을 사용 할 수 없어하고 있습니다. 707 00:59:57,630 --> 01:00:00,470 그래. >> [학생] 가자 당신은 정말 긴 배열을 말한다. 708 01:00:00,470 --> 01:00:03,900 >> 따라서 가상 메모리에, 모든 연속으로 나타납니다 709 01:00:03,900 --> 01:00:05,640 서로 바로 옆에있는 요소와 같은, 710 01:00:05,640 --> 01:00:08,770 하지만 실제 메모리에 따라 최대 분할 할 그 일에 대한 수 있겠지? >> 예. 711 01:00:08,770 --> 01:00:16,860 메모리 작품이 얼마나 가상 단지 분리 - 712 01:00:19,220 --> 01:00:24,860 할당 단위는 4킬로바이트 경향이 페이지입니다 713 01:00:24,860 --> 01:00:29,680 그래서 프로세스가 말할 때, 이봐 요, 난이 메모리를 사용하려면 714 01:00:29,680 --> 01:00:35,970 운영 체제는 그것을 메모리의 작은 블록 4킬로바이트을 할당 할 것이다. 715 01:00:35,970 --> 01:00:39,100 당신은 단지 메모리의 전체 블록에서 단일 약간 바이트를 사용하더라도 716 01:00:39,100 --> 01:00:42,850 운영 체제는 그것을 전체 4킬로바이트를 제공 할 수 있습니다. 717 01:00:42,850 --> 01:00:49,410 그래서 의미가 무엇인지 그럴 수도 -이 내 스택이라고합시다. 718 01:00:49,410 --> 01:00:53,180 이 스택은 분리 될 수 있습니다. 내 스택은 메가 바이트와 메가바이트 될 수 있습니다. 719 01:00:53,180 --> 01:00:55,020 내 스택은 거대한 될 수 있습니다. 720 01:00:55,020 --> 01:01:00,220 그러나 스택 자체는 개별 페이지로 분할해야합니다 721 01:01:00,220 --> 01:01:09,010 이것이 우리의 RAM 말하는 우리가 여기에 보면 어느합시다, 722 01:01:09,010 --> 01:01:16,600 나는 RAM의 2 기가 바이트가있는 경우,이 내 RAM의 0번째 바이트와 같은 실제 주소 0입니다 723 01:01:16,600 --> 01:01:22,210 이 여기 2기가바이트 쭉 있습니다. 724 01:01:22,210 --> 01:01:27,230 그래서이 페이지는 여기로이 블록에 해당 할 수 있습니다. 725 01:01:27,230 --> 01:01:29,400 이 페이지는 여기로이 블록에 해당 할 수 있습니다. 726 01:01:29,400 --> 01:01:31,560 이 사람은 여기로 대응 할 수 있습니다. 727 01:01:31,560 --> 01:01:35,540 운영 체제는 물리적 메모리를 할당 할 무료입니다 그래서 728 01:01:35,540 --> 01:01:39,320 임의로 개별 페이지에. 729 01:01:39,320 --> 01:01:46,180 그리고 그 의미이 경계선은 배열을 두 다리 쭉 벌리고 타라고 무슨 일이 생긴다면, 730 01:01:46,180 --> 01:01:50,070 배열이 왼쪽 할 일이, 오른쪽 페이지의 주문 731 01:01:50,070 --> 01:01:54,460 해당 배열은 물리적 메모리에 분할 예정이다. 732 01:01:54,460 --> 01:01:59,280 프로세스가 끝날 때 그리고 당신은 프로그램을 종료 할 때, 733 01:01:59,280 --> 01:02:05,690 이 매핑은 삭제하고 다음 다른 일을위한 작은 블록을 사용하는 무료입니다. 734 01:02:14,730 --> 01:02:17,410 더 질문? 735 01:02:17,410 --> 01:02:19,960 [학생] 포인터 연산. >> 오, 그래. 736 01:02:19,960 --> 01:02:28,410 문자열은 쉽게했지만, ints 같은보고 737 01:02:28,410 --> 01:02:35,000 그래서 돌아 가기 INT X [4]; 738 01:02:35,000 --> 01:02:41,810 이 배열인지 여부 또는 4 정수의 malloced 배열의 포인터 일지 739 01:02:41,810 --> 01:02:47,060 이 같은 방법으로 처리 할거야. 740 01:02:50,590 --> 01:02:53,340 따라서 배열은 힙에서 [학생]입니까? 741 01:03:01,400 --> 01:03:05,270 [보덴] 배열은 힙에 없습니다. >> [학생] 오. 742 01:03:05,270 --> 01:03:08,320 >> [보덴] 배열의 이러한 유형의 스택에있을 경향이 743 01:03:08,320 --> 01:03:12,220 하지 않는 한 당신은에서 선언 - 전역 변수를 무시합니다. 전역 변수를 사용하지 마십시오. 744 01:03:12,220 --> 01:03:16,280 내가하는 말은 함수의 내부 INT X [4]; 745 01:03:16,280 --> 01:03:22,520 그것은이 배열 스택에 4 정수 블록을 만들거야. 746 01:03:22,520 --> 01:03:26,960 그러나이 malloc (4 * sizeof (int는)이), 힙에 갈 수 있습니다. 747 01:03:26,960 --> 01:03:31,870 그러나이 시점 후에는 거의 같은 방법으로 x와 P를 사용할 수 있습니다 748 01:03:31,870 --> 01:03:36,140 당신은 P를 다시 할당 할 수 있습니다에 대한 전에 말했다 예외가 아닌. 749 01:03:36,140 --> 01:03:40,960 기술적으로, 그들의 크기는 약간 다릅니다,하지만 완전히 무관입니다. 750 01:03:40,960 --> 01:03:43,310 당신은 실제로 자신의 크기를 사용하지 않습니다. 751 01:03:48,020 --> 01:03:56,810 내가 말할 수있는 P P [3] = 2, 또는 X [3] = 2; 752 01:03:56,810 --> 01:03:59,680 당신은 정확히 같은 방법으로 사용할 수 있습니다. 753 01:03:59,680 --> 01:04:01,570 이제 그럼 포인터 산술 - 예. 754 01:04:01,570 --> 01:04:07,390 [학생]는 당신이 괄호가있는 경우 P *를 수행 할 필요가 없습니다합니까? 755 01:04:07,390 --> 01:04:11,720 괄호는 암시 역 참조입니다. 좋아요 >>. 756 01:04:11,720 --> 01:04:20,200 사실, 또한 당신이와 말하는 것은 당신은 다차원 배열을 얻을 수 있습니다 757 01:04:20,200 --> 01:05:02,650 포인터와 함께, 당신이 할 수있는 것은의 말하자, 뭔가 같은 것입니다, INT ** PP = malloc (sizeof (int는 *) * 5); 758 01:05:02,650 --> 01:05:06,900 난 그냥 모든을 먼저 작성됩니다. 759 01:05:37,880 --> 01:05:41,020 난 하나를 싶지 않았어. 760 01:05:41,020 --> 01:05:42,550 좋아요. 761 01:05:42,550 --> 01:05:48,910 여기 무슨 짓입니다 - 그건 PP [I]해야합니다. 762 01:05:48,910 --> 01:05:53,680 따라서 PP는 포인터에 대한 포인터입니다. 763 01:05:53,680 --> 01:06:02,420 당신은 5 INT 별의 배열을 가리 키도록 PP mallocing하고 있습니다. 764 01:06:02,420 --> 01:06:10,950 따라서 메모리에 당신은 스택 pp.에 있습니다 765 01:06:10,950 --> 01:06:20,150 다 포인터 자체의 5 블록의 배열을 가리 키도록거야. 766 01:06:20,150 --> 01:06:28,210 그리고 때 여기서 내가 malloc 다운, 나는 malloc하시는 분들은 개별 포인터의 각 767 01:06:28,210 --> 01:06:32,080 힙에 4 바이트의 별도의 블록를 가리켜 야합니다. 768 01:06:32,080 --> 01:06:35,870 4 바이트에 따라서이 포인트. 769 01:06:37,940 --> 01:06:40,660 그리고 다른 4 바이트로 이것 가리 킵니다. 770 01:06:40,660 --> 01:06:43,200 >> 그리고 그들 모두는 자신의 4 바이트를 가리 킵니다. 771 01:06:43,200 --> 01:06:49,080 이 나에게 다차원 일을하는 방법을 제공합니다. 772 01:06:49,080 --> 01:06:58,030 나는 PP [3] [4] 지금이 같은 일이 아닙니다와 같은 다차원 배열을 말할 수 773 01:06:58,030 --> 01:07:05,390 다차원 배열은 번역 때문에 [3] [4] X 배열에 오프셋 하나에.주세요 774 01:07:05,390 --> 01:07:14,790 이 dereferences의 P는 dereferences 다음, 세 번째 인덱스를 액세스하는 것 775 01:07:14,790 --> 01:07:20,790 및 접근 - 4가 잘못된거야 - 두 번째 색인을 생성합니다. 776 01:07:24,770 --> 01:07:31,430 반면에 우리가 있었을 때 INT X [3] [4] 다차원 배열로 이전 777 01:07:31,430 --> 01:07:35,740 그리고 브래킷을 두 배로 때, 정말 단 하나의 역 참조입니다 778 01:07:35,740 --> 01:07:40,490 , 당신은 하나의 포인터를 따라 가고 한 다음 오프셋 779 01:07:40,490 --> 01:07:42,850 이거 정말 2D 참조입니다. 780 01:07:42,850 --> 01:07:45,840 당신은 2 개의 포인터를 따르십시오. 781 01:07:45,840 --> 01:07:50,420 이 또한 기술적으로 할 수 있습니다 그래서 당신은 당신의 다차원 배열을 가지고있는 782 01:07:50,420 --> 01:07:53,550 각각의 배열은 서로 다른 크기입니다. 783 01:07:53,550 --> 01:07:58,000 그래서 가변 다차원 배열이이란 생각 784 01:07:58,000 --> 01:08:01,870 정말 가장 먼저 10 요소가 무언가를 가리킬 수 있으므로, 785 01:08:01,870 --> 01:08:05,540 두 번째는 100 요소를 가지고 뭔가를 가리 킵니다 수 있습니다. 786 01:08:05,540 --> 01:08:10,790 [학생]이 (가) 당신이 할 수 포인터의 수에 제한이 있나요 787 01:08:10,790 --> 01:08:14,290 다른 포인터를 가리키는? >> 번호 788 01:08:14,290 --> 01:08:17,010 당신은 INT ***** P 할 수 있습니다. 789 01:08:18,050 --> 01:08:23,760 다시 포인터 연산으로 - >> [학생] 오. >> 그래. 790 01:08:23,760 --> 01:08:35,649 [학생] 내가 그때 INT *** P을 가지고 있다면 나는 dereferencing을 내가 P의 *이 값과 동일하다고, 791 01:08:35,649 --> 01:08:39,560 그것은 단지 dereferencing 1 수준의 일을 할거야? >> 예. 792 01:08:39,560 --> 01:08:43,340 - 그 마지막 포인터가 가리키고 있다는 것을 액세스 할면 793 01:08:43,340 --> 01:08:46,210 그럼 당신은 ***의 P 해. 좋아요 >>. 794 01:08:46,210 --> 01:08:54,080 그래서 1 블록, 다른 블록을 가리키는 또 다른 블록 포인트에 P 점입니다. 795 01:08:54,080 --> 01:09:02,010 당신은 *을하면 다음 P는 = 다른 한 다음이를 변경 796 01:09:02,010 --> 01:09:13,640 이제 다른 블록을 가리 키도록. 좋아요 >>. 797 01:09:13,640 --> 01:09:17,649 >> 이러한이 malloced 된 경우 [보덴]는 그리고 다음 이제 메모리를 유출 한 798 01:09:17,649 --> 01:09:20,430 여러분이 다른 참조가 발생하지 않는 한 799 01:09:20,430 --> 01:09:25,270 당신이 방금 버렸 것을 그 사람에게 올 수없는 때문입니다. 800 01:09:25,270 --> 01:09:29,550 포인터 산술. 801 01:09:29,550 --> 01:09:36,310 INT X [4], 4 정수의 배열을 할당 할 것이다 802 01:09:36,310 --> 01:09:40,670 x는 배열의 시작 부분을 가리 키도록가는 곳. 803 01:09:40,670 --> 01:09:50,420 그럼 언제는 x [1]과 같은 말을, 나는 배열의 두 번째 정수로 이동을 의미 할 804 01:09:50,420 --> 01:09:53,319 어떤이 하나가 될 것입니다. 805 01:09:53,319 --> 01:10:04,190 이 정수는 4 바이트를 차지부터하지만 실제로는, 그 배열로 4 바이트입니다. 806 01:10:04,190 --> 01:10:08,470 1의 오프셋 정말 1의 오프셋을 의미합니다 그래서 807 01:10:08,470 --> 01:10:12,030 배열의 유형은 무엇이든의 시간은 크기입니다. 808 01:10:12,030 --> 01:10:17,170 이 정수의 배열이므로 오프셋하고자 할 때 그 정수의 1 번 크기를 할 알고 있습니다. 809 01:10:17,170 --> 01:10:25,260 다른 구문입니다. 이 * (x + 1)과 동일합니다 기억, 810 01:10:25,260 --> 01:10:35,250 나는 포인터 뭘 그 반환하면 포인터가 저장되어있는 주소입니다 + 1, 말할 때 811 01:10:35,250 --> 01:10:40,360 플러스 1 번 포인터의 타입의 크기입니다. 812 01:10:40,360 --> 01:10:59,510 그래서, 만약 X = ox100 다음, X + 1 = ox104. 813 01:10:59,510 --> 01:11:19,750 그리고 당신이 이것을 악용하고 말을 할 수 숯불 같은 * C = (숯불 *) X, 814 01:11:19,750 --> 01:11:23,050 지금 C는 x와 동일한 주소가 될 것입니다. 815 01:11:23,050 --> 01:11:26,040 C는, ox100 같 될 것입니다 816 01:11:26,040 --> 01:11:31,490 하지만 C + 1 ox101 동일 될 것입니다 817 01:11:31,490 --> 01:11:38,030 포인터 산술 당신이 추가되는 포인터의 종류에 따라 다릅니다 때문입니다. 818 01:11:38,030 --> 01:11:45,390 따라서 C + 1, 이건 C를 바라보고, 그 숯불 포인터이고, 그래서이 문자의 1 번 크기를 추가 할거야 819 01:11:45,390 --> 01:11:48,110 어느 항상 1이 될 것입니다, 그래서 당신은 101를 얻을 820 01:11:48,110 --> 01:11:54,890 난 아직도 100 X을한다면, X + 1은 104이 될 것입니다 반면. 821 01:11:56,660 --> 01:12:06,340 [학생] 당신은 C + + 1하여 포인터를 전진하기 위해 사용할 수 있습니까? 822 01:12:06,340 --> 01:12:09,810 예, 할 수 있습니다. 823 01:12:09,810 --> 01:12:16,180 x는 단지 상징이기 때문에 당신은 X로 그렇게 할 수 없어, 그것은 상수이다, 당신은 X를 변경할 수 없습니다. 824 01:12:16,180 --> 01:12:22,610 >> 그러나 C는 포인터로 발생하므로 C + + 완벽하게 유효하고 1 증가합니다. 825 01:12:22,610 --> 01:12:32,440 C는 단지 정수 *이라면, 다음에 c + + 104 될 것입니다. 826 01:12:32,440 --> 01:12:41,250 + + 않는 포인터 산술 마찬가지로 C + 1 포인터 산술 짓을 한 것 있습니다. 827 01:12:43,000 --> 01:12:48,870 이와 같은 사실은 실제로 병합 정렬 등의 방법이 많이 있습니다 - 828 01:12:49,670 --> 01:12:55,710 대신 물건의 복사본을 만드는 대신 전달할 수 있습니다 - 829 01:12:55,710 --> 01:13:02,400 이 중 일부를 삭제까요? - 나는 배열의 절반을 통과하고자하는 경우처럼. 830 01:13:04,770 --> 01:13:10,520 자, 내가 함수에 배열의 측면을 통과하고 싶어 말한다. 831 01:13:10,520 --> 01:13:12,700 내가 그 함수에 전달할거야? 832 01:13:12,700 --> 01:13:17,050 나는 X를 전달하면,이 주소를 전달하고 있습니다. 833 01:13:17,050 --> 01:13:23,780 하지만이 특정 주소를 전달하고 싶습니다. 그래서 어떻게 통과해야하나요? 834 01:13:23,780 --> 01:13:26,590 [학생] 포인터 + 2? 835 01:13:26,590 --> 01:13:29,350 [보덴] 지금 X + 2. 예. 836 01:13:29,350 --> 01:13:31,620 그래서이 주소거야. 837 01:13:31,620 --> 01:13:42,810 당신은 또한 자주로 볼 수 X [2] 다음 해당의 주소. 838 01:13:42,810 --> 01:13:47,850 그래서 브래킷이 암시 적 역 참조하기 때문에 그것의 주소를해야합니다. 839 01:13:47,850 --> 01:13:53,250 X [2],이 상자에 값을 참조하고 해당 상자의 주소를 원하는 840 01:13:53,250 --> 01:13:56,850 그래서 당신은 말 & X [2]. 841 01:13:56,850 --> 01:14:02,880 그럼 자네가 뭔가를 절반 목록을 전달하려는 병합 정렬의 방법은 뭔가 842 01:14:02,880 --> 01:14:08,790 당신이 정말로 그러고 & X [2], 지금까지 재귀 호출에 관한 한, 843 01:14:08,790 --> 01:14:12,510 나의 새로운 배열이 시작됩니다. 844 01:14:12,510 --> 01:14:15,130 마지막 분 질문입니다. 845 01:14:15,130 --> 01:14:20,050 [학생] 우리는 앰퍼샌드를 게시하거나하지 않은 경우 - 그게 뭐였죠? >> 스타? 846 01:14:20,050 --> 01:14:23,200 [학생] 스타. >> 기술적으로 역 참조 연산자,하지만 ... - >> [학생] 역 참조. 847 01:14:23,200 --> 01:14:29,310 >> 우리가 스타 앰퍼샌드를 넣어하지 않는 경우 그냥 y를 말한다면 어떤 일이 벌어 질까요 = x와 X 포인터입니까?주세요 848 01:14:29,310 --> 01:14:34,620 y의 유형은 무엇입니까? >> [학생] 방금 그건 포인터 2를 말할 수 있습니다. 849 01:14:34,620 --> 01:14:38,270 당신은 말하려면 Y = X, 지금 x와 y 포인트 같은합니다. >> 같은에 [학생] 가리 킵니다. 850 01:14:38,270 --> 01:14:45,180 그리고 x는 정수 포인터가있는 경우? 당신은 포인터를 할당 할 수 없기 때문에 >>이 불평합니다. 851 01:14:45,180 --> 01:14:46,540 [학생] 좋아. 852 01:14:46,540 --> 01:14:51,860 우리가 화살표로 그려에도 해당 포인터를 기억 853 01:14:51,860 --> 01:15:02,010 정말 모든 사람들이 상점 - 정수 * X - 정말 모든 x가 저장되며, ox100 같은 것이지 854 01:15:02,010 --> 01:15:06,490 있는 우리는 100 저장된 블록을 가리키는로 표현하기 위해 발생합니다. 855 01:15:06,490 --> 01:15:19,660 그래서 말을 할 때 INT * Y = X, 난 그냥 Y로 ox100을 복사 해 856 01:15:19,660 --> 01:15:24,630 있는 우리는 또한 ox100을 가리키는, y로 나타냅니다거야. 857 01:15:24,630 --> 01:15:39,810 그리고 말한다면, INT I = (INT) ×, 그럼 내가 ox100의 값이 뭐든간에 저장 것입니다 858 01:15:39,810 --> 01:15:45,100 그것의 내부하지만, 지금은 대신 포인터의 정수로 해석 될거야. 859 01:15:45,100 --> 01:15:49,310 하지만 당신은 캐스트가 필요하거나 다른이 불평합니다. 860 01:15:49,310 --> 01:15:53,300 [학생] 그래서 당신은 주조 건가요? - 861 01:15:53,300 --> 01:16:00,290 는 Y의 X 또는 주조 INT의 정수를 캐스팅 할 예정입니까? 862 01:16:00,290 --> 01:16:03,700 [보덴 뭐? 863 01:16:03,700 --> 01:16:07,690 [학생] 좋아. 이 괄호 이후에는 X 또는이 불안하실 건가요? 864 01:16:07,690 --> 01:16:11,500 >> [보덴]도. x와 y는 같습니다. >> [학생] 좋아요. 865 01:16:11,500 --> 01:16:14,390 그 둘은 포인터니까. >> 그래. 866 01:16:14,390 --> 01:16:21,050 [학생] 지금은 정수 형태로 16 진수 100을 저장까요? >> [보덴] 그래. 867 01:16:21,050 --> 01:16:23,620 그러나이을 가리키는대로의 값입니다. 868 01:16:23,620 --> 01:16:29,940 [보덴] 그래. >> [학생] 지금 정수 형식으로 만 주소. 좋아요. 869 01:16:29,940 --> 01:16:34,720 당신은 어떤 기괴한 이유에 원 [보덴] 경우 870 01:16:34,720 --> 01:16:38,900 당신은 독점적 포인터 처리와 정수 처리 수 없었 871 01:16:38,900 --> 01:16:49,240 불과 INT * X = 0처럼. 872 01:16:49,240 --> 01:16:53,000 그런 다음 포인터 연산이 일어나는 시작되면 정말 혼란스러워 할거야. 873 01:16:53,000 --> 01:16:56,570 그래서 그들은 저장하는 숫자는 의미입니다. 874 01:16:56,570 --> 01:16:58,940 그것은 당신이 그들을 해석 결국 그냥 방법은 다음과 같습니다. 875 01:16:58,940 --> 01:17:02,920 그래서, int로 int는 *에서 ox100를 복사 할 자유 다 876 01:17:02,920 --> 01:17:07,790 아마도 캐스팅하지 못한 화가나 것 같으니 - 그리고 난 할당 할 자유 야 - 877 01:17:07,790 --> 01:17:18,160 이 임의의 정수를 *로 (INT *) ox1234 같은 무언가를 할당 할 무료입니다. 878 01:17:18,160 --> 01:17:25,480 그럼 ox123에 유효한 메모리 주소가 아니라 & Y 불과으로합니다. 879 01:17:25,480 --> 01:17:32,060 & y는 거의 ox123이 무언가를 반환하는 발생합니다. 880 01:17:32,060 --> 01:17:35,430 [학생]은 그 진수의 소수점 형태로 이동하는 정말 멋진 방법이 될 줄래? 881 01:17:35,430 --> 01:17:39,230 당신은 포인터가 있으면 좋아하고 당신은 정수로 캐스팅? 882 01:17:39,230 --> 01:17:44,860 [보덴] 당신은 단지 printf처럼 사용하는 인쇄 할 수 있습니다. 883 01:17:44,860 --> 01:17:50,300 자, 내가 INT Y = 100가 있다고 가정 해 봅시다. 884 01:17:50,300 --> 01:18:02,700 따라서 printf (% d 개 \ N - 이미 알다시피 - 인쇄와 같은 정수, %의 X. 885 01:18:02,700 --> 01:18:05,190 우리는 단지 진수로 인쇄됩니다. 886 01:18:05,190 --> 01:18:10,760 그래서 포인터는, 16 진수로 저장되지 않습니다 887 01:18:10,760 --> 01:18:12,960 와 정수는 십진수로 저장되지 않습니다. 888 01:18:12,960 --> 01:18:14,700 모든 바이너리로 저장됩니다. 889 01:18:14,700 --> 01:18:17,950 우리가 진수로 포인터를 표시하는 경향이 단지 890 01:18:17,950 --> 01:18:23,260 우리는이 4 바이트 블록의 일을 생각하기 때문에 891 01:18:23,260 --> 01:18:25,390 및 메모리 주소는 알고 있어야하는 경향이 있습니다. 892 01:18:25,390 --> 01:18:28,890 가 BF로 시작하는 경우, 그것은 스택에 있다는데처럼 우리는하고 있습니다. 893 01:18:28,890 --> 01:18:35,560 그럼 그냥 진수로 포인터 우리의 해석입니다. 894 01:18:35,560 --> 01:18:39,200 좋아요. 마지막으로 질문 있나요? 895 01:18:39,200 --> 01:18:41,700 >> 당신은 다른 일이있을 경우 후에 잠시 여기있을거야. 896 01:18:41,700 --> 01:18:46,070 그래서 그 끝입니다. 897 01:18:46,070 --> 01:18:48,360 >> [학생] 야호! [박수] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]