Trabalho prático de introdução à programação com C++ em ambiente Visual C++ Bolas para as parábolas! 1. Antes de começar com o Visual C++, prepare a sua área de trabalho. Na directoria My Documents (ou noutra com a mesma vocação) crie uma área com o seu número de aluno e o do seu parceiro. Depois, dentro dessa directoria crie outras quatro directorias: C++, Solutions, Texts e Library. Na directoria C++ você guardará todos os ficheiros com programas C++ que escrever ao longo do curso. A directoria Solutions; não será usada por si directamente, mas sim pelo Visual C++; que aí guardará as suas soluções (veremos o que é isto já a seguir). A directoria Texts servirá para você guardar outros documentos com textos relativos à cadeira, como, por exemplo, este guião. Na directoria Library você guardará cópias dos ficheiros das classes “oficiais” que serão fornecidas ao longo do curso. Respeite sempre rigorosamente esta organização. Se não o fizer, depois não se queixe. 2. Como o computador das aulas práticas não é só seu, no fim de cada sessão é preciso guardar o trabalho na sua área “permanente”. Para facilitar essa tarefa, crie na área permanente uma directoria P2; e lá dentro as mesmas quatro directorias C++, Texts, Solutions e Library. Desta primeira vez, estas directorias estão vazias, mas a ideia é que quando você for continuar trabalho já começado, começa por transferir os ficheiros da sua área permanente para o PC. Quando trabalhar em casa, use a mesma organização. Verá que lhe poupa muito trabalho. 3. As directorias estão prontas? Está tudo no seu lugar? Os nomes estão escritos como deve ser? Então avancemos. 4. O nosso primeiro exercício vai ser escrever um programa para trabalhar com parábolas, representadas por polinómios do segundo grau em x. Como isto é programação com classes, vamos ter uma classe Parabola com operações para achar os zeros, os extremos, o valor num dado ponto, a derivada num dado ponto, calcular o integral, desenhar o gráfico, etc. Já vamos ver como é que isso se faz. Antes; temos de criar uma solução e um projecto; no Visual C++ 5. Abra o Visual C++, biclicando no seu (seu, do Visual C++) ícone (um oito deitado colorido). Escolha File>New>Blank Solution, e crie uma solução de nome ParabolaSolution, tendo o cuidado de fazer com que esta solução seja cria da na directoria Solutions (atenção à caixa Location) que você próprio preparou no ponto 2 do guião. Depois de ter criado a solução (escreveu o nome exactamente conforme indicado?), vá por fora (por fora do Visual C++) ver como é que está a sua directoria Solutions. Existe lá dentro uma directoria ParabolaSolution? Se sim, tudo bem. Se não, você enganou-se: ou não criou a solução ou criou-a no sítio errado. Se acha que criou no sítio errado, procure-a, e apague. Depois repita. Espreite na directoria ParabolaSolution. Deve estar lá o ficheiro de nome ParabolaSolution e extensão .sln. Confere? (Repare bem: se as coisas não ficarem nos sítios certos, você até conseguirá trabalhar, mas depois vai perder o rasto ao que fez hoje; e da próxima vez vai ter de repetir tudo L.) 6. A seguir faça File>Add Project>New Project, no Project Type escolha a pasta Visual C++ Projects, nos Templates seleccione Win32 Project, dê ao projecto o nome ParabolaProject, e marque o botão OK. Na janela Win32 Application Wizard seleccione Application Settings, marque Console Application e Empty Project e faça Finish. 7. Verifique o conteúdo das suas directorias neste momento. Dentro da directoria ParabolaSolution há agora uma directoria ParabolaProject e um novo ficheiro ParabolaSolution.ncb. É essa a ideia: uma solução é um conjunto de projectos relacionados. Cada projecto corresponde a uma aplicação. Neste momento você tem uma solução e um projecto. No fim do curso terá uma dúzia de soluções, cada uma com vários 1 8. 9. 10. 11. 12. 13. 14. 15. 16. projectos. Ao aparecer um programa novo, você tem que decidir se é um mais um projecto numa solução velha ou o primeiro projecto de uma solução nova. Em cada momento você terá no Visual C++ uma solução aberta e dentro dela um projecto activo. Comecemos agora a escrever o programa. Faça File>Add New Item, marque Header File, escolha o nome Parabola, seleccione a sua directoria C++ como Location; e faça Open. Verifique por fora se existe um ficheiro Parabola.h na directoria C++. Se não existe, você fez alguma coisa mal. Neste caso, o melhor é localizar o ficheiro Parabola.h, que foi criado algures e apagá-lo, recomeçando o ponto anterior. Evite ter ficheiros com o mesmo nome em directorias diferentes. Em princípio, não faz mal, mas mais tarde ou mais cedo você vai baralhar-se e depois coisas estranhas podem acontecer. Observe o conteúdo da sua janela Solution Explorer. Repare nas pastas Source Files, Header Files, e Resource Files. Apague esta última, que não faz falta aqui. O nomes das outras são auto-explicativos. Abra as duas: na Header Files aparece o ficheiro Parabola.h. Note que estas pastas não têm nada a ver com as pastas do Windows: são apenas para você organizar o seu trabalho dentro do Visual C++. Por exemplo, se apagar um ficheiro de uma pasta destas, não está a apagá-lo mesmo da sua pasta do Windows. (Em breve haverá dezenas de ficheiros em cada projecto; e, tal como no Windows, é boa ideia arrumá-los nestas pastas fictícias.) Na janela do ficheiro Parabola.h, aberta no espaço de edição, escreva a declaração da classe Parabola. Terá três membros de dados, privados, a, b, c, de tipo double, representado os coeficientes de grau 2, 1, 0. Para já, inclua apenas um construtor por defeito, que criará a parábola de equação y = x2 , o construtor elementar, que dá valores aos três coeficie ntes, o destrutor (para marcar lugar, pois não tem nada que fazer) e as funções (públicas) Set (com três argumentos), para atribuir novos valores aos membros de dados, Value (com um argumento), que dá o valor da parábola num ponto, CountZeros, que diz quantos zeros tem a parábola (0, 1 ou 2), LeftZero, que dá o valor do zero da esquerda, e RightZero, que dá o valor do zero da direita. Faça isto com cuidado, guiandose pelo exemplo da classe Point da sebenta. Que funções são selectores, que funções são modificadores? Não se esqueça dos virtual e dos const. Não se esqueça dos tipos de retorno nas funções e do tipo void, quando a função não retorna nada. E veja bem que argumentos é que as funções têm, em cada caso. Por exemplo, a função CountZeros não tem argumentos. Ela será chamada para um objecto de tipo parábola, na forma ... p.CountZeros() ... assim calculando o número de zeros da parábola p. Já a função Value tem um argumento, como vimos, que representa o ponto x para o qual queremos conhecer valor da parábola. Respeite o espaçamento, para o seu programa ficar bonito. No fim guarde. Na janela Solution Explorer seleccione o projecto ParabolaProject (o único existente neste momento) e faça novamente File>Add New Item, marque C++ File, escolha o nome Parabola , seleccione a sua directoria C++ como Location; dê Open. Este ficheiro, com extensão .cpp, conterá as definições das funções da classe. Verifique se está na directoria C++; e verifique que foi adicionado ao projecto. Escreva no ficheiro Parabola.cpp a linha de include para o ficheiro Parabola.h, #include “parabola.h”, e mais nada. Guarde. Compile o ficheiro Parabola.cpp, (só tem uma linha, é mesmo assim), com Build>Compile, ou directamente com Ctrl+F7. Tem erros? Veja quais são com Ctr+Shift+F12, e corrija -os. Se tiver muitos erros não se assuste: provavelmente é uma coisinha de nada que dá aquela confusão toda. Se não tem erros, force um erro, apagando um ponto e vírgula ou um sinal de parêntesis, para ver como é. Observe bem as mensagens de erro, tente ir-se lembrando delas e do que elas realmente significam. Active a janela do ficheiro Parabola.h e dê Ctrt+F7. Não se pode compilar, pois não? O C++ só compila ficheiros de extensão .cpp. Os ficheiros .h são compilados “indirectamente”, quando o ficheiro .cpp que os inclui é compilado. Faça File>Add New Item, seleccione Text File; e crie um ficheiro de texto com nome Erros; na sua directoria Texts. Verifique que ficou no sítio certo. Copie para o ficheiro de erros a mensagem do primeiro erro; e acrescente a verdadeira causa do erro. Faça isso 2 sempre que o primeiro erro for novo. Vá guardando a sua colecção de erros. No fim, quem tiver uma colecção maior será nomeado “Campeão P2 dos Erros, ano 2002”. 17. Quando já não tiver erros nenhuns, para o ficheiro só com uma linha, defina os construtores e o destrutor. Inspire-se na classe Point, mas repare que no construtor por defeito não basta por tudo a zero: o construtor por defeito representa a parábola de equação y = x2 , em que o coeficiente de segundo grau é 1.0. Compile. Quando já não houver erros de compilação, passe ao passo seguinte. 18. Defina a função Value. Esta função dá o valor na parábola num ponto. Quantas multiplicações usou? Se usou mais do que duas, tente exprimir os cálculos usando apenas duas multiplicações. O C++ não tem uma função para elevar ao quadrado, como tinha o Pascal, mas mesmo que tivesse, elevar ao quadrado contaria como uma multiplicação. 19. Teste agora as funções que já definiu. Tal como anteriormente, crie um ficheiro C++ File chamando M_Parabola.cpp, na directoria C++, para conter a função main. Insira os includes necessários (<iostream> e “Parabola.h”), e escreva a função main assim: int main() { Parabola p(1, -4, 3); for (;;) { double x; double y; std::cout << "x = "; std::cin >> x; y = p.Value(x); std::cout << "y = " << y << std::endl; } return 0; } 20. Um truque: quando for preciso criar mais um ficheiro na mesma directoria que outro, abra o outro, guarde-o com Save As... dando o nome do ficheiro novo, apague tudo (depois de verificar que o nome do ficheiro na barra superior é mesmo o nome do ficheiro a criar). Adicione-o ao projecto movendo-o, na janela Explorer Solution, da pasta Miscellaneous Files para a pasta correspondente, Source Files ou Header Files e já está. Por vezes isto é mais prático do que o processo descrito nos pontos 8 e 12. 21. Compile. Agora, depois de os seus dois ficheiros cpp estarem compilados sem erros, é preciso lincar (lincar = aportuguesamento do verbo inglês “to link”), ou construir (“to build”) o projecto. Faça isso com Build>Build ParabolaProject ou directamente com Ctr+Shift+B. Tudo bem? 22. Não, não está tudo bem: deve haver vários erros de lincagem, porque ainda não programámos algumas das funções da classe Parabola. Para não gastar muito tempo nisso, usemos apenas “stubs”, isto é, pedaços de programa que não fazem nada mas que compilam sem erro: os modificadores ficam vazios, os selectores devolvem zero. Quando o programa compilar e lincar sem erros, avance. 23. Não havendo erros de lincagem, corra o programa, com Debug>Start Without Debugging ou directamente com Ctrl+F5. Saia quando se fartar, com Ctrl+C. 24. Modifique o ficheiro M_Parabola.cpp, criando uma função de teste TestValue que faz o que a anterior função main faz. Agora a função main limita-se a chamar a função TestValue. Recompile, linque de novo e corra. O seu programa tem a seguinte organização? #include <iostream> #include "parabola.h" 3 void TestValue(); int main() { TestValue(); return 0; } void TestValue() { // o mesmo que a função main anterior, menos o return 0; } 25. Programe agora a função Set. Compile. 26. Escreva uma segunda função de teste no ficheiro M_Parabola.cpp, análoga à anterior, mas que agora pede em cada passo do ciclo três novos coeficientes e o valor de x. Compile (Ctrl+F7), linque (Ctr+Shift+B), execute (Ctrl+F5). 27. Escreva agora as funções que tratam dos zeros: CountZeros, ZeroLeft e ZeroRight. Use uma função auxiliar, privada, Delta, que calcula o discriminante. Para ajudar, aqui tem a função CountZeros: int Parabola::CountZeros() const { return (Delta() >= 0) + (Delta() > 0); } 28. Esta função é engraçada e mostra que os booleanos são convertidos automaticamente para inteiros, quando é preciso. Repare que há aqui conversões implícitas: os booleanos não são inteiros. Também há; em C++; conversões implícitas ao contrário, de int para bool, mas são de mau gosto, geralmente. Em todo o caso, saiba que zero converte para false; e que todos os outros valores convertem para true. 29. Depois de ter tudo a compilar sem erros, regresse ao ficheiro M_Parábola.cpp e acrescente uma função TestZeros, do mesmo género das outras. Agora; em cada passo do ciclo, o programa pede três novos coeficientes; e mostra os zeros da parábola, se houver. 30. Nesta altura, o seu ficheiro M_Parabola.cpp deve ter o seguinte aspecto: #include <iostream> #include "parabola.h" void TestValue(); void TestSet(); void TestZeros(); int main() { // TestValue(); // TestSet(); TestZeros(); return 0; } void TestValue() { // ... } 4 void TestSet() { // ... } void TestZeros() { // ... } 31. Escreva agora os selectores para calcular o valor da derivada num ponto, Derivative, o integral (entre dois limites de integração), Integral, e o extremo, Extreme, e teste-os como de costume. O extremo é o mínimo ou o máximo da parábola, consoante a concavidade estiver virada para cima ou para baixo. 32. Programe agora uma função Plot, que escreva num ficheiro de texto os valores da parábola em n pontos equidistantes num intervalo. Em cada linha vem um valor de x e um valor de y. A declaração será assim: void Plot(std::ostream& output, double lowerBound, double upperBound, int countPoints) const; 33. Para poder usar o tipo std::ostream, é preciso incluir <iostream>. O ficheiro M_Parabola.cpp já o tem, mas o Parabola.cpp não. Ponha-o lá; ou compilador reclamará. 34. Teste a função como anteriormente. Eis, como exemplo, uma função de teste com tudo fixo (coeficientes, limites, número de pontos): void TestPlot0() { Parabola p(1, -4, 3); std::ofstream output("C:\\My Documents\\My C++\\Lab\\PlotParabola.txt"); p.Plot(output, 0, 5, 11); } 35. Para poder usar o tipo ofstream precisa incluir <fstream>. Basta incluir no ficheiro M_Parabola.cpp, claro. 36. (Extra) Importe o ficheiro resultante para o Excel e desenhe o gráfico da parábola. 37. (Extra) Programe agora modificadores ShiftUp, para deslocar a parábola para cima, ShiftRight, para deslocar para a direita, e Invert para inverter em relação ao vértice da parábola, e InvertX para inverter em relação ao eixo dos X. Teste como de costume. (Estas questões requerem um pouquinho mais de matemática, mas nada do outro mundo.) 38. Quando tiver que se ir embora, não se esqueça de guardar o seu trabalho na área permanente. Antes disso, vá à directoria ParabolaProject e apague a directoria Debug que lá aparece, à confiança. Essa directoria contém ficheiros temporários volumosos que não vale a pena guardar. 39. Divirta-se! 5