1 00:00:00,000 --> 00:00:02,520 [Powered by Google Translate] [Sección 4 - máis cómodo] 2 00:00:02,520 --> 00:00:04,850 [Rob Bowden - Harvard University] 3 00:00:04,850 --> 00:00:07,370 [Esta é CS50. - CS50.TV] 4 00:00:08,920 --> 00:00:13,350 Temos un exame mañá, se vostedes non sabían diso. 5 00:00:14,810 --> 00:00:20,970 É basicamente sobre todo o que podería ter visto en clase ou debería ter visto en clase. 6 00:00:20,970 --> 00:00:26,360 Isto inclúe agullas, a pesar de seren un tema moi recente. 7 00:00:26,360 --> 00:00:29,860 Debe, polo menos, entender os altos niveis de los. 8 00:00:29,860 --> 00:00:34,760 Calquera cousa que se foi en clase, ten que entender o quiz. 9 00:00:34,760 --> 00:00:37,320 Entón se ten preguntas sobre eles, pode preguntar-lles agora. 10 00:00:37,320 --> 00:00:43,280 Pero esta vai ser unha sesión moi liderado por estudantes, onde vostedes preguntas, 11 00:00:43,280 --> 00:00:45,060 por iso espero que as persoas teñen preguntas. 12 00:00:45,060 --> 00:00:48,020 Alguén ten dúbidas? 13 00:00:49,770 --> 00:00:52,090 Si >> [Alumno] pode ir máis de punteiros de novo? 14 00:00:52,090 --> 00:00:54,350 Vou pasar por riba de punteiros. 15 00:00:54,350 --> 00:00:59,180 Todas as súas variables, necesariamente, vivir na memoria, 16 00:00:59,180 --> 00:01:04,450 pero xeralmente non hai problema con iso e acaba de dicir x + 2 e + 3 y 17 00:01:04,450 --> 00:01:07,080 eo compilador pode descubrir onde as cousas están a vivir para ti. 18 00:01:07,080 --> 00:01:12,990 Unha vez que está lidando con punteiros, agora está explícitamente usando os enderezos de memoria. 19 00:01:12,990 --> 00:01:19,800 Así, unha única variable só vai vivir nun único enderezo en calquera momento. 20 00:01:19,800 --> 00:01:24,040 Se queremos declarar un punteiro, que é o tipo vai parecer? 21 00:01:24,040 --> 00:01:26,210 >> Quero declarar un punteiro p. O que fai o tipo de aspecto? 22 00:01:26,210 --> 00:01:33,530 [Estudante] int * p. Si >>. Así, int * p. 23 00:01:33,530 --> 00:01:38,030 E como fago para facelo apuntar x? >> [Alumno] ampersand. 24 00:01:40,540 --> 00:01:45,300 [Bowden] Entón comercial é chamado literalmente o enderezo do operador. 25 00:01:45,300 --> 00:01:50,460 Polo tanto, cando digo & x está quedando o enderezo de memoria da variable x. 26 00:01:50,460 --> 00:01:56,790 Entón agora eu teño o punteiro p, e en calquera lugar no meu código podo usar p * 27 00:01:56,790 --> 00:02:02,960 ou eu podería usar X e vai ser exactamente a mesma cousa. 28 00:02:02,960 --> 00:02:09,520 (* P). O que se está facendo? O que significa que a estrela significa? 29 00:02:09,520 --> 00:02:13,120 [Estudante] significa un valor nese punto. Si >>. 30 00:02:13,120 --> 00:02:17,590 Entón, se miramos para el, pode ser moi útil para aproveitar os diagramas 31 00:02:17,590 --> 00:02:22,230 onde esta é unha pequena caixa de memoria para x, que pasa de ter o valor 4, 32 00:02:22,230 --> 00:02:25,980 entón temos unha pequena caixa de memoria para p, 33 00:02:25,980 --> 00:02:31,590 e así p apunta x, para que debuxe unha frecha de p para x. 34 00:02:31,590 --> 00:02:40,270 Así, cando dicimos p * estamos dicindo ir a caixa que é p. 35 00:02:40,270 --> 00:02:46,480 Star é seguir a frecha e, a continuación, facer o que quere con esta caixa aí. 36 00:02:46,480 --> 00:03:01,090 Entón eu podo dicir * p = 7, e que pode para o cadro que é x e cambio que a 7. 37 00:03:01,090 --> 00:03:13,540 Ou eu podería dicir int z = * p * 2; Isto é confuso porque é estrela estrela. 38 00:03:13,540 --> 00:03:19,230 A estrela é unha dereferencing p, outra estrela está multiplicando por 2. 39 00:03:19,230 --> 00:03:26,780 Repare que eu podería ter tan ben substituíu o p * con x. 40 00:03:26,780 --> 00:03:29,430 Podes usalos da mesma forma. 41 00:03:29,430 --> 00:03:38,000 E máis tarde eu podo ter punto P para unha cousa totalmente nova. 42 00:03:38,000 --> 00:03:42,190 Só podo dicir p = &z; 43 00:03:42,190 --> 00:03:44,940 Entón, agora p sen puntos máis longos para x, que apunta a z. 44 00:03:44,940 --> 00:03:50,510 E en calquera momento que fago p * é o mesmo que facer z. 45 00:03:50,510 --> 00:03:56,170 Entón o único útil sobre iso é cando comezan a entrar en funcións. 46 00:03:56,170 --> 00:03:59,790 >> É unha especie de inútil para declarar un punteiro que apunta a algo 47 00:03:59,790 --> 00:04:03,140 e entón está só dereferencing-lo 48 00:04:03,140 --> 00:04:06,060 cando podería ter usado a variable orixinal para comezar. 49 00:04:06,060 --> 00:04:18,190 Pero cando entra en funcións - entón imos dicir que temos algunha función, int foo, 50 00:04:18,190 --> 00:04:32,810 que leva un punteiro e só fai * p = 6; 51 00:04:32,810 --> 00:04:39,990 Como vimos antes, con intercambio, non se pode facer un intercambio de efectivo e unha función separada 52 00:04:39,990 --> 00:04:45,180 por só pasando enteiros porque todo na C está sempre pasando por valor. 53 00:04:45,180 --> 00:04:48,360 Mesmo cando está pasando punteiros está pasando por valor. 54 00:04:48,360 --> 00:04:51,940 O que pasa é que eses valores son enderezos de memoria. 55 00:04:51,940 --> 00:05:00,770 Polo tanto, cando digo foo (p), eu estou pasando o punteiro para a función foo 56 00:05:00,770 --> 00:05:03,910 e, a continuación, fai foo * p = 6; 57 00:05:03,910 --> 00:05:08,600 Así, dentro desa función, * p é aínda equivalente a x, 58 00:05:08,600 --> 00:05:12,720 pero eu non podo usar x dentro desa función, porque non é ámbito dentro desa función. 59 00:05:12,720 --> 00:05:19,510 Entón * p = 6 é a única forma que podo acceder a unha variable local doutra función. 60 00:05:19,510 --> 00:05:23,600 Ou, ben, os punteiros son o único xeito que podo acceder a unha variable local doutra función. 61 00:05:23,600 --> 00:05:31,600 [Alumno] Digamos que quería volver a un punteiro. Como exactamente fai iso? 62 00:05:31,600 --> 00:05:44,270 [Bowden] Voltar un punteiro como algo int y = 3; retorno e y? >> [Estudante] Yeah. 63 00:05:44,270 --> 00:05:48,480 [Bowden] Okay. Vostede non debe facelo. Isto é malo. 64 00:05:48,480 --> 00:05:59,480 Eu creo que vin nestes diapositivas das clases que comezaron a ver neste diagrama toda a memoria 65 00:05:59,480 --> 00:06:02,880 onde ata aquí ten o enderezo de memoria 0 66 00:06:02,880 --> 00:06:09,550 e aquí ten de enderezo de memoria 4 GB ou 2 elevado á 32. 67 00:06:09,550 --> 00:06:15,120 Entón tes algunhas cousas e algunhas cousas e entón ten a súa pila 68 00:06:15,120 --> 00:06:21,780 e ten a súa pila, que só comezou a aprender sobre, crecendo. 69 00:06:21,780 --> 00:06:24,390 [Alumno] non é a pila enriba da pila? 70 00:06:24,390 --> 00:06:27,760 >> Si A pila é por riba, non é? >> [Alumno] Ben, el puxo 0 encima. 71 00:06:27,760 --> 00:06:30,320 [Estudante] Oh, el puxo 0 encima. >> [Alumno] Ah, ok. 72 00:06:30,320 --> 00:06:36,060 Disclaimer: Calquera lugar con CS50 vai velo deste xeito. >> [Alumno] Okay. 73 00:06:36,060 --> 00:06:40,290 É que cando está a ver primeiro pilas, 74 00:06:40,290 --> 00:06:45,000 como cando pensar en unha pila pensas de apilar as cousas enriba da outra. 75 00:06:45,000 --> 00:06:50,810 Entón, temos a tendencia de virar esta en torno de xeito conxunto está crecendo como unha pila normalmente 76 00:06:50,810 --> 00:06:55,940 en vez da pila colgada abaixo. >> [Alumno] non montes tecnicamente crecer moito, aínda que? 77 00:06:55,940 --> 00:07:01,100 Depende do que entende por crecer. 78 00:07:01,100 --> 00:07:04,010 A pila e heap crecer sempre en direccións opostas. 79 00:07:04,010 --> 00:07:09,420 Unha pila é sempre crecendo no sentido de que está crecendo 80 00:07:09,420 --> 00:07:12,940 para enderezos de memoria máis altas, ea pila está crecendo para abaixo 81 00:07:12,940 --> 00:07:17,260 en que é crecente para enderezos menores de memoria. 82 00:07:17,260 --> 00:07:20,250 Así, o cumio é 0 e no fondo e enderezos de memoria de alta. 83 00:07:20,250 --> 00:07:26,390 Ambos están crecendo, só en direccións opostas. 84 00:07:26,390 --> 00:07:29,230 [Estudante] Eu só quería dicir que porque dixo que poñer pila na parte inferior 85 00:07:29,230 --> 00:07:33,640 porque parece máis intuitivo porque, para a pila para comezar na parte superior de unha pila, 86 00:07:33,640 --> 00:07:37,520 pila é por riba de ti tamén, entón iso é - >> Yeah. 87 00:07:37,520 --> 00:07:44,960 Tamén pensa da pila como o crecemento e maior, pero a pila máis. 88 00:07:44,960 --> 00:07:50,280 Así, a pila é o que nós medio que queremos mostrar crecendo. 89 00:07:50,280 --> 00:07:55,390 Pero en todo lugar que mira de outra forma vai amosar o enderezo 0 arriba 90 00:07:55,390 --> 00:07:59,590 eo enderezo de memoria máis alto na parte inferior, por iso esta é a súa visión usual de memoria. 91 00:07:59,590 --> 00:08:02,100 >> Ten unha pregunta? 92 00:08:02,100 --> 00:08:04,270 [Alumno] Pode dicir máis sobre o monte? 93 00:08:04,270 --> 00:08:06,180 Si Eu vou chegar a iso nun segundo. 94 00:08:06,180 --> 00:08:12,220 En primeiro lugar, por que volver para devolver & y é unha cousa ruín, 95 00:08:12,220 --> 00:08:18,470 na pila ten unha morea de cadros de pila que representan todas as funcións 96 00:08:18,470 --> 00:08:20,460 que foron chamados. 97 00:08:20,460 --> 00:08:27,990 Entón, ignorando as cousas anteriores, o principio da súa pila é sempre vai ser a función principal 98 00:08:27,990 --> 00:08:33,090 xa que é a primeira función que está a ser chamado. 99 00:08:33,090 --> 00:08:37,130 E entón cando chamar outra función, a pila vai medrar para abaixo. 100 00:08:37,130 --> 00:08:41,640 Entón, se eu chamar algunha función, foo, e fai a súa estrutura propia pila, 101 00:08:41,640 --> 00:08:47,280 pode chamar dalgunha función bar, que recibe o seu cadro de pila propia. 102 00:08:47,280 --> 00:08:49,840 E bar pode ser recursiva e que podería chamarse, 103 00:08:49,840 --> 00:08:54,150 e para que segunda chamada para a barra vai estar a súa estrutura propia pila. 104 00:08:54,150 --> 00:08:58,880 E así o que pasa nestes cadros de pila son as variables locais 105 00:08:58,880 --> 00:09:03,450 e todos os argumentos da función que - 106 00:09:03,450 --> 00:09:08,730 Todas as cousas que están no lugar delimitado para esta función vai neses cadros de pila. 107 00:09:08,730 --> 00:09:21,520 Entón isto significa que cando dixo algo así como bar é unha función, 108 00:09:21,520 --> 00:09:29,270 Eu só vou declarar un enteiro e, a continuación, voltar un punteiro para este enteiro. 109 00:09:29,270 --> 00:09:33,790 Entón onde é que y vivir? 110 00:09:33,790 --> 00:09:36,900 [Estudante] y vive no bar. >> [Bowden] Yeah. 111 00:09:36,900 --> 00:09:45,010 En algún lugar neste pequeno cadrado de memoria é unha praza que ten littler y nel. 112 00:09:45,010 --> 00:09:53,370 Cando volten & y, estou volvendo un punteiro para este pequeno bloque de memoria. 113 00:09:53,370 --> 00:09:58,400 Pero entón, cando a función devolve o seu cadro de pila é pego na pila. 114 00:10:01,050 --> 00:10:03,530 E é por iso que se chama de pila. 115 00:10:03,530 --> 00:10:06,570 É como a estrutura de datos de pila, se sabe o que é. 116 00:10:06,570 --> 00:10:11,580 Ou incluso como unha pila de bandexas é sempre o exemplo 117 00:10:11,580 --> 00:10:16,060 principal a ir na parte inferior, a continuación, a función de primeiro ligar está a ir enriba do que, 118 00:10:16,060 --> 00:10:20,400 e non pode volver ao inicio ata voltar todas as funcións que foron chamados 119 00:10:20,400 --> 00:10:22,340 que foron colocados na parte superior do mesmo. 120 00:10:22,340 --> 00:10:28,650 >> [Alumno] Entón, se realmente fixo retornar a Y &, ese valor está suxeito a modificación sen previo aviso. 121 00:10:28,650 --> 00:10:31,290 Si, é - >> [alumno] Podería ser substituído. Si >>. 122 00:10:31,290 --> 00:10:34,660 É completamente - Se tentar - 123 00:10:34,660 --> 00:10:38,040 Esta sería tamén unha barra * int porque está retornando un punteiro, 124 00:10:38,040 --> 00:10:41,310 así, o seu tipo de retorno é int *. 125 00:10:41,310 --> 00:10:46,500 Se tentar usar o valor de retorno desa función, é un comportamento indefinido 126 00:10:46,500 --> 00:10:51,770 porque ese punteiro apunta a memoria malo. >> [Alumno] Okay. 127 00:10:51,770 --> 00:11:01,250 Entón, o que, por exemplo, declarou int * y = malloc (sizeof (int))? 128 00:11:01,250 --> 00:11:03,740 Así é mellor. Si 129 00:11:03,740 --> 00:11:07,730 [Alumno] Nós conversas sobre como cando arrastrar as cousas para a nosa lixo 130 00:11:07,730 --> 00:11:11,750 eles non están realmente borrado, só perden os seus punteiros. 131 00:11:11,750 --> 00:11:15,550 Polo tanto, neste caso realmente borrar o valor ou é aínda existe na memoria? 132 00:11:15,550 --> 00:11:19,130 Para a maior parte, vai estar alí. 133 00:11:19,130 --> 00:11:24,220 Pero imos dicir que ocorrer para chamar algunha outra función, Baz. 134 00:11:24,220 --> 00:11:28,990 Baz vai estar a súa estrutura propia pila aquí. 135 00:11:28,990 --> 00:11:31,470 Vai ser a substitución de todas estas cousas, 136 00:11:31,470 --> 00:11:34,180 e entón se tentar máis tarde e usar o punteiro que ten antes, 137 00:11:34,180 --> 00:11:35,570 non vai ser o mesmo valor. 138 00:11:35,570 --> 00:11:38,150 Vai cambiar só porque chamou o Baz función. 139 00:11:38,150 --> 00:11:43,080 [Alumno] Pero se non tivésemos, estariamos aínda obter 3? 140 00:11:43,080 --> 00:11:44,990 [Bowden] En toda probabilidade, que o faría. 141 00:11:44,990 --> 00:11:49,670 Pero non pode contar con iso. C só di comportamento indefinido. 142 00:11:49,670 --> 00:11:51,920 >> [Estudante] Oh, é verdade. Okay. 143 00:11:51,920 --> 00:11:58,190 Entón, cando quere voltar un punteiro, que é o lugar onde malloc vén en uso. 144 00:12:00,930 --> 00:12:15,960 Eu estou escribindo en realidade, só devolver malloc (3 * sizeof (int)). 145 00:12:17,360 --> 00:12:24,050 Nós falaremos sobre malloc máis nun segundo, pero a idea de malloc é todo das súas variables locais 146 00:12:24,050 --> 00:12:26,760 sempre van para a pila. 147 00:12:26,760 --> 00:12:31,570 Calquera cousa que é malloced vai na pila, e será para sempre e sempre na pila 148 00:12:31,570 --> 00:12:34,490 ata que explicitamente libertá-lo. 149 00:12:34,490 --> 00:12:42,130 Entón isto significa que cando malloc algo, que vai sobrevivir tras o retorno da función. 150 00:12:42,130 --> 00:12:46,800 [Alumno] Será que vai sobrevivir despois de que o programa deixa de funcionar? Non >> 151 00:12:46,800 --> 00:12:53,180 Ok, entón vai estar alí ata que o programa é todo o camiño feito en execución. Si >>. 152 00:12:53,180 --> 00:12:57,510 Podemos ir máis detalles do que acontece cando o programa deixa de funcionar. 153 00:12:57,510 --> 00:13:02,150 Podes ter para me lembrar, pero que é unha cousa separada enteiramente. 154 00:13:02,150 --> 00:13:04,190 [Estudante] Entón malloc crea un punteiro? Si >>. 155 00:13:04,190 --> 00:13:13,030 Malloc - >> [estudante] Coido que malloc designa un bloque de memoria que un punteiro pode usar. 156 00:13:15,400 --> 00:13:19,610 [Bowden] Eu quero que diagrama novo. >> [Alumno] Entón, esa función funciona, aínda que? 157 00:13:19,610 --> 00:13:26,430 [Alumno] Si, malloc designa un bloque de memoria que pode usar, 158 00:13:26,430 --> 00:13:30,470 e, a continuación, retorna o enderezo do primeiro bloque de memoria que. 159 00:13:30,470 --> 00:13:36,750 >> [Bowden] Yeah. Entón, cando malloc vostede, está pegando un bloque de memoria 160 00:13:36,750 --> 00:13:38,260 que está actualmente no heap. 161 00:13:38,260 --> 00:13:43,040 Se a pila é moi pequeno, entón a pila só vai medrar, e crece nesa dirección. 162 00:13:43,040 --> 00:13:44,650 Entón, digamos que a pila é moi pequeno. 163 00:13:44,650 --> 00:13:49,960 Entón, está a piques de crecer un pouco e voltar un punteiro para este bloque que só creceu. 164 00:13:49,960 --> 00:13:55,130 Cando o material libre, está facendo máis espazo no heap, 165 00:13:55,130 --> 00:14:00,030 Entón unha chamada posterior para malloc pode reutilizar que a memoria que xa liberado. 166 00:14:00,030 --> 00:14:09,950 A cousa importante sobre malloc e free é que lle dá o control completo 167 00:14:09,950 --> 00:14:12,700 sobre a vida destes bloques de memoria. 168 00:14:12,700 --> 00:14:15,420 As variables globais son sempre vivo. 169 00:14:15,420 --> 00:14:18,500 As variables locais están vivos dentro do seu alcance. 170 00:14:18,500 --> 00:14:22,140 Así que pasar unha chaveta, as variables locais están mortos. 171 00:14:22,140 --> 00:14:28,890 Memoria Malloced está vivo cando quere estar vivo 172 00:14:28,890 --> 00:14:33,480 e despois é liberado cando diga a el para ser lanzado. 173 00:14:33,480 --> 00:14:38,420 Estes son realmente os únicos tres tipos de memoria, realmente. 174 00:14:38,420 --> 00:14:41,840 Hai xestión automática de memoria, que é a pila. 175 00:14:41,840 --> 00:14:43,840 As cousas acontecen automaticamente para ti. 176 00:14:43,840 --> 00:14:46,910 Cando di int x, memoria é alocada para int x. 177 00:14:46,910 --> 00:14:51,630 Cando x sae do ámbito, a memoria é recuperado para x. 178 00:14:51,630 --> 00:14:54,790 Despois, hai a xestión de memoria dinámica, que é o que malloc é, 179 00:14:54,790 --> 00:14:56,740 que é cando ten control. 180 00:14:56,740 --> 00:15:01,290 Decide dinámicamente cando a memoria debe e non debe ser alocado. 181 00:15:01,290 --> 00:15:05,050 E despois hai o estático, que só significa que vive para sempre, 182 00:15:05,050 --> 00:15:06,610 que é o que as variables globais son. 183 00:15:06,610 --> 00:15:10,240 Son só sempre na memoria. 184 00:15:10,960 --> 00:15:12,760 >> Preguntas? 185 00:15:14,490 --> 00:15:17,230 [Estudante] Pode definir un bloque de só usando claves 186 00:15:17,230 --> 00:15:21,220 pero non ter que ter un? se declaración ou declaración de tempo ou algo así 187 00:15:21,220 --> 00:15:29,130 Podes establecer un bloque como unha función, pero que ten chaves tamén. 188 00:15:29,130 --> 00:15:32,100 [Alumno] Entón, non pode só ter como un par chou de claves no seu código 189 00:15:32,100 --> 00:15:35,680 que teñen variables locais? >> Si, pode. 190 00:15:35,680 --> 00:15:45,900 Dentro do bar int poderiamos ter {int y = 3;}. 191 00:15:45,900 --> 00:15:48,440 Isto debería estar aquí. 192 00:15:48,440 --> 00:15:52,450 Pero que define completamente o ámbito de int y. 193 00:15:52,450 --> 00:15:57,320 Despois de que chaveta segundo, y non pode ser máis usado. 194 00:15:57,910 --> 00:16:00,630 Vostede case nunca o fan, con todo. 195 00:16:02,940 --> 00:16:07,370 Volvendo ao que acontece cando un programa remata, 196 00:16:07,370 --> 00:16:18,760 hai unha especie de mentira equívoco / media que damos a fin de só facer as cousas máis fáciles. 197 00:16:18,760 --> 00:16:24,410 Nós dicimos a vostedes que cando reservar memoria 198 00:16:24,410 --> 00:16:29,860 está alocando algún anaco de memoria RAM para esta variable. 199 00:16:29,860 --> 00:16:34,190 Pero non está realmente tocar directamente RAM sempre nos seus programas. 200 00:16:34,190 --> 00:16:37,490 Se pensar sobre iso, como eu deseño - 201 00:16:37,490 --> 00:16:44,330 E, de feito, se pasar o GDB vai ver a mesma cousa. 202 00:16:51,120 --> 00:16:57,590 Independentemente do número de veces que executar o programa ou o programa que está en execución, 203 00:16:57,590 --> 00:16:59,950 a pila sempre vai comezar - 204 00:16:59,950 --> 00:17:06,510 sempre vai ver variables en torno a algo oxbffff enderezo. 205 00:17:06,510 --> 00:17:09,470 É xeralmente en algún lugar na rexión. 206 00:17:09,470 --> 00:17:18,760 Pero como pode, eventualmente, ter dous programas de punteiros para a memoria mesmo? 207 00:17:20,640 --> 00:17:27,650 [Alumno] Hai algunha designación arbitraria de onde oxbfff se quere que sexa na memoria RAM 208 00:17:27,650 --> 00:17:31,320 que realmente pode estar en diferentes lugares, dependendo de cando a función foi chamada. 209 00:17:31,320 --> 00:17:35,920 Si O termo é a memoria virtual. 210 00:17:35,920 --> 00:17:42,250 A idea é que cada proceso único, cada programa que está en execución no ordenador 211 00:17:42,250 --> 00:17:49,450 ten o seu propio - imos supor que 32 bits - espazo de enderezo completamente independente. 212 00:17:49,450 --> 00:17:51,590 Este é o espazo de enderezo. 213 00:17:51,590 --> 00:17:56,220 El ten as súas propias completamente independentes 4 gigabytes de usar. 214 00:17:56,220 --> 00:18:02,220 >> Entón, se executar dous programas ó mesmo tempo, este programa vese catro gigabytes para si, 215 00:18:02,220 --> 00:18:04,870 este programa vese catro gigabytes para si, 216 00:18:04,870 --> 00:18:07,720 e é imposible para este programa dereference un punteiro 217 00:18:07,720 --> 00:18:10,920 e acabar coa memoria a partir deste programa. 218 00:18:10,920 --> 00:18:18,200 E o que a memoria virtual é un mapeamento dun espazo de enderezo de procesos 219 00:18:18,200 --> 00:18:20,470 a cousas reais na RAM. 220 00:18:20,470 --> 00:18:22,940 Polo tanto, cabe ao seu sistema operativo para saber que, 221 00:18:22,940 --> 00:18:28,080 hey, cando este cara oxbfff punteiro dereferences, que realmente significa 222 00:18:28,080 --> 00:18:31,040 que quere RAM byte 1000, 223 00:18:31,040 --> 00:18:38,150 mentres que se este programa oxbfff dereferences, realmente quere RAM byte 10000. 224 00:18:38,150 --> 00:18:41,590 Eles poden ser arbitrariamente afastadas. 225 00:18:41,590 --> 00:18:48,730 Isto é aínda certo das cousas dentro dun espazo único de procesos de enderezo. 226 00:18:48,730 --> 00:18:54,770 Entón, como se ve todos os 4 gigabytes para si mesmo, pero imos dicir - 227 00:18:54,770 --> 00:18:57,290 [Alumno] Será que cada proceso - 228 00:18:57,290 --> 00:19:01,350 Imos dicir que ten un ordenador con só 4 gigabytes de memoria RAM. 229 00:19:01,350 --> 00:19:06,430 Cada proceso ver a 4 gigabytes? Si >>. 230 00:19:06,430 --> 00:19:13,060 Pero os 4 gigabytes que ve é unha mentira. 231 00:19:13,060 --> 00:19:20,460 É só el cre que ten toda a memoria que xa non coñece ningún outro proceso existe. 232 00:19:20,460 --> 00:19:28,140 É só usar a memoria, tanto como realmente precisa. 233 00:19:28,140 --> 00:19:32,340 O sistema operativo non vai dar RAM para este proceso 234 00:19:32,340 --> 00:19:35,750 se non é utilizar calquera memoria en toda esta rexión. 235 00:19:35,750 --> 00:19:39,300 Non vai dar-lle a memoria para esa rexión. 236 00:19:39,300 --> 00:19:54,780 Pero a idea é que - eu estou tentando pensar - Eu non podo pensar nunha analoxía. 237 00:19:54,780 --> 00:19:56,780 Analoxías son difíciles. 238 00:19:57,740 --> 00:20:02,700 Unha das cuestións de memoria virtual ou unha das cousas que está resolvendo 239 00:20:02,700 --> 00:20:06,810 é a de que os procesos deben ser completamente alleos un ao outro. 240 00:20:06,810 --> 00:20:12,140 E así pode escribir calquera programa que só dereferences calquera punteiro, 241 00:20:12,140 --> 00:20:19,340 como só escribir un programa que se * (ox1234), 242 00:20:19,340 --> 00:20:22,890 e iso é o enderezo de memoria dereferencing 1234. 243 00:20:22,890 --> 00:20:28,870 >> Pero cabe ao sistema operativo para despois traducir o que significa 1234. 244 00:20:28,870 --> 00:20:33,960 Así, 1234 pasa de ser un enderezo de memoria válido para este proceso, 245 00:20:33,960 --> 00:20:38,800 como é na pila ou algo así, entón iso vai devolver o valor do enderezo de memoria 246 00:20:38,800 --> 00:20:41,960 na medida en que o proceso sabe. 247 00:20:41,960 --> 00:20:47,520 Pero se 1234 non é un enderezo válido, como acontece á terra 248 00:20:47,520 --> 00:20:52,910 nalgún pedazo de memoria aquí que está alén da pila e ademais da pila 249 00:20:52,910 --> 00:20:57,200 e realmente non teño usado que, a continuación, que é cando facer as cousas como segfaults 250 00:20:57,200 --> 00:21:00,260 porque está tocando memoria que non debe tocar. 251 00:21:07,180 --> 00:21:09,340 Isto tamén é certo - 252 00:21:09,340 --> 00:21:15,440 Un sistema de 32 bits, 32 bits significa que ten 32 bits para definir un enderezo de memoria. 253 00:21:15,440 --> 00:21:22,970 É por iso que os punteiros son 8 bytes, porque 32 bits son 8 bytes - ou 4 bytes. 254 00:21:22,970 --> 00:21:25,250 Os punteiros son 4 bytes. 255 00:21:25,250 --> 00:21:33,680 Entón, cando ve un punteiro como oxbfffff, que é - 256 00:21:33,680 --> 00:21:40,080 Dentro dun determinado programa pode só construír calquera punteiro arbitraria, 257 00:21:40,080 --> 00:21:46,330 en calquera lugar de ox0 para boi 8 f 's - ffffffff. 258 00:21:46,330 --> 00:21:49,180 [Alumno] Non dixen que son 4 bytes? Si >>. 259 00:21:49,180 --> 00:21:52,730 [Alumno] A continuación, cada byte terá - >> [Bowden] hexadecimal. 260 00:21:52,730 --> 00:21:59,360 Hexadecimal - 5, 6, 7, 8. Entón punteiros vai sempre ver en hexadecimal. 261 00:21:59,360 --> 00:22:01,710 É exactamente como nós clasificamos punteiros. 262 00:22:01,710 --> 00:22:05,240 Cada 2 díxitos do hexadecimal é un byte. 263 00:22:05,240 --> 00:22:09,600 Entón alí vai ser de 8 díxitos hexadecimais de 4 bytes. 264 00:22:09,600 --> 00:22:14,190 Así, cada punteiro único nun sistema de 32 bits vai ser 4 bytes, 265 00:22:14,190 --> 00:22:18,550 o que significa que, no seu proceso, pode construír calquera arbitrarias 4 bytes 266 00:22:18,550 --> 00:22:20,550 e facer un punteiro de fóra, 267 00:22:20,550 --> 00:22:32,730 o que significa que, na medida é consciente, pode dirixir un enteiro 2 para os 32 bytes de memoria. 268 00:22:32,730 --> 00:22:34,760 Aínda que realmente non ten acceso a iso, 269 00:22:34,760 --> 00:22:40,190 mesmo se o seu ordenador ten só 512 megabytes, el pensa que ten esa cantidade de memoria. 270 00:22:40,190 --> 00:22:44,930 E o sistema operativo é intelixente o suficiente para que el só pode reservar o que realmente precisa. 271 00:22:44,930 --> 00:22:49,630 Non só tes que ir, oh, un novo proceso: catro concertos. 272 00:22:49,630 --> 00:22:51,930 >> Si >> [Alumno] O que é que o boi significa? Por que escribe? 273 00:22:51,930 --> 00:22:54,980 É só o símbolo para hexadecimal. 274 00:22:54,980 --> 00:22:59,590 Cando ve un número con inicio boi, as cousas son sucesivas hexadecimal. 275 00:23:01,930 --> 00:23:05,760 [Alumno] Vostede estaba explicando o que pasa cando un programa remata. Si >>. 276 00:23:05,760 --> 00:23:09,480 O que acontece cando un programa remata é o sistema operativo 277 00:23:09,480 --> 00:23:13,600 só elimina os mapeamento que para estes enderezos, e é iso. 278 00:23:13,600 --> 00:23:17,770 O sistema operativo pode agora dar só que a memoria a outro programa para usar. 279 00:23:17,770 --> 00:23:19,490 [Alumno] Okay. 280 00:23:19,490 --> 00:23:24,800 Entón, cando aloca algo na pila ou as variables de pila ou global ou calquera cousa, 281 00:23:24,800 --> 00:23:27,010 todos eles simplemente desaparecer así que o programa remata 282 00:23:27,010 --> 00:23:32,120 porque o sistema operativo é agora a liberdade de dar esa memoria para calquera outro proceso. 283 00:23:32,120 --> 00:23:35,150 [Alumno] Aínda que probablemente hai aínda valores escritos en? Si >>. 284 00:23:35,150 --> 00:23:37,740 Os valores son probablemente aínda está alí. 285 00:23:37,740 --> 00:23:41,570 É só iso que vai ser difícil chegar a eles. 286 00:23:41,570 --> 00:23:45,230 É moito máis difícil para chegar a eles que é para chegar a un ficheiro eliminado 287 00:23:45,230 --> 00:23:51,450 porque o tipo de ficheiro que foi eliminado está alí por un longo tempo e disco duro é moito maior. 288 00:23:51,450 --> 00:23:54,120 Por iso, vai a substituír partes diferentes de memoria 289 00:23:54,120 --> 00:23:58,640 antes de que aconteza para substituír o anaco de memoria que o ficheiro utilizado para estar. 290 00:23:58,640 --> 00:24:04,520 Pero a memoria principal, memoria RAM, percorrer moito máis rápido, 291 00:24:04,520 --> 00:24:08,040 por iso vai moi rapidamente ser substituído. 292 00:24:10,300 --> 00:24:13,340 Dúbidas sobre esta ou calquera outra cousa? 293 00:24:13,340 --> 00:24:16,130 [Alumno] Teño dúbidas sobre un tema diferente. Ok >>. 294 00:24:16,130 --> 00:24:19,060 Alguén ten dúbidas sobre iso? 295 00:24:20,170 --> 00:24:23,120 >> Okay. Tema diferente. >> [Alumno] Okay. 296 00:24:23,120 --> 00:24:26,550 Eu estaba pasando por algúns dos tests prácticos, 297 00:24:26,550 --> 00:24:30,480 e nunha delas estaba falando sobre o sizeof 298 00:24:30,480 --> 00:24:35,630 eo valor que retorna ou distintos tipos de variables. Si >>. 299 00:24:35,630 --> 00:24:45,060 E dixo que tanto int e longo retorno tanto 4, entón ambos son 4 bytes. 300 00:24:45,060 --> 00:24:48,070 ¿Hai algunha diferencia entre un int e un longo, ou é a mesma cousa? 301 00:24:48,070 --> 00:24:50,380 Si, hai unha diferenza. 302 00:24:50,380 --> 00:24:52,960 O patrón C - 303 00:24:52,960 --> 00:24:54,950 Probablemente, vou romper. 304 00:24:54,950 --> 00:24:58,800 O patrón C é como o que é C, a documentación oficial do C. 305 00:24:58,800 --> 00:25:00,340 Isto é o que di. 306 00:25:00,340 --> 00:25:08,650 Así, o estándar C só di que un char para sempre e sempre un byte. 307 00:25:10,470 --> 00:25:19,040 Todo o que despois - un curto é sempre só definida como maior que ou igual a un char. 308 00:25:19,040 --> 00:25:23,010 Isto pode ser estrictamente maior que, pero non positiva. 309 00:25:23,010 --> 00:25:31,940 Un int é só definida como maior que ou igual a unha curta distancia. 310 00:25:31,940 --> 00:25:36,210 E unha lonxitude é só definida como maior que ou igual a un enteiro. 311 00:25:36,210 --> 00:25:41,600 E un longo tempo é maior que ou igual a lonxitude. 312 00:25:41,600 --> 00:25:46,610 Entón, a única cousa que o estándar C define é a ordenación relativa de todo. 313 00:25:46,610 --> 00:25:54,880 A cantidade real de memoria que as cousas levan xeralmente ata a súa implementación, 314 00:25:54,880 --> 00:25:57,640 Pero é moi ben definida neste momento. >> [Alumno] Okay. 315 00:25:57,640 --> 00:26:02,490 Entón shorts son case sempre vai ser de 2 bytes. 316 00:26:04,920 --> 00:26:09,950 Ints son case sempre vai ser de 4 bytes. 317 00:26:12,070 --> 00:26:15,340 Longs longos son case sempre vai ser de 8 bytes. 318 00:26:17,990 --> 00:26:23,160 E quere, iso depende se está a usar un de 32 bits ou un sistema de 64 bits. 319 00:26:23,160 --> 00:26:27,450 Así, un tempo que vai corresponder ao tipo de sistema. 320 00:26:27,450 --> 00:26:31,920 Se está usando un sistema de 32 bits, como o aparello, que vai ser de 4 bytes. 321 00:26:34,530 --> 00:26:42,570 Se está usando unha de 64 bits como unha morea de computadores máis recentes, que vai ser de 8 bytes. 322 00:26:42,570 --> 00:26:45,230 >> Ints son case sempre 4 bytes neste momento. 323 00:26:45,230 --> 00:26:47,140 Longs longos son case sempre de 8 bytes. 324 00:26:47,140 --> 00:26:50,300 No pasado, o ints usado para ser só 2 bytes. 325 00:26:50,300 --> 00:26:56,840 Pero teña en conta que este cumpre completamente todas esas relacións de maior e igual a. 326 00:26:56,840 --> 00:27:01,280 Sempre é perfectamente permitido ter o mesmo tamaño como un enteiro, 327 00:27:01,280 --> 00:27:04,030 e está tamén autorizado a ser do mesmo tamaño que unha lonxitude longo. 328 00:27:04,030 --> 00:27:11,070 E iso só pasa de ser que 99,999% dos sistemas, que vai ser igual a 329 00:27:11,070 --> 00:27:15,800 ou int ou un longo tempo. Depende só de 32-bit ou 64 bits. >> [Alumno] Okay. 330 00:27:15,800 --> 00:27:24,600 En coches alegóricos, como é o punto decimal designada en termos de bits? 331 00:27:24,600 --> 00:27:27,160 Como como binario? Si >>. 332 00:27:27,160 --> 00:27:30,570 Non é preciso saber que a CS50. 333 00:27:30,570 --> 00:27:32,960 Non é preciso nin saber que en 61. 334 00:27:32,960 --> 00:27:37,350 Vostede non aprende que realmente en calquera curso. 335 00:27:37,350 --> 00:27:42,740 É só unha representación. 336 00:27:42,740 --> 00:27:45,440 Eu esquezo os loteamentos bit exactas. 337 00:27:45,440 --> 00:27:53,380 A idea de punto flotante é que asignar un número específico de bits para representar - 338 00:27:53,380 --> 00:27:56,550 Basicamente, todo está en notación científica. 339 00:27:56,550 --> 00:28:05,600 Entón asignar un número específico de bits para representar o número en si, como 1,2345. 340 00:28:05,600 --> 00:28:10,200 Eu nunca pode representar un número con máis díxitos que 5. 341 00:28:12,200 --> 00:28:26,300 Entón tamén asignar un número específico de bits para que tende a ser semellante 342 00:28:26,300 --> 00:28:32,810 só pode ir ata un certo número, que ese é o maior expoñente quizais, 343 00:28:32,810 --> 00:28:36,190 e só pode ir ata un certo expoñente, 344 00:28:36,190 --> 00:28:38,770 así é menor expoñente pode ter. 345 00:28:38,770 --> 00:28:44,410 >> Eu non me lembro os bits xeito exacta son asignados a todos estes valores, 346 00:28:44,410 --> 00:28:47,940 pero un certo número de bits son dedicados a 1,2345, 347 00:28:47,940 --> 00:28:50,930 outro determinado número de bits son dedicados a expoñente, 348 00:28:50,930 --> 00:28:55,670 e só é posible para representar un expoñente dun determinado tamaño. 349 00:28:55,670 --> 00:29:01,100 [Estudante] e un dobre? É que, como un flotador extra longa? Si >>. 350 00:29:01,100 --> 00:29:07,940 É a mesma cousa que un coche alegórico só que agora está a usar 8 bytes no canto de 4 bytes. 351 00:29:07,940 --> 00:29:11,960 Agora vai ser capaz de utilizar 9 díxitos ou 10 díxitos, 352 00:29:11,960 --> 00:29:16,630 e iso vai ser capaz de ir ata 300 en vez de 100. >> [Alumno] Okay. 353 00:29:16,630 --> 00:29:21,550 E flota tamén son 4 bytes. Si >>. 354 00:29:21,550 --> 00:29:27,520 Ben, unha vez máis, probablemente depende global sobre a aplicación xeral, 355 00:29:27,520 --> 00:29:30,610 pero flotadores son 4 bytes, dobres son 8. 356 00:29:30,610 --> 00:29:33,440 Dobres son chamados de parella, porque son o dobre do tamaño dos coches alegóricos. 357 00:29:33,440 --> 00:29:38,380 [Alumno] Okay. E hai dobre dobra? >> Non hai. 358 00:29:38,380 --> 00:29:43,660 Eu creo - >> [estudante] Como longs longas? Si >>. Penso que non. Si 359 00:29:43,660 --> 00:29:45,950 [Estudante] En proba o ano pasado, houbo unha pregunta sobre a principal función 360 00:29:45,950 --> 00:29:49,490 ter que facer parte do seu programa. 361 00:29:49,490 --> 00:29:52,310 A resposta foi que non ten que ser parte do seu programa. 362 00:29:52,310 --> 00:29:55,100 En que situación? Isto é o que eu vin. 363 00:29:55,100 --> 00:29:59,090 [Bowden] Parece - >> [alumno] Que situación? 364 00:29:59,090 --> 00:30:02,880 Ten o problema? >> [Alumno] Si, eu sempre podo puxa-lo cara arriba. 365 00:30:02,880 --> 00:30:07,910 Non ten que ser, tecnicamente, pero basicamente vai ser. 366 00:30:07,910 --> 00:30:10,030 [Estudante] Eu vin un en un ano diferente. 367 00:30:10,030 --> 00:30:16,220 Era como verdadeiro ou falso: Un válido - >> Ah, un arquivo c.? 368 00:30:16,220 --> 00:30:18,790 . [Alumno] Calquera ficheiro debe C - [ambos falando dunha vez - inintelixible] 369 00:30:18,790 --> 00:30:21,120 Okay. Entón, iso é separado. 370 00:30:21,120 --> 00:30:26,800 >> Unha. Arquivo c só precisa ter funcións. 371 00:30:26,800 --> 00:30:32,400 Pode compilar un arquivo en código de máquina, binario, calquera que sexa, 372 00:30:32,400 --> 00:30:36,620 sen que sexa executábel aínda. 373 00:30:36,620 --> 00:30:39,420 Un executable válido debe ter unha función principal. 374 00:30:39,420 --> 00:30:45,460 Podes escribir 100 funcións nun arquivo, pero non principais 375 00:30:45,460 --> 00:30:48,800 e despois compilar que ata binario, 376 00:30:48,800 --> 00:30:54,460 entón escribir outro arquivo que ten só principal, pero chama moito desas funcións 377 00:30:54,460 --> 00:30:56,720 neste ficheiro binario por aquí. 378 00:30:56,720 --> 00:31:01,240 E así, cando está facendo o executábel, que é o que fai o linker 379 00:31:01,240 --> 00:31:05,960 é el combina estes dous arquivos binarios nun arquivo executable. 380 00:31:05,960 --> 00:31:11,400 Así, un. Arquivo c non precisa ter unha función principal de todo. 381 00:31:11,400 --> 00:31:19,220 E en grandes bases de código verás miles de arquivos. C e 1 ficheiro principal. 382 00:31:23,960 --> 00:31:26,110 Máis preguntas? 383 00:31:29,310 --> 00:31:31,940 [Alumno] Había outra cuestión. 384 00:31:31,940 --> 00:31:36,710 El dixo que facer é un compilador. Verdadeiro ou falso? 385 00:31:36,710 --> 00:31:42,030 E a resposta era falsa, e eu entendín por que non é como Clang. 386 00:31:42,030 --> 00:31:44,770 Pero o que chamamos de facer, se non é? 387 00:31:44,770 --> 00:31:49,990 Facer é, basicamente, só - Eu podo ver exactamente o que el chama. 388 00:31:49,990 --> 00:31:52,410 Pero iso só fai comandos. 389 00:31:53,650 --> 00:31:55,650 Facer. 390 00:31:58,240 --> 00:32:00,870 Podo tirar isto. Si 391 00:32:10,110 --> 00:32:13,180 Ah, si. Fai tamén o fai. 392 00:32:13,180 --> 00:32:17,170 Este di que o propósito do utilidade make é determinar automaticamente 393 00:32:17,170 --> 00:32:19,610 que partes dun gran programa deben ser recompilados 394 00:32:19,610 --> 00:32:22,350 e emitir os comandos para recopila-los. 395 00:32:22,350 --> 00:32:27,690 Podes facer facer arquivos que son absolutamente enorme. 396 00:32:27,690 --> 00:32:33,210 Fai mira as marcas de tempo de arquivos e, como dixemos antes, 397 00:32:33,210 --> 00:32:36,930 pode compilar arquivos individuais para abaixo, e non é ata chegar ao linker 398 00:32:36,930 --> 00:32:39,270 que están xuntos nun executable. 399 00:32:39,270 --> 00:32:43,810 Entón, se ten 10 arquivos diferentes e fai unha modificación nun deles, 400 00:32:43,810 --> 00:32:47,870 entón o que fai vai facer é só recompilar dun ficheiro 401 00:32:47,870 --> 00:32:50,640 e, despois, religar todo xuntos. 402 00:32:50,640 --> 00:32:53,020 Pero é moito máis burro do que iso. 403 00:32:53,020 --> 00:32:55,690 É ata a definir completamente que iso é o que debería estar facendo. 404 00:32:55,690 --> 00:32:59,560 É por defecto ten a capacidade de recoñecer estas cousas selo de tempo, 405 00:32:59,560 --> 00:33:03,220 pero pode escribir un ficheiro de make para facer calquera cousa. 406 00:33:03,220 --> 00:33:09,150 Podes escribir un ficheiro para facer que cando escribe facelo só cd para outro directorio. 407 00:33:09,150 --> 00:33:15,560 Eu estaba quedando errado porque eu todo rumbo dentro da miña Appliance 408 00:33:15,560 --> 00:33:21,740 e despois eu ver o PDF do Mac 409 00:33:21,740 --> 00:33:30,720 >> Entón eu vou para Finder e que eu poida facer Vai, conectar co servidor, 410 00:33:30,720 --> 00:33:36,950 eo servidor de eu conectar o meu dispositivo e, a continuación, abrir o PDF 411 00:33:36,950 --> 00:33:40,190 que está feita polo LaTeX. 412 00:33:40,190 --> 00:33:49,320 Pero eu estaba quedando errado porque cada vez que eu precisaba actualizar o PDF, 413 00:33:49,320 --> 00:33:53,900 Eu tiña que copia-lo para un directorio específico que podería acceder 414 00:33:53,900 --> 00:33:57,710 e foi quedando aburrido. 415 00:33:57,710 --> 00:34:02,650 Entón, en vez escribín un ficheiro make, que ten que definir a forma como fai as cousas. 416 00:34:02,650 --> 00:34:06,130 Como fai iso é en PDF LaTeX. 417 00:34:06,130 --> 00:34:10,090 Así como calquera outro arquivo de outra marca - ou eu creo que aínda non viu os ficheiros de facer, 418 00:34:10,090 --> 00:34:13,510 pero temos no aparello un arquivo de marca global que só di: 419 00:34:13,510 --> 00:34:16,679 se está compilando un ficheiro C, use Clang. 420 00:34:16,679 --> 00:34:20,960 E aquí no meu arquivo make que fago eu digo, 421 00:34:20,960 --> 00:34:25,020 este ficheiro que vai querer compilar con LaTeX PDF. 422 00:34:25,020 --> 00:34:27,889 E por iso é LaTeX PDF que está facendo a compilación. 423 00:34:27,889 --> 00:34:31,880 Facer non é compilar. É só executar estes comandos na secuencia eu especifiquei. 424 00:34:31,880 --> 00:34:36,110 Por iso, corre LaTeX PDF, el copia ao directorio que quero que sexa copiado para, 425 00:34:36,110 --> 00:34:38,270 que cd para o directorio e fai outras cousas, 426 00:34:38,270 --> 00:34:42,380 pero todo o que fai é recoñecer cando un arquivo é modificado, 427 00:34:42,380 --> 00:34:45,489 e se cambia, entón el vai executar os comandos que se quere para realizar 428 00:34:45,489 --> 00:34:48,760 cando os cambios do ficheiro. >> [Alumno] Okay. 429 00:34:50,510 --> 00:34:54,420 Eu non sei de onde os ficheiros fanse globais son para eu dar un ollo. 430 00:34:57,210 --> 00:35:04,290 Outras preguntas? Calquera cousa do pasado quizzes? Calquera cousas punteiro? 431 00:35:06,200 --> 00:35:08,730 Hai cousas sutís con punteiros como - 432 00:35:08,730 --> 00:35:10,220 Eu non vou ser capaz de atopar a unha pregunta sobre el - 433 00:35:10,220 --> 00:35:16,250 pero como este tipo de cousas. 434 00:35:19,680 --> 00:35:24,060 Asegúrese de entender que cando eu digo int * x * y - 435 00:35:24,890 --> 00:35:28,130 Este non é exactamente nada aquí, eu creo. 436 00:35:28,130 --> 00:35:32,140 Pero, como * x * y, aqueles son 2 variables que están na pila. 437 00:35:32,140 --> 00:35:37,220 Cando digo que x = malloc (sizeof (int)), x aínda é unha variable na pila, 438 00:35:37,220 --> 00:35:41,180 malloc é unha pista no heap, e nós estamos tendo punto x no heap. 439 00:35:41,180 --> 00:35:43,900 >> Entón, algo sobre os puntos de pila para o heap. 440 00:35:43,900 --> 00:35:48,100 Sempre que malloc nada, está inevitablemente almacena-lo dentro dun punteiro. 441 00:35:48,100 --> 00:35:55,940 Así que o punteiro estea na pila, o bloque é malloced na pila. 442 00:35:55,940 --> 00:36:01,240 Moitas persoas se confunden e din int * x = malloc; x na pila. 443 00:36:01,240 --> 00:36:04,100 Non ¿Que é x apunta para a pila. 444 00:36:04,100 --> 00:36:08,540 x si é na pila, a non ser que, por calquera razón, x ser unha variable global, 445 00:36:08,540 --> 00:36:11,960 caso en que pasa a ser noutra rexión de memoria. 446 00:36:13,450 --> 00:36:20,820 Entón, manter o control, estes diagramas de caixa e frecha son bastante comúns para o quiz. 447 00:36:20,820 --> 00:36:25,740 Ou se non está no exame 0, estará no cuestionario 1. 448 00:36:27,570 --> 00:36:31,940 Debes saber todo iso, os pasos en compilación 449 00:36:31,940 --> 00:36:35,740 sempre que tivo que responder a preguntas sobre aqueles. Si 450 00:36:35,740 --> 00:36:38,940 [Alumno] Podemos ir máis desas etapas - >> Por suposto. 451 00:36:48,340 --> 00:36:58,640 Antes de pasos e compilación temos o pre-procesamento, 452 00:36:58,640 --> 00:37:16,750 compilación, montaxe e conexión. 453 00:37:16,750 --> 00:37:21,480 Pre-procesamento. O que iso fai? 454 00:37:29,720 --> 00:37:32,290 É o paso máis fácil - ben, non como - 455 00:37:32,290 --> 00:37:35,770 iso non significa que debería ser obvio, pero é o paso máis doado. 456 00:37:35,770 --> 00:37:38,410 Vostedes poderían implementar lo vós mesmos. Si 457 00:37:38,410 --> 00:37:43,410 [Alumno] Colla o que ten no seu inclúe como este e copia e despois tamén define. 458 00:37:43,410 --> 00:37:49,250 El procura por cousas como # include e # define, 459 00:37:49,250 --> 00:37:53,800 e só copiar e cola que aqueles realmente significan. 460 00:37:53,800 --> 00:37:59,240 Entón, cando di # include cs50.h, o pre-procesador está copiando e colando cs50.h 461 00:37:59,240 --> 00:38:01,030 en que a liña. 462 00:38:01,030 --> 00:38:06,640 Cando di # define x para 4, o pre-procesador pasa por todo o programa 463 00:38:06,640 --> 00:38:10,400 e substitúe todas as ocorrencias de x por 4. 464 00:38:10,400 --> 00:38:17,530 Así, o pre-procesador ten un arquivo C válido e xera un ficheiro válido C 465 00:38:17,530 --> 00:38:20,300 onde as cousas teñen copiado e pegado. 466 00:38:20,300 --> 00:38:24,230 Entón agora compilar. O que iso fai? 467 00:38:25,940 --> 00:38:28,210 [Alumno] El vai de C para binario. 468 00:38:28,210 --> 00:38:30,970 >> [Bowden] Non percorrer todo o camiño para binario. 469 00:38:30,970 --> 00:38:34,220 [Estudante] para código de máquina, entón? >> Non é un código de máquina. 470 00:38:34,220 --> 00:38:35,700 [Alumno] Asemblea? >> Asemblea. 471 00:38:35,700 --> 00:38:38,890 El vai para a Asemblea antes de que vaia todo o camiño para o código C, 472 00:38:38,890 --> 00:38:45,010 ea maioría das linguas facer algo así. 473 00:38:47,740 --> 00:38:50,590 Escolla calquera linguaxe de alto nivel, e se está indo para recompila-lo, 474 00:38:50,590 --> 00:38:52,390 é probable que compilar en etapas. 475 00:38:52,390 --> 00:38:58,140 Primeiro vai compilar o Python para C, entón vai para compilar C a Asemblea, 476 00:38:58,140 --> 00:39:01,600 e Asemblea vai estar traducido para binario. 477 00:39:01,600 --> 00:39:07,800 Entón compilación vai trae-lo de C para Assembly. 478 00:39:07,800 --> 00:39:12,130 A palabra compilando normalmente significa trae-lo a partir dun nivel máis elevado 479 00:39:12,130 --> 00:39:14,340 a un menor nivel de linguaxe de programación. 480 00:39:14,340 --> 00:39:19,190 Polo tanto, esta é a única etapa na compilación onde comeza cunha linguaxe de alto nivel 481 00:39:19,190 --> 00:39:23,270 e acaban nunha linguaxe de baixo nivel, e é por iso que a etapa chámase compilación. 482 00:39:25,280 --> 00:39:33,370 [Alumno] Durante a compilación, imos dicir que fixo # include cs50.h. 483 00:39:33,370 --> 00:39:42,190 Será que o compilador recompilar o cs50.h, como as funcións que están aí, 484 00:39:42,190 --> 00:39:45,280 e traducir iso en código Asemblea, así como, 485 00:39:45,280 --> 00:39:50,830 ou vai copiar e pegar algo que foi pre-montaxe? 486 00:39:50,830 --> 00:39:56,910 cs50.h vai practicamente nunca acabar na Asemblea. 487 00:39:59,740 --> 00:40:03,680 Cousas como prototipos de función e as cousas son só para ti ter coidado. 488 00:40:03,680 --> 00:40:09,270 El asegura que o compilador pode comprobar as cousas que está chamando funcións 489 00:40:09,270 --> 00:40:12,910 cos tipos de retorno de dereita e os argumentos correctos e outras cousas. 490 00:40:12,910 --> 00:40:18,350 >> Entón cs50.h serán pre-procesados ​​no arquivo, e entón cando está compilando 491 00:40:18,350 --> 00:40:22,310 é basicamente xogado fóra despois que garante que todo está chamado correctamente. 492 00:40:22,310 --> 00:40:29,410 Pero as funcións definidas na biblioteca CS50, que son separados cs50.h, 493 00:40:29,410 --> 00:40:33,610 aqueles que non será compilado por separado. 494 00:40:33,610 --> 00:40:37,270 Que realmente vai vir abaixo na etapa de conexión, así que nós imos chegar a iso nun segundo. 495 00:40:37,270 --> 00:40:40,100 Pero, primeiro, o que é montaxe? 496 00:40:41,850 --> 00:40:44,500 [Estudante] Asemblea para binario? Si >>. 497 00:40:46,300 --> 00:40:48,190 Montaxe. 498 00:40:48,190 --> 00:40:54,710 Non chamalo de compilación porque Asemblea é practicamente unha tradución pura de binario. 499 00:40:54,710 --> 00:41:00,230 Hai unha lóxica moi pouco en ir Asemblea para binario. 500 00:41:00,230 --> 00:41:03,180 É como mirar para arriba na táboa, oh, temos esa instrución; 501 00:41:03,180 --> 00:41:06,290 que corresponde ao binario 01110. 502 00:41:10,200 --> 00:41:15,230 E así os arquivos que a montaxe xeralmente saídas son. Arquivos o. 503 00:41:15,230 --> 00:41:19,020 E arquivos. O son que estabamos dicindo antes, 504 00:41:19,020 --> 00:41:21,570 como un arquivo non é preciso ter unha función principal. 505 00:41:21,570 --> 00:41:27,640 Calquera ficheiro pode ser compilado para abaixo para un ficheiro a. Mentres el é un arquivo C válido. 506 00:41:27,640 --> 00:41:30,300 Pode ser feita a abaixo. O. 507 00:41:30,300 --> 00:41:43,030 Agora, ligando é o que realmente trae unha chea de. O ficheiros e os leva para un executable. 508 00:41:43,030 --> 00:41:51,110 E entón o que fai é que liga pode pensar a biblioteca como un arquivo CS50 o .. 509 00:41:51,110 --> 00:41:56,980 É un arquivo binario xa compilado. 510 00:41:56,980 --> 00:42:03,530 E así, cando compilar o seu arquivo, o seu hello.c, que chama GetString, 511 00:42:03,530 --> 00:42:06,360 hello.c está feita ata hello.o, 512 00:42:06,360 --> 00:42:08,910 hello.o está agora en binario. 513 00:42:08,910 --> 00:42:12,830 El usa GetString, polo que cómpre ir cs50.o, 514 00:42:12,830 --> 00:42:16,390 eo vinculador smooshes-los xuntos e copiar GetString para este ficheiro 515 00:42:16,390 --> 00:42:20,640 e sae cun executable que ten todas as funcións que precisa. 516 00:42:20,640 --> 00:42:32,620 Entón cs50.o non é realmente un ficheiro do, pero está preto o suficiente para que non hai diferenza fundamental. 517 00:42:32,620 --> 00:42:36,880 Entón, conectando só trae unha morea de arquivos xuntos 518 00:42:36,880 --> 00:42:41,390 que por separado conter todas as funcións que teño uso 519 00:42:41,390 --> 00:42:46,120 e crea o executable que vai realmente funcionar. 520 00:42:48,420 --> 00:42:50,780 >> E por iso é tamén o que diciamos antes 521 00:42:50,780 --> 00:42:55,970 onde pode ter 1000. arquivos C, recompila-los todos. arquivos o, 522 00:42:55,970 --> 00:43:00,040 que probablemente vai levar un pouco, entón cambiar unha. arquivo c. 523 00:43:00,040 --> 00:43:05,480 Só ten recompilar que 1. Arquivo C e despois conectar de novo todo o máis, 524 00:43:05,480 --> 00:43:07,690 vincular todo de volta xuntos. 525 00:43:09,580 --> 00:43:11,430 [Alumno] Cando estamos ligando escribimos lcs50? 526 00:43:11,430 --> 00:43:20,510 Si, así lcs50. Que os signos de bandeira para o vinculador que debe estar ligando nesta biblioteca. 527 00:43:26,680 --> 00:43:28,910 Preguntas? 528 00:43:41,310 --> 00:43:46,860 Temos ido máis binario distinto que 5 segundos en primeira charla? 529 00:43:50,130 --> 00:43:53,010 Penso que non. 530 00:43:55,530 --> 00:43:58,820 Debe saber todo o SO grande que xa sabemos, 531 00:43:58,820 --> 00:44:02,670 e ten que ser capaz de se lle deu unha función, 532 00:44:02,670 --> 00:44:09,410 ten que ser capaz de dicir que é grande, aproximadamente. Ou ben grande, o é áspera. 533 00:44:09,410 --> 00:44:15,300 Entón, se ves aniñados loops looping sobre o mesmo número de cousas, 534 00:44:15,300 --> 00:44:22,260 como int i, i > [alumno] n ao cadrado. >> Tende a ser n ao cadrado. 535 00:44:22,260 --> 00:44:25,280 Se triplo aniñados, el tende a ser n cubos. 536 00:44:25,280 --> 00:44:29,330 Entón, que tipo de cousas ten que ser capaz de apuntar inmediatamente. 537 00:44:29,330 --> 00:44:33,890 Debe saber o tipo de inserción e bubble sort e merge sort e de todos aqueles. 538 00:44:33,890 --> 00:44:41,420 É máis fácil entender por que eles son os n ao cadrado e n log n e todo iso 539 00:44:41,420 --> 00:44:47,810 porque eu creo que houbo un quiz un ano no que, basicamente, deulle 540 00:44:47,810 --> 00:44:55,050 unha implementación do bubble sort, e dixo: "O que é o tempo de execución desta función?" 541 00:44:55,050 --> 00:45:01,020 Entón, se recoñecelo como unha especie de burbulla, entón podes dicir inmediatamente n ao cadrado. 542 00:45:01,020 --> 00:45:05,470 Pero se ollar para el, non precisa aínda de entender que é unha especie de burbulla; 543 00:45:05,470 --> 00:45:08,990 pode só dicir que este está facendo isto e isto. Este é n ao cadrado. 544 00:45:12,350 --> 00:45:14,710 [Alumno] Hai exemplos difíciles que pode vir enriba con, 545 00:45:14,710 --> 00:45:20,370 como unha idea semellante de descubrir? 546 00:45:20,370 --> 00:45:24,450 >> Eu non creo que vai dar-lle algúns exemplos difíciles. 547 00:45:24,450 --> 00:45:30,180 O bubble sort é tan resistente como iamos nós, 548 00:45:30,180 --> 00:45:36,280 e aínda que, sempre que entenda que está interactuando sobre a matriz 549 00:45:36,280 --> 00:45:41,670 para cada elemento da matriz, o que vai ser algo que n ao cadrado. 550 00:45:45,370 --> 00:45:49,940 Hai cuestións xerais, como aquí temos - Ah. 551 00:45:55,290 --> 00:45:58,530 Aínda o outro día, Doug afirmou: "Eu inventei un algoritmo que pode clasificar un array 552 00:45:58,530 --> 00:46:01,780 "De n números en O (log n) o tempo!" 553 00:46:01,780 --> 00:46:04,900 Así como sabemos que iso é imposible? 554 00:46:04,900 --> 00:46:08,850 [Resposta do alumno inaudível] >> Yeah. 555 00:46:08,850 --> 00:46:13,710 Como mínimo, ten que tocar cada elemento na matriz, 556 00:46:13,710 --> 00:46:16,210 por iso é imposible de clasificar unha matriz de - 557 00:46:16,210 --> 00:46:20,850 Se todo está en orde non separado, entón vai estar tocando todo na matriz, 558 00:46:20,850 --> 00:46:25,320 por iso é imposible facelo en menos de O de n. 559 00:46:27,430 --> 00:46:30,340 [Alumno] nos mostrou que o exemplo de ser capaz de facelo en O de n 560 00:46:30,340 --> 00:46:33,920 se usa unha morea de memoria. Si >>. 561 00:46:33,920 --> 00:46:37,970 E iso é - eu esquezo o que é - e contando tipo? 562 00:46:47,360 --> 00:46:51,330 Hmm Que é un algoritmo de ordenación enteiro. 563 00:46:59,850 --> 00:47:05,100 Eu estaba mirando para o nome especial para iso que eu non podía me lembrar a semana pasada. 564 00:47:05,100 --> 00:47:13,000 Si Estes son os tipos de tipos que poden realizar as cousas en grande de n. 565 00:47:13,000 --> 00:47:18,430 Pero hai limitacións, como só se pode usar números enteiros ata un determinado número. 566 00:47:20,870 --> 00:47:24,560 Ademais, se está tentando clasificar Si Aí algo - 567 00:47:24,560 --> 00:47:30,750 Se a súa matriz é 012, -12, 151, 4 millóns, 568 00:47:30,750 --> 00:47:35,120 a continuación, o elemento único vai arruinar completamente a selección enteiro. 569 00:47:42,060 --> 00:47:44,030 >> Preguntas? 570 00:47:49,480 --> 00:47:58,870 [Alumno] Se vostede ten unha función recursiva, e iso só fai as chamadas recursivas 571 00:47:58,870 --> 00:48:02,230 dentro dunha instrución de retorno, que é rabo recursiva, 572 00:48:02,230 --> 00:48:07,360 e así que non vai utilizar máis memoria durante o tempo de execución 573 00:48:07,360 --> 00:48:12,550 ou sería, polo menos, utilizar a memoria comparable como solución iterativa? 574 00:48:12,550 --> 00:48:14,530 [Bowden] Si 575 00:48:14,530 --> 00:48:19,840 Probablemente sería un pouco máis lento, pero non realmente. 576 00:48:19,840 --> 00:48:23,290 Cola recursiva é moi bo. 577 00:48:23,290 --> 00:48:32,640 Mirando de novo para cadros de pila, imos dicir que temos principal 578 00:48:32,640 --> 00:48:42,920 e temos barra int (int x) ou algo así. 579 00:48:42,920 --> 00:48:52,310 Esta non é unha función recursiva perfecto, pero barra de retorno (x - 1). 580 00:48:52,310 --> 00:48:57,620 Entón, obviamente, que é fallo. Debe casos base e outras cousas. 581 00:48:57,620 --> 00:49:00,360 Pero a idea aquí é que esta é a cola recursiva, 582 00:49:00,360 --> 00:49:06,020 o que significa que cando a barra de chamadas principal que vai ter o seu cadro de pila. 583 00:49:09,550 --> 00:49:12,440 Neste cadro de pila alí vai ser un pequeno bloque de memoria 584 00:49:12,440 --> 00:49:17,490 que corresponde ao seu argumento x. 585 00:49:17,490 --> 00:49:25,840 E así imos dicir principal pasa a chamarse bar (100); 586 00:49:25,840 --> 00:49:30,050 Entón x vai comezar como 100. 587 00:49:30,050 --> 00:49:35,660 O compilador recoñece que esta é unha función recursiva cola, 588 00:49:35,660 --> 00:49:38,540 a continuación, cando a barra fai a súa chamada recursiva para untar, 589 00:49:38,540 --> 00:49:45,490 en vez de facer un novo cadro de pila, que é onde a pila comeza a crecer en gran parte, 590 00:49:45,490 --> 00:49:48,220 finalmente, el será executado na pila e entón comeza segfaults 591 00:49:48,220 --> 00:49:51,590 porque a memoria comeza a chocar. 592 00:49:51,590 --> 00:49:54,830 >> Entón, en vez de facer o seu propio cadro de pila, pode realizar, 593 00:49:54,830 --> 00:49:59,080 Ola, eu nunca realmente precisa para volver a este cadro de pila, 594 00:49:59,080 --> 00:50:08,040 Así, en vez vou substituír ese argumento con 99 e, a continuación, comezar a barra de todo. 595 00:50:08,040 --> 00:50:11,810 E entón el vai facer iso de novo e vai chegar barra de retorno (x - 1), 596 00:50:11,810 --> 00:50:17,320 e en vez de facer un novo cadro de pila, que vai só substituír o seu argumento actual con 98 597 00:50:17,320 --> 00:50:20,740 e despois ir de volta para o inicio do bar. 598 00:50:23,860 --> 00:50:30,430 Estas operacións, substituíndo este valor 1 na pila e ir de volta para o inicio, 599 00:50:30,430 --> 00:50:32,430 son bastante eficaces. 600 00:50:32,430 --> 00:50:41,500 Polo tanto, non é só o uso de memoria aínda que unha función propia, que é iterativo 601 00:50:41,500 --> 00:50:45,390 porque está usando só un cadro de pila, pero non está sufrindo os inconvenientes 602 00:50:45,390 --> 00:50:47,240 de ter que chamar funcións. 603 00:50:47,240 --> 00:50:50,240 Funcións de chamada pode ser un pouco caro, porque ten que facer toda esa configuración 604 00:50:50,240 --> 00:50:52,470 e desmontaxe e todas esas cousas. 605 00:50:52,470 --> 00:50:58,160 Polo tanto, este recursão de cola é bo. 606 00:50:58,160 --> 00:51:01,170 [Alumno] Por que non crear novos pasos? 607 00:51:01,170 --> 00:51:02,980 Porque entende que non precisa. 608 00:51:02,980 --> 00:51:07,800 A chamada á barra está só retornando a chamada recursiva. 609 00:51:07,800 --> 00:51:12,220 Por iso, non precisa de facer calquera cousa co valor de retorno. 610 00:51:12,220 --> 00:51:15,120 El só vai inmediatamente devolve-lo. 611 00:51:15,120 --> 00:51:20,530 Por iso, só vai substituír o seu propio argumento e comezar de novo. 612 00:51:20,530 --> 00:51:25,780 E tamén, se non ten a versión cola recursiva, 613 00:51:25,780 --> 00:51:31,460 entón obter todos estes bares onde, cando esta barra retorna 614 00:51:31,460 --> 00:51:36,010 ten que voltar ao seu valor para este, a continuación, que a barra retorna inmediatamente 615 00:51:36,010 --> 00:51:39,620 e retorna o seu valor para este, a continuación, é só ir para voltar inmediatamente 616 00:51:39,620 --> 00:51:41,350 e voltar o seu valor a este. 617 00:51:41,350 --> 00:51:45,350 Entón está salvando esta aparecendo todas estas cousas fóra da pila 618 00:51:45,350 --> 00:51:48,730 unha vez que o valor de retorno é só vai ser pasado por todo o camiño de volta de calquera maneira. 619 00:51:48,730 --> 00:51:55,400 Entón por que non substituír o noso argumento co argumento actualizado e comezar de novo? 620 00:51:57,460 --> 00:52:01,150 Se a función non é recursiva cola, se fai algo así como - 621 00:52:01,150 --> 00:52:07,530 [Alumno] se bar (x + 1). Si >>. 622 00:52:07,530 --> 00:52:11,770 >> Entón, se poñelas en condicións, entón está facendo algo co valor de retorno. 623 00:52:11,770 --> 00:52:16,260 Ou mesmo se acaba de facer return 2 * bar (x - 1). 624 00:52:16,260 --> 00:52:23,560 Entón bar agora (x - 1) precisa volver para que para calcular 2 veces ese valor, 625 00:52:23,560 --> 00:52:26,140 entón agora é necesario o seu cadro de pila separada, 626 00:52:26,140 --> 00:52:31,180 e agora, non importa o quão duro vostede probe, vai ter - 627 00:52:31,180 --> 00:52:34,410 Esta non é a cola recursiva. 628 00:52:34,410 --> 00:52:37,590 [Alumno] Será que eu intento traer unha recursão a apuntar para unha recursão de cola - 629 00:52:37,590 --> 00:52:41,450 [Bowden] Nun mundo ideal, pero na CS50 non precisa facer iso. 630 00:52:43,780 --> 00:52:49,280 A fin de obter recursão de cola, xeralmente, ten establece un argumento adicional 631 00:52:49,280 --> 00:52:53,550 onde bar terá int x en y 632 00:52:53,550 --> 00:52:56,990 e y corresponde á última cousa que quere volver. 633 00:52:56,990 --> 00:53:03,650 Entón esta vai estar retornando bar (x - 1), 2 * y. 634 00:53:03,650 --> 00:53:09,810 Entón, iso é só un alto nivel como transformar as cousas para ser cola recursiva. 635 00:53:09,810 --> 00:53:13,790 Pero o argumento extra - 636 00:53:13,790 --> 00:53:17,410 E entón, ao final, cando chegar ao seu caso base, acaba de volver y 637 00:53:17,410 --> 00:53:22,740 porque foi acumulando o tempo o valor de retorno que quere. 638 00:53:22,740 --> 00:53:27,280 Vostede medio que ten feito de forma iterativa, mais a través de chamadas recursivas. 639 00:53:32,510 --> 00:53:34,900 Preguntas? 640 00:53:34,900 --> 00:53:39,890 [Estudante] Quizais sobre a aritmética de punteiro, coma cando se usa cordas. >> Suposto. 641 00:53:39,890 --> 00:53:43,610 Aritmética de punteiro. 642 00:53:43,610 --> 00:53:48,440 Ao usar cordas é fácil porque as cordas son estrelas char, 643 00:53:48,440 --> 00:53:51,860 chars son para sempre e sempre un único byte, 644 00:53:51,860 --> 00:53:57,540 e así a aritmética de punteiro é equivalente a aritmética regular, cando está lidando con cordas. 645 00:53:57,540 --> 00:54:08,790 Nós só dicir que char * s = "Ola". 646 00:54:08,790 --> 00:54:11,430 Polo tanto, temos un bloque na memoria. 647 00:54:19,490 --> 00:54:22,380 Precisa de 6 bytes, porque sempre precisa do terminador nulo. 648 00:54:22,380 --> 00:54:28,620 E char * s vai apuntar para o inicio desta matriz. 649 00:54:28,620 --> 00:54:32,830 Así s apunte alí. 650 00:54:32,830 --> 00:54:36,710 Agora, iso é basicamente como calquera matriz funciona, 651 00:54:36,710 --> 00:54:40,780 independentemente de que era un retorno por malloc ou se é a pila. 652 00:54:40,780 --> 00:54:47,110 Calquera matriz é, basicamente, un punteiro para o inicio da matriz, 653 00:54:47,110 --> 00:54:53,640 e despois de calquera operación de matriz, calquera indexación, é só ir en que a matriz dun determinado desprazamento. 654 00:54:53,640 --> 00:55:05,360 >> Polo tanto, cando digo algo así como s [3], o que vai s e contando 3 caracteres dentro 655 00:55:05,360 --> 00:55:12,490 Así, s [3], temos 0, 1, 2, 3, de xeito s [3] vai para referirse a este l. 656 00:55:12,490 --> 00:55:20,460 [Alumno] E nós poderíamos chegar ao mesmo valor, facendo s + 3 e estrela parénteses? 657 00:55:20,460 --> 00:55:22,570 Si 658 00:55:22,570 --> 00:55:26,010 Isto é equivalente a * (S + 3); 659 00:55:26,010 --> 00:55:31,240 e que é para sempre e sempre equivalentes, non importa o que fai. 660 00:55:31,240 --> 00:55:34,070 Vostede non precisa usar a sintaxe de soporte. 661 00:55:34,070 --> 00:55:37,770 Sempre pode usar * (S + 3) sintaxe. 662 00:55:37,770 --> 00:55:40,180 As persoas tenden a gustar da sintaxe soporte, con todo. 663 00:55:40,180 --> 00:55:43,860 [Alumno] Entón, todas as matrices son en realidade só punteiros. 664 00:55:43,860 --> 00:55:53,630 Hai unha lixeira distinción cando digo int x [4]; >> [alumno] Será que crear a memoria? 665 00:55:53,630 --> 00:56:03,320 [Bowden] Isto vai crear 4 ints na pila, de modo xeral 16 bytes. 666 00:56:03,320 --> 00:56:05,700 Vai crear 16 bytes na pila. 667 00:56:05,700 --> 00:56:09,190 X non é almacenada en calquera lugar. 668 00:56:09,190 --> 00:56:13,420 É só un símbolo sobre o inicio da cousa. 669 00:56:13,420 --> 00:56:17,680 Porque declarou a matriz dentro da función, 670 00:56:17,680 --> 00:56:22,340 o que o compilador vai facer é substituír todas as ocorrencias da variable x 671 00:56:22,340 --> 00:56:26,400 co lugar onde se produciu a opción de poñer estes 16 bytes. 672 00:56:26,400 --> 00:56:30,040 Non pode facer iso con char * s porque s é un punteiro real. 673 00:56:30,040 --> 00:56:32,380 Ela é libre para, a continuación, apuntar para outras cousas. 674 00:56:32,380 --> 00:56:36,140 x é unha constante. Vostede non pode apuntar para unha matriz diferente. >> [Alumno] Okay. 675 00:56:36,140 --> 00:56:43,420 Pero esta idea, esta indexación, é o mesmo, independentemente de se tratar dunha matriz tradicional 676 00:56:43,420 --> 00:56:48,230 ou se é un punteiro para algo ou se é un punteiro para unha matriz malloced. 677 00:56:48,230 --> 00:56:59,770 E, de feito, é así equivalente que esa é tamén a mesma cousa. 678 00:56:59,770 --> 00:57:05,440 El realmente só traduce o que está dentro dos corchetes eo que sobrou dos soportes, 679 00:57:05,440 --> 00:57:07,970 engadila los xuntos, e dereferences. 680 00:57:07,970 --> 00:57:14,710 Polo tanto, esta é tan válida como * (S + 3) ou s [3]. 681 00:57:16,210 --> 00:57:22,090 [Estudante] Pode ter punteiros ligan con 2-dimensional arrays? 682 00:57:22,090 --> 00:57:27,380 >> É máis difícil. Tradicionalmente, no. 683 00:57:27,380 --> 00:57:34,720 Unha matriz de 2 dimensións é só unha matriz 1-dimensional con algunha sintaxe cómodo 684 00:57:34,720 --> 00:57:54,110 porque cando eu digo int x [3] [3], que é realmente só unha matriz con 9 valores. 685 00:57:55,500 --> 00:58:03,000 E entón cando índice, o compilador sabe o que quero dicir. 686 00:58:03,000 --> 00:58:13,090 Se eu dixer x [1] [2], el sabe que eu quero ir para a segunda liña, polo que vai saltar o primeiro 3, 687 00:58:13,090 --> 00:58:17,460 e entón el quere que a segunda cousa en que, por iso vai recibir un agasallo. 688 00:58:17,460 --> 00:58:20,480 Pero aínda é só unha matriz unidimensional. 689 00:58:20,480 --> 00:58:23,660 E así se eu quería dar un punteiro para esa matriz, 690 00:58:23,660 --> 00:58:29,770 Eu diría int * p = x; 691 00:58:29,770 --> 00:58:33,220 O tipo de x é só - 692 00:58:33,220 --> 00:58:38,280 É tipo dicindo aproximada de x, xa que é só un símbolo e non é unha variable real, 693 00:58:38,280 --> 00:58:40,140 pero é só un int *. 694 00:58:40,140 --> 00:58:44,840 x é só un punteiro para o inicio desta. >> [Alumno] Okay. 695 00:58:44,840 --> 00:58:52,560 E por iso non vou ser capaz de acceder [1] [2]. 696 00:58:52,560 --> 00:58:58,370 Eu creo que hai unha sintaxe especial para declarar un punteiro, 697 00:58:58,370 --> 00:59:12,480 algo ridículo como int (* p [-. algo absolutamente ridículo que eu non sei mesmo. 698 00:59:12,480 --> 00:59:17,090 Pero hai unha sintaxe para declarar punteiros como con parénteses e cousas. 699 00:59:17,090 --> 00:59:22,960 Pode até non deixar facer iso. 700 00:59:22,960 --> 00:59:26,640 Eu podería ollar cara atrás, algo que me diga a verdade. 701 00:59:26,640 --> 00:59:34,160 Vou buscalo máis tarde, se hai unha sintaxe para punto. Pero nunca vai velo. 702 00:59:34,160 --> 00:59:39,670 E mesmo a sintaxe é tan arcaico que usalo, as persoas van perplexo. 703 00:59:39,670 --> 00:59:43,540 Matrices multidimensionais son moi raros como ela é. 704 00:59:43,540 --> 00:59:44,630 Está moi ben - 705 00:59:44,630 --> 00:59:48,490 Ben, se está facendo as cousas da matriz non vai ser raro, 706 00:59:48,490 --> 00:59:56,730 pero en C raramente vai utilizar matrices multidimensionais. 707 00:59:57,630 --> 01:00:00,470 Si >> [Alumno] Digamos que ten unha matriz moi longo. 708 01:00:00,470 --> 01:00:03,900 >> Así, na memoria virtual parece ser todos consecutivos, 709 01:00:03,900 --> 01:00:05,640 como os elementos ao lado uns dos outros, 710 01:00:05,640 --> 01:00:08,770 pero na memoria física, sería posible para que isto se separaron? Si >>. 711 01:00:08,770 --> 01:00:16,860 Como a memoria funciona virtuais é só separa - 712 01:00:19,220 --> 01:00:24,860 A unidade de distribución é unha páxina, que tende a ser de 4 kilobytes, 713 01:00:24,860 --> 01:00:29,680 e así, cando un proceso di, hey, eu quero usar esa memoria, 714 01:00:29,680 --> 01:00:35,970 o sistema operativo vai asignar-lle 4 kilobytes para ese pequeno bloque de memoria. 715 01:00:35,970 --> 01:00:39,100 Mesmo se usa só un único byte pouco en todo o bloque de memoria, 716 01:00:39,100 --> 01:00:42,850 o sistema operativo vai dar o total de 4 kilobytes. 717 01:00:42,850 --> 01:00:49,410 Entón, o que isto significa que eu podería ter - digamos que esta é a miña pila. 718 01:00:49,410 --> 01:00:53,180 Esta pila podían ser separados. A miña pila podería ser megabytes e megabytes. 719 01:00:53,180 --> 01:00:55,020 A miña pila pode ser enorme. 720 01:00:55,020 --> 01:01:00,220 Pero a pila en si debe ser dividido en páxinas individuais, 721 01:01:00,220 --> 01:01:09,010 que, se olharmos para acá, digamos que esta é a nosa memoria RAM, 722 01:01:09,010 --> 01:01:16,600 se eu tivera 2 gigabytes de memoria RAM, este é o enderezo real 0 como byte 0 da miña memoria RAM, 723 01:01:16,600 --> 01:01:22,210 e este é de 2 gigabytes todo o camiño ata aquí. 724 01:01:22,210 --> 01:01:27,230 Polo tanto, esta páxina pode corresponder a este bloque aquí. 725 01:01:27,230 --> 01:01:29,400 Esta páxina pode corresponder a este bloque aquí. 726 01:01:29,400 --> 01:01:31,560 Este pode corresponder a este aquí. 727 01:01:31,560 --> 01:01:35,540 Así, o sistema operativo é libre para asignar memoria física 728 01:01:35,540 --> 01:01:39,320 para calquera páxina individual arbitrariamente. 729 01:01:39,320 --> 01:01:46,180 E isto significa que, se isto ocorre fronteira para straddle dunha matriz, 730 01:01:46,180 --> 01:01:50,070 unha matriz pasa a ser deixada deste e dereita da orde dunha páxina, 731 01:01:50,070 --> 01:01:54,460 a continuación, que a matriz vai ser dividida en memoria física. 732 01:01:54,460 --> 01:01:59,280 E entón cando saia do programa, ao final do proceso, 733 01:01:59,280 --> 01:02:05,690 eses mapeamento obter borrado e entón é libre para usar estes pequenos bloques para outras cousas. 734 01:02:14,730 --> 01:02:17,410 Máis preguntas? 735 01:02:17,410 --> 01:02:19,960 [Alumno] aritmética O punteiro. >> Oh yeah. 736 01:02:19,960 --> 01:02:28,410 Cordas foron máis fáciles, pero mirando para algo así como ints, 737 01:02:28,410 --> 01:02:35,000 Entón, de volta para int x [4]; 738 01:02:35,000 --> 01:02:41,810 Se isto é unha matriz ou se é un punteiro para unha matriz malloced de 4 números enteiros, 739 01:02:41,810 --> 01:02:47,060 vai ser tratado da mesma maneira. 740 01:02:50,590 --> 01:02:53,340 [Estudante] Entón matrices son na pila? 741 01:03:01,400 --> 01:03:05,270 [Bowden] matrices non son na pila. >> [Alumno] Oh 742 01:03:05,270 --> 01:03:08,320 >> [Bowden] Este tipo de arranxo tende a ser na pila 743 01:03:08,320 --> 01:03:12,220 a menos que declarou na - ignorando variables globais. Non use variables globais. 744 01:03:12,220 --> 01:03:16,280 Dentro dunha función que digo int x [4]; 745 01:03:16,280 --> 01:03:22,520 Vai crear un bloque de 4 enteiro na pila para esta matriz. 746 01:03:22,520 --> 01:03:26,960 Pero este malloc (4 * sizeof (int)); está a ir na pila. 747 01:03:26,960 --> 01:03:31,870 Pero tras este punto podo usar X e P en practicamente do mesmo xeito, 748 01:03:31,870 --> 01:03:36,140 Ademais das excepcións que eu dixen antes sobre se pode reatribuir p. 749 01:03:36,140 --> 01:03:40,960 Tecnicamente, as súas dimensións son un pouco diferentes, pero iso é totalmente irrelevante. 750 01:03:40,960 --> 01:03:43,310 Vostede non realmente usar os seus tamaños. 751 01:03:48,020 --> 01:03:56,810 O que eu podería dicir p p [3] = 2; ou x [3] = 2; 752 01:03:56,810 --> 01:03:59,680 Podes usalos en exactamente da mesma maneira. 753 01:03:59,680 --> 01:04:01,570 Así, a aritmética de punteiro agora - Si 754 01:04:01,570 --> 01:04:07,390 [Alumno] Non ten que facer p * se ten os soportes? 755 01:04:07,390 --> 01:04:11,720 Os soportes son unha dereference implícita. Ok >>. 756 01:04:11,720 --> 01:04:20,200 En realidade, tamén o que está dicindo o que pode obter matrices multidimensionais 757 01:04:20,200 --> 01:05:02,650 con punteiros, o que pode facer é algo así como, digamos, int ** pp = malloc (sizeof (int *) * 5); 758 01:05:02,650 --> 01:05:06,900 Eu só vou escribir todo primeiro. 759 01:05:37,880 --> 01:05:41,020 Eu non quería iso. 760 01:05:41,020 --> 01:05:42,550 Okay. 761 01:05:42,550 --> 01:05:48,910 O que eu fixen aquí é - Isto debe ser pp [i]. 762 01:05:48,910 --> 01:05:53,680 Así, pp é un enlace a un enlace. 763 01:05:53,680 --> 01:06:02,420 Vostede está mallocing pp, para apuntar para unha matriz de 5 estrelas int. 764 01:06:02,420 --> 01:06:10,950 Así, en memoria que ten sobre a pila PP 765 01:06:10,950 --> 01:06:20,150 Vai apuntar unha matriz de 5 bloques que son todos propios punteiros. 766 01:06:20,150 --> 01:06:28,210 E entón cando malloc aquí, malloc eu que cada un destes indicadores individuais 767 01:06:28,210 --> 01:06:32,080 debería apuntar un bloque separado de 4 bytes na pila. 768 01:06:32,080 --> 01:06:35,870 Polo tanto, este apunta a 4 bytes. 769 01:06:37,940 --> 01:06:40,660 E iso apunta a unha distinta 4 bytes. 770 01:06:40,660 --> 01:06:43,200 >> E todos eles apuntan para as súas propias 4 bytes. 771 01:06:43,200 --> 01:06:49,080 Isto dá-me unha forma de facer as cousas multidimensionais. 772 01:06:49,080 --> 01:06:58,030 Eu podería dicir pp [3] [4], pero agora iso non é a mesma cousa como matrices multidimensionais 773 01:06:58,030 --> 01:07:05,390 porque as matrices multidimensionais é traducido [3] [4] nun único desprazamento para a matriz X. 774 01:07:05,390 --> 01:07:14,790 Este p dereferences, accede a terceira índice, a continuación, que dereferences 775 01:07:14,790 --> 01:07:20,790 e accesos - 4 sería válida - o segundo índice. 776 01:07:24,770 --> 01:07:31,430 Considerando que, cando tivemos a int x [3] [4] antes como unha matriz multidimensional 777 01:07:31,430 --> 01:07:35,740 e cando lle dá un dobre soporte é realmente só dereference unha única 778 01:07:35,740 --> 01:07:40,490 está seguindo un único punteiro e, a continuación, un desprazamento, 779 01:07:40,490 --> 01:07:42,850 iso é realmente referencias 2D. 780 01:07:42,850 --> 01:07:45,840 Vostede segue dous punteiros separados. 781 01:07:45,840 --> 01:07:50,420 Polo tanto, esta tamén tecnicamente permite que teña matrices multidimensionais 782 01:07:50,420 --> 01:07:53,550 onde cada arranxo individuo e tamaños diferentes. 783 01:07:53,550 --> 01:07:58,000 Entón eu creo irregulares matrices multidimensionais é o que se chama 784 01:07:58,000 --> 01:08:01,870 xa que realmente o primeiro que podería apuntar cara algo que ten 10 elementos, 785 01:08:01,870 --> 01:08:05,540 A segunda cousa que podería apuntar cara algo que ten 100 elementos. 786 01:08:05,540 --> 01:08:10,790 [Alumno] Existe un límite para o número de punteiros que pode ter 787 01:08:10,790 --> 01:08:14,290 apuntando a outros punteiros? Non >> 788 01:08:14,290 --> 01:08:17,010 Pode ter int ***** p. 789 01:08:18,050 --> 01:08:23,760 Voltar á aritmética de punteiro - >> [alumno] Oh Si >>. 790 01:08:23,760 --> 01:08:35,649 [Alumno] Se eu tivera int p *** e entón eu fago un dereferencing e digo p * é igual a este valor, 791 01:08:35,649 --> 01:08:39,560 é que só vai facer un nivel de dereferencing? Si >>. 792 01:08:39,560 --> 01:08:43,340 Entón, se eu queira acceder a cousa que o último punteiro está a apuntar cara - 793 01:08:43,340 --> 01:08:46,210 Entón fai p ***. Ok >>. 794 01:08:46,210 --> 01:08:54,080 Polo tanto, este é p apunta a un bloque, apunta a outro bloque, apunta a outro bloque. 795 01:08:54,080 --> 01:09:02,010 Entón, se fai * p = outra cousa, entón está cambiando esta 796 01:09:02,010 --> 01:09:13,640 agora a apuntar cara a un bloque distinto. Ok >>. 797 01:09:13,640 --> 01:09:17,649 >> [Bowden] E estes foron malloced, entón xa se filtrou memoria 798 01:09:17,649 --> 01:09:20,430 a menos que acontecer ter referencias distintas destas 799 01:09:20,430 --> 01:09:25,270 sempre que non pode volver a aquelas que só xogou fóra. 800 01:09:25,270 --> 01:09:29,550 Aritmética de punteiro. 801 01:09:29,550 --> 01:09:36,310 int x [4]; vai reservar unha matriz de 4 enteiros 802 01:09:36,310 --> 01:09:40,670 onde x vai apuntar para o inicio da matriz. 803 01:09:40,670 --> 01:09:50,420 Polo tanto, cando digo algo x [1], quero que signifique ir para o segundo enteiro na matriz, 804 01:09:50,420 --> 01:09:53,319 o que sería un agasallo. 805 01:09:53,319 --> 01:10:04,190 Pero, realmente, que é 4 bytes na matriz dende que este número enteiro ocupa 4 bytes. 806 01:10:04,190 --> 01:10:08,470 Entón, un desprazamento de 1 realmente significa un desprazamento dunha 807 01:10:08,470 --> 01:10:12,030 veces o tamaño de calquera que sexa o tipo de matriz é. 808 01:10:12,030 --> 01:10:17,170 Este é un array de enteiros, para que saiba facer unha veces o tamaño de int cando quere compensar. 809 01:10:17,170 --> 01:10:25,260 A sintaxe outro. Lembre que isto é equivalente a * (x + 1); 810 01:10:25,260 --> 01:10:35,250 Cando digo punteiro + 1, o que que retorna é o enderezo que o punteiro está almacenando 811 01:10:35,250 --> 01:10:40,360 máis 1 veces o tamaño do tipo de punteiro. 812 01:10:40,360 --> 01:10:59,510 Entón, se x = ox100, entón x + 1 = ox104. 813 01:10:59,510 --> 01:11:19,750 E pode abusar dese e dicir algo así como char * c = (char *) x; 814 01:11:19,750 --> 01:11:23,050 e agora c vai ser o mesmo enderezo x. 815 01:11:23,050 --> 01:11:26,040 c vai ser igual a ox100, 816 01:11:26,040 --> 01:11:31,490 pero c + 1 será igual a ox101 817 01:11:31,490 --> 01:11:38,030 desde a aritmética de punteiro depende do tipo de punteiro que está engadindo. 818 01:11:38,030 --> 01:11:45,390 Entón c + 1, que mira para c, é un punteiro char, por iso vai engadir unha veces o tamaño do char, 819 01:11:45,390 --> 01:11:48,110 que sempre vai ser un, para que obteña 101, 820 01:11:48,110 --> 01:11:54,890 mentres que se o fai x, o cal é tamén aínda 100, x + 1 vai ser 104. 821 01:11:56,660 --> 01:12:06,340 [Estudante] Podes usar C + + para avanzar o punteiro por un? 822 01:12:06,340 --> 01:12:09,810 Si, pode. 823 01:12:09,810 --> 01:12:16,180 Vostede non pode facelo con x porque x é só un símbolo, é unha constante, non pode cambiar x. 824 01:12:16,180 --> 01:12:22,610 >> Pero c pasa de ser só un punteiro, entón C + + é perfectamente válido e será incrementado en 1. 825 01:12:22,610 --> 01:12:32,440 Se c fose só un int *, entón c + + sería 104. 826 01:12:32,440 --> 01:12:41,250 + + Aritmética de punteiro fai exactamente como C + 1 tería feito aritmética de punteiro. 827 01:12:43,000 --> 01:12:48,870 Este é, en realidade, como unha morea de cousas como merge sort - 828 01:12:49,670 --> 01:12:55,710 En vez de crear copias de cousas, pode pasar en vez - 829 01:12:55,710 --> 01:13:02,400 Como se eu quería pasar esta metade da matriz - imos borrar un pouco iso. 830 01:13:04,770 --> 01:13:10,520 Imos dicir que eu quería pasar deste lado da matriz nunha función. 831 01:13:10,520 --> 01:13:12,700 O que eu ía pasar esa función? 832 01:13:12,700 --> 01:13:17,050 Se eu pasar x, eu estou pasando este enderezo. 833 01:13:17,050 --> 01:13:23,780 Pero quero pasar ese enderezo particular. Entón o que debo pasar? 834 01:13:23,780 --> 01:13:26,590 [Estudante] Punteiro + 2? 835 01:13:26,590 --> 01:13:29,350 [Bowden] Entón x + 2. Si 836 01:13:29,350 --> 01:13:31,620 Isto vai ser este enderezo. 837 01:13:31,620 --> 01:13:42,810 Tamén vai moi frecuentemente velo como x [2] e, a continuación, o enderezo do. 838 01:13:42,810 --> 01:13:47,850 Entón, necesitas ter o enderezo dela, porque o soporte é un dereference implícita. 839 01:13:47,850 --> 01:13:53,250 x [2] refírese ao valor que está na caixa, e entón quere o enderezo desa caixa, 840 01:13:53,250 --> 01:13:56,850 entón di & x [2]. 841 01:13:56,850 --> 01:14:02,880 Entón é así que algo merge sort onde quere pasar a metade da lista para algo 842 01:14:02,880 --> 01:14:08,790 realmente só pasan & x [2], e agora ata a chamada recursiva está en causa, 843 01:14:08,790 --> 01:14:12,510 miña nova matriz comeza aí. 844 01:14:12,510 --> 01:14:15,130 Última preguntas minutos. 845 01:14:15,130 --> 01:14:20,050 [Alumno] Se non poñer un ou un - que é o que chama? >> Star? 846 01:14:20,050 --> 01:14:23,200 [Alumno] Star. >> Tecnicamente, operador dereference, pero - >> [alumno] Referencia no. 847 01:14:23,200 --> 01:14:29,310 >> Se non poñer unha estrela ou un comercial, o que acontece se eu só dicir y = x e x é un punteiro? 848 01:14:29,310 --> 01:14:34,620 Cal é o tipo de y? >> [Alumno] Eu só vou dicir que é punteiro 2. 849 01:14:34,620 --> 01:14:38,270 Entón, se acaba de dicir y = x, agora x e y punto para o mesmo. >> [Estudante] Punto para a mesma cousa. 850 01:14:38,270 --> 01:14:45,180 E, se x é un punteiro int? Sería >> reclamar, porque non pode asignar punteiros. 851 01:14:45,180 --> 01:14:46,540 [Alumno] Okay. 852 01:14:46,540 --> 01:14:51,860 Lembre que os punteiros, a pesar de atrae-los como flechas, 853 01:14:51,860 --> 01:15:02,010 realmente tenda todos eles - int * x - realmente todo x está almacenando é algo así como ox100, 854 01:15:02,010 --> 01:15:06,490 que acontecer para representar como apuntando para o bloque almacenado a 100. 855 01:15:06,490 --> 01:15:19,660 Polo tanto, cando digo int * y = x, eu só estou copiando ox100 en y, 856 01:15:19,660 --> 01:15:24,630 que está indo só para representar como y, apuntando tamén para ox100. 857 01:15:24,630 --> 01:15:39,810 E se eu dixer int i = (int) X; entón eu vai almacenar calquera que sexa o valor ox100 é 858 01:15:39,810 --> 01:15:45,100 dentro del, pero agora vai ser interpretado como un enteiro, en vez de un punteiro. 859 01:15:45,100 --> 01:15:49,310 Pero precisa do reparto ou entón el vai reclamar. 860 01:15:49,310 --> 01:15:53,300 [Estudante] Entón quere dicir para lanzar - 861 01:15:53,300 --> 01:16:00,290 Será que vai estar lanzando int X ou y int reparto? 862 01:16:00,290 --> 01:16:03,700 [Bowden] O que? 863 01:16:03,700 --> 01:16:07,690 [Alumno] Okay. Tras estes parénteses está alí vai ser un x ou ay alí? 864 01:16:07,690 --> 01:16:11,500 >> [Bowden] De calquera. x e y son equivalentes. >> [Alumno] Okay. 865 01:16:11,500 --> 01:16:14,390 Porque son os dous punteiros. Si >>. 866 01:16:14,390 --> 01:16:21,050 [Estudante] Entón sería almacenar os 100 hexadecimal na forma enteiro? >> [Bowden] Yeah. 867 01:16:21,050 --> 01:16:23,620 Pero non o valor de todo o que apunta. 868 01:16:23,620 --> 01:16:29,940 [Bowden] Yeah. >> [Alumno] Entón, só o enderezo en forma de número enteiro. Okay. 869 01:16:29,940 --> 01:16:34,720 [Bowden] Se quixese, por algunha razón estraña, 870 01:16:34,720 --> 01:16:38,900 podería exclusivamente xestione punteiros e nunca tratar con números enteiros 871 01:16:38,900 --> 01:16:49,240 e só ser como int * x = 0. 872 01:16:49,240 --> 01:16:53,000 Entón, vai estar moi confuso, xa aritmética de punteiro comeza a ocorrer. 873 01:16:53,000 --> 01:16:56,570 Así, os números que almacenan son sen sentido. 874 01:16:56,570 --> 01:16:58,940 É exactamente como acaba interpretala-las. 875 01:16:58,940 --> 01:17:02,920 Entón, eu estou libre para copiar ox100 dun * int para un int, 876 01:17:02,920 --> 01:17:07,790 e eu son libre para asignar - é, probablemente, vai ser repreendidos por non publicar - 877 01:17:07,790 --> 01:17:18,160 Eu son libre para asignar algo (int *) ox1234 neste int * arbitraria. 878 01:17:18,160 --> 01:17:25,480 Entón ox123 é tan enderezo válido de memoria como e y. 879 01:17:25,480 --> 01:17:32,060 & Y pasa para voltar algo que é moi fermoso ox123. 880 01:17:32,060 --> 01:17:35,430 [Alumno] Tería que ser unha forma moi legal para ir hexadecimal para a forma decimal, 881 01:17:35,430 --> 01:17:39,230 Como se ten un punteiro e lanzalo como un int? 882 01:17:39,230 --> 01:17:44,860 [Bowden] Pode realmente só imprimir usando como printf. 883 01:17:44,860 --> 01:17:50,300 Imos dicir que eu teño int y = 100. 884 01:17:50,300 --> 01:18:02,700 Entón printf% (d \ n - como xa debería saber - que imprimir como un enteiro x,%. 885 01:18:02,700 --> 01:18:05,190 Nós só imprimir lo como hexadecimal. 886 01:18:05,190 --> 01:18:10,760 Así, un enlace non é almacenado como hexadecimal, 887 01:18:10,760 --> 01:18:12,960 é un número enteiro non é almacenado como decimal. 888 01:18:12,960 --> 01:18:14,700 Todo é almacenado como binario. 889 01:18:14,700 --> 01:18:17,950 É que tenden a mostrar punteiros como hexadecimal 890 01:18:17,950 --> 01:18:23,260 porque pensamos de cousas neses bloques de 4 bytes, 891 01:18:23,260 --> 01:18:25,390 e enderezos de memoria tenden a ser familiar. 892 01:18:25,390 --> 01:18:28,890 Somos como, se comeza con bf, el pasa a ser na pila. 893 01:18:28,890 --> 01:18:35,560 Entón é só nosa interpretación de punteiros como hexadecimal. 894 01:18:35,560 --> 01:18:39,200 Okay. Calquera dúbida últimos? 895 01:18:39,200 --> 01:18:41,700 >> Eu estarei aquí para un pouco despois, se ten calquera outra cousa. 896 01:18:41,700 --> 01:18:46,070 E ese é o fin de todo. 897 01:18:46,070 --> 01:18:48,360 >> [Alumno] Yay! [Aplausos] 898 01:18:51,440 --> 01:18:53,000 >> [CS50.TV]