1 00:00:00,000 --> 00:00:02,500 [Powered by Google Translate] [제 5 - 더 편안한] 2 00:00:02,500 --> 00:00:04,690 [롭 보덴 - 하버드 대학교 (Harvard University)] 3 00:00:04,690 --> 00:00:07,250 [이 CS50입니다. - CS50.TV] 4 00:00:08,990 --> 00:00:14,250 >> 내 이메일에 말씀 드렸듯이, 당신이 사용할 수있는 일들이 많이 있습니다 5 00:00:14,250 --> 00:00:17,060 실제로 문제 세트를 수행 할 수있는 기기가 아닌. 6 00:00:17,060 --> 00:00:19,910 우리는 우리가 더 쉽게 당신을 도울 수해서 사용하면 어플라이언스에서 수행하는 것이 좋습니다 7 00:00:19,910 --> 00:00:22,070 우리는 모든 일 것입니다 방법을 알고. 8 00:00:22,070 --> 00:00:26,950 그러나 말한다면 당신이 일을 할 수있는 곳 중 하나가 예를 들어, 당신은 권한이 없습니다 9 00:00:26,950 --> 00:00:31,570 어플라이언스에하거나 과학 센터 지하에서 일하려면 - 10 00:00:31,570 --> 00:00:33,090 어떤 사실 그들도 어플라이언스가 - 11 00:00:33,090 --> 00:00:35,150 어디서든 작업 할 경우. 12 00:00:35,150 --> 00:00:42,370 하나의 예를 들어 당신은 본적이 / SSH를 들어 본 적이있다? 13 00:00:44,380 --> 00:00:47,780 SSH는 뭔가에 연결처럼 기본적으로 있습니다. 14 00:00:47,780 --> 00:00:51,340 사실, 지금 나는 어플라이언스에 SSHed거야. 15 00:00:51,340 --> 00:00:54,290 나는이 어플라이언스에 직접 작동하지 않습니다. 16 00:00:55,930 --> 00:01:01,060 여기 어플라이언스이며, 여기에 보면이 IP 주소를 참조하십시오. 17 00:01:01,060 --> 00:01:03,650 나는 어플라이언스의 자체에서 일할 수 없을; 18 00:01:03,650 --> 00:01:08,840 항상 iTerm2 창 / 터미널 창으로 있습니다. 19 00:01:08,840 --> 00:01:15,910 당신은 IP 주소, SSH jharvard@192.168.129.128에 SSH 할 수 있습니다. 20 00:01:15,910 --> 00:01:20,390 그러한 좋은 패턴이기 때문에 매우 쉽게 번호를 기억 해요. 21 00:01:20,390 --> 00:01:24,920 하지만 그건 제 암호를 물어 것이며, 지금은 어플라이언스에있어. 22 00:01:24,920 --> 00:01:33,060 기본적으로,이 시점에서, 경우는 기기 자체의 내부 터미널을 열어 23 00:01:33,060 --> 00:01:36,350 이 인터페이스는, 그러나 당신이 그것을 사용할 정확히 동일합니다 24 00:01:36,350 --> 00:01:40,010 인터페이스로 전 여기 사용하지만 이제 당신 SSHed하고 있습니다. 25 00:01:42,240 --> 00:01:44,920 당신은 어플라이언스에 SSH 할 필요가 없습니다. 26 00:01:44,920 --> 00:01:52,360 에게 당신은 수 SSH 다른 곳의 한 예는 당신이 기본적으로 가지고 확신입니다 - 27 00:01:52,360 --> 00:01:55,020 오. 큰. 28 00:01:55,020 --> 00:02:01,130 당신의 모든 FAS 서버의 기본 FAS 계정이 있어야합니다. 29 00:02:01,130 --> 00:02:06,840 나에게, 나 SSH는 rbowden@nice.fas.harvard.edu 싶습니까. 30 00:02:06,840 --> 00:02:11,610 당신의 그 처음 물을 거예요, 그리고 네 말한다. 31 00:02:11,610 --> 00:02:15,840 비밀번호 그냥 내 FAS 비밀번호 될 것입니다. 32 00:02:15,840 --> 00:02:22,650 그리고 지금, 나는 좋은 서버에 SSHed, 나는 여기에서 원하는 무엇이든 할 수 있습니다. 33 00:02:22,650 --> 00:02:28,560 당신은 124와 같이 걸릴 수 있습니다 클래스의 많은, 여기에 콘텐츠를 업로드 할 거예요 34 00:02:28,560 --> 00:02:30,950 실제로 문제 세트를 제출합니다. 35 00:02:30,950 --> 00:02:34,100 그러나이 어플라이언스에 액세스 할 수 없습니다 말한다. 36 00:02:34,100 --> 00:02:37,910 그럼 당신은 일을 할 수있다 여기서처럼 말 것 - 37 00:02:37,910 --> 00:02:42,160 이건 그냥 질문에 우리의 섹션입니다. 38 00:02:42,160 --> 00:02:45,070 이 어플라이언스에이 작업을 수행하라는 메시지가 표시됩니다. 39 00:02:45,070 --> 00:02:47,790 대신 난 그냥 서버에서 할 수 있습니다. 40 00:02:47,790 --> 00:02:50,560 난 압축을 풀고거야. 41 00:02:50,560 --> 00:02:55,670 문제는 당신이 gedit 같은 것을 사용하여 사용중인 될 것입니다 42 00:02:55,670 --> 00:02:58,160 어플라이언스의 또는 무엇이든 내부. 43 00:02:58,160 --> 00:03:01,830 당신은 FAS 서버에 해당이되지 않을 꺼예요. 44 00:03:01,830 --> 00:03:04,110 모든 게이 텍스트 인터페이스거야. 45 00:03:04,110 --> 00:03:09,180 그래서, 그들은이 있다는 텍스트 편집기 내용 중 하나 시도 수 있습니다. 46 00:03:09,180 --> 00:03:12,130 그들은 나노가 있습니다. 47 00:03:12,130 --> 00:03:14,990 나노는 일반적으로 사용하기 매우 편리합니다. 48 00:03:14,990 --> 00:03:19,470 귀하의 화살표를 사용하여 정상적으로 입력 할 수 있습니다. 49 00:03:19,470 --> 00:03:21,250 그래서 열심히 아닙니다. 50 00:03:21,250 --> 00:03:24,720 당신이 정말로 멋진 싶은 경우, 이맥스를 사용할 수 있습니다 51 00:03:24,720 --> 00:03:29,850 나는 심지어 이맥스을 닫는 방법을 알고하지 않기 때문에 어느 아마도 열 사람이 아니란 것입니다. 52 00:03:29,850 --> 00:03:32,760 제어 X, 제어 C? 그래. 53 00:03:32,760 --> 00:03:35,310 아니면 내가 사용하는 무엇 VIM을 사용할 수 있습니다. 54 00:03:35,310 --> 00:03:37,800 그리고 그 귀하의 옵션이 있습니다. 55 00:03:37,800 --> 00:03:43,830 네가 그렇게하지 ​​않으면 또한, 당신은 보면 manual.cs50.net .. - 56 00:03:43,830 --> 00:03:45,410 오. 57 00:03:45,410 --> 00:03:49,920 PC에서는 SSH는 퍼티를 사용하여 수 58 00:03:49,920 --> 00:03:51,940 당신은 별도로 다운로드해야 할거야된다. 59 00:03:51,940 --> 00:03:55,460 Mac에서는, 당신은 단지 기본 사용 터미널 또는 당신은 iTerm2을 다운로드 할 수 있습니다 수 60 00:03:55,460 --> 00:03:58,490 이는 좋은, 멋진 터미널과 같은 것입니다. 61 00:03:58,490 --> 00:04:03,780 당신이 manual.cs50.net로 이동합니다 경우 메모장에 대한 링크를 볼 수 있습니다 + +, 62 00:04:03,780 --> 00:04:07,120 이는 당신이 PC에 사용할 수 있습니다. 63 00:04:07,120 --> 00:04:13,340 이 메모장에서 당신은 SFTP 수 있습니다 + +, 이는 기본적으로 SSH입니다. 64 00:04:13,340 --> 00:04:17,750 이게 당신이하게 될 것은 로컬 파일을 편집합니다 65 00:04:17,750 --> 00:04:20,670 그리고 당신이 그들을 저장할 때마다 그것은 nice.fas에 저장됩니다 66 00:04:20,670 --> 00:04:23,670 당신은 그것들을 실행할 수있는. 67 00:04:23,670 --> 00:04:26,880 그리고 Mac에서 이에 상응하는 TextWrangler 될 것입니다. 68 00:04:26,880 --> 00:04:28,760 그래서 당신이 같은 일을 수행 할 수 있습니다. 69 00:04:28,760 --> 00:04:32,800 지금 당신은 로컬 파일을 편집하고 nice.fas에 저장 할 수 있습니다 70 00:04:32,800 --> 00:04:35,730 당신은 그것들을 실행할 수있는. 71 00:04:35,730 --> 00:04:40,400 당신은 어느 기기없이 붙어있는 경우 그럼,이 옵션을 사용할 수 있습니다 72 00:04:40,400 --> 00:04:44,230 문제 세트를 계속합니다. 73 00:04:44,230 --> 00:04:48,250 한 문제는 CS50 라이브러리가 않을 거라고 될 것입니다 74 00:04:48,250 --> 00:04:51,580 nice.fas은 기본적으로 그렇게하지 ​​않기 때문에. 75 00:04:51,580 --> 00:04:55,970 당신도 CS50 라이브러리를 다운로드 할 수 있습니다 - 76 00:04:55,970 --> 00:04:58,470 나는이 시점에서 그 필요하다고 생각하지 않습니다. 77 00:04:58,470 --> 00:05:03,270 당신도 CS50 라이브러리를 다운로드하여 nice.fas에 이상 복사 할 수 있습니다 78 00:05:03,270 --> 00:05:07,450 아니면 내가이 시점에서 우리는 어차피 더 이상 사용하지 않습니다 생각합니다. 79 00:05:07,450 --> 00:05:12,720 우리가 할 경우 또는 시간으로 대체되고 있습니다 80 00:05:12,720 --> 00:05:18,480 어쨌든 CS50 라이브러리에있는 함수의 구현. 81 00:05:18,480 --> 00:05:21,370 그래서 그런 제한의 정도 안됩니다. 82 00:05:21,370 --> 00:05:23,710 그리고 했어. 83 00:05:26,460 --> 00:05:29,820 >> 지금은 어플라이언스으로 데려 갈 테니, 우리는 어플라이언스에 모든 걸 할게요. 84 00:05:29,820 --> 00:05:37,510 내 이메일에 말처럼, 처음에, 질문 우리의 절을 보면, 85 00:05:37,510 --> 00:05:43,620 우리는 당신이보고하기로 한 짧은 하나에 대해 이야기해야합니다. 86 00:05:43,620 --> 00:05:51,980 우리는 리디렉션 및 파이프 이러한 세 가지 질문이 있습니다. 87 00:05:51,980 --> 00:05:56,070 >> 할 스트림과 같은 기능은 printf 기본적으로 작성해야합니까? 88 00:05:56,070 --> 00:05:59,130 스트림 그럼. 스트림은 무엇입니까? 89 00:06:06,520 --> 00:06:15,100 그냥 어떤 것 스트림은 기본적이다 - 90 00:06:15,100 --> 00:06:21,450 심지어 1 초와 0s의 원천이 아니야. 91 00:06:21,450 --> 00:06:24,920 여기 부탁 스트림은 표준 부족합니다. 92 00:06:24,920 --> 00:06:27,250 그리고 표준 아웃은 스트림 당신이 그것에게 쓸 때 93 00:06:27,250 --> 00:06:30,940 이 화면에 나타납니다. 94 00:06:30,940 --> 00:06:36,860 표준 아웃은 스트림에 의해, 당신이 단지 1 초와 거기에 0s 쓰고 95 00:06:36,860 --> 00:06:40,220 및 표준 밖으로의 다른 쪽 끝을 그냥 스트림에서 읽습니다. 96 00:06:40,220 --> 00:06:43,540 단지 1 초와 0s의 문자열입니다. 97 00:06:43,540 --> 00:06:45,570 당신은 스트림에 쓸하거나 스트림에서 읽을 수 있습니다 98 00:06:45,570 --> 00:06:47,950 스트림이 실제로 무엇인지에 따라 다릅니다. 99 00:06:47,950 --> 00:06:52,800 다른 두 기본 스트림과 표준 오류의 표준입니다. 100 00:06:52,800 --> 00:06:57,540 당신은 GetString 수행 할 때마다의 표준은, 당신에 대한 입력 걸을 기다리고있어. 101 00:06:57,540 --> 00:07:01,570 그래서 당신을 위해 기다리고, 사실에 표준을 기다리고있어 102 00:07:01,570 --> 00:07:04,880 이것은 당신이 키보드에 입력 할 때 이런 기분 정말입니다. 103 00:07:04,880 --> 00:07:07,530 당신이 꼭 표준에 입력하는 104 00:07:07,530 --> 00:07:10,050 표준 오류, 표준 글쓰기 기본적으로 동일합니다 105 00:07:10,050 --> 00:07:13,280 당신이 표준 오류로 인쇄하면하지만, 그 전문입니다 106 00:07:13,280 --> 00:07:16,770 당신은 그것에 오류 메시지를 인쇄해야하는 107 00:07:16,770 --> 00:07:20,200 그래서 당신은 화면에 인쇄 정기적으로 메시지를 구별 할 수 있습니다 108 00:07:20,200 --> 00:07:24,560 그들은 표준 출력이나 표준 오류에 가서 여부에 따라 오류 메시지 대. 109 00:07:24,560 --> 00:07:28,660 너무 파일이 있습니다. 110 00:07:28,660 --> 00:07:32,440 표준 아웃에서 표준 및 표준 오류, 그냥 특별한 스트림 아르 111 00:07:32,440 --> 00:07:36,810 하지만 정말 모든 파일은, 당신은 파일을 열 때, 그것은 바이트의 스트림이된다 112 00:07:36,810 --> 00:07:40,740 어디 그 스트림에서 읽을 수 있습니다. 113 00:07:40,740 --> 00:07:47,770 당신은 대부분의 단지 바이트 스트림으로 파일을 생각할 수 있습니다. 114 00:07:47,770 --> 00:07:51,190 그래서 스트림은 기본적으로로 작성하려면 어떻게해야합니까? 표준 아웃. 115 00:07:51,190 --> 00:07:56,980 >> >와 >> 사이의 차이점은 무엇입니까? 116 00:07:58,140 --> 00:08:03,710 사람이 미리 동영상을 감상나요? 좋아요. 117 00:08:03,710 --> 00:08:10,960 >는, 당신이 파일로 리디렉션하는 방법이 될 것입니다 118 00:08:10,960 --> 00:08:15,240 그리고 >> 또한, 파일로 출력을 리디렉션하는 것이다 119 00:08:15,240 --> 00:08:17,820 하지만 대신 파일에 추가 할거야. 120 00:08:17,820 --> 00:08:23,430 예를 들어, 주자 나, 여기 DICT가 생긴다고 121 00:08:23,430 --> 00:08:27,020 그리고 DICT 내부 유일한 물건은 고양이, 고양이, 개, 물고기, 개입니다. 122 00:08:27,020 --> 00:08:31,530 당신은 커맨드 라인에서 가지고 하나의 명령은, 고양이 123 00:08:31,530 --> 00:08:34,539 이는 단지 파일에 어떤 인쇄 할 것이다. 124 00:08:34,539 --> 00:08:40,679 그래서 고양이 DICT 말을 할 때, 고양이, 고양이, 개, 물고기, 개를 인쇄 할거야. 그게 전부 고양이가 수행입니다. 125 00:08:40,679 --> 00:08:46,280 그게 고양이, 고양이, 개, 물고기, 개 밖에 표준 출력을 의미합니다. 126 00:08:46,280 --> 00:08:53,240 내가 대신 파일로 그를 리디렉션 할 수 있다면 사용>와 파일이 뭐든간에으로 리디렉션 할 수 있습니다. 127 00:08:53,240 --> 00:08:56,460 나는 파일을 파일을 호출합니다. 128 00:08:56,460 --> 00:09:00,320 제가 혹시 있다면 이제, 제가 파일을라는 새 파일을 볼 수 있습니다. 129 00:09:00,320 --> 00:09:05,700 내가 열한다면, 그것은 고양이가 커맨드 라인에서 넣어 정확하게 할거야. 130 00:09:05,700 --> 00:09:11,040 다시는 그렇게 됐다면, 다음, 파일에 출력을 리디렉션하는거야 131 00:09:11,040 --> 00:09:13,930 와 같은 정확한 일을하지 않을 수 없네요. 132 00:09:13,930 --> 00:09:17,910 따라서 기술적으로는 완전히 우리가했던 일 overrode. 133 00:09:17,910 --> 00:09:22,970 그리고 DICT을 변경하는 경우 우리가 볼거야, 개를 꺼냈다. 134 00:09:22,970 --> 00:09:29,980 다시 파일에 우리 고양이가 DICT 경우, 우리는 개를 삭제 한 새로운 버전을거야. 135 00:09:29,980 --> 00:09:32,400 그래서 완전히 무시합니다. 136 00:09:32,400 --> 00:09:36,640 우리가 >> 사용하는 경우 대신, 그것은 파일을 추가 할거야. 137 00:09:36,640 --> 00:09:40,860 이제 파일을 여는, 우리는 두 번 인쇄 단지 같은 일을해야 볼 수 138 00:09:40,860 --> 00:09:44,920 그것은 한 번가있어서, 우리는 원래에 추가. 139 00:09:44,920 --> 00:09:48,130 그럼 그 무엇>와 >>는 않습니다. 140 00:09:48,130 --> 00:09:50,580 다음 묻지 않는다 - 이건에 대해 문의하지 않습니다. 141 00:09:50,580 --> 00:09:59,050 >> 우리가하는 다른 하나는 표준 아웃을 리디렉션 <경우>입니다 142 00:09:59,050 --> 00:10:01,970 <표준을 인치로 리디렉션 할 것입니다 143 00:10:01,970 --> 00:10:12,050 우리가 예를 들어이 있으면 봅시다. 144 00:10:14,750 --> 00:10:16,930 한 실제 빠른을 작​​성할 수 있습니다. 145 00:10:17,870 --> 00:10:25,700 의 어떤 파일, hello.c를 보자. 146 00:10:56,060 --> 00:10:59,070 비교적 간단 파일입니다. 147 00:10:59,070 --> 00:11:03,570 난 그저 내가 방금 입력 한 문자열은 이었든 "안녕하세요"를 인쇄 한 다음 문자열을 받고거야. 148 00:11:03,570 --> 00:11:07,990 그럼,여보세요하고 확인. /. 149 00:11:07,990 --> 00:11:10,720 이제 뭔가를 입력하라고 메시지거야 150 00:11:10,720 --> 00:11:15,070 그 말은 인치 표준에 입력 할 일을 기다리고있어 의미 151 00:11:15,070 --> 00:11:20,450 그래서 우리는 단지 롭 안녕하세요, 무슨 말을 인치 나 표준에 원하는 입력! 152 00:11:20,450 --> 00:11:23,310 그럼, 안녕 아웃 표준에 로브를 인쇄거야! 153 00:11:23,310 --> 00:11:28,860 나는. / 인사 한 후 리디렉션 할 경우 154 00:11:30,740 --> 00:11:34,310 지금 당신은 단지 파일에서 리디렉션 할 수 있습니다. 155 00:11:34,310 --> 00:11:41,720 나는 일부 파일, TXT에 넣어, 나는, 롭 넣어면 156 00:11:41,720 --> 00:11:52,300 내 안부 실행 한 다음에 파일을 TXT를 리디렉션하는 경우. / 안녕하세요, 롭, 인사거야! 즉시. 157 00:11:52,300 --> 00:11:57,160 그것은 먼저 GetString 수 없게은에 표준을 기다리고있어 때 158 00:11:57,160 --> 00:12:01,730 의 표준 입력하게 ​​할 데이터의 키보드에서 기다리고 더 이상 사용할 수 없습니다. 159 00:12:01,730 --> 00:12:05,980 대신, 우리는 파일을 TXT를 읽는의 표준 이동합니다. 160 00:12:05,980 --> 00:12:10,290 그리고 이제, 그냥 선 로브 파일 TXT에서 읽을거야 161 00:12:10,290 --> 00:12:13,380 다음은 안녕하세요, 롭를 인쇄 할거야! 162 00:12:13,380 --> 00:12:18,180 그리고 내가하고 싶은 경우, 또 할 수있는. / 안녕하세요 00:12:21,500 그리고 표준 그걸 안녕하세요, 그렇지의 인쇄, 롭!, 164 00:12:21,500 --> 00:12:24,700 나는 그것의 자신의 파일에 해당 리디렉션 할 수 있습니다. 165 00:12:24,700 --> 00:12:29,790 난 그냥 인사 파일을 전화 할게 - 아니, 난 안 하겠어, 그 실행 파일이기 때문에 - txt2. 166 00:12:29,790 --> 00:12:40,150 이제 txt2는 헬로 될 것입니다. / 안녕하세요 00:12:43,520 >> 질문이 있으십니까? 168 00:12:45,900 --> 00:12:49,090 >> 좋아요. 그래서 여기에 우리는 파이프 라인을 갖추고 있습니다. 169 00:12:49,090 --> 00:12:53,510 파이프 리디렉션의 마지막 단위입니다. 170 00:12:53,510 --> 00:12:58,750 >> 오. 나는 리디렉션을 한번 더 유닛 경우 대신 이네요>는 2 일> 171 00:12:58,750 --> 00:13:01,070 그 표준 오류를 리디렉션있어. 172 00:13:01,070 --> 00:13:06,280 일이 표준 오류에 갔다면, 그것은 txt2으로 쓰지 않습니다. 173 00:13:06,280 --> 00:13:12,480 하지만 2>를하지 않으면 발견하고 그것은 여전히​​ 롭여보세요를 인쇄거야! 명령 줄 174 00:13:12,480 --> 00:13:18,600 나는 단지 표준 오류 리디렉션하는거야 때문에, 나는 표준을 리디렉션 아니에요. 175 00:13:18,600 --> 00:13:22,210 표준 오류 및 표준 출력이 다릅니다. 176 00:13:24,210 --> 00:13:27,080 당신은 실제로 표준 오류에 기록하고 싶었 경우 177 00:13:27,080 --> 00:13:35,080 그럼 내가 STDERR to fprintf 할이 변경 될 수 있습니다. 178 00:13:35,080 --> 00:13:37,850 따라서 printf 기본적으로 표준 곳으로 출력합니다. 179 00:13:37,850 --> 00:13:41,720 제가 수동으로 표준 오류에 인쇄하려는 경우 그럼 내가 fprintf 이용해야 180 00:13:41,720 --> 00:13:45,010 내가에 인쇄하고자하는 지정합니다. 181 00:13:45,010 --> 00:13:49,720 대신 나는 fprintf STDOUT 짓을한다면, 그 printf에 기본적으로 동등한입니다. 182 00:13:49,720 --> 00:13:55,530 그러나 fprintf 표준 오류합니다. 183 00:13:57,790 --> 00:14:03,650 그래서 지금, 내가 txt2에이 방향을 바꾸는 경우,여보세요, 아버지! 여전히 커맨드 라인에서 인쇄하는데 184 00:14:03,650 --> 00:14:08,270 그것은 표준 오류에 인쇄지고, 난 단지 표준을 리디렉션하는거야 때문입니다. 185 00:14:08,270 --> 00:14:16,420 지금 표준 오류를 리디렉션하는 경우, 지금이 인쇄되지 않은, 그리고 txt2가, 안녕 롭 될 것입니다! 186 00:14:16,420 --> 00:14:21,910 이제, 당신은 표준 오류로 실제 오류를 인쇄 할 수 있습니다 187 00:14:21,910 --> 00:14:24,720 과 표준 출력에 정기적으로 메시지를 인쇄 할 수 있습니다. 188 00:14:24,720 --> 00:14:31,420 그리고 당신이 프로그램을 실행하므로 때 2 인사 이러한 종류로 실행합니다. / 수> 189 00:14:31,420 --> 00:14:33,800 프로그램은 정상적으로 실행 것입니다 수 있도록 190 00:14:33,800 --> 00:14:38,400 하지만 당신을 얻을 오류 메시지가 귀하의 오류 로그에서 나중에 확인하실 수 있습니다 191 00:14:38,400 --> 00:14:44,500 오류 있도록 한 후 나중에 볼 및 오류 파일이 일어난 오류를해야합니다. 192 00:14:45,200 --> 00:14:47,540 >> 질문이 있으십니까? 193 00:14:47,540 --> 00:14:58,070 >> 마지막 하나는 한 명령의 표준을 뽑아내는 등의 방법으로 생각할 수 파이프입니다 194 00:14:58,070 --> 00:15:01,210 하고 다음 명령에서 표준 만들기. 195 00:15:01,210 --> 00:15:05,570 예를 들어 여기에 에코는 명령 줄 것입니다 196 00:15:05,570 --> 00:15:11,840 그 단지는 인자로 넣어 어떤 반향 것입니다. 나는 따옴표를 넣어하지 않습니다. 197 00:15:11,840 --> 00:15:16,150 에코 나불 나불는 어쩌구는, 어쩌구 저쩌구를 인쇄하는 것이다. 198 00:15:16,150 --> 00:15:20,600 전에 말했듯 때 txt 파일로 로브를 넣어했습니다 199 00:15:20,600 --> 00:15:28,830 나는 단지 txt 파일을 리디렉션 대신 할 수 있기 때문에, / 나는 로브를 반향하는 경우 200 00:15:28,830 --> 00:15:35,520 그리고 파이프 그것을에. /여보세요, 또한 일을 같은 유형을 다할 것입니다. 201 00:15:35,520 --> 00:15:39,160 이이 명령의 출력, 에코 롭을하고있다 202 00:15:39,160 --> 00:15:43,610 과에 대한 입력으로 사용합니다. / 안녕하세요. 203 00:15:44,790 --> 00:15:49,560 귀하는 먼저 파일에 에코 롭을 리디렉션 그것을 생각할 수 204 00:15:49,560 --> 00:15:54,160 그리고. / 안녕하세요 해당 파일에 입력 단 출력 거죠. 205 00:15:54,160 --> 00:15:57,850 그러나 그림의 임시 파일을 꺼낸다. 206 00:16:01,890 --> 00:16:04,460 >> 그 질문 있나? 207 00:16:04,460 --> 00:16:07,150 >> 다음 질문이 포함 예정이다. 208 00:16:07,150 --> 00:16:15,310 어떤 파이프 라인은 당신이 names.txt라는 파일에 고유 한 이름의 수를 찾기 위해 사용할 수? 209 00:16:15,310 --> 00:16:24,160 우리가 여기서 사용하고자 할거야 명령은 독특한, 그래서 uniq하고 화장실입니다. 210 00:16:24,160 --> 00:16:28,840 당신은 실제로 그 무엇을 보는 사람이 uniq을 수행 할 수 211 00:16:28,840 --> 00:16:34,840 그리고는 그냥 입력에서 옆에 일치하는 행을 필터링 할거야. 212 00:16:34,840 --> 00:16:40,690 그리고 남자 화장실은 줄 바꿈, 단어, 각 파일에 대한 바이트 수를 인쇄 할 것이다. 213 00:16:40,690 --> 00:16:43,760 그리고 우리가 사용하고자 할거야 마지막 하나는 일종의 214 00:16:43,760 --> 00:16:47,410 이는 단지 txt 파일의 행을 정렬 할 것이다. 215 00:16:47,410 --> 00:16:58,080 좀 txt 파일, names.txt을 만들고 그 로브, 토미, 요셉, 토미, 요셉, RJ, 로브,면 216 00:16:58,080 --> 00:17:03,910 내가 여기서하고 싶은 것은이 파일에서 고유 한 이름의 번호를 찾을 수 있습니다. 217 00:17:03,910 --> 00:17:08,750 그래서 답은 무엇이어야 하는가? >> [학생] 4. >> 그래. 218 00:17:08,750 --> 00:17:13,780 그것은 롭, 토미, 조셉부터 4 여야합니다, RJ이 파일에서 유일한 고유 한 이름입니다. 219 00:17:13,780 --> 00:17:20,180 첫 번째 단계, 난 그냥 names.txt에 단어 수를하면, 220 00:17:20,180 --> 00:17:24,290 이 사실은 나에게 모든 걸 얘기하고 있습니다. 221 00:17:24,290 --> 00:17:32,560 이와 같은 사실은 실제로 인쇄입니다 - 뉴 라인, 단어, 바이트 수 - 남자 화장실, 보자. 222 00:17:32,560 --> 00:17:38,270 나는 단지 라인에 관심 있다면, 난 그냥 WC-난 names.txt을 수행 할 수 있습니다. 223 00:17:41,730 --> 00:17:44,300 그래서 단계 1. 224 00:17:44,300 --> 00:17:50,510 names.txt는 모든 이름을 포함되어 있기 때문에하지만, 화장실 - 난 names.txt하고 싶지 않아요 225 00:17:50,510 --> 00:17:54,170 나는 비 고유 사람을 필터링하고 싶습니다. 226 00:17:54,170 --> 00:18:01,200 나는 uniq의 names.txt을 그럼, 만약 꽤 내가 원하는 걸주지 않습니다 227 00:18:01,200 --> 00:18:03,760 중복 이름은 아직 거기 때문입니다. 228 00:18:03,760 --> 00:18:07,690 왜 그럴까요? 왜 uniq 내가 원하는 일을하지 않습니까? 229 00:18:07,690 --> 00:18:10,500 [학생] 중복되지 않습니다 [안 들리게] >> 그래. 230 00:18:10,500 --> 00:18:16,370 uniq에 대한 man 페이지를 기억 필터 옆에 일치하는 라인을 말한다. 231 00:18:16,370 --> 00:18:19,680 그들은 인접하지 때문에이를 필터링하지 않습니다. 232 00:18:19,680 --> 00:18:31,100 내가 그들을 먼저 정렬하면 정렬 names.txt 함께 모든 중복 행을 넣어 것입니다. 233 00:18:31,100 --> 00:18:34,450 이제 정렬 names.txt이 있다는 것입니다. 234 00:18:34,450 --> 00:18:40,550 uniq | I는 uniq에 입력으로 해당을 사용하려는거야. 235 00:18:40,550 --> 00:18:43,390 그게 날 요셉, RJ, 로브, 토미를 제공합니다 236 00:18:43,390 --> 00:18:49,260 그리고, 화장실 - 난에 입력으로 해당을 사용하려면 237 00:18:49,260 --> 00:18:52,740 이는 나에게 4 줄 예정이다. 238 00:18:52,740 --> 00:18:56,930 여기 말처럼, 어떤 파이프 라인을 사용할 수? 239 00:18:56,930 --> 00:19:01,390 당신은 명령 일련의를 사용하여 같은 일을 많이 할 수 240 00:19:01,390 --> 00:19:05,130 당신은 다음 명령의 입력으로 한 명령의 출력을 사용하여 곳. 241 00:19:05,130 --> 00:19:08,780 당신은 많은, 말썽 많은 작업을 수행 할 수 있습니다. 242 00:19:08,780 --> 00:19:11,440 >> 질문이 있으십니까? 243 00:19:12,910 --> 00:19:14,600 좋아요. 244 00:19:14,600 --> 00:19:17,880 파이프 리디렉션은 기록이다. 245 00:19:18,370 --> 00:19:24,090 >> 이제 우리는 실제 물건 코딩 재료로 이동합니다. 246 00:19:24,090 --> 00:19:29,100 이 PDF의 내부, 당신은이 명령이 표시됩니다 247 00:19:29,100 --> 00:19:32,950 그리고 당신은 어플라이언스에서이 명령을 실행하는 것이 좋습니다. 248 00:19:36,240 --> 00:19:42,250 wget은 기본적으로, 그냥 인터넷에서 뭔가를위한 명령입니다 249 00:19:42,250 --> 00:19:45,180 그래서 wget이 URL. 250 00:19:45,180 --> 00:19:49,110 귀하의 브라우저에서이 URL에 간 경우, 해당 파일을 다운로드해야합니다. 251 00:19:49,110 --> 00:19:52,510 난 그냥 클릭, 그래서 나 파일을 다운로드. 252 00:19:52,510 --> 00:19:55,650 그러나 터미널의 내부에 그 일을 wget 쓰기 253 00:19:55,650 --> 00:19:58,620 그냥 터미널에 다운로드 할 수 있습니다. 254 00:19:58,620 --> 00:20:02,750 전 section5.zip이 있고 당신은 section5.zip의 압축을 풉니 다하고자합니다 255 00:20:02,750 --> 00:20:06,520 그 때문에 당신에게 section5라는 폴더를 드릴 겁니다 256 00:20:06,520 --> 00:20:11,550 우리가 내부 오늘날 사용하려고하는 모든 파일을 가야된다. 257 00:20:33,380 --> 00:20:37,710 이러한 프로그램 '파일 이름이 제안으로, 그들은 약간의 버그가있어, 258 00:20:37,710 --> 00:20:40,990 그래서 당신의 임무는 gdb를 사용하는 이유를 알아내는 것입니다. 259 00:20:40,990 --> 00:20:44,560 그들을 모두 다운로드 / 그들을 다운로드 얻는 방법을 알고있다니까 260 00:20:44,560 --> 00:20:47,480 자신의 어플라이언스에? 좋아요. 261 00:20:47,480 --> 00:20:56,400 >> ./buggy1 실행, 그것은 세그먼트 오류 (코어 버려진)를 말할 것이다 262 00:20:56,400 --> 00:21:00,500 귀하가 segfault를 언제든지, 그건 나쁜 일이야. 263 00:21:00,500 --> 00:21:03,810 어떤 상황에서는 당신이 segfault하려면 어떻게해야합니까? 264 00:21:03,810 --> 00:21:08,210 [학생] 널 포인터를 Dereferencing. >> 그래. 그래서 그 한 예입니다. 265 00:21:08,210 --> 00:21:11,580 당신은 segfault을받을거야 널 포인터를 Dereferencing. 266 00:21:11,580 --> 00:21:16,720 당신은 메모리를 만지고 어떤 수단을 segfault 것은 당신이 만지는해서는 안됩니다. 267 00:21:16,720 --> 00:21:21,350 그래서 널 포인터를 dereferencing하는 것은, 주소 0을 터치합니다 268 00:21:21,350 --> 00:21:28,060 기본적으로 모든 컴퓨터는 요즘 주소 0 당신이 만지고하지 말아야 메모리 있다고합니다. 269 00:21:28,060 --> 00:21:31,920 segfault의 NULL 포인터 결과를 dereferencing 그래서 그게. 270 00:21:31,920 --> 00:21:37,210 당신은 포인터를 초기화하지 어떻게하면 다음은 쓰레기 값을 갖는다 271 00:21:37,210 --> 00:21:41,520 그래서 당신이 역 참조하려고 할 때 그것은 모든 가능성에 메모리를 만지시 네요 272 00:21:41,520 --> 00:21:43,540 그 곳의 한복판에 있어요. 273 00:21:43,540 --> 00:21:45,650 당신은 운이와 쓰레기 값을 얻을 발생할 경우 274 00:21:45,650 --> 00:21:48,440 스택 또는 뭔가 어딘가를 가리 키도록 일, 275 00:21:48,440 --> 00:21:50,820 그리고 때 포인터를 초기화하지 않은 당신은 역 참조, 276 00:21:50,820 --> 00:21:52,730 아무 것도 잘못되지 않습니다. 277 00:21:52,730 --> 00:21:55,480 가 가리키는 건지, 어딘가에 스택과 힙 사이 말 278 00:21:55,480 --> 00:21:59,850 아니면 그냥 어딘가, 아직 프로그램에서 사용되지 않은 해당 눈치입니다 279 00:21:59,850 --> 00:22:02,240 그럼 당신은 당신이 만지고하지 말아야 메모리를 만지고 당신은 segfault. 280 00:22:02,240 --> 00:22:06,370 당신은 재귀 함수를 작성하고 너무 여러 번 recurses 때 281 00:22:06,370 --> 00:22:08,720 귀하의 스택은 일에 너무 크고 스택 충돌 증가 282 00:22:08,720 --> 00:22:12,270 당신은 터치하지 말아야은 충돌해서는 안된다는, 당신은 메모리를 만지고, 283 00:22:12,270 --> 00:22:14,810 그래서 당신은 segfault. 284 00:22:14,810 --> 00:22:17,010 그게 무슨 segfault 방식입니다. 285 00:22:17,010 --> 00:22:21,810 >> 또한 같은 이유 당신이 같은 문자열이있을 경우 - 286 00:22:21,810 --> 00:22:23,930 가 이전 프로그램에 다시 가자. 287 00:22:23,930 --> 00:22:28,530 에서 hello.c - - 그냥 다른 뭔가를 만들려고. 288 00:22:28,530 --> 00:22:33,770 숯불 * S = "여러분, 안녕하세요!"; 289 00:22:33,770 --> 00:22:42,310 나는 사용하는 경우 * S = 무언가 또는 S [0] = 'X';주세요 290 00:22:42,310 --> 00:22:47,290 이렇게 인사합니다. / 안녕하세요, 이유는 s​​egfault거야? 291 00:22:48,410 --> 00:22:51,250 왜이 segfault 거죠? 292 00:22:55,660 --> 00:22:57,890 어떻게 될 것으로 예상까요? 293 00:22:57,890 --> 00:23:06,640 제가 printf 한 경우 ( "% s의 \ N", S), 너 뭐 인쇄 할 기대? 294 00:23:06,640 --> 00:23:09,930 [학생] X 안녕하세요. >> 그래. 295 00:23:09,930 --> 00:23:15,140 문제는이 같은 문자열을 때 선언이다 296 00:23:15,140 --> 00:23:18,190 S는 스택에 갈거야 포인터 297 00:23:18,190 --> 00:23:25,880 과 s이 (가)을 가리키는 것은 읽기 전용 메모리에 포함되는이 문자열입니다. 298 00:23:25,880 --> 00:23:30,560 단지 이름, 읽기 전용 메모리에 의해 그럼, 당신은 아이디어를 얻을합니다 299 00:23:30,560 --> 00:23:33,010 당신이 읽기 전용 메모리에 어떤 변경하려고하는 경우, 300 00:23:33,010 --> 00:23:36,670 당신은 메모리 짓을하지 말았어야 무언가를하고있는 당신은 segfault. 301 00:23:36,670 --> 00:23:45,360 이와 같은 사실은 실제로 숯불 * s와 숯불 S [] 사이에 큰 차이가 있습니다. 302 00:23:45,360 --> 00:23:48,790 따라서 숯불 님의 [], 이제이 문자열은 스택에 넣어 것입니다, 303 00:23:48,790 --> 00:23:53,960 그리고 스택이 완벽하게 잘 작동합니다 즉, 읽기 전용이 아닙니다. 304 00:23:55,500 --> 00:23:57,370 그리고하지 않습니다. 305 00:23:57,370 --> 00:24:06,250 기억이 나는 숯불 할 때 * s은 (는) = "안녕하세요!"S 자체가 스택에 306 00:24:06,250 --> 00:24:10,390 하지만 님의 다른 곳을 가리키는, 그 다른 곳 읽기 전용으로 발생합니다. 307 00:24:10,390 --> 00:24:15,640 그러나 숯은 S []는 스택에 뭔가입니다. 308 00:24:17,560 --> 00:24:21,760 그래서 그런 segfault가 발생의 또 다른 예입니다. 309 00:24:21,760 --> 00:24:27,820 >> 우리는 ./buggy1는 segfault의 결과 것을 보았다. 310 00:24:27,820 --> 00:24:31,810 이론적으로, 당신은 즉시 buggy1.c 보면 안 되죠. 311 00:24:31,810 --> 00:24:35,170 대신, 우리는 gdb를 통해 살펴 보겠습니다. 312 00:24:35,170 --> 00:24:37,750 당신이 세그먼트 오류 (코어 버려진)을 때 그렇게주의, 313 00:24:37,750 --> 00:24:40,850 여기라는 핵심으로이 파일을. 314 00:24:40,850 --> 00:24:45,200 우리 LS-리터다면, 우리는 그 핵심은 일반적으로 매우 큰 파일입니다 볼 수 있습니다. 315 00:24:45,200 --> 00:24:51,580 이 파일의 바이트 수이므로 250 뭔가를 킬로바이트 것 같은데. 316 00:24:51,580 --> 00:24:56,120 그 이유는 코어 덤프가 실제로 무엇이라는 것입니다 317 00:24:56,120 --> 00:25:01,410 이 때 프로그램 충돌, 프로그램의 메모리 상태 318 00:25:01,410 --> 00:25:05,230 그냥 복사하고이 파일에 붙여 넣기됩니다. 319 00:25:05,230 --> 00:25:07,270 그것은 그 파일에 버려진됩니다. 320 00:25:07,270 --> 00:25:13,060 이 프로그램은, 그것이 실행하는 동안, 250 주변 킬로바이트의 메모리 사용량을 가지고 일 321 00:25:13,060 --> 00:25:17,040 그리고 그렇게이 파일에 버려 졌어요거야. 322 00:25:17,040 --> 00:25:23,630 우리는 gdb의 buggy1 코어를한다면 이제 당신은 그 파일을 볼 수 있습니다. 323 00:25:23,630 --> 00:25:30,130 우리는 gdb에 buggy1을 할 수 있으며, 그, 그냥 정기적으로 gdb를 시작합니다 324 00:25:30,130 --> 00:25:33,800 의 입력 파일로 buggy1을 사용합니다. 325 00:25:33,800 --> 00:25:38,260 당신이 gdb를 buggy1 코어를한다면, 그것을 구체적으로 gdb를 시작하는거야 326 00:25:38,260 --> 00:25:40,330 이 코어 파일을보고 추론하는 것이었다. 327 00:25:40,330 --> 00:25:45,560 그리고 당신이 buggy1 의미 gdb를 말하는 것은 그 핵심 파일이 buggy1 프로그램에서 제공하는 알고 있습니다. 328 00:25:45,560 --> 00:25:49,580 따라서 gdb를 buggy1 핵심은 바로 우리에게 가져다 것입니다 329 00:25:49,580 --> 00:25:52,060 프로그램이 종료하기 일어난 곳이 있습니다. 330 00:25:57,720 --> 00:26:02,340 우리는 프로그램 신호를 11 세그먼트 오류와 함​​께 종료 여기를 참조하십시오. 331 00:26:02,340 --> 00:26:10,110 우리는 아마 매우 도움이되지 않습니다 조립, 한 줄을 볼 수있어. 332 00:26:10,110 --> 00:26:15,360 당신은 BT 또는 역 추적을 입력한다면, 그 기능이 될거에요 333 00:26:15,360 --> 00:26:19,430 그걸 가지고 우리가 현재 스택 프레임의 목록을 제공합니다. 334 00:26:19,430 --> 00:26:23,150 그래서 추적 (backtrace). 우리는 두 스택 프레임을 가지고있는 것 같습니다. 335 00:26:23,150 --> 00:26:26,310 첫 번째는, 우리의 주요 스택 프레임입니다 336 00:26:26,310 --> 00:26:29,810 두 번째는, 우리가 할 일이 바로이 기능을 위해 스택기구입니다 337 00:26:29,810 --> 00:26:34,440 우리가 만 어셈블리 코드가 같은있는 것으로 알고 있습니다. 338 00:26:34,440 --> 00:26:38,050 따라서이 우리의 주요 기능으로 돌아 가자, 339 00:26:38,050 --> 00:26:42,300 우리가 프레임 1을 할 수있는 일, 그리고 우리가 또한 다운 할 수 있다고 생각하기 위해, 340 00:26:42,300 --> 00:26:45,160 위 -하지만 거의 다운 직전하지 않습니다. 그래. 341 00:26:45,160 --> 00:26:50,710 위, 아래로. 최대 당신은 스택 프레임을 당신을 제공합니다 아래 하나의 스택 프레임을 제공합니다. 342 00:26:50,710 --> 00:26:53,240 난 사용하지 않습니다하는 경향이 있습니다. 343 00:26:53,240 --> 00:26:59,120 난 그냥 특별히 1이라는 프레임에 가고 프레임 1을 말한다. 344 00:26:59,120 --> 00:27:01,750 프레임 1은 기본 스택 프레임에 우리를 가지고 것입니다 345 00:27:01,750 --> 00:27:05,570 그리고 바로 여기에 우리가 집에있는 일이 코드 줄을 말한다. 346 00:27:05,570 --> 00:27:07,950 우리가 코드의 몇 가지 행을 원한다면, 우리는 목록을 말할 수 347 00:27:07,950 --> 00:27:11,280 그리고 우리에게 주변 코드의 모든 라인을 제공거야. 348 00:27:11,280 --> 00:27:13,360 우리가에서 오류를 발생시키고 말았다 라인은 6 살 : 349 00:27:13,360 --> 00:27:17,360 경우 (strcmp ( "CS50 바위", argv가 [1]) == 0). 350 00:27:17,360 --> 00:27:24,130 그것은 아직 분명하지 않을 경우, 당신은이 오류를 발생시키고 말았다 이유를 생각하여 여기에서 직선을 얻을 수 있습니다. 351 00:27:24,130 --> 00:27:28,800 하지만 우리는 한 걸음 더 나아가 볼까요 인사, "왜 변수는 argv [1] segfault거야?"할 수 있습니다 352 00:27:28,800 --> 00:27:38,830 가자 인쇄 변수는 argv [1],하고 NULL 포인터 그건 0x0, 것 같습니다. 353 00:27:38,830 --> 00:27:44,750 우리는 segfault거야 그게 그렇게 CS50 바위와 null을 strcmping, 그리고하고 있습니다. 354 00:27:44,750 --> 00:27:48,280 왜이 변수는 argv [1] 널? 355 00:27:48,640 --> 00:27:51,280 [학생] 우리가 아무 명령 줄 인수를 제공하지 않았으므로. 356 00:27:51,280 --> 00:27:53,390 그래. 우리는 아무 명령 줄 인수를 제공하지 않았습니다. 357 00:27:53,390 --> 00:27:58,460 따라서 ./buggy1는 변수는 argv [0] ./buggy1 될 수 있습니다 것입니다. 358 00:27:58,460 --> 00:28:02,100 이 변수는 argv가 [1]을 보낸다는 뜻이 아니라, segfault 것 인 것. 359 00:28:02,100 --> 00:28:07,450 대신, 난 그저 CS50 그래요,한다면, 당신은 D를 말할거야 360 00:28:07,450 --> 00:28:09,950 그는 예정된 일을 때문입니다. 361 00:28:09,950 --> 00:28:15,240 buggy1.c을 보면, 그것은 인쇄해야하는 "당신은 D를"- 362 00:28:15,240 --> 00:28:20,820 변수는 argv는 [1] "CS50 바위"는 다른, "당신은 D를"하지 않는 경우 "당신이 기회를 놓치지 마세요!" 363 00:28:20,820 --> 00:28:25,660 우리가 원하는면, 우리는 사실로 비교이 필요합니다 364 00:28:25,660 --> 00:28:28,710 그 말은 0으로 비교 것을 의미합니다. 365 00:28:28,710 --> 00:28:31,100 따라서 변수는 argv [1] "CS50 바위"있어야합니다. 366 00:28:31,100 --> 00:28:35,660 당신은 커맨드 라인에서 해당 작업을 수행하려는 경우, 당신은 공간을 이스케이프 \를 사용해야합니다. 367 00:28:35,660 --> 00:28:41,690 따라서 CS50 \ 바위와 당신이 기회를 놓치지 마세요! 368 00:28:41,690 --> 00:28:44,060 당신은 백 슬래시하지 않으면, 왜이 작동하지 않는 이유는 무엇인가요? 369 00:28:44,060 --> 00:28:47,190 [학생] 그것은 두 개의 다른 인수입니다. >> 그래. 370 00:28:47,190 --> 00:28:52,540 변수는 argv [1]은 CS50 될 것입니다, 그리고 변수는 argv가 [2] 바위가 될 것입니다. 좋아요. 371 00:28:52,540 --> 00:28:56,470 >> 지금 ./buggy2 다시 segfault 예정이다. 372 00:28:56,470 --> 00:29:01,880 대신 핵심 파일을 열어 때문에, 우리가 직접 buggy2을 열어 373 00:29:01,880 --> 00:29:05,000 gdb를 buggy2 그럼. 374 00:29:05,000 --> 00:29:09,590 우리가 우리의 프로그램을 실행하는 경우 이제 다음은 프로그램 신호 SIGSEGV를받은 말거야 375 00:29:09,590 --> 00:29:15,530 그 말은이 신호를 segfault이며, 어디서 무슨 일이 일어날 그 장소입니다. 376 00:29:15,530 --> 00:29:21,250 우리의 추적 (backtrace)을 보면, 우리는 우리가 함수 oh_no에 있던 것을 볼 377 00:29:21,250 --> 00:29:23,900 어떤은 함수 빙키에 의해 호출 된 함수가 작은에 의해 호출되었습니다 378 00:29:23,900 --> 00:29:26,460 어떤은 주에 의해 호출되었습니다. 379 00:29:26,460 --> 00:29:31,680 우리는 또한 이러한 기능에 대한 인수를 볼 수 있습니다. 380 00:29:31,680 --> 00:29:34,680 작은와 빙키에 대한 인수는 1이었다. 381 00:29:34,680 --> 00:29:44,390 우리가 기능 oh_no을 나열하면, 우리는 oh_no 그냥 숯불 ** S = NULL을 다하고 있습니다 것을 볼; 382 00:29:44,390 --> 00:29:47,410 * S = "붐"; 383 00:29:47,410 --> 00:29:50,330 왜 실패까요? 384 00:29:54,330 --> 00:29:58,380 [학생] 당신은 역 참조 널 포인터를 수 없습니다? >> 그래. 385 00:29:58,380 --> 00:30:06,090 그 숯불 **에서 일어나는 경우는 관계없이, s이 (가) null입니다 말한 386 00:30:06,090 --> 00:30:12,070 당신이 그것을 해석하는 방법에 따라, 그것은 문자열에 대한 포인터에 대한 포인터 될 수있는 387 00:30:12,070 --> 00:30:15,550 또는 문자열의 배열입니다. 388 00:30:15,550 --> 00:30:21,430 그것은 s이 (가) NULL입니다, 그러니까 * S는 널 포인터를 dereferencing 있습니다 389 00:30:21,430 --> 00:30:24,800 그래서이 충돌 것이다. 390 00:30:24,800 --> 00:30:27,540 이렇게하면 가능한 segfault 수있는 가장 빠른 방법 중 하나입니다. 391 00:30:27,540 --> 00:30:31,300 이건 그냥 NULL 포인터를 선언하고 즉시 segfaulting있어. 392 00:30:31,300 --> 00:30:34,570 그래서 oh_no 무엇을하고 있는지입니다. 393 00:30:34,570 --> 00:30:43,400 우리가 한 프레임을 이동한다면, 우리는 oh_no라는 함수로받을거야. 394 00:30:43,400 --> 00:30:44,830 내가 내려 그렇게해야합니다. 395 00:30:44,830 --> 00:30:48,610 당신이 명령을 입력하고하지 않으면 당신은 다시 Enter 키를 누르 396 00:30:48,610 --> 00:30:52,350 그것은 당신이 실행하는 이전 명령을 반복합니다. 397 00:30:52,350 --> 00:30:56,610 우리는 프레임 1에 있습니다. 398 00:30:56,610 --> 00:31:04,650 이 프레임 목록, 여기서 우리의 기능을 참조하십시오. 399 00:31:04,650 --> 00:31:08,520 다시 목록을 누르거나 목록 20 할 수 있으며 더 나열됩니다. 400 00:31:08,520 --> 00:31:13,640 함수 작은 내가 한 경우 다음 oh_no 함수에 갈 수 있다고 401 00:31:13,640 --> 00:31:15,960 다른 화끈 기능으로 이동합니다. 402 00:31:15,960 --> 00:31:18,700 그리고 우리가 여기 볼 일 당신은 내가 1 알 403 00:31:18,700 --> 00:31:22,560 그 작은은 인수 1 불렀습니다. 404 00:31:22,560 --> 00:31:27,560 아니면 내가를 인쇄합니까 수 있으며 내가 1 말 것입니다. 405 00:31:27,560 --> 00:31:33,770 우리는 작은 현재 있으며, 우리가 다른 프레임을 가면, 우리는 빙키에서 죽은 거예요. 406 00:31:33,770 --> 00:31:36,600 최대. 이제 우리는 빙키에 있어요. 407 00:31:36,600 --> 00:31:41,340 절반이 끼어되기 이전 목록 - -이 기능을 나열 408 00:31:41,340 --> 00:31:52,670 내가 0이면대로 시작한 다음, 우리가 oh_no 전화를하고, 다른 작은 전화하십시오. 409 00:31:52,670 --> 00:31:57,000 우리는 내가 한 줄 때문에 작은했다. 410 00:31:57,000 --> 00:32:05,030 그리고 지금 우리는 주에 왔고, 주요는 INT I = 란드 () % 3이 될 것입니다; 411 00:32:05,030 --> 00:32:08,790 그건 단지 당신에게 하나를 0, 1, 또는 2 인 임의의 숫자를 제공 할 수 있습니다. 412 00:32:08,790 --> 00:32:12,780 그것은 그 번호와 빙키 전화를거야, 그것은 0을 반환합니다. 413 00:32:12,780 --> 00:32:16,700 이걸 보면, 414 00:32:16,700 --> 00:32:19,880 단, 즉시 실행하지 않고 수동으로 프로그램을 통해 도보 415 00:32:19,880 --> 00:32:25,400 당신은 주에서 중단 점을 설정해야되는데,이 우리가 프로그램을 실행할 때 의미 416 00:32:25,400 --> 00:32:31,020 이 브레이크 포인트에 도달 할 때까지 프로그램까지 실행됩니다. 417 00:32:31,020 --> 00:32:35,450 프로그램을 실행 그래서, 그것은 실행됩니다 다음은 주요 기능을 누르고 실행을 중지합니다. 418 00:32:35,450 --> 00:32:44,700 이제 우리는 주 안에하고 있으며, 단계 또는 다음 코드의 다음 줄에 저희를 데려 갈 수 있습니다. 419 00:32:44,700 --> 00:32:47,050 당신은 단계 또는 다음을 수행 할 수 있습니다. 420 00:32:47,050 --> 00:32:51,800 다음 타격, 이제 내가 란드 () % 3, 이제 내가의 가치를 인쇄 할 수 있습니다로 설정되었습니다 421 00:32:51,800 --> 00:32:55,280 그리고 내가 1 말 것입니다. 422 00:32:55,280 --> 00:32:58,110 이제 우리는 다음 또는 단계를 사용하는지 여부에 상관하지 않습니다. 423 00:32:58,110 --> 00:33:01,000 나는 이전에 중요한 것, 그러나 우리는 다음에 사용할 수 있습니다. 424 00:33:01,000 --> 00:33:06,000 우리는 단계를 사용하는 경우, 우리는 함수로 단계, 즉 실제 문제에 모습을 의미합니다 425 00:33:06,000 --> 00:33:07,940 그 빙키의 내부 일어나고 있습니다. 426 00:33:07,940 --> 00:33:10,510 우리가 다음에 사용하는 경우 다음이 기능을 통해 이동을 의미합니다 427 00:33:10,510 --> 00:33:14,070 그리고 우리의 주요 기능에 코드의 다음 줄로 이동합니다. 428 00:33:14,070 --> 00:33:17,900 여기이 줄에, 나는 란드 () % 3 전했다에 있었어요; 429 00:33:17,900 --> 00:33:21,320 I 단계 짓을한다면, 그것은 랜드의 구현에 갈거야 430 00:33:21,320 --> 00:33:25,110 그리고 무슨 일이 일어나고 있는지보세요, 나는 RAND 함수를 통해 단계 수 있습니다. 431 00:33:25,110 --> 00:33:26,920 하지만 RAND 함수에 대해 신경 쓰지 않습니다. 432 00:33:26,920 --> 00:33:30,190 난 그냥 메인에 코드의 다음 줄에 가고 싶어, 그래서 다음 사용합니다. 433 00:33:30,190 --> 00:33:35,800 하지만 지금은 빙키 함수에 대한 관리 작업을 수행, 그래서 그걸 한 단계 싶습니다. 434 00:33:35,800 --> 00:33:37,730 지금은 빙키에있어. 435 00:33:37,730 --> 00:33:42,040 코드의 첫 번째 줄은 (i == 0), 전 단계를 받아들이면 말 것입니다, 436 00:33:42,040 --> 00:33:44,930 우리는 작은에 도착을 참조하십시오. 437 00:33:44,930 --> 00:33:51,620 우리 목록 일들이, 우리는이 선택되는 경우 전 = 0입니다. 438 00:33:51,620 --> 00:33:55,470 , 난 0 같지 않음 때문에 다른 조건에 갔다 439 00:33:55,470 --> 00:33:59,540 이는 작은을 (I)를 호출 할 수 있습니다. 440 00:33:59,540 --> 00:34:04,030 당신은 혼란스러워 할 수 있습니다. 441 00:34:04,030 --> 00:34:07,380 당신이 방금 직접이 줄을 보면, 당신은 생각할 수는 (i == 0)하는 경우 442 00:34:07,380 --> 00:34:10,800 좋아, 그럼 내가 단계를했고 지금은 작은은 (i)에있어 443 00:34:10,800 --> 00:34:14,120 당신은 내가 = 0 또는 무언가 의미합니다 생각할 수 있습니다. 444 00:34:14,120 --> 00:34:18,980 아니, 그냥이 줄 작은은 (i)에 직접 넣을 수 알고 있다는 것을 의미합니다. 445 00:34:18,980 --> 00:34:23,300 내가가 0이 아니기 때문에, 다음 단계는 다른에 종료하지 않을 수 있습니다. 446 00:34:23,300 --> 00:34:26,239 다른이에서 멈출 거예요 선이 없습니다. 447 00:34:26,239 --> 00:34:31,570 단지 실제로 어떤은 (i) 작은이며, 실행할 수있는 다음 줄에 시작합니다. 448 00:34:31,570 --> 00:34:36,090 작은은 (i)에 스테핑, 우리는 볼 (I == 1)하는 경우. 449 00:34:36,090 --> 00:34:42,670 우리는 우리가 단계 때 우리가 oh_no에 끝날 거라는 거 알아요, 내가 할 = 1 알 겠어 450 00:34:42,670 --> 00:34:46,489 난 = 1은 한 단계 씩 할 수있는 기능 oh_no를 호출하기 때문에 451 00:34:46,489 --> 00:34:52,969 설정하려고하는 문자 ** S = NULL 즉시 "꽝"할 수 있습니다. 452 00:34:54,270 --> 00:34:59,690 그리고 사실, buggy2의 구현을보고 453 00:34:59,690 --> 00:35:04,590 0, 1, 또는 2 - - 전화 빙키,이, 난 그냥 임의의 숫자를지고 454 00:35:04,590 --> 00:35:10,610 제가이 0 인 경우가 oh_no 호출하는 다른 그 작은 호출되는데,이 여기에 있습니다. 455 00:35:10,610 --> 00:35:18,100 제가 전화 oh_no 1이면 다른, 여기에 오는있는 화끈 전화 456 00:35:18,100 --> 00:35:20,460 난 2 경우 oh_no를 호출합니다. 457 00:35:20,460 --> 00:35:24,720 난 방법이 아닌 것 같아 - 458 00:35:24,720 --> 00:35:30,030 사람이 segfault하지 않습니다 프로그램을 만드는 방법을 참조합니까? 459 00:35:30,030 --> 00:35:37,530 내가 뭔가를 누락하지 않는 한 나는이 0 인 경우, 귀하는 즉시 segfault 드리 자면, 460 00:35:37,530 --> 00:35:41,250 그렇지 않으면, 당신이 segfault 한 경우 함수로 이동 461 00:35:41,250 --> 00:35:44,540 다른 당신은 내가 경우 2는 segfault 함수로 이동합니다. 462 00:35:44,540 --> 00:35:46,810 더 당신이 뭘해도 상관 그래서, 당신은 segfault 없습니다. 463 00:35:46,810 --> 00:35:52,380 >> 난 그 대신 숯불 ** S = NULL를하는 것 고치는 방법 중 하나를 추측 464 00:35:52,380 --> 00:35:55,610 그 문자열을위한 공간을 malloc 수 있습니다. 465 00:35:55,610 --> 00:36:04,230 sizeof 어떤 - 우리는 malloc (sizeof)을 할 수? 466 00:36:09,910 --> 00:36:15,190 [학생] (자) * 5? >>이 바로 보이는가? 467 00:36:15,190 --> 00:36:21,060 나는 실제로 그것을 실행하는 경우이 문제가 해결됩니다 있으리라 믿고있어하지만 내가 원하는 건 그게 아니에요. 468 00:36:24,400 --> 00:36:32,940 s의 종류 좀 봐. 가 INT *를 추가 할 수 있도록, 그래서 정수 * X. 469 00:36:32,940 --> 00:36:35,600 나는 (sizeof (int는)) malloc을 것입니다. 470 00:36:35,600 --> 00:36:40,490 아니면 내가 5의 배열을 원한다면, 나는 (sizeof (int는) * 5) 할 것이다; 471 00:36:40,490 --> 00:36:44,210 내가 INT **이 있다면? 472 00:36:46,260 --> 00:36:49,140 내가 뭘 malloc 겠어? 473 00:36:49,140 --> 00:36:53,510 포인터의 [학생] 크기입니다. >> 그래. (sizeof (int는 *)); 474 00:36:53,510 --> 00:36:56,960 여기 그런 것 같아요. 475 00:36:56,960 --> 00:37:01,280 나는 (sizeof (숯불 *)) 원, 476 00:37:06,170 --> 00:37:12,840 이 "꽝"를 가리 포인터를위한 공간을 할당 할 것이다. 477 00:37:12,840 --> 00:37:15,330 "꽝"은 그 자체를위한 공간을 할당 할 필요가 없습니다 478 00:37:15,330 --> 00:37:17,210 이게 내가 전에 말했듯이 내용과 기본적으로 동등한 때문에 479 00:37:17,210 --> 00:37:20,870 숯불의 * X = "붐". 480 00:37:20,870 --> 00:37:27,950 "붐"이 (가) 이미 존재합니다. 이 메모리의 읽기 전용 지역에 존재하는 발생합니다. 481 00:37:27,950 --> 00:37:35,200 s이 (가) 숯불 **이 경우 그것은 이미, 코드이 줄을 즉, 존재 482 00:37:35,200 --> 00:37:43,900 그리고 * s은 (는) 숯불 * 그리고 당신은 "꽝"을 가리 키도록이 숯불 *을 설정하고 있습니다. 483 00:37:43,900 --> 00:37:50,040 나는 S에 "붐"을 복사하려고하면, 난 s에 대한 공간을 할당해야합니다. 484 00:37:55,170 --> 00:38:03,900 제가 해드릴 게요 * S = malloc (sizeof (자) * 5); 485 00:38:03,900 --> 00:38:06,210 왜 5? 486 00:38:06,210 --> 00:38:10,860 왜 네? "붐"4 자입니다 것 같습니다. >> [학생] 널 문자입니다. 487 00:38:10,860 --> 00:38:14,580 그래. 귀하의 문자열의 모든 널 (null) 문자를해야 할 것입니다. 488 00:38:14,580 --> 00:38:23,590 지금은 strcat 같은 뭔가를 할 수 - 문자열을 복사하는 기능은 무엇입니까? 489 00:38:23,590 --> 00:38:28,520 [학생] cpy? >> strcpy. 490 00:38:28,520 --> 00:38:32,700 남자 strcpy. 491 00:38:36,120 --> 00:38:39,590 그래서 strcpy 나 strncpy. 492 00:38:39,590 --> 00:38:43,410 지정할 수 있기 때문에 strncpy은 약간 안전 정확히 얼마나 많은 문자 493 00:38:43,410 --> 00:38:46,190 우리가 알고 있기 때문에하지만 여기서 중요하지 않습니다. 494 00:38:46,190 --> 00:38:50,340 그래서 strcpy와 인수를 봅니다. 495 00:38:50,340 --> 00:38:53,100 첫 번째 인수는 우리의 목적지입니다. 496 00:38:53,100 --> 00:38:56,770 두 번째 인자는 우리의 소스입니다. 497 00:38:56,770 --> 00:39:10,310 우리는 대상 *에 복사 할거야하면 포인터가 "붐"S. 498 00:39:10,310 --> 00:39:19,820 왜 전에 대신 우리가 가진 단지 무엇 strcpy와 함께이 작업을 수행 할 수도 있습니다 499 00:39:19,820 --> 00:39:22,800 * s의 = "붐"? 500 00:39:22,800 --> 00:39:28,630 가이 작업을 수행 할 수도 있습니다 이유이지만, 그 이유는 무엇입니까? 501 00:39:28,630 --> 00:39:31,940 [학생]는 당신이 "꽝"에서 뭔가를 변경하려면. >> 그래. 502 00:39:31,940 --> 00:39:37,950 지금은 S와 같은 뭔가를 할 수 [0] = 'X'; 503 00:39:37,950 --> 00:39:48,190 님의 포인트는 힙에 힙 그 공간에 s은 (는)를 가리키는 때문 504 00:39:48,190 --> 00:39:52,320 "붐"을 저장하는 힙에 더 많은 공간에 대한 포인터입니다. 505 00:39:52,320 --> 00:39:55,150 따라서 "꽝"이 사본은 힙에 저장되고 있습니다. 506 00:39:55,150 --> 00:39:58,780 프로그램에서 "붐"의 두 사본은 기술적 있습니다. 507 00:39:58,780 --> 00:40:03,500 그냥이 "꽝"은 문자열 상수에 의해 주어있어 첫 번째가 있어요 508 00:40:03,500 --> 00:40:09,250 와 "붐"의 두 번째 복사본은 strcpy는 "붐"의 복사본을 만들었습니다. 509 00:40:09,250 --> 00:40:13,100 그러나 "붐"의 복사본이 힙에 저장하고, 힙은 변경하실되고 있습니다. 510 00:40:13,100 --> 00:40:17,250 힙은 읽기 전용이 아닙니다, 그래서 즉, S [0] 511 00:40:17,250 --> 00:40:20,500 당신이 "꽝"의 값을 변경할 예정이다. 512 00:40:20,500 --> 00:40:23,130 당신이 그 문자를 변경할거야. 513 00:40:23,130 --> 00:40:26,640 >> 질문이 있으십니까? 514 00:40:27,740 --> 00:40:29,290 좋아요. 515 00:40:29,290 --> 00:40:35,500 >> , buggy3으로가 봅시다 gdb를 buggy3을 움직여. 516 00:40:35,500 --> 00:40:39,840 우리는 단지 그것을 실행하고 우리는 segfault를 참조하십시오. 517 00:40:39,840 --> 00:40:46,550 우리 추적 (backtrace) 경우, 두 기능이 있습니다. 518 00:40:46,550 --> 00:40:52,970 우리는 main () 함수에 갈 경우, 우리는 우리가이 라인에서 오류를 발생시키고 말았다 것을 볼 수 있습니다. 519 00:40:52,970 --> 00:41:00,180 그러므로 (에이 라인을보고 INT 라인 = 0; fgets이 물건 같지 않음 NULL을 수행; 520 00:41:00,180 --> 00:41:03,770 라인 + +). 521 00:41:03,770 --> 00:41:08,010 이전 프레임 _IO_fgets 불렀습니다. 522 00:41:08,010 --> 00:41:10,720 당신은 내장 된 C 기능이있는 많은 볼 수 있습니다 523 00:41:10,720 --> 00:41:15,350 당신이 segfault를받을 때, 정말 알 수없는 함수 이름이있을 것 524 00:41:15,350 --> 00:41:18,090 이 _IO_fgets처럼. 525 00:41:18,090 --> 00:41:21,770 그러나이 fgets 전화에 관한거야. 526 00:41:21,770 --> 00:41:25,850 여기 어딘가 내부의, 우리는 segfaulting 있습니다. 527 00:41:25,850 --> 00:41:30,340 우리는 fgets에 인수 보면, 우리는 버퍼를 인쇄 할 수 있습니다. 528 00:41:30,340 --> 00:41:41,180 의 인쇄하자로 - 오, 이런. 529 00:41:48,980 --> 00:41:51,900 인쇄 정확히 내가 원하는대로 작동하지 않을 수 있습니다. 530 00:41:55,460 --> 00:41:58,000 가 실제 프로그램 살펴 보도록하겠습니다. 531 00:42:02,200 --> 00:42:09,640 버퍼는 문자 배열입니다. 그것은 128 자 문자 배열입니다. 532 00:42:09,640 --> 00:42:14,980 그래서 인쇄 버퍼라고 할 때, 그 128 문자를 인쇄 할거야 533 00:42:14,980 --> 00:42:18,300 어떤 제 생각 엔이 예상됩니다. 534 00:42:18,300 --> 00:42:21,390 내가 찾고 있었던 것은, 버퍼의 주소를 인쇄합니다 535 00:42:21,390 --> 00:42:23,680 하지만 저 한테 정말 많은 얘기하지 않습니다. 536 00:42:23,680 --> 00:42:30,770 그래서 여기에 X 버퍼 말하고 일어날 때, 그것은 나에게 0xbffff090를 보여줍니다 537 00:42:30,770 --> 00:42:38,690 당신이 이전 또는 어떤 시점에서 기억하면 Oxbffff는 스택 틱 지역이 될 경향이있는. 538 00:42:38,690 --> 00:42:46,020 스택은 0xc000 아래 어딘가에서 시작하는 경향이있다. 539 00:42:46,020 --> 00:42:51,890 바로이 주소를 확인하여, 나는 버퍼가 스택에 것을 알고있다. 540 00:42:51,890 --> 00:43:04,500 버퍼, 최대, 실행, 내 프로그램을 다시 시작 우리였다 문자의 순서를보고 541 00:43:04,500 --> 00:43:06,530 그 방법이 정말 의미가 있습니다. 542 00:43:06,530 --> 00:43:12,270 그런 다음 파일을 인쇄 어떤 파일처럼 보여? 543 00:43:15,120 --> 00:43:17,310 [학생] 널. >> 그래. 544 00:43:17,310 --> 00:43:22,610 , 파일 유형은 파일 *의이므로 포인터 545 00:43:22,610 --> 00:43:26,610 그 포인터의 값은 null입니다. 546 00:43:26,610 --> 00:43:33,240 그래서 fgets는 간접적 인 방법으로 그 포인터에서 읽을하려 할거야 547 00:43:33,240 --> 00:43:37,320 하지만 포인터를 사용하기 위해서는, 그것은 역 참조를해야 돼. 548 00:43:37,320 --> 00:43:40,550 아니면, 그것이 dereferences를,로 연결해야하는지에 액세스하기 위해 인치 549 00:43:40,550 --> 00:43:43,810 그럼 NULL 포인터와 segfaults을 dereferencing있어. 550 00:43:46,600 --> 00:43:48,730 내가 거기를 다시 시작 수 있습니다. 551 00:43:48,730 --> 00:43:52,170 우리는 주요 지점에서 해제하고 실행하면은, 552 00:43:52,170 --> 00:43:57,320 코드의 첫 번째 줄은 숯불 * 파일 이름 = "nonexistent.txt"이다; 553 00:43:57,320 --> 00:44:00,870 그래서이 프로그램이 실패 이유에 꽤 큰 힌트를 제공해야합니다. 554 00:44:00,870 --> 00:44:06,080 내가이 파일을 열 수있는 곳 옆에 입력하면, 다음 줄에 날을 제공 555 00:44:06,080 --> 00:44:11,140 그리고 나서 바로 한번 다음엔 어디를 공격의 선에 들어가, 그것은 segfault거야. 556 00:44:11,140 --> 00:44:16,880 사람이 우리가 segfaulting 될 수있는 이유를 던져할까요? 557 00:44:16,880 --> 00:44:19,130 [학생] 파일이 존재하지 않습니다. >> 그래. 558 00:44:19,130 --> 00:44:22,250 이것은 힌트 있어야합니다 559 00:44:22,250 --> 00:44:29,570 당신이 파일을 열하는 때마다이 파일이 실제로 존재하는지 확인해야. 560 00:44:29,570 --> 00:44:31,510 그래서 여기, "nonexistent.txt"; 561 00:44:31,510 --> 00:44:34,700 우리 읽기를위한 fopen 파일 이름, 우리는 말을해야 할 경우 562 00:44:34,700 --> 00:44:45,870 경우 (파일 == NULL)와 printf ( "파일이 존재하지 않습니다!"라고 563 00:44:45,870 --> 00:44:56,340 또는 - 아직 더 - 파일 이름); 반환 1; 564 00:44:56,340 --> 00:45:00,300 이제 우리는 NULL 있는지 확인 565 00:45:00,300 --> 00:45:03,930 전에 실제로 계속하고 해당 파일에서 읽는. 566 00:45:03,930 --> 00:45:08,800 우리는 그 작품 그를 볼 수를 리메이크 할 수 있습니다. 567 00:45:11,020 --> 00:45:14,970 나는 새 줄을 포함하기위한. 568 00:45:21,090 --> 00:45:25,290 이제 nonexistent.txt가 존재하지 않습니다. 569 00:45:26,890 --> 00:45:30,040 당신은 항상 이런 건에 대해 확인해야합니다. 570 00:45:30,040 --> 00:45:33,870 당신은 항상 fopen은 NULL을 반환하는지 확인해야합니다. 571 00:45:33,870 --> 00:45:38,170 당신은 항상 malloc이 NULL을 반환하지 않습니다 있는지 확인해야합니다 572 00:45:38,170 --> 00:45:41,410 또는 다른 당신은 segfault. 573 00:45:42,200 --> 00:45:45,930 >> 지금 buggy4.c. 574 00:45:49,190 --> 00:45:58,440 실행. 나는 입력 또는 가능성이 무한 반복을 기다리고 있습니다이 추측거야. 575 00:45:58,440 --> 00:46:01,870 네, 무한 반복입니다. 576 00:46:01,870 --> 00:46:05,560 buggy4 그럼. 우리가 무한 반복중인 것 같습니다. 577 00:46:05,560 --> 00:46:12,590 우리는 메인에 날릴 수 있지만, 프로그램을 실행합니다. 578 00:46:12,590 --> 00:46:20,180 gdb의에서, 만약 사용하는 약어가 모호하므로 579 00:46:20,180 --> 00:46:23,420 또는 당신을 위해 제공하는 특별 약어, 580 00:46:23,420 --> 00:46:29,020 다음 대신 다음에 모든 방법을 입력 할 필요의 옆에를 사용하는 n을 사용할 수 있습니다. 581 00:46:29,020 --> 00:46:33,730 그리고 지금은 한 번 누르 N 한, 난 그냥 옆에 계속 입력을 칠 수 582 00:46:33,730 --> 00:46:36,640 대신 누르 N 입력 N 입력 N 입력해야하는. 583 00:46:36,640 --> 00:46:44,630 나는 [I]을 0으로 배열을 설정있어 루프에 대한 어떤 종류의에 있어요 것 같습니다. 584 00:46:44,630 --> 00:46:50,510 내가 루프에 빠져 위반 절대 나처럼 보입니다. 585 00:46:50,510 --> 00:46:54,780 난 내가를 인쇄, 그래서이 있다면, 다음 갈거야. 586 00:46:54,780 --> 00:46:59,250 다음은 제가 갈 게요 그럼 난 3, 내가를 인쇄합니다. 587 00:46:59,250 --> 00:47:05,360 난 내가를 인쇄합니다 그리고 난은 3입니다. 다음으로, 인쇄, 전 4입니다. 588 00:47:05,360 --> 00:47:14,520 사실, 인쇄 sizeof (배열), 그래서 배열의 크기는 20입니다. 589 00:47:16,310 --> 00:47:32,870 일부 특수 gdb의 명령은 무슨 일이 때까지 계속 거기에있는 것 그러나 같습니다. 590 00:47:32,870 --> 00:47:37,620 이 변수의 값에 조건을 설정 같아요. 하지만 그게 뭔지 기억이 안나요. 591 00:47:37,620 --> 00:47:44,100 - 우리는 계속한다면 592 00:47:44,100 --> 00:47:47,120 무슨 말을 했지? 무슨 얘기 했어? 593 00:47:47,120 --> 00:47:50,500 [학생] 표시 제가 추가합니까 - >> 예. 그래서 도움이 표시됩니다. 594 00:47:50,500 --> 00:47:54,530 우리가 단지를 표시하면, 내가의 가치는 얼마입니까 여기에 넣어합니다 595 00:47:54,530 --> 00:47:56,470 그래서 매번 그것을 인쇄 할 필요가 없습니다. 596 00:47:56,470 --> 00:48:02,930 우리가 다음에 계속하면, 우리는 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5를 참조하십시오. 597 00:48:02,930 --> 00:48:08,530 뭔가 심각하게 잘못된 것이다, 나는 0으로 재설정되고 있습니다. 598 00:48:13,330 --> 00:48:22,220 buggy4.c을 보면, 우리는 그런 일이 일어날 모든 정수 배열 [5]입니다 참조; 599 00:48:22,220 --> 00:48:26,200 (; 나는 <= sizeof (배열); 전 + + I = 0)에 대한 600 00:48:26,200 --> 00:48:28,550 배열 [i] = 0; 601 00:48:28,550 --> 00:48:31,390 우리가 그렇게 여기 뭐가 잘못 표시되는 이유는 무엇입니까? 602 00:48:31,390 --> 00:48:39,480 힌트으로, gdb에 buggy4을 할 때 - 메인, 실행을 깰의 보자 - 603 00:48:39,480 --> 00:48:45,980 나는 인쇄 sizeof (배열) 내가 드디어 탈출 위치를 상태가 무엇인지 볼 않았습니다. 604 00:48:47,690 --> 00:48:51,100 여기가 어디야? 내가 도망나요? 605 00:48:51,100 --> 00:48:54,280 아직 선언되지 않았습니다. 606 00:48:54,280 --> 00:48:58,680 그래서, sizeof를 (배열) 인쇄하고는 20입니다 607 00:48:58,680 --> 00:49:06,690 어떤은 내 배열의 크기 (5)의이기 때문에 기대하고 5 정수되는 것은 608 00:49:06,690 --> 00:49:12,410 그래서 전체 것은 sizeof (INT)가 4 살이 경향이 5 * sizeof (int는) 바이트 있어야합니다. 609 00:49:12,410 --> 00:49:14,780 그래서 sizeof (배열) 20입니다. 610 00:49:14,780 --> 00:49:17,420 이것은 무엇을해야합니까? 611 00:49:17,420 --> 00:49:21,720 [학생] sizeof (int는)으로 나눈 값입니다. >> 네, / sizeof (int는). 612 00:49:21,720 --> 00:49:30,630 문제가 아직 여기가있는 것 같습니다. 이 단지해야한다고 생각 < 613 00:49:30,630 --> 00:49:36,960 가 거의 항상부터 <결코 <=. 614 00:49:36,960 --> 00:49:44,860 지금의이가 부러 이유 생각해 보죠. 615 00:49:44,860 --> 00:49:53,370 사람이 왜 루프의 각 반복을 통해 0으로 추측 재설정이 있습니까? 616 00:50:01,300 --> 00:50:09,350 여기서 무슨 일이 있었 그 안에있는 유일한 방법은 [I]는 0으로 설정되고 그 배열입니다. 617 00:50:09,350 --> 00:50:15,350 그래서 어떻게 든,이 코드 줄은 난을 0으로 설정 될 수 있도록 INT를 일으키는 것입니다. 618 00:50:16,730 --> 00:50:23,130 이제 내가이 부분의 기억을 재정의하기 때문에 [학생] 혹시 619 00:50:23,130 --> 00:50:27,970 그것이 배열의 다음 요소 야? 생각하면 >> [보덴] 예. 620 00:50:27,970 --> 00:50:33,880 우리는 배열의 끝을 넘어 때, 621 00:50:33,880 --> 00:50:39,870 우리가 재정의하고 있는지 어떻게 든 그 공간은 내가의 가치를 재정의하고 있습니다. 622 00:50:39,870 --> 00:50:48,030 우리가 buggy4을 보면 그리고, 메인, 실행을 깰 623 00:50:48,030 --> 00:50:53,120 의는 내가의 주소를 인쇄 보자. 624 00:50:53,120 --> 00:50:57,280 이 bffff124 것 같은데. 625 00:50:57,280 --> 00:51:03,930 이번에는 배열의 주소를 인쇄하게 [0​​]. 110. 626 00:51:03,930 --> 00:51:06,290 무엇 [1]은 어때? 114. 627 00:51:06,290 --> 00:51:07,920 [2], 118. 628 00:51:07,920 --> 00:51:14,530 11c, 120. 배열 [5] bfff124입니다. 629 00:51:14,530 --> 00:51:26,990 배열 그래서 [5] 난, 그 배열 [5] 나는 것을 의미와 같은 주소가 있습니다. 630 00:51:26,990 --> 00:51:30,720 이 동일한 주소를 가지고있는 경우, 그들은 같은 일입니다. 631 00:51:30,720 --> 00:51:38,410 그래서 우리는 배열 [5]로 설정하면 0으로, 우리는 0으로 i를 설정합니다. 632 00:51:38,410 --> 00:51:46,070 그리고 당신은 스택의 관점에서 생각해 경우, 633 00:51:46,070 --> 00:51:55,590 INT 난 내가 스택에 공간이 도착 즉, 먼저 선언되어 있습니다. 634 00:51:55,590 --> 00:52:04,730 그런 다음 배열 [5] 그래서 20 바이트가 스택에 할당되며, 할당됩니다. 635 00:52:04,730 --> 00:52:08,400 그래서 그 다음이 20 바이트가 할당받을 우선 할당됩니다. 636 00:52:08,400 --> 00:52:11,400 그래서, 바로 배열하기 전에 발생 637 00:52:11,400 --> 00:52:19,230 때문에 방법처럼 나는 기술적으로 스택이 아래로 증가 곳, 지난 주 말 638 00:52:19,230 --> 00:52:28,520 배열로 할 때 인덱스, 우리는 보장됩니다 배열의 0번째 위치 639 00:52:28,520 --> 00:52:31,970 항상 배열의 첫 번째 위치하기 전에 발생합니다. 640 00:52:31,970 --> 00:52:35,900 이건 내가 지난 주에 그것을 그렸다 방법 종류입니다. 641 00:52:35,900 --> 00:52:42,210 아래에 우리가 주소 0을 가지고 있고 상단에 우리가 주소 최대가납니다. 642 00:52:42,210 --> 00:52:44,880 스택은 항상 아래로 성장하고있다. 643 00:52:48,100 --> 00:52:53,500 자, 우리는 i를 할당 말한다. 644 00:52:53,500 --> 00:52:59,680 우리는 정수 할당 전, 가자 그냥 여기서 정수 제가 할당됩니다 말하고 의미합니다. 645 00:52:59,680 --> 00:53:06,420 그리고 우리는 그 아래에 그 의미 5 정수의 배열을, 할당 646 00:53:06,420 --> 00:53:11,230 스택이 아래로 성장해 가고 있기 때문에, 그 다섯 정수가 할당받을. 647 00:53:11,230 --> 00:53:15,900 그러나 배열을 사용하는 방법에 때문에, 우리는 보장하고 그 배열의 첫 번째 위치 648 00:53:15,900 --> 00:53:22,260 항상 배열의 두 번째 이하 주소가 있습니다. 649 00:53:22,260 --> 00:53:28,270 따라서 배열 위치 0 항상 메모리에 첫번째 일이 있습니다 650 00:53:28,270 --> 00:53:30,700 배열의 위치 1 그 후에 발생하는 반면, 651 00:53:30,700 --> 00:53:33,310 및 배열 위치 2, 그 이후 발생하는 652 00:53:33,310 --> 00:53:37,900 이는 그 배열 위치 0, 거기에 어디 선가 무슨 일이 일어날 것을 의미 653 00:53:37,900 --> 00:53:40,690 배열 위치 1은 위에서 무슨 일이 일어날 654 00:53:40,690 --> 00:53:45,530 까지 옮기는 ​​것이 최대 주소가 여기에 있기 때문에 높은 주소를 의미합니다. 때문에 655 00:53:45,530 --> 00:53:50,490 여기로 배열 [0] 지금, 배열 [1] 여기까지, 배열 [2] 여기까지, 배열 [3] 여기 요. 656 00:53:50,490 --> 00:53:55,620 우리가이 모든 방법은, 정수를 할당하는 방법 전에 해당 내용을 미리 공지 657 00:53:55,620 --> 00:54:01,040 우리는 배열에 추가 및 추가 이동, 우리는 점점 더 가까이 우리 정수 전을 받고 있습니다. 658 00:54:01,040 --> 00:54:07,640 그건 아주, 그 우리의 배열보다 한 위치에 있으며, 그 배열 할 [5] 일 659 00:54:07,640 --> 00:54:13,010 정확히 내가 할당 할 수 있었던 곳 정수입니다. 660 00:54:13,010 --> 00:54:16,920 그럼 우리가 스택에 공간을 때리는 할 일이 핵심 이죠, 661 00:54:16,920 --> 00:54:21,680 그는 정수 전에 할당되었고, 우리는 0으로 설정하고 있습니다. 662 00:54:21,680 --> 00:54:26,160 >> 그거 작동 방법은 다음과 같습니다. 질문이 있으십니까? 그래. 663 00:54:26,160 --> 00:54:30,710 [학생] 신경 쓰지 마. 좋아요. 664 00:54:30,710 --> 00:54:33,090 [학생] 어떻게 이러한 오류 종류를 방지합니까? 665 00:54:33,090 --> 00:54:41,190 이러한 오류인가? 프로그래밍 언어로 C를 사용하지 마십시오. 666 00:54:41,190 --> 00:54:45,840 확인 배열 경계가있는 언어를 사용합니다. 667 00:54:45,840 --> 00:54:55,900 그 동안 조심스럽게 한, 당신은 당신의 배열의 범위를 넘어 가지 않기 위해 필요합니다. 668 00:54:55,900 --> 00:54:58,300 [학생] 그래서 여기에 우리가 배열의 범위를 넘어 갔을 때 - 669 00:54:58,300 --> 00:55:01,840 [보덴] 일이 잘못 갈 시작할 곳입니다. >> [학생] 아, 그래요. 670 00:55:01,840 --> 00:55:05,730 그 동안 귀하의 배열에 할당 된 메모리 내에 있어야 한, 당신은 괜찮아요. 671 00:55:05,730 --> 00:55:12,400 그러나 C는 오류 검사를 수행하지 않습니다. 제가 배열을 할 경우 [1000]은 기꺼이 단지 무슨 일이 생기면 수정됩니다 - 672 00:55:12,400 --> 00:55:16,500 그것은 배열의 시작 부분에 갔다가 그 후 1000 위치를 간다하고 0으로 설정합니다. 673 00:55:16,500 --> 00:55:20,000 그것은 오,이 실제로 1000 일이없는 한 검사를하지 않습니다. 674 00:55:20,000 --> 00:55:22,750 1000, 방법 나는 변화해야하는지 넘어 675 00:55:22,750 --> 00:55:26,940 자바 아님 당신이 범위를 인덱스의 배열을 나갈거야 반면, 676 00:55:26,940 --> 00:55:29,820 또는 범위 예외의 색인 아웃. 677 00:55:29,820 --> 00:55:33,950 높은 수준의 언어로 많은 일이 좀있어서 이유 678 00:55:33,950 --> 00:55:37,340 당신이 배열의 범위를 넘어 가면 어디에서, 당신은 실패 679 00:55:37,340 --> 00:55:40,070 당신은 수렁에서 일을 변경할 수 없습니다 있도록 680 00:55:40,070 --> 00:55:42,590 그리고 이제 막 예외를 점점 것보다 훨씬 더 이동 681 00:55:42,590 --> 00:55:44,940 당신은 배열의 끝 넘어 갔다고 말하는. 682 00:55:44,940 --> 00:55:50,970 [학생] 그리고 우리가 변경해야 <= 바로 > [보덴] 그래. 683 00:55:50,970 --> 00:55:54,800 그것은 00:55:59,560 sizeof (배열) 20이지만 우리는 5 원부터. >> [학생] 맞아. 685 00:55:59,560 --> 00:56:04,060 더 질문? 좋아요. 686 00:56:04,060 --> 00:56:07,380 >> [학생] 질문이 있습니다. >> 그래. 687 00:56:07,380 --> 00:56:16,440 [학생] 실제 배열 변수는 무엇입니까? 688 00:56:16,440 --> 00:56:20,000 [보덴]처럼 배열 무엇입니까? 689 00:56:20,000 --> 00:56:24,930 배열 자체는 상징입니다. 690 00:56:24,930 --> 00:56:31,490 그것은 우리가 참조하고있는 20 바이트의 시작의 주소입니다. 691 00:56:31,490 --> 00:56:38,070 당신은 포인터로 생각할 수 있지만 상수 포인터입니다. 692 00:56:38,070 --> 00:56:44,140 가능한 한 빨리 일이 컴파일대로, 변수 배열은 더 이상 존재하지 않습니다. 693 00:56:44,140 --> 00:56:48,210 [학생] 그럼 어떻게 그 배열의 크기를 찾을 수 있습니까? 694 00:56:48,210 --> 00:56:54,130 배열의 크기는 기호로 연결되는 것이 그 블록의 크기를 의미합니다. 695 00:56:54,130 --> 00:57:01,240 나는 printf와 같은 무언가를 ( "% P \ N", 배열) 할 때, 696 00:57:01,240 --> 00:57:05,140 한번 해보도록하지. 697 00:57:12,960 --> 00:57:15,530 난 그냥 뭘 잘못 했어? 698 00:57:15,530 --> 00:57:19,220 배열 '배열'여기를 선언했다. 699 00:57:20,820 --> 00:57:23,200 아, 여기 요. 700 00:57:23,200 --> 00:57:31,250 꽝은 똑똑하고, 내가 5 요소로 배열을 선언 알고들 어떻게 701 00:57:31,250 --> 00:57:34,540 하지만 위치를 1000으로 색인을 생성 할거야. 702 00:57:34,540 --> 00:57:38,450 이 단지 상수이기 때문에 그런게을 수행 할 수 있습니다. 703 00:57:38,450 --> 00:57:43,370 이건 내가 배열의 범위를 넘어 갈이 없었죠에 지금까지 이동할 수 있습니다. 704 00:57:43,370 --> 00:57:46,880 그러나, 우리는 내가 잘못했을 때 이전에 발견 705 00:57:46,880 --> 00:57:51,040 그것은 아마도, 내가에 걸릴 수 있습니다 얼마나 많은 값을 확인할 수 없습니다 706 00:57:51,040 --> 00:57:55,540 그래서 내가 배열의 끝 넘어가는 것으로 판단 할 수 없습니다. 707 00:57:55,540 --> 00:57:59,430 그건 그냥 똑똑해 꽝입니다. 708 00:57:59,430 --> 00:58:03,340 >> 그러나 지금 buggy4을합니다. 그래서 잘못 다른 뭘하고있는 거지? 709 00:58:03,340 --> 00:58:05,970 암시 적으로 라이브러리 함수가 'printf'선언. 710 00:58:05,970 --> 00:58:14,960 나는 # 를 포함 할거야. 711 00:58:14,960 --> 00:58:18,710 좋아요. 지금 buggy4를 실행 해보십시오. 712 00:58:18,710 --> 00:58:24,840 같은 배열의 값을 인쇄 나는 포인터로 인쇄 솜씨가 713 00:58:24,840 --> 00:58:30,060 과 같은 인쇄 뭔가 - bfb8805c - 일부 주소입니다 714 00:58:30,060 --> 00:58:33,450 그 스택 틱 지역에 있어요. 715 00:58:33,450 --> 00:58:41,820 , 배열 자체는 포인터처럼이지만, 실제 포인터가 아닙니다 716 00:58:41,820 --> 00:58:45,410 일반 포인터부터 우리는 변경할 수 있습니다. 717 00:58:45,410 --> 00:58:54,700 배열은 그냥 상수입니다. 메모리의 20 블록 주소 0xbfb8805c부터 시작합니다. 718 00:58:54,700 --> 00:59:09,020 이 주소를 통해 등록 bfb8805c +20- 또는 전 -20 생각에 - 719 00:59:09,020 --> 00:59:17,400 이 배열에 할당 된 메모리의 전부입니다. 720 00:59:17,400 --> 00:59:20,350 배열, 변수 자체는 저장되지 않습니다. 721 00:59:20,350 --> 00:59:27,660 당신은 컴파일하고 컴파일러 - 그것을 손으로 파 - 722 00:59:27,660 --> 00:59:33,060 이 배열로 알고하지만 어디 컴파일러는 사용합니다. 723 00:59:33,060 --> 00:59:36,090 그 배열이 시작하는 위치는 알 724 00:59:36,090 --> 00:59:40,910 그래서 항상 그 처음부터 오프셋의 관점에서 일을 할 수있다. 725 00:59:40,910 --> 00:59:43,960 이 배열을 대표 할 수있는 변수 자체가 필요하지 않습니다. 726 00:59:43,960 --> 00:59:53,730 하지만 INT * P = 배열​​과 같은 일을 할 때, 지금 P, 그 배열을 가리 키 포인터 727 00:59:53,730 --> 00:59:57,830 지금 P는 실제로 스택에 존재 않습니다. 728 00:59:57,830 --> 01:00:01,950 내가 P를 변경할 수입니다. 내가 P = malloc을 수행 할 수 있습니다. 729 01:00:01,950 --> 01:00:06,500 그래서 원래 배열로 지적, 지금은 힙에서 여유 공간을 가리 킵니다. 730 01:00:06,500 --> 01:00:09,620 나는 배열 =의 malloc을 수행 할 수 없습니다. 731 01:00:09,620 --> 01:00:13,710 꽝이 똑똑하면 바로 박쥐에서 좀 지르지합니다. 732 01:00:17,000 --> 01:00:21,430 사실, gcc가 너무 이런 짓을 했을까 확신합니다. 733 01:00:21,430 --> 01:00:25,010 따라서 배열 유형 'int는 [5]의'양도하지 않습니다. 734 01:00:25,010 --> 01:00:28,040 당신은 배열 유형에 무언가를 할당 할 수 없습니다 735 01:00:28,040 --> 01:00:30,500 배열은 상수이기 때문이다. 736 01:00:30,500 --> 01:00:34,760 그것은 어떤 참조 그 20 바이트 상징입니다. 난 변경할 수 없습니다. 737 01:00:34,760 --> 01:00:37,690 >> [학생] 그리고 배열의 크기가 어디에 저장됩니까? 738 01:00:37,690 --> 01:00:40,670 [보덴] 이것은 저장되지있어. 이 컴파일있어 때입니다. 739 01:00:40,670 --> 01:00:46,310 따라서 배열의 크기는 어디에 저장됩니까? 740 01:00:46,310 --> 01:00:51,870 귀하는 배열 자체를 선언하는 함수의 내부 sizeof를 (배열)를 사용할 수 있습니다. 741 01:00:51,870 --> 01:01:03,150 좀 기능, 푸, 어떻게 내가 할면 (INT 배열 []) 742 01:01:03,150 --> 01:01:10,450 printf ( "% d 개 \ N", sizeof (배열)); 743 01:01:10,450 --> 01:01:21,330 그리고 여기 제가 푸 (배열)를 호출; 744 01:01:21,330 --> 01:01:24,840 이 기능의 내부 - 한번 실행합니다. 745 01:01:34,200 --> 01:01:36,840 다시는 똑똑해 꽝입니다. 746 01:01:36,840 --> 01:01:43,890 이 말은 그게 배열 함수 매개 변수에 sizeof 747 01:01:43,890 --> 01:01:46,690 'int는 *'의 크기를 반환합니다. 748 01:01:46,690 --> 01:01:55,150 이제 내가 일을하고 싶 아니라면이 오류가 될 것입니다. 749 01:01:55,150 --> 01:01:58,960 의 실제 Werror을 해제 보자. 750 01:02:14,950 --> 01:02:17,590 경고. 경고 잘 수 있습니다. 751 01:02:17,590 --> 01:02:19,960 이 경고가로 아직도 오래 컴파일합니다. 752 01:02:19,960 --> 01:02:22,910 . / a.out의 4를 인쇄 할 것이다. 753 01:02:22,910 --> 01:02:28,650 생성 된 경고는 무엇이 잘못되었는지에 대한 명확한 지표입니다. 754 01:02:28,650 --> 01:02:34,120 이 정수 배열은 sizeof을 (INT *) 인쇄 할 것이다. 755 01:02:34,120 --> 01:02:39,790 내가 여기에 배열 [5] 넣어하더라도, 여전히 단지 sizeof을 (INT *) 인쇄 할거야. 756 01:02:39,790 --> 01:02:47,440 따라서 가능한 한 빨리 당신이 함수에 합격으로 배열과 포인터의 차이 757 01:02:47,440 --> 01:02:49,670 존재하지 않는 것입니다. 758 01:02:49,670 --> 01:02:52,640 이것은 스택에 선언 된 배열 할 일 759 01:02:52,640 --> 01:02:58,300 하지만, 우리는 곧 그 가치를 전달로 그 0xbf, 어쩌구이 기능에 어쩌고 760 01:02:58,300 --> 01:03:03,350 다음이 포인터가 스택에 그 배열을 가리 킵니다. 761 01:03:03,350 --> 01:03:08,310 sizeof는 배열이 선언 된 함수에서 적용되는 것을 의미하므로, 762 01:03:08,310 --> 01:03:11,230 그 말은 당신이 기능을 컴파일 할 때 763 01:03:11,230 --> 01:03:17,330 꽝이 기능을 통해가는 때, 배열의 크기는 5 정수 배열입니다보고있다. 764 01:03:17,330 --> 01:03:20,640 그래서는 sizeof를 (배열)보고있다. 음, 20입니다. 765 01:03:20,640 --> 01:03:26,440 그래서 sizeof는 기본적으로 거의 모든 경우에 작동 방법을 실제로입니다. 766 01:03:26,440 --> 01:03:31,150 Sizeof는 함수가 아니라 연산자입니다. 767 01:03:31,150 --> 01:03:33,570 당신은 sizeof 함수를 호출하지 않습니다. 768 01:03:33,570 --> 01:03:38,280 Sizeof (INT)는 컴파일러는 그 4 변환합니다. 769 01:03:41,480 --> 01:03:43,700 알았어? 좋아요. 770 01:03:43,700 --> 01:03:47,520 >> [학생] 지금 메인 및 foo는에서 sizeof (배열)의 차이점은 무엇입니까? 771 01:03:47,520 --> 01:03:52,840 우리가 유형 INT의 *입니다 sizeof를 (배열), 말 때문입니다 772 01:03:52,840 --> 01:03:57,120 배열 여기하지 않습니다 타입 int는 *의 반면, 그것은 정수 배열입니다. 773 01:03:57,120 --> 01:04:04,540 >> [학생] 그래서 당신은 배열 [] 대신 INT * 배열에서 매개 변수가 있다면, 774 01:04:04,540 --> 01:04:09,230 그 지금은 포인터이기 때문에 아직도 배열을 변경할 수 있다는 의미? 775 01:04:09,230 --> 01:04:14,250 [보덴] 이렇게요? >> [학생] 그래. 이제 함수에서 배열을 변경할 수 있습니까? 776 01:04:14,250 --> 01:04:18,420 [보덴] 당신은 두 경우 모두에 배열을 변경할 수 있습니다. 777 01:04:18,420 --> 01:04:23,130 이러한 경우 모두에서 당신은 배열 [4] = 0 말을 무료로 이용하실 수 있습니다. 778 01:04:23,130 --> 01:04:26,590 [학생]하지만 당신은 다른 뭔가를 배열 지점을 만들 수 있습니까? 779 01:04:26,590 --> 01:04:30,230 [보덴] 오. 그래. 두 경우 모두 - >> [학생] 그래. 780 01:04:30,230 --> 01:04:38,410 [보덴] 배열 []와 int는 * 배열 사이의 구분은 아무 것도 없습니다. 781 01:04:38,410 --> 01:04:42,570 당신은 또한 여기에 몇 가지 다차원 배열을 얻을 수 있습니다 782 01:04:42,570 --> 01:04:47,050 일부 편리한 구문에 대해,하지만 단지 포인터입니다. 783 01:04:47,050 --> 01:04:56,400 이건 내가 배열을 할 자유임을 의미 = malloc (sizeof (int는)), 그리고 지금 다른 곳에서 지적한다. 784 01:04:56,400 --> 01:04:59,610 그러나 단지이 영원히 항상 작동 방식 좋아 785 01:04:59,610 --> 01:05:03,210 을하여이 배열을 변경하면 다른 뭔가를 가리 킵니다 786 01:05:03,210 --> 01:05:07,570 가, 인수의 복사본이기 때문에 여기에이 배​​열을 변경하지 않습니다 787 01:05:07,570 --> 01:05:10,780 그렇게 인수에 대한 포인터 없습니다. 788 01:05:10,780 --> 01:05:16,070 그리고 사실, 그냥 똑같은 걸 더 표시 등 - 789 01:05:16,070 --> 01:05:21,100 우리는 이미 인쇄 배열 프린트 무엇을 봤어 - 790 01:05:21,100 --> 01:05:31,410 우리는 배열의 주소 또는 배열의 주소의 주소를 인쇄하는 경우 791 01:05:31,410 --> 01:05:36,290 그 중 하나에? 792 01:05:41,770 --> 01:05:45,220 의이 하나를 무시 보자. 793 01:05:48,140 --> 01:05:51,660 좋아요. 이 유효합니다. 지금은. / a.out을 실행있어. 794 01:05:51,660 --> 01:06:00,220 인쇄 배열 한 다음 배열의 주소를 인쇄 같은 것이다. 795 01:06:00,220 --> 01:06:02,870 배열은 존재하지 않습니다. 796 01:06:02,870 --> 01:06:08,190 당신이 배열을 인쇄 할 때, 당신은 그 20 바이트를 의미있는 기호를 인쇄하는 알고 있습니다. 797 01:06:08,190 --> 01:06:11,940 배열의 주소를 인쇄, 잘, 배열이 존재하지 않습니다. 798 01:06:11,940 --> 01:06:17,200 이 주소를 가지고 있지 않습니다, 그래서 그냥 그 20 바이트의 주소를 인쇄합니다. 799 01:06:20,820 --> 01:06:28,150 최대한 빨리 아래로 컴파일으로, 당신의 컴파일 buggy4처럼. / a.out 800 01:06:28,150 --> 01:06:30,340 배열 존재입니다. 801 01:06:30,340 --> 01:06:33,640 포인터는 존재합니다. 배열은하지 않습니다. 802 01:06:34,300 --> 01:06:38,060 배열을 대표하는 메모리의 블록은 여전히​​ 존재 803 01:06:38,060 --> 01:06:43,270 하지만 변수 배열과 해당 유형의 변수가 존재하지 않습니다. 804 01:06:46,260 --> 01:06:50,270 사람들은 배열과 포인터 사이의 주요 차이점과 같다 805 01:06:50,270 --> 01:06:55,590 최대한 빨리 함수 호출을 따라서, 어떤 차이가 없습니다. 806 01:06:55,590 --> 01:07:00,460 그러나 내부 배열 자체가 선언되어있는 함수의, sizeof는 다르게 작동 807 01:07:00,460 --> 01:07:05,190 대신 타입의 크기의 블록의 크기를 인쇄하고 있기 때문에, 808 01:07:05,190 --> 01:07:08,950 그 상징이기 때문에 당신은 그것을 변경할 수 없습니다. 809 01:07:08,950 --> 01:07:14,370 일 것과 주소를 인쇄하면 같은 일을 인쇄합니다. 810 01:07:14,370 --> 01:07:18,480 그리고 그 방법은 아주 많아요. 811 01:07:18,480 --> 01:07:20,820 [학생] 당신은 한 번 더 말을 할 수있어? 812 01:07:21,170 --> 01:07:24,170 내가 뭔가를 놓친했을 수 있습니다. 813 01:07:24,170 --> 01:07:29,260 배열의 인쇄 배열과 주소가 같은 일을 인쇄 814 01:07:29,260 --> 01:07:33,180 당신은 포인터의 주소 대 포인터를 인쇄하는 경우 반면에, 815 01:07:33,180 --> 01:07:36,010 하나는 가리키는하고있는 일의 주소를 인쇄, 816 01:07:36,010 --> 01:07:40,360 다른 하나는 스택에있는 포인터의 주소를 인쇄합니다. 817 01:07:40,360 --> 01:07:47,040 당신은 포인터를 변경할 수 있습니다, 당신은 배열 기호를 변경할 수 없습니다. 818 01:07:47,740 --> 01:07:53,270 그리고 sizeof 포인터는 포인터 타입의 크기를 인쇄 할 것이다. 819 01:07:53,270 --> 01:07:57,470 따라서 정수 * P sizeof (P)는 4를 인쇄 할 것입니다 820 01:07:57,470 --> 01:08:04,110 하지만 INT 배열 [5] 인쇄 sizeof (배열) 20을 인쇄 할 것이다. 821 01:08:04,110 --> 01:08:07,480 [학생] 지금 INT 배열 [5] 20 인쇄됩니까? >> 예. 822 01:08:07,480 --> 01:08:13,300 왜 내 buggy4의 IT sizeof (배열)로 사용 때입니다 823 01:08:13,300 --> 01:08:16,660 이 내가 할 <20 일을 저지르고, 그게 바로 우리가 원하던 게 아니 잖아. 824 01:08:16,660 --> 01:08:20,880 우리는 내가 <5 싶습니다. >> [학생] 좋아요. 825 01:08:20,880 --> 01:08:25,569 [보덴] 그리고 최대한 빨리 기능을 전달하기 시작, 826 01:08:25,569 --> 01:08:34,340 우리가 그랬다면 INT * P = 어레이; 827 01:08:34,340 --> 01:08:39,779 이 기능의 내부에, 우리는 기본적으로 동일 방법으로 P와 배열을 사용할 수 있습니다 828 01:08:39,779 --> 01:08:43,710 sizeof 문제와 변화 문제에 대한 제외. 829 01:08:43,710 --> 01:08:49,810 그러나 P는 [0] = 1; 배열 [0] = 1 말과 같은이다; 830 01:08:49,810 --> 01:08:55,600 그리고 곧 우리가 foo는 (배열) 말대로, 또는 foo는 (P)을, 831 01:08:55,600 --> 01:08:59,760 foo는 기능의 내부에,이 두 번 같은 전화입니다. 832 01:08:59,760 --> 01:09:03,350 이 두 통화 사이에 차이가 없습니다. 833 01:09:07,029 --> 01:09:11,080 >> 그에서 좋은 사람들? 좋아요. 834 01:09:14,620 --> 01:09:17,950 우리는 10 분 있습니다. 835 01:09:17,950 --> 01:09:28,319 >> 우리는이 해커 Typer 프로그램을 통해 알아 보도록하겠습니다 836 01:09:28,319 --> 01:09:32,350 작년이나 뭐 나온이 웹 사이트. 837 01:09:34,149 --> 01:09:41,100 당신이 무작위로 입력하고 출력처럼 막 재밌을 거에요 - 838 01:09:41,100 --> 01:09:46,729 간에 파일이로드에서 일어나는하면 입력하는 것처럼 생겼다. 839 01:09:46,729 --> 01:09:52,069 그것은 운영 체제 코드의 어떤 것 같습니다. 840 01:09:53,760 --> 01:09:56,890 우리가 구현하려는거야. 841 01:10:08,560 --> 01:10:11,690 당신은 hacker_typer라는 이름의 바이너리 실행 파일이 있어야합니다 842 01:10:11,690 --> 01:10:14,350 그에게 파일을 하나의 인수에 소요 "해커 입력하십시오." 843 01:10:14,350 --> 01:10:16,480 실행 파일을 실행하면 화면을 삭제해야합니다 844 01:10:16,480 --> 01:10:20,850 그리고 사용자가 누를 키를 때마다 전달 된 파일에서 한 문자를 인쇄 할 수 있습니다. 845 01:10:20,850 --> 01:10:24,990 이 키를 눌러 어떤 키를 그래서, 그것은 버려야 대신 파일에서 문자를 인쇄해야합니다 846 01:10:24,990 --> 01:10:27,810 그 인자입니다. 847 01:10:29,880 --> 01:10:34,350 난 아주 우리가 알아야 할 거에요 일이 무엇인지 말해주지. 848 01:10:34,350 --> 01:10:36,440 그러나 우리는 termios 라이브러리를 체크 아웃하고 싶습니다. 849 01:10:36,440 --> 01:10:44,840 내 평생에이 라이브러리를 사용하지 않은, 그래서 아주 최소한의 목적이 있습니다. 850 01:10:44,840 --> 01:10:48,610 그러나 우리는 너희가 턴 문자를 멀리 던져하는 데 사용할 수있는 라이브러리가 될 것입니다 851 01:10:48,610 --> 01:10:52,390 당신은 인치 표준에 입력하는 경우 852 01:10:56,970 --> 01:11:05,840 따라서 hacker_typer.c, 우리는 # 를 포함 할거야. 853 01:11:05,840 --> 01:11:12,870 termios의 man 페이지를보고 - 난 그게 단말기 OS라도 추측 - 854 01:11:12,870 --> 01:11:16,240 내가 읽는 방법을 모르겠어요. 855 01:11:16,240 --> 01:11:21,040 이를 살펴보면, 이러한 2 파일을 포함 말합니다, 그래서 우리는 그렇게 할 수 있습니다. 856 01:11:37,620 --> 01:11:46,820 >> 우선 먼저, 우리는 우리가 열립니다 파일입니다 하나의 인수에 받고 있습니다. 857 01:11:46,820 --> 01:11:52,420 그래서 어떻게할까요? 어떻게 내가 단일 인자를 확인합니까? 858 01:11:52,420 --> 01:11:56,480 [학생] argc가 동일합니다. >> [보덴] 그래. 859 01:11:56,480 --> 01:12:21,250 그래서, 만약 (argc = 2!) printf ( "사용법 : % s의 [파일 열려면]"). 860 01:12:21,250 --> 01:12:32,750 내가 두 번째 인수를 제공하지 않고 실행하는 경우 이제 - 오, 내가 새 줄이 필요합니다 - 861 01:12:32,750 --> 01:12:36,240 당신이 말하는 사용이 표시됩니다. / hacker_typer, 862 01:12:36,240 --> 01:12:39,770 그리고 두 번째 인자는 I 열려는 파일이어야합니다. 863 01:12:58,430 --> 01:13:01,260 지금은 어떻게해야 하죠? 864 01:13:01,260 --> 01:13:08,490 이 파일에서 읽을 수 있습니다. 어떻게 파일에서 읽습니까? 865 01:13:08,490 --> 01:13:11,920 [학생] 먼저 엽니 다. >> 그래. 866 01:13:11,920 --> 01:13:15,010 그래서 fopen. fopen은 어떻게 생겼어요? 867 01:13:15,010 --> 01:13:22,980 [학생] 파일 이름. >> [보덴] 파일 이름 변수는 argv는 [1]가 될 것입니다. 868 01:13:22,980 --> 01:13:26,110 [학생] 그리고 당신이 그것으로 뭘하려는, 그래서 - >> [보덴] 그래. 869 01:13:26,110 --> 01:13:28,740 기억하지 않은 경우 그럼, 사람 fopen을 할 단지 수 870 01:13:28,740 --> 01:13:32,960 이 경로는 파일 이름입니다 const 숯불 * 경로 될거야 곳 871 01:13:32,960 --> 01:13:34,970 const 숯불 * 모드. 872 01:13:34,970 --> 01:13:38,660 이 모드가 무엇인지 기억하지 발생할 경우에는 모드에 볼 수 있습니다. 873 01:13:38,660 --> 01:13:44,660 맨 페이지의 내부, 슬래시 문자는 당신이 일을 검색하는 데 사용할 수 있습니다. 874 01:13:44,660 --> 01:13:49,790 그래서 모드를 검색 할 수 / 모드를 입력합니다. 875 01:13:49,790 --> 01:13:57,130 N과 N은 검색 검색을 통해주기에 사용할 수 있습니다. 876 01:13:57,130 --> 01:13:59,800 여기가 문자열로 인자 모드 점을 말한다 877 01:13:59,800 --> 01:14:01,930 다음 시퀀스 중 하나가 시작. 878 01:14:01,930 --> 01:14:06,480 읽기에 대한 R 자, 열기 텍스트 파일입니다. 우리가하고 싶은거야. 879 01:14:08,930 --> 01:14:13,210 읽기, 난 저장할하십시오. 880 01:14:13,210 --> 01:14:18,720 문제는 파일 *가 될 것입니다. 지금은 뭘하고 싶어요? 881 01:14:18,720 --> 01:14:21,200 잠시만 요. 882 01:14:28,140 --> 01:14:30,430 좋아요. 지금은 뭘하고 싶어요? 883 01:14:30,430 --> 01:14:32,940 [학생]가 NULL이라면 확인합니다. >> [보덴] 그래. 884 01:14:32,940 --> 01:14:38,690 당신은 파일을 열 때마다, 당신이 성공적으로 열어 할 수 있는지 확인하십시오. 885 01:14:58,930 --> 01:15:10,460 >> 처음 현재 설정을 읽을 수있는 지금은 그 termios 일을하고 싶어 886 01:15:10,460 --> 01:15:14,050 무언가에 그 내용을 저장 한 후 내 설정을 변경하려면 887 01:15:14,050 --> 01:15:19,420 내가 입력하는 모든 문자를 버릴 888 01:15:19,420 --> 01:15:22,520 그리고 난 그 설정을 업데이트하고 싶습니다. 889 01:15:22,520 --> 01:15:27,250 그리고 프로그램의 끝 부분에, 내 원래 설정으로 다시 변경하고 싶습니다. 890 01:15:27,250 --> 01:15:32,080 따라서 구조체 유형은 termios이 될 것입니다, 나는 그 중 두 가지를하려는거야. 891 01:15:32,080 --> 01:15:35,600 첫 번째는 내 current_settings 될 것입니다 892 01:15:35,600 --> 01:15:42,010 그리고 그들은 내 hacker_settings 될거야. 893 01:15:42,010 --> 01:15:48,070 첫째, 내 현재 설정을 저장하려면 겠어 894 01:15:48,070 --> 01:15:53,790 그럼 내가, hacker_settings를 업데이트하려는거야 895 01:15:53,790 --> 01:16:01,570 그리고 내 프로그램의 끝에서 저쪽 현재 설정으로 되돌리려하고 싶습니다. 896 01:16:01,570 --> 01:16:08,660 그럼, 우리 사람 termios를 작동하는 방법은 현재 설정을 저장할 수 있습니다. 897 01:16:08,660 --> 01:16:15,810 우리는 우리가이 INT tcsetattr, INT tcgetattr하신 것으로 알고 있습니다. 898 01:16:15,810 --> 01:16:22,960 나는 그것의 포인터로 termios 구조체를 전달합니다. 899 01:16:22,960 --> 01:16:30,640 이 표시됩니다 방법입니다 - 키이스, 이미 함수가 호출 된 것을 잊어. 900 01:16:30,640 --> 01:16:34,930 복사하고 붙여 넣습니다. 901 01:16:39,150 --> 01:16:45,500 tcgetattr 그래서, 그럼 내가의 정보를 저장한다는 구조체에 전달하려는 902 01:16:45,500 --> 01:16:49,650 이는, current_settings이 될 것입니다 903 01:16:49,650 --> 01:16:59,120 그리고 첫 번째 인수는 내가의 특성을 저장하고자하는 것은에 대한 파일 설명입니다. 904 01:16:59,120 --> 01:17:04,360 어떤 파일 설명이되어 당신이 파일을 열 언제든지처럼, 그것은 파일 설명자를 얻을 수 있습니다. 905 01:17:04,360 --> 01:17:14,560 언제 fopen 변수는 argv [1], 당신이 참조하는 파일 설명자를 도착 906 01:17:14,560 --> 01:17:16,730 당신이을 읽거나 기록 할 때마다. 907 01:17:16,730 --> 01:17:19,220 그래서 제가 여기 사용하려는 파일 설명 없습니다. 908 01:17:19,220 --> 01:17:21,940 당신은 기본적으로 세 건 파일 설명이 있습니다 909 01:17:21,940 --> 01:17:24,310 이는에 표준 아웃 및 표준 오류 표준입니다. 910 01:17:24,310 --> 01:17:29,960 기본적으로, 나는 0, 표준 출력은 1이고, 표준 오차은 2입니다의 표준 것 같아요. 911 01:17:29,960 --> 01:17:33,980 그래서 나는의 설정을 변경하려면 어떻게해야합니까? 912 01:17:33,980 --> 01:17:37,370 내가 문자를 누르 때마다의 설정을 변경하려면 913 01:17:37,370 --> 01:17:41,590 나는 대신 화면에 출력을 멀리 그 문자를 던져하고 싶습니다. 914 01:17:41,590 --> 01:17:45,960 무엇 스트림 - - 표준 아웃, 또는 표준 오류의 표준 915 01:17:45,960 --> 01:17:52,050 나는 키보드에 입력 할 때 일에 응답? >> >> 예 인치 [학생] 표준. 916 01:17:52,050 --> 01:17:56,450 그러니 난 영을 할 수 아니면 표준 입력을 수행 할 수 있습니다. 917 01:17:56,450 --> 01:17:59,380 나는 인치 표준의 current_settings를 받고 918 01:17:59,380 --> 01:18:01,720 >> 지금은 그 설정을 업데이트하려면 919 01:18:01,720 --> 01:18:07,200 그래서 일단 내 current_settings가 무엇 hacker_settings에 복사됩니다. 920 01:18:07,200 --> 01:18:10,430 그리고 structs 작업이 얼마나 그냥 복사됩니다. 921 01:18:10,430 --> 01:18:14,510 당신이 기대하는대로이 모든 분야 복사합니다. 922 01:18:14,510 --> 01:18:17,410 >> 지금은 필드의 일부를 업데이트하고 싶습니다. 923 01:18:17,410 --> 01:18:21,670 termios을 보면,이 많은을 읽어해야 924 01:18:21,670 --> 01:18:24,110 당신이 찾도록 할 것입니다 볼하려면, 925 01:18:24,110 --> 01:18:28,210 하지만 당신이보고 싶지 나갈 수있는 플래그는, 에코 아르 926 01:18:28,210 --> 01:18:33,110 그래서 에코 입력 문자가 포착 됐습니다. 927 01:18:33,110 --> 01:18:37,710 우선 설정하려면 - 필드가 무엇인지 이미 잊어 했어요. 928 01:18:45,040 --> 01:18:47,900 이 구조체의 모양입니다. 929 01:18:47,900 --> 01:18:51,060 입력 모드 그래서 나는 우리가 변경하고자하는 생각합니다. 930 01:18:51,060 --> 01:18:54,210 우리가 그렇게 우리가 바꾸고 싶습니다 있는지 확인하기 위해 솔루션을 살펴 보겠습니다. 931 01:19:04,060 --> 01:19:12,610 우리 모두를 볼 필요 방지하기 위해 lflag를 변경하고 싶습니다. 932 01:19:12,610 --> 01:19:14,670 우리는 지역의 모드를 변경하고 싶습니다. 933 01:19:14,670 --> 01:19:17,710 당신은 최선을 다가 있어야 할 곳 이해이 모든 게 읽어해야 934 01:19:17,710 --> 01:19:19,320 우리가 변경하고자하는. 935 01:19:19,320 --> 01:19:24,120 그러나 우리가 그를 변경하려면 거예요 현지 모드의 내부입니다. 936 01:19:27,080 --> 01:19:33,110 따라서 hacker_settings.cc_lmode은이란이다. 937 01:19:39,630 --> 01:19:43,020 c_lflag. 938 01:19:49,060 --> 01:19:52,280 우리는 비트 연산자로 얻을 곳입니다. 939 01:19:52,280 --> 01:19:54,860 우린 시간이 좀 만, 우리는 진정한 빠르게 통과합니다. 940 01:19:54,860 --> 01:19:56,600 우리가 비트 연산자에 들어가 곳입니다 941 01:19:56,600 --> 01:19:59,950 내 생각은 어디 한 번 오래 전에 말한 당신이 플래그를 처리 시작할 때마다, 942 01:19:59,950 --> 01:20:03,370 당신은 비트 연산자를 많이 사용거야. 943 01:20:03,370 --> 01:20:08,240 플래그의 각 비트는 행동을 일종의에 해당합니다. 944 01:20:08,240 --> 01:20:14,090 그래서 여기,이 플래그는 모두 다른 일을 의미 여러 가지의 무리가 있습니다. 945 01:20:14,090 --> 01:20:18,690 하지만 내가보고 싶은 것만 메아리에 해당하는 비트를 해제합니다. 946 01:20:18,690 --> 01:20:25,440 그럼 방향으로 회전 내가 어떻게에서 & = ¬ 에코. 947 01:20:25,440 --> 01:20:30,110 사실,이 수첩 같은 거 같아요. 난 그냥 다시 확인해거야. 948 01:20:30,110 --> 01:20:34,050 난 termios 할 수 있습니다. 단지 에코있어. 949 01:20:34,050 --> 01:20:38,440 에코는 단일 비트가 될 것입니다. 950 01:20:38,440 --> 01:20:44,230 ¬ 에코는 모든 플래그가 true로 설정되어 즉, 모든 비트가 1로 설정되어 의미 것입니다 951 01:20:44,230 --> 01:20:47,140 에코 비트를 제외하고. 952 01:20:47,140 --> 01:20:53,830 이걸 내 로컬 플래그를 종료함으로써, 현재 true로 설정되어있는 모든 플래그를 의미 953 01:20:53,830 --> 01:20:56,520 여전히 true로 설정됩니다. 954 01:20:56,520 --> 01:21:03,240 내 에코 플래그가 true로 설정되어있는 경우, 이것은 반드시 에코 플래그를 false로 설정되어 있습니다. 955 01:21:03,240 --> 01:21:07,170 따라서이 코드 라인은 에코 플래그를 해제합니다. 956 01:21:07,170 --> 01:21:16,270 코드의 다른 라인은, 단지 그것들 시간에 관심을 복사 한 다음이를 설명 할 것이다. 957 01:21:27,810 --> 01:21:30,180 솔루션에서 그는 0 밝혔다. 958 01:21:30,180 --> 01:21:33,880 그것은 명시 적으로 표준 입력을 말 낫겠 네요. 959 01:21:33,880 --> 01:21:42,100 >> 여기 ICANON | 나 또한 반향을하고있는 것을 확인할 수 있습니다. 960 01:21:42,100 --> 01:21:46,650 ICANON는 표준 모드를​​ 의미합니다 별도의 뭔가를 의미합니다. 961 01:21:46,650 --> 01:21:50,280 당신이 명령 줄을 입력 할 때 어떤 표준 모드 수단은, 보통이다 962 01:21:50,280 --> 01:21:54,670 당신은 줄 바꿈 나오기 전까지의 표준은 아무것도 처리하지 않습니다. 963 01:21:54,670 --> 01:21:58,230 그래서 당신은 GetString 않는 경우, 당신은 줄 바꿈 공격 후, 물건의 무리를 입력합니다. 964 01:21:58,230 --> 01:22:00,590 이 인치 표준에 전송 때입니다 965 01:22:00,590 --> 01:22:02,680 그 기본입니다. 966 01:22:02,680 --> 01:22:05,830 당신이 키를 눌러 지금 모든 단일 문자를 표준 모드를​​ 해제하면 967 01:22:05,830 --> 01:22:10,910 어떻게, 이런 일을 처리 할 속도가 느린이기 때문에 보통 나쁜 거라고되며, 처리 치기 968 01:22:10,910 --> 01:22:14,330 이 전체 라인에를 버퍼링하는 것이 좋은 이유입니다. 969 01:22:14,330 --> 01:22:16,810 하지만 각 문자를 처리하고 싶어 970 01:22:16,810 --> 01:22:18,810 저 한테 개행를 공격 할 것이 싫은부터 971 01:22:18,810 --> 01:22:21,280 이 모든 문자를 처리 전에 입력 된습니다. 972 01:22:21,280 --> 01:22:24,760 이 표준 모드를​​ 해제합니다. 973 01:22:24,760 --> 01:22:31,320 실제로 문자를 처리 할 때이 물건은 그냥 의미합니다. 974 01:22:31,320 --> 01:22:35,830 최대한 빨리 그들을 입력있어로를 처리,이 즉시 처리 의미합니다. 975 01:22:35,830 --> 01:22:42,510 그리고이에 표준 내 설정을 업데이트하는 기능입니다 976 01:22:42,510 --> 01:22:45,480 그리고 TCSA 수단은 지금 해. 977 01:22:45,480 --> 01:22:50,310 스트림에 현재 모든이 처리 될 때까지 다른 옵션은 기다릴 수 있습니다. 978 01:22:50,310 --> 01:22:52,030 그건 정말 중요하지 않습니다. 979 01:22:52,030 --> 01:22:56,920 그냥 지금 내 설정이 hacker_typer_settings 현재 무엇이든 할 변경합니다. 980 01:22:56,920 --> 01:23:02,210 내가 그것을 hacker_settings라고 추측 있으니, 그걸를 변경 보자. 981 01:23:09,610 --> 01:23:13,500 hacker_settings에 이르기까지 모든을 변경합니다. 982 01:23:13,500 --> 01:23:16,870 >> 지금 우리의 프로그램의 끝에서 우리는 되돌릴 싶을 거예요 983 01:23:16,870 --> 01:23:20,210 normal_settings의 내부 현재 무엇을, 984 01:23:20,210 --> 01:23:26,560 이는 단지 및 normal_settings 같이 예정이다. 985 01:23:26,560 --> 01:23:30,650 제가 원래 발생 이후 내 normal_settings 중 하나를 변경하지 않은 확인합니다. 986 01:23:30,650 --> 01:23:34,520 그런 다음 그들을 다시 변경, 내가 말을 다시 전달합니다. 987 01:23:34,520 --> 01:23:38,390 이 업데이트했습니다. 좋아요. 988 01:23:38,390 --> 01:23:43,900 >> 내부 여기 지금이 시간에 관심의 코드를 설명 할 것이다. 989 01:23:43,900 --> 01:23:46,350 그렇게 많은 코드가 없습니다. 990 01:23:50,770 --> 01:24:03,750 우리는 파일에서 문자를 읽을 참조하십시오. 우리는 F했다. 991 01:24:03,750 --> 01:24:07,850 이제 남자 fgetc 할 수 있습니다,하지만 어떻게 fgetc 일 것입니다 992 01:24:07,850 --> 01:24:11,910 그냥 당신이 방금 읽거나 EOF하는 문자를 반환하는거야 있으며, 993 01:24:11,910 --> 01:24:15,680 이는 파일이나 일부 오류 일어나고의 마지막에 해당합니다. 994 01:24:15,680 --> 01:24:19,900 우리는 파일의 단일 문자를 읽을 계속, 루프 아르 995 01:24:19,900 --> 01:24:22,420 우리는 읽을 문자가 부족까지. 996 01:24:22,420 --> 01:24:26,650 우리가 그렇게하는 동안, 우리는 인치 표준에서 단일 문자를 기다려 997 01:24:26,650 --> 01:24:29,090 매번 당신은 명령 줄에서 뭔가를 입력 998 01:24:29,090 --> 01:24:32,820 인치 표준에서 캐릭터 읽는 그 999 01:24:32,820 --> 01:24:38,330 그런 다음 putchar은 우리가 파일의 표준 출력을 여기에 읽기 숯불을 넣어 것입니다. 1000 01:24:38,330 --> 01:24:42,890 당신은 남자 putchar 할 수 있지만, 그냥 일반에게 태우고, 그 문자를 인쇄있어. 1001 01:24:42,890 --> 01:24:51,600 같은 생각, 당신은 또한 단지 printf ( "% C", C)를 할 수 있습니다. 1002 01:24:53,330 --> 01:24:56,670 그게 우리 작품의 대량을 할거야. 1003 01:24:56,670 --> 01:25:00,300 >> 우리가 원하는거야 마지막 것은 우리의 파일을 fclose입니다. 1004 01:25:00,300 --> 01:25:03,310 당신은 fclose하지 않은 경우에는 메모리 누수입니다. 1005 01:25:03,310 --> 01:25:06,680 우리는 우리가 원래 열 파일을 fclose하려면, 그게 그건 생각합니다. 1006 01:25:06,680 --> 01:25:13,810 우리가 할 경우, 이미 문제가 생겼. 1007 01:25:13,810 --> 01:25:17,260 어디 봅시다. 1008 01:25:17,260 --> 01:25:19,960 그것은 무엇을 불평 했지? 1009 01:25:19,960 --> 01:25:30,220 예상 'INT'는 주장 유형 '구조체 _IO_FILE *'입니다. 1010 01:25:36,850 --> 01:25:39,370 그이 성공한다면 우리는 볼 수 있습니다. 1011 01:25:45,210 --> 01:25:53,540 만 C99에서 허용. Augh. 좋아요, hacker_typer을합니다. 1012 01:25:53,540 --> 01:25:57,760 이제 우리는보다 유용한 설명을. 1013 01:25:57,760 --> 01:25:59,900 그래서 선언하지 않은 식별자 'normal_settings'중 하나를 사용하십시오. 1014 01:25:59,900 --> 01:26:04,170 나는 normal_settings 전화하지 않았어. 나는 current_settings했다. 1015 01:26:04,170 --> 01:26:12,090 그럼 그 모든 변경 보자. 1016 01:26:17,920 --> 01:26:21,710 지금 인수를 전달. 1017 01:26:26,290 --> 01:26:29,500 지금은이 공을드립니다. 1018 01:26:29,500 --> 01:26:36,720 좋아요. . / hacker_typer cp.c. 1019 01:26:36,720 --> 01:26:39,590 나는 또한 처음에 화면을 지우 없습니다. 1020 01:26:39,590 --> 01:26:42,960 하지만 당신은 화면을 삭제 방법에 대해 알아 보려면 마지막 문제 세트로 볼 수 있습니다. 1021 01:26:42,960 --> 01:26:45,160 단지 일부 문자를 인쇄 할거야 1022 01:26:45,160 --> 01:26:47,210 이게 내가하고 싶었던 일을하고있는 동안. 1023 01:26:47,210 --> 01:26:48,900 좋아요. 1024 01:26:48,900 --> 01:26:55,280 그리고이 대신 표준 입력 0이되기 위해 필요한 이유에 대한 생각 1025 01:26:55,280 --> 01:27:00,560 어떤 #, 0를 정의해야합니다 1026 01:27:00,560 --> 01:27:03,890 이 그렇게 불평 - 1027 01:27:13,150 --> 01:27:19,360 I 파일 설명가 있다고하지만이 또한 FILE *을있을 때하기 전에, 1028 01:27:19,360 --> 01:27:23,210 파일 설명은 단지 하나의 정수입니다 1029 01:27:23,210 --> 01:27:26,970 FILE *는 그와 관련된 물건을 왕창 가지고 반면. 1030 01:27:26,970 --> 01:27:30,380 우리가 대신 표준 입력 0 말을 할 필요가있는 이유 1031 01:27:30,380 --> 01:27:37,480 그 표준 입력 파일 설명자 0 참조하는 이야기로 가리키는 파일 *입니다. 1032 01:27:37,480 --> 01:27:45,070 그래서, 여기까지 제가 fopen을 할 때 (변수는 argv [1], 내가 다시 FILE *를 발생합니다. 1033 01:27:45,070 --> 01:27:51,180 하지만 어느 해당 파일 *에서 해당 파일에 대한 파일 설명자에 해당하는 일입니다. 1034 01:27:51,180 --> 01:27:57,430 당신이 열려있는 동안 man 페이지를 보면 나는 당신이 남자 3 공개해야 할 것 같아요 - 아뇨 - 1035 01:27:57,430 --> 01:27:59,380 사람이 오픈 - 예. 1036 01:27:59,380 --> 01:28:06,250 당신은 열린의 페이지를 보면, 오픈은 낮은 수준의 fopen 같다 1037 01:28:06,250 --> 01:28:09,350 그리고 실제 파일 설명을 반환있어. 1038 01:28:09,350 --> 01:28:12,050 fopen이 열려 위에 물건을 많이 수행, 1039 01:28:12,050 --> 01:28:17,640 대신 파일 기술자가 전체 파일에 * 포인터를 반환 그냥 반환하는 1040 01:28:17,640 --> 01:28:20,590 내부에있는 우리의 작은 파일 설명입니다. 1041 01:28:20,590 --> 01:28:25,020 FILE의 *들 이야기로 의미에서 너무 표준 1042 01:28:25,020 --> 01:28:29,120 0 자체가 단지 파일 설명자 표준을 의미합니다 반면. 1043 01:28:29,120 --> 01:28:32,160 >> 질문이 있으십니까? 1044 01:28:32,160 --> 01:28:35,930 [웃음]은 꺼졌습니다. 1045 01:28:35,930 --> 01:28:39,140 괜찮아요. 우리는 끝났어. [웃음] 1046 01:28:39,140 --> 01:28:42,000 >> [CS50.TV]