[Powered by Google Translate] Imos falar sobre estruturas. Estruturas fornecer un xeito de agrupar unha morea de variables xuntas un bo paquete. É probablemente máis doado para ver un exemplo de inmediato, por iso dicimos struct, a continuación, unha chave de apertura, e nesa estrutura, imos ter unha idade int, un nome de char *, e é iso. Pode parecer estraño cun punto e coma despois dunha chaveta, pero é, de feito, é necesario, con estruturas. Calquera tipo válido pode ir dentro da definición de struct. Aquí usamos un int e un char *, pero tamén pode usar unha matriz, de, digamos, 100 elementos ou mesmo struct outro. Cando está a usar structs en C, está creando novos tipos dunha colección de outros tipos. Aquí, nós estamos facendo un novo tipo dun enteiro e un char *. Como veremos máis adiante, un tipo de estrutura está unha morea de formas equivalentes a calquera outro tipo que está acostumado. Normalmente, eu vou estar comparando como un tipo de estrutura é semellante a un tipo enteiro. Mentres o código que escribiu é válido C, non é moi útil, e bumbum vai dar un aviso. Teña en conta que como estruturas e os seus son semellantes? Ben, basicamente, só dixo int, o que non é unha liña moi útil. Entón, imos realmente declarar unha variable deste tipo , Dándolle un nome antes do punto e coma. Imos chamar o estudante variable. Agora que xa declarou un estudante variable chamada co tipo de dado pola estrutura. Como chegamos ás variables dentro da estrutura? Tecnicamente, os nomes para esas variables son membros. Para acceder calquera membro particular nunha estrutura de estudante, vostede engadir un punto para o nome da variable, seguido do nome do membro que desexe. Entón, aquí, as únicas dúas posibilidades válidos son student.age e student.name. E podemos facer algo como student.age = 12 e student.name = estudante. Agora, o que se quería facer un segundo alumno? Podes pensar que copiar e pegar estas liñas e cambiar alumno para alumno dous ou algo así, e que pode traballar, pero tecnicamente alumno e alumno 2 non teñen o mesmo tipo. Mira, non será capaz de atribuílo los a outro. Isto é porque, ata agora, súa estrutura foi anónima. Necesitamos darlle un nome. Para facer isto, introduza o nome da struct tras a struct palabra. estudante, seguido pola definición. Aínda podemos inmediatamente declarar unha variable do tipo struct alumno, como fixemos antes. Imos chamalo de S1 Ao dar a estrutura dun nome, agora podemos utilizar estudante struct en case exactamente o mesmo que usaría int. Así, podemos declarar unha variable de tipo struct alumno, como struct alumno S2. Como arrays, estruturas proporcionan unha sintaxe de inicio de atallo, así podemos dicir struct alumno S2 é igual esquerda rizados cinta 3, S2. Aquí, S2.age será de 3, e S2.name ha apuntar S2. Debería todas as cousas que podes facer con un tipo int ea maioría deles pode facer un tipo de estudante struct. Podemos usar un estudante de estrutura como un tipo de parámetro de función. Podemos usar struct alumno dentro dunha estrutura nova. Podemos ter un punteiro para un estudante struct. Podemos facer o tamaño alumno struct. Estudante struct é un tipo como int é un tipo. Podemos tamén dar S1 a S2 xa que ambos son do mesmo tipo, para que poidamos facer S1 = S2. Qué acontece se non facemos S1.age = 10? Cambia S2 en todo? Unha vez máis, creo que as estruturas só como enteiros regulares. Se atribuirmos algunha X int a algún Y int, como X = Y e despois cambiar X, como en X + +, Y non cambia en nada? Y non é alterado aquí, e así tampouco S2 anterior. S2.age aínda é 3. Pero nótese que, cando a asignación dunha estrutura a outra, todos os punteiros aínda apuntan á mesma cousa, xa que só foron copiados. Se non quere que os punteiros para ser compartido, terá que tratar con isto manualmente quizais por malicking un bloque de memoria para un dos punteiros para apuntar para e copiar os datos máis. Pode ser aburrido ter que escribir struct alumno en todas as partes. Empregando un def tipo, podemos facer Tipo de def struct e imos chamalo de estudante. Agora, podemos utilizar estudante en todos os lugares que adoitaba empregar estudante struct. Este tipo de def é unha estrutura anónima e chámase alumno. Pero tamén manter o identificador de estudante á beira do struct palabra, como no estudante typedef struct, podemos utilizar tanto o alumno e alumno struct alternativamente agora. Eles nin sequera teñen que ter o mesmo nome. Poderiamos escribir def estudante estrutura para Bob e despois struct alumno e Bob sería tipo intercambiábeis. Independentemente do tipo de def, necesitamos do próximo identificador para a estrutura a definición da estrutura é recursiva. Por exemplo, a def tipo struct nodo e ela defínese como un int val e terá un punteiro que apunta a outro nodo struct., como na estrutura do nó * seguinte. E entón imos chamalo de nós. Esta estrutura é recursiva, unha vez que a definición de nodo struct contén dentro del un punteiro para un nó de estrutura. Teña en conta que temos que dicir struct node * próxima dentro da definición do nodo struct, desde a definición do tipo aínda non rematou para permitir simplificar este * Só para o próximo nó. Vai saber máis sobre estruturas semellantes a este cando se trate de listas ligadas e árbores. E sobre estruturas en función? Isto tamén é perfectamente válida. Poderiamos ter void func que toma como argumento, estudante s e fai algo con ese alumno. E entón podemos pasalo como struct alumno así. Func de S1 de antes. A estrutura comporta exactamente como un número enteiro que cando pasadas a unha función. Func recibe unha copia de S1 e por iso non pode modificar S1; en vez diso, só a copia do mesmo que está almacenado en S. Se queres que a función de ser capaz de modificar S1, función terá de ter un alumno * S, e vai ter que pasar por enderezo S1, así. Estudante * S, func & S1. Hai outra razón para pasar por enderezo aquí. E se a nosa estrutura contiña 100 campos? Cada vez que pasar por un estudante a func, noso programa necesita copiar os 100 campos en función do S argumento, aínda que el nunca usa a gran maioría deles. Así, aínda que función non planea modificar o alumno, aínda pode ser útil para pasar por enderezo. Ok, o que se desexa crear un punteiro para un struct? Nós poderiamos facer algo como estudante * S é igual malloc tamaño do alumno. Teña en conta que o tamaño aínda traballa aquí. Entón, como imos agora acceder ao membro idade do bloque que apunta para S? Podes primeiro pensar en facer * S.age = 4, pero iso non funciona moi ben. Dende que iso vai realmente ser interpretada como * S.age entre parénteses = 4, que non vai mesmo compilar, desde S non é unha estructura ou mellor, un punteiro para unha estrutura, e así o punto non vai funcionar aquí. Nós poderiamos facer (* S) idade. = 4 pero os parénteses poden estar aburrido e confuso. Afortunadamente, temos un operador frecha especial que é algo así como S-> idade = 4. Estas dúas formas de referenciamento idade son equivalentes e nós realmente non precisa de o operador frecha, pero iso fai as cousas máis fermosos. Dende que S é un enlace a un bloque de memoria que contén a estrutura, pode pensar S idade> como segue o punteiro de e coller o membro idade. Entón por que debemos usar sempre estruturas? É en definitiva posible para fuxir con só os números enteiros primitivos, chars, enlaces e similares que estamos afeitos; en vez de antes S1 e S2, poderiamos ter idade1, idade2, nome1, nome2 e todos de variables separadas. Iso é bo, con só dous alumnos, pero o que se tivésemos 10 deles? E se en vez de só dous campos, a estrutura estudante tivo 100 campos? GPa, cursos, cor do cabelo, sexo, e así por diante. En vez de só 10 estruturas, necesitamos mil variables separadas. Ademais, considerada unha función que leva ese estrutura con 100 campos co seu único argumento e imprime todos os campos. Se non usar unha estrutura, cada vez que chamar esa función, temos que pasar en todas as 100 variables, e se temos 100 variables nunha estudante, e 100 variables para estudante, 2 necesitamos ter seguro de que non poida pasar algunhas variables dun estudante e algunhas variables de estudante 2. É imposible facer ese erro cunha estrutura, unha vez que todas as variables son 100 contida nunha única embalaxe. Só un par de notas finais: Se entendeu todo ata este punto, gran. O resto do vídeo é para ser completo. Como estruturas poden realizar calquera tipo de punteiro, eles tamén poden conter punteiros de función. Se está familiarizado coa programación orientada a obxectos, Isto proporciona unha maneira de usar estruturas de programa nun estilo de obxecto orientado. Máis sobre punteiros de función noutro momento. Tamén, ás veces pode ter dúas estruturas cuxas definicións dependen un do outro. Por exemplo, a poderiamos ter struct A, que é definido como un enlace a un B struct, struct B * X, e agora podemos ter unha estrutura B que é definido como un punteiro para unha estrutura A, struct A * Y. Pero iso non vai compilar, desde B struct non existe no momento en que struct A está compilado. E se cambiar struct struct A e B, entón nós só queda con el; esta vez con struct A non existente. Para solucionar isto, podemos escribir struct B; antes da definición de struct A. Iso é chamado de unha declaración para a fronte. Isto só deixa o compilador saber que struct B é un tipo válido que será totalmente definido máis tarde ou noutro lugar. O meu nome é Rob Bowden, e este é o CS50. [CS50.TV]