Faça uma simulação, por meio do Diagrama de Cubos,
para descobrir o problema.
Diagrama de Cubos aqui, na prática, é um Diagrama de Objetos, tá, que eu
dei uma derivada e chamei de Diagrama de Cubos, mas tudo bem.
Vamos lá.
Então, a gente tá nesse momento de execução aqui, tá.
Poderia ter começado do zero,
feito toda aquela amarração, mas a gente já sabe que vai chegar nesse resultado
e agora vamos incluir o endereço do triplo A no Computacao2_2007.
Então, apareceu ali o Computacao2_2007.
Inclusive, ela tá... isso aqui já é uma lista.
Vejam que interessante, isso aqui já é uma lista encadeada e
conectada lá no, provavelmente, no Departamento lá que é o DAELN.
Vejam lá, tá.
Inclusive, tá ali, ó.
Computacao2_2007 e Metodos2_2007.
De fato eles se lincam ali na lista do DAELN.
Mas isso aqui não é importante, o importante agora é ver
como é que eu vou incluir o triplo A nessa lista aqui também.
Vamos ver o que acontece ali.
É uma simulação do IncluaAlunos.
Então, ele vai fazer o quê?
Vai chamar o IncluaAlunos de Computacao2_2007 passando o endereço do triplo A.
Resultando nessa chamada aqui.
Vai passar no primeiro if e no segundo, né.
Porque em Computacao2_2007 o pPrimeiro e pAtual ainda estão nulos.
Ali, ó, pAlunoPrim é nulo.
Então, vai haver a execução
Ele amarrou o triplo A como primeiro Computacao2_2007.
E vai terminar a execução. E, aqui, nessa situação, não apresentou problema nenhum.
Legal. Então, vamos continuar.
Vamos incluir o triplo C agora no Computacao2_2007.
Fez essa chamada. Criou o ponteiro temporário, ponteiro aluno (pa)
que aponta pra quem foi passado por parâmetro no endereço de triplo C.
Ele vai passar no primeiro if, mas não no segundo. Então, vai cair no else.
Ué, por que que ele não passa no segundo if, professor?
Ué, porque agora o pAlunoPrim não é mais nulo,
ele já aponta pro endereço do triplo A.
Ah, tá, então ele cai no else. Legal.
E ali ele vai fazer as amarrações, tá.
Ele vai fazer as amarrações de próximo e anterior, naturalmente.
Bom, vamos ver o que acontece ali.
Olhe só, pessoal.
No âmbito dessa lista aqui, de fato,
o pProx do triplo A, no âmbito dessa lista de Computacao2, aqui, vai ser o triplo C, ó.
Ele é o próximo de fato. Até o código mostra isso.
Ele tá ali, ó. Ele faz a amarração.
E aqui que mora o problema.
Porque pra eu construir uma lista, eu destruí outra.
O triplo A tá apontando pro triplo C no pProx.
O que tá muito legal pra essa lista aqui,
mas isso desmonta a lista anterior.
O que mostra que essa solução que a gente tinha utilizado de um pra n,
relações um pra n, não funciona em n pra n.
Bom, na prática, perdeu-se a conexão do triplo A para triplo B
necessária à lista duplamente encadeada de Metodos2_2007.
E agora a lista só é útil em Computacao2_2007.
E nós vamos ter que resolver essa situação.
Bom, primeira coisa pra você resolver esse tipo de situação, tá,
é você pensar um pouquinho orientado a objetos.
Como assim, professor?
Pense no mundo real. Você enquanto aluno
Você sabe de cor e salteado
quais são todos os próximos e anteriores
de você na lista de chamada de cada disciplina?
Você tem esse conhecimento de pProximo e pAnterior?
Bom, normalmente, não, né.
Você até pode memorizar um semestre ou outro ali e tal,
algo aqui e acolá, mas na prática você não tem esse conhecimento, tá,
de todas as disciplinas, de todos os semestres que você cursou
quem que era o pProximo e pAnterior de você na lista de presença de cada disciplina.
Então, na verdade, existe um elemento, além de ter o Aluno
existe um elemento pra gerenciar o Aluno na lista.
Esse elemento pode ser as linhas lá da lista de chamada se ela for uma lista impressa.
Ou, computacionalmente, pode ser outra coisa.
Então, isso nos leva a uma reflexão sabe.
Quando você monta um objeto, você pensa: mas, e no mundo real
ou no mundo que eu imagino que seja inspirado no mundo real,
é razoável o que eu tô fazendo?
Nesse caso, é razoável eu ter no próprio Aluno pProximo e pAnterior?
Tava simpático até o Aluno colaborar pra compor a lista tal,
tal qual as Disciplinas colaboravam pra compor a lista de Departamento,
mas será que isso é justo do ponto de vista da orientação a objetos?
É assim que acontece numa situação real?
Ou na situação de inspiração do mundo real pelo menos?
Não, né.
Então, por isso que eu criei aqui, usando essa tática que eu tô mostrando pra vocês,
um Elemento Aluno, tá.
Isso aqui... isso aqui é pontilhado, tá. Tá vendo, ó.
Aqui é pontilhado. Aqui é pontilhado.
A hora que eu coloco em Modo Exibição, aqui,
por algum motivo, ele resolve fazer uma linha contínua, tá.
Por defeito de exibição aqui da minha tela,
mas se bem que no projetor de aula também acontece isso.
Enfim, mas é uma linha tracejada.
Até deixa eu deixar aqui a tracejada, porque isso tá me incomodando um pouco.
O que tá acontecendo aqui?
O que tá acontecendo aqui é o seguinte
agora o aluno vai ter as coisas que só interessam de Aluno.
Por exemplo, o Registro Acadêmico.
Também ele vai ter um nome, porque ele é derivado de Pessoa.
Eu não tô mostrando a relação aqui, mas ele é derivado de Pessoa
Poderia mostrar, tá.
Tô mostrando só o que me interessa pra esse foco desse exercício.
O fato é que o Aluno só vai ter as coisas que interessam pra ele.
setRA, getRA etc e tal.
Agora, as coisas que são pertinentes
à lista, ao pProximo e pAnterior
vão pra um novo elemento, um novo camarada aqui,
que é o Elemento Aluno (ElAluno).
O ElAluno, ela é, enquanto classe,
ela é uma classe criada pra gerar objetos que vão tratar dos Alunos na lista.
É por isso que cada ElAluno tem um ponteiro pra aluno,
ou seja, ele conhece o Aluno que ele vai tratar na lista
e ele tem um pProx e pAnte
pra marcar os próximos elementos, ou os elementos anteriores, né.
O elemento próximo e o elemento anterior que tratam o próximo Aluno
e o Aluno anterior na lista.
Bom, aqui, na verdade, então a Disciplina... o que vai acontecer agora com a Disciplina?
Ela não vai conhecer mais um pAlunoPrim e um pAlunoAtual.
Por quê?
Porque agora ela vai conhecer um pElAlunoPrim e um pElAlunoAtual
que são os objetos que vão cuidar dos Alunos na lista.
Naturalmente, o pProx e o pAnt, né. O Conhecer Próximo e o Conhecer Anterior.
É uma relação aqui dita, reflexiva, no ponto de vista da classe, tá.
Então, um objeto dessa classe aqui, ElAluno, conhece
um outro... objetos da mesma classe.
Nesse caso aqui, a relação chama Conhecer Anterior.
Então, cada objeto de ElAluno conhece 0 ou 1 como anterior,
e esse anterior é conhecido por 0 e cada... perdão,
cada ElAluno pode ser conhecido por 0 ou 1 anterior.
Então, tem essa relação aqui
de... pra permitir que
objetos da mesma classe se conheçam que é o caso aqui.
Legal.
Então, vamos lá. Eu tenho a Disciplina
que tem o conhecimento de primeiro e de atual, agora ElAluno,
e cada ElAluno pode conhecer um outro objeto anterior e um outro objeto próximo, né.
Apontamento pra próximo e pra anterior, outramente dito.
Pessoal, como essa classe aqui
como essa classe aqui,
ela surgiu pra permitir implementar essa associação
isso na UML é chamado de Classe de Associação.
Posso até generalizar e chamar de Classe de Relacionamento.
que serve para implementar uma dada relação modelada.
Onde você tem esse pontilhado aqui, ligando uma classe a um relacionamento
isso significa que essa classe aqui serve pra tratar aquele relacionamento.
Isso pode ser importante na sequência.
Ah, tá. Vejam só.
Aqui, então, tem uma série de relacionamentos, tá.
Quem bate o olho aqui, "Conhecer Primeiro", "Conhecer Atual", entende de relacionamento
"Conhecer Anterior", "Conhecer Próximo", e entende de lista encadeada, ele vai falar: "Ah, uma lista encadeada".
Mas você pode deixar uma dica no modelo, tá.
Você pode dizer: "Olhe, na verdade,
todos esses relacionamentos aqui em,
que eu tô destacando aqui com o mouse, em azul aqui:
Conhecer Primeiro, Conhecer Atual, Conhecer Anterior, Conhecer Próximo.
Eles realizam, tá vendo, que você tem a realização, ó.
Eles realizam, eles são equivalentes
a agregar, ainda que fracamente, ElAlunos na Disciplina.
Uma Disciplina ela tem, ainda que imbricado dentro dela,
aqui,
a lista de Disciplinas, por meio de pAlunoPrim e pAlunoAtual,
então, ela, na prática, ela agrega um conjunto de ElAlunos.
Ela agrega esses elementos que vão permitir compor um encadeamento
que vai cuidar dos Alunos na lista dela.
Então, eu posso fazer esse lembrete aqui, tá.
Dizer: olha na prática essas quatro relações aqui
essas quatro associações, servem pra realizar a agregação.
Isso aqui é importante também, tá.
Muito bem.
Deixa eu colocar em Modo Exibição aqui de volta.
Aqui, ó, voltou a ficar tudo contínuo, tá,
no entanto isso aqui é pontilhado, mas tudo bem, é a vida.
Aqui eu tô colocando coisa só pura, agora, aqui, tá, só em Projeto,
eliminando qualquer elemento intermediário,
tô mostrando só a coisa crua como vai ser no código.
Legal. Falando em código vamos pro código.
Tá aí a classe Aluno à direita.
Só com o que interessa de Aluno não tem mais pProximo e pAnterior, insisto.
Mesmo porque agora você tem a classe ElAluno
que vai cuidar de Aluno na lista.
construtora e destrutora, pProximo e pAnterior,
setAluno e getAluno, porque, ó, o ponteiro ali é privado.
Esses ponteiros que tão aqui desalmados aqui, no sentido de tá públicos, tá.
Depois tem que privá-los também.
set e getAluno e getNome.
Ué, mas o ElAluno não tem nome.
Ah, mas veja só, ele vai do Aluno que ele cuida
recuperar o nome do Aluno que ele tá cuidando.
Então, aqui é uma maneira de eu recuperar
o nome do Aluno que o Elemento tá cuidando via o próprio Elemento.
Legal.
Na classe Disciplina, sublinhei lá, tá, insisto
não tem mais pAlunoPrim, o que tem agora é pElAlunoPrim
que é ponteiro ElAluno.
Também tem o pElAlunoAtual que é ponteiro de ElAluno.
Construtora, destrutora, aqueles códigos que a gente já conhecia aqui no meio
E aqui o que interessa pra nós pra composição da lista,
e agora uma lista mais decente
que vai atender um relacionamento n pra n.
Graças ao fato de eu usar ElAluno agora
que é um elemento aí, terceiro pra gerenciar os encadeamentos.
Agora vai funcionar aqui no âmbito dessas funções.
Pessoal, aqui tem um momento muito particular, tá.
Vocês tão vendo que eu tô incluindo o Aluno, não estou?
Com a função incluaAluno.
Mas vejam o que eu tô fazendo aqui dentro.
Tô criando uma variável temporária pAux, tá.
Nada impediria de eu aterrar aqui com nulo, tá.
Vamos salvar isso aqui.
Tá aterrado com nulo, muito embora eu já vá inicializar a variável logo em seguida.
Então, é até por isso que ela não tava aterrada. Novamente,
sempre é prudente aterrar o máximo possível.
E tá aí, gente, ó.
paux é um ponteiro auxiliar, ponteiro de Aluno.
Vejam o que eu tô fazendo aqui, ó. Aqui eu tô inicializando paux.
Eu estou criando um Elemento Aluno, um ElAluno,
que na leitura eu chamo de Elemento Aluno, né,
vocês tão vendo que tá escrito ElAluno, mas na leitura eu chamo de Elemento Aluno
pra ficar mais fácil meu discurso.
Então esse ElAluno, ou Elemento Aluno,
Ele é criado em tempo de execução.
Esse aqui, essa é a memória dinâmica própria do C++ o new, o novo.
É um ponteiro, aponta pra um novo Elemento Aluno que é criado em tempo de execução.
Isso aqui é o equivalente ao malloc, tá.
Memory allocation, do C++... aliás, da linguagem C, tá.
Memory allocation também funciona no C++,
mas é mais usual a gente usar o ponteiro new, mesmo porque ele é um pouco mais alto nível.
Lá no malloc você tem que ficar contando o tamanho do elemento alocado, através do size of etc, tá.
E aqui ele é mais enxuto mais limpo.
Legal.
Agora que eu criei um novo elemento, em tempo de execução,
que eu faço ele conhecer o Aluno que tá vindo por parâmetro
pra cuidar dele na lista.
Vou testar a contagem de Alunos, vou ver se o ponteiro que tá vindo não é nulo, aquela coisa toda.
Inclusive, eu até podia fazer essa criação aqui, ó,
dentro do if, aqui, esse primeiro if,
pra evitar uma alocação desnecessária caso não passasse no if, tá.
Provavelmente ficaria melhor, mas tudo bem.
E, aqui, eu faço os testes pra ver se o
pPrimeiro é nulo na Disciplina em questão.
Se for eu faço amarramentos de primeiro e atual, né,
porque esse cara enquanto primeiro e segundo na lista vai ser o primeiro e o atual.
Do contrário vai fazer as amarrações subsequentes
pProximo pAnterior e atualização do atual.
Contagem de Alunos.
Mensagem de erro no caso se o if não fosse ser aprovado.
Aqui, tem a listagem, tá, de percorrimento, tá, que vocês já conhecem
Veja que aqui no printf, ó: Aluno tal seria matriculado tanto...
Eu tô navegando via pElemento aqui, tá.
Via um paux que é ponteiro de Elemento Aluno,
e o Elemento ele pode ter um getNome(), aliás, ele tem um getNome() que chama justamente
o getNome do Aluno cuidado por esse Elemento, tá.
Por isso que isso aqui funciona.
Mas, enfim, isso aqui não é o nosso foco no momento, o nosso foco é
no InicializaDisciplinas.
Olhem que interessante, gente.
A gente tá nesse momento aqui, aonde, agora, a gente mudou de estratégia.
Nessa estratégia os Alunos não tem mais pProximo e anterior.
Vejam que inclusive aqui, ó, nesse mapa de memória aqui, ó,
no formato de Diagrama de Cubos ou de Objetos,
não tem mais, de fato, ponteiro nenhum.
Por quê? Porque esses objetos não tem mais ponteiros. Ele não colaboram sozinhos
na construção da lista, porque a gente viu que isso não funciona pra um relacionamento n pra n.
Então, vamos ver o que a gente tá fazendo aqui, que traquinagem a gente tá fazendo aqui.
Estou chamando o incluaAluno do Metodos2_2007,
e passando como parâmetro o endereço do triplo A.
O ponteiro Aluno como é uma variável temporária, né, parametral
aponta pra quem é indicado, o endereço do triplo A.
Agora, eu vou criar uma variável temporária paux. Tá ali.
Eu vou fazer paux apontar pra new Elemento Aluno. Tá ali, ó.
Muito bem.
Aí eu tenho aqui um...
Bom isso aqui é um momento muito importante, na verdade, dessa execução, tá.
Novamente, vamos voltar aqui um pouquinho se me permitirem.
Olha só o que aconteceu.
Eu criei a variável temporária paux
que é um ponteiro de Aluno que não aponta pra nenhum lugar nesse momento.
Se eu tivesse inicializado ela com nulo aqui, ela ia apontar ali pra nulo.
Agora ela aponta pra um lixo de memória, tá.
Uma posição da memória que a gente não tem noção do que seja nesse momento.
Ainda bem que logo em seguida eu crio dinamicamente,
em tempo de execução, eu vou criar um novo Elemento Aluno
Tanto é que acontece isso no slide ali, ó. Vejam bem.
O novo Elemento Aluno.
Como eu criei algo dinamicamente, ele cria o objeto, mas esse objeto não tem nome.
Os objetos estaticamente criado na unha,
olha lá, eles tem nome, triplo A, triplo B, triplo C.
Por quê? Porque eu criei lá dentro da Principal o objeto de antemão e pus o nome nele.
Quando é dinamicamente não tem nome.
Ele não tem nome, mas ele não é desalmado, ele tem endereço de memória.
Tanto é que esse endereço aqui, ó.
É apontado por paux. Tanto que tá ali, ó.
Agora eu posso fazer, colocar o quê?
Fazer o elemento que foi criado nesse momento apontado por paux
cuidar, apontar portanto, pro triplo A.
É o triplo A que tá sendo inserido nesse momento,
Ele está sendo apontado por ponteiro de Aluno.
Quando eu faço setAluno do cara apontado por paux
é esse cara aqui, portanto,
recebe o endereço de pa, ou seja, o endereço de triplo A.
Ah, então agora eu vou permitir que o Elemento aponte pro triplo A.
É isso aí que vai acontecer.
E tá ali, ó, gente. Tá vendo? Legal.
Daí eu vou testar o if ali, ó.
O contador de Alunos é menor que o numero de Alunos?
0 vai ser menor que 45.
O ponteiro a gente já sabe que não é nulo a gente tá... não é nulo, a gente tá vindo com o triplo A.
Legal.
Ele vai passar o primeiro if.
Ele vai passar no segundo? O pPrimeiro, que é o do Metodos2_2007 é nulo? É nulo.
Ah, tá. Aqui tá inicializando.
A gente vai, ali, fazer os amarramentos de pPrimeiro e pAtual
mas vejam que, obviamente,
agora, o pPrimeiro é o pElemento Aluno Primeiro e o pElemento Aluno Atual.
Vão se... vão apontar pra esse cara que foi criado em tempo de execução, ó,
paux ali, ó.
Se agora ele executou o if, ele não executa o else
Então, eu vou eliminar as variáveis temporárias que eu criei e terminar a execução.
Agora eu vou incluir o triplo B.
E aí, ele vai fazer o quê?
Vai criar o parâmetro, né, porque eu tô fazendo a chamada da função.
Apontar pra quem eu passei por parâmetro que é o endereço do triplo B.
Ponteiro de Aluno aponte pro endereço do triplo B.
Vou criar o paux. Tá criado.
Vou criar um novo Elemento Aluno em tempo de execução. Vou criar um novo objeto.
Alocar ele dinamicamente em tempo de execução. Tá ali, ó.
Voilà.
Inclusive, esse cara, aqui, apontado
ele é apelidado em tempo de... pelo menos, temporariamente pelo paux .
Através do paux eu tenho acesso à ele, pra fazer com que ele aponte
pro ponteiro de Aluno que é o triplo B.
Ele vai passar no primeiro if, mas não vai passar no segundo.
Porque o pPrimeiro não é mais nulo, ele já aponta pra esse cara que foi criado aqui anteriormente.
Legal.
Aí ele faz o quê, gente? Vai cair no else então.
No else ele vai fazer o quê?
que o pElemento Aluno Atual,
pElemento Aluno Atual é esse cara aqui,
o pProximo dele vai apontar o paux.
Quem que é paux? É aquele cara ali.
Ah, tá. Daí ele vai apontar pra esse cara aqui.
Professor, mas ele vai apontar pro paux
É, isso aqui significa que ele vai apontar
que o pElemento Atual, segunda linha aqui, tanto quanto o pElemento Primeiro, que tá aqui,
esses ponteiros aqui...
perdão, deixa eu retificar meu discurso um pouquinho.
Eu estou aonde gente? Estou no else.
Não é isso?
Sim, estamos na execução do else.
Então, vamos retomar aqui o discurso, tá.
Passei no primeiro if. O segundo if não executa,
porque o pAluno Elemento Primeiro não é mais nulo, ele aponta pra esse cara aqui.
E, agora sim, onde que eu estava, corretamente, tá.
É nesse momento aqui.
De fato, eu tava focado no pElemento Aluno Atual
que é esse companheiro aqui.
Ele aponta pra quem?
Aponta pra esse cara. Então, na verdade, eu tô falando desse objeto aqui.
Ah, legal.
O que significa eu dizer que o pProximo, do cara em questão,
vai receber o paux?
Significa dizer que o pProximo, ele vai apontar pro mesmo lugar que o paux.
Ou seja, vai apontar pra esse cara ali.
Então pProximo vai ser esse cara aqui, ó.
Tal qual vocês vão ver ali.
Agora eu vou fazer o pAux Anterior,
paux Anterior,
apontar pro mesmo lugar que o pAluno Atual
Fazer a amarração ali, ó.
E agora eu vou atualizar o pElemento Aluno Atual do corrente paux. Tá ali.
Vou terminar a execução da função eliminando variáveis temporárias.
Daí vocês podem fazer o resto, tá, incluindo os demais.
E vocês vão chegar na solução aonde vocês vão ter criado, pra cada elemento que é inserido na lista,
você cria Elemento Aluno.
Elemento Aluno.
E esse Elemento Aluno sempre vai tá amarrando o próximo e o anterior quando pertinente.
No primeiro caso, aqui, por exemplo, ele amarra só próximo, nunca anterior.
No caso do último elemento, ele vai amarrar só anterior e não pProximo, naturalmente.
Mas o fato é que, o que mudou aqui? Em resumo da ópera.
Agora não são mais os alunos que fazem pProximo e pAnterior.
Eu criei um elemento pra isso,
pra desacoplar.
O Aluno cuida de coisas de Aluno.
O Elemento Aluno, ou ElAluno, cuida do Aluno e os encadeamentos de lista encadeada.
E ficou aí bem interessante e bem feitinho.
Agora a gente pode fazer a inclusão dos demais
aliás, desses demais, ou, nesse caso, coincidentes Alunos no Computacao2_2007.
O que vai acontecer?
A hora que ele incluir o triplo A na lista dele, ele vai criar um Elemento Aluno
pra cuidar do triplo A naquela lista
que é distinto do Elemento Aluno que foi criado pra cuidar do triplo A na lista de Metodos2_2007.
Cada um no seu quadrado.
Esse elemento Aluno aqui em questão, que eu tô passando o mouse aqui,
ele cuida do triplo A nessa lista.
Já esse outro elemento Aluno aqui, cuida do triplo A naquela outra lista ali.
A hora que incluir o triplo C. Ó lá o triplo C.
Ele tem agora um Elemento pra cuidar dele nessa lista de Computacao2_2007
que é diferente do Elemento que cuida dele lá na outra lista.
Assim não dá confusão de pProximo e pAnterior.
Esses caras se amarram direitinho ali, nesse contexto dado,
e aqueles outros caras lá, todos se amarram
corretamente naquele contexto prévio ali que é de Metodos2_2007.
Então, isso aqui resolveu nosso impasse, é uma solução que agora atende
ao relacionamento de ordem n pra n.
Esta solução é apropriada, pois cada vez que um aluno é inserido em uma lista de Disciplina,
é também criado um elemento_aluno para tratá-lo naquela lista em específico.
Conforme eu já tava dizendo no meu discurso anterior.
Aqui, daí tem, naturalmente o mecanismo de
listagem de alunos, tá, e você pode simular pra ver se tá certo.
Pega aqui a execução, por exemplo, do Metodos2_2007.
O que que vai acontecer aqui? paux, ele vai criar um...
paux, então, vai ser uma variável temporária, né. Ponteiro elemento aluno.
Tá aqui. É o mouse a minha variável temporária.
Essa variável temporária vai apontar pra onde?
Na segunda linha ali, ó, ela diz que ela aponta pro elemento primeiro.
Ah, elemento aluno primeiro, então tá aqui.
O que ele faz ali?
pAux, que é o meu mouse, aqui, girando aqui, é nulo? Não, não é.
Ah, tá. Por quê? Porque é esse cara que eu tô apontando aqui.
O ponteiro do mouse é o ponteiro, inclusive.
O Aluno tal matriculado na Disciplina tal.
Então, tá.
O paux->getNome e nome.
o paux->getNome ele faz o quê?
Vocês já viram lá a definição na definição na classe.
Ele vai e chama o getNome do Aluno.
Então, ele imprime o getNome do Aluno. Volta.
Daí imprime o nome da própria Disciplina que é onde a coisa tá rodando.
Legal.
Eu tô com o ponteiro aqui. Daí eu faço ele fazer o quê? Ir pro próximo.
Dou loop.
paux é nulo? Não, não é. Ele tá aqui.
Ah, então, tá.
Ele vai imprimir o nome do triplo B o nome da Disciplina.
Vai dar próximo. Vai dar loop.
É nulo? Não, não é, e assim ele vai até finalizar a execução,
encontrando um pProximo finalmente nulo.