diff --git a/README.md b/README.md index 8d0219e..9c929d4 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,27 @@ # c2learn Examples and exercises in C and C++. We currently have only the Portuguese version in the "pt" directory. +The last stable tested and stable version: + +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/santanche/c2learn/v1.0.0?urlpath=lab) + +The last available version: + [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/santanche/c2learn/master?urlpath=lab) # (Portuguese) c2learn Exemplos e exercícios em C e C++. -Os exercícios são preparados para serem executados no ambiente Jupyter sob o Binder. Para ativar o ambiente online clique em: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/santanche/c2learn/master?urlpath=lab) +Os exercícios são preparados para serem executados no ambiente Jupyter sob o Binder. Para ativar o ambiente online clique em: + +* Última versão testada e estável: + +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/santanche/c2learn/v1.0.0?urlpath=lab) + +* Última versão disponível: + +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/santanche/c2learn/master?urlpath=lab) Para entender o que é o Jupyter e o Binder assista o vídeo do Matheus Mota: diff --git a/notebook/pt/c51oo/s01emprestimo/s01exercicios/emprestimo01.ipynb b/notebook/pt/c51oo/s01emprestimo/s01exercicios/emprestimo01.ipynb index ffe609e..2b065cb 100644 --- a/notebook/pt/c51oo/s01emprestimo/s01exercicios/emprestimo01.ipynb +++ b/notebook/pt/c51oo/s01emprestimo/s01exercicios/emprestimo01.ipynb @@ -1,172 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Memória, Variáveis, Comunicação e Estado de um Programa\n", - "\n", - "Há várias possíveis estratégias para usar a memória de um computador para se realizar a comunicação entre partes dele -- por exemplo, entre duas funções -- e para se manter o **estado atual** de execução de um programa. Dentre elas, podemos destacar o uso de variáveis locais, globais e parâmetros entre funções.\n", - "\n", - "Vamos fazer aqui um exercício nesse contexto e você será conduzido a experimentar cada uma dessas estratégias, mesmo que em algumas ocasiões não seja a forma recomendada de se desenvolver um programa.\n", - "\n", - "\n", - "# Exercício do Empréstimo\n", - "\n", - "Em um financiamento com juros compostos e número de parcelas fixas parte-se dos seguintes parâmetros:\n", - "* `S` - valor da primeira parcela\n", - "* `N` - número de parcelas\n", - "* `J` - percentual de juros mensal\n", - "\n", - "A primeira parcela a ser paga do financiamento é sempre igual a `S`. A partir daí é feita uma atualização mensal da parcela, em que cada nova parcela é calculada a partir da parcela do mês anterior, conforme a fórmula:\n", - "\n", - "> #### Parcelamês = Parcelamês-1 * (1 + `J` / 100)\n", - "\n", - "O financiamento encerra quando as `N` parcelas são pagas.\n", - "\n", - "Exemplo:\n", - "* `S`: 200\n", - "* `N`: 5\n", - "* `J`: 1%\n", - "\n", - "Parcelas do financiamento:\n", - "`200`; `202`; `204.02`; `206.06`; `208.12`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercício Parte 1 - Escrevendo um Módulo\n", - "\n", - "Dado o problema descrito, escreva um programa que calcule as parcelas de um empréstimo para os seguintes valores:\n", - "* `S`: 200\n", - "* `N`: 5\n", - "* `J`: 1%" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercício Parte 2 - Escrevendo um Módulo (Função)\n", - "\n", - "Reescreva o código acima de forma que seu programa faça uso de uma função `proximaParcela` que seja responsável pelo cálculo de uma única parcela X do empréstimo. Utilize as boas práticas de modularização que você aprendeu, evitando dependências do módulo com o programa principal. A função deve apenas calcular uma única parcela, portanto, ficará a cargo da função principal que chama `proximaParcela` realizar o restante do processo, para que sejam apresentadas todas as parcelas do financiamento." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercício Parte 3 - Mantendo o Estado\n", - "\n", - "Modifique a função (módulo) `proximaParcela` acima de modo que ela tenha uma memória da situação em que estão as coisas, sem que o `main` precise ficar informando novamente coisas que já informou no início. Para isso serão permitidas as seguintes modificações:\n", - "\n", - "1. você pode desmembrar a função em mais de uma, por exemplo, uma você chama no começo do empréstimo e outra a cada parcela;\n", - "\n", - "2. você pode usar técnicas de uso de variáveis não recomendadas que geram dependência dos módulos com o programa principal.\n", - "\n", - "Você deve organizar o código de tal maneira que o `main` informe para as funções os dados do financiamento apenas uma única vez e depois possa solicitar o cálculo da parcela subsequente sem informar tudo novamente." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercício Parte 4 - Minimizando os Parâmetros\n", - "\n", - "Retomando a solução da `Parte 2`, em que a função `main` deve ter usado vários parâmetros para a comunicação com a função `proximaParcela`, modifique a forma como você representa o empréstimo, de forma que a função `proximaParcela` receba sempre um único parâmetro capaz de representar o estado completo do empréstimo." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercício Parte 5 - Múltiplos Empréstimos\n", - "\n", - "Considere que há múltiplos empréstimos que podem ser controlados em paralelo. A sua função `main` deve ser capaz de apresentar no console as parcelas de mais de um empréstimo de modo paralelo, mantendo um controle para cada empréstimo separadamente. Você deve decidir qual das soluções tomará como ponto de partida, se deve modificar a função `main`, a função `proximaParcela` ou ambas para atender esse requisito da melhor forma possível.\n", - "\n", - "Adote uma solução compacta e generalizável, de tal modo que, cada novo empréstimo só exija a informação dos parâmetros de partida, sem expansão do código.\n", - "\n", - "Por exemplo, suponha os seguintes dois empréstimos em paralelo:\n", - "\n", - "### Empréstimo 1\n", - "* `S`: 200\n", - "* `N`: 5\n", - "* `J`: 1%\n", - "\n", - "### Empréstimo 2\n", - "* `S`: 500\n", - "* `N`: 7\n", - "* `J`: 2%\n", - "\n", - "A saída esperada é:\n", - "~~~\n", - "Emprestimo 1: parcela 1 eh 200.00\n", - "Emprestimo 2: parcela 1 eh 500.00\n", - "Emprestimo 1: parcela 2 eh 202.00\n", - "Emprestimo 2: parcela 2 eh 510.00\n", - "Emprestimo 1: parcela 3 eh 204.02\n", - "Emprestimo 2: parcela 3 eh 520.20\n", - "Emprestimo 1: parcela 4 eh 206.06\n", - "Emprestimo 2: parcela 4 eh 530.60\n", - "Emprestimo 1: parcela 5 eh 208.12\n", - "Emprestimo 2: parcela 5 eh 541.22\n", - "Emprestimo 2: parcela 6 eh 552.04\n", - "Emprestimo 2: parcela 7 eh 563.08\n", - "~~~\n", - "\n", - "O exemplo mostra dois empréstimos, mas a estrutura deve ser genérica o suficiente para controlar N empréstimos em paralelo." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} +{"metadata":{"kernelspec":{"display_name":"C","language":"c","name":"c"},"language_info":{"file_extension":".c","mimetype":"text/plain","name":"c"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Memória, Variáveis, Comunicação e Estado de um Programa\n\nHá várias possíveis estratégias para usar a memória de um computador para se realizar a comunicação entre partes dele -- por exemplo, entre duas funções -- e para se manter o **estado atual** de execução de um programa. Dentre elas, podemos destacar o uso de variáveis locais, globais e parâmetros entre funções.\n\nVamos fazer aqui um exercício nesse contexto e você será conduzido a experimentar cada uma dessas estratégias, mesmo que em algumas ocasiões não seja a forma recomendada de se desenvolver um programa.\n\n\n# Exercício do Empréstimo\n\nEm um financiamento com juros compostos e número de parcelas fixas parte-se dos seguintes parâmetros:\n* `S` - valor da primeira parcela\n* `N` - número de parcelas\n* `J` - percentual de juros mensal\n\nA primeira parcela a ser paga do financiamento é sempre igual a `S`. A partir daí é feita uma atualização mensal da parcela, em que cada nova parcela é calculada a partir da parcela do mês anterior, conforme a fórmula:\n\n> Parcelamês = Parcelamês-1 * (1 + `J` / 100)\n\nO financiamento encerra quando as `N` parcelas são pagas.\n\nExemplo:\n* `S`: 200\n* `N`: 5\n* `J`: 1%\n\nParcelas do financiamento:\n`200`; `202`; `204.02`; `206.06`; `208.12`","metadata":{}},{"cell_type":"markdown","source":"## Exercício Parte 1 - Escrevendo um Programa\n\nDado o problema descrito, escreva um programa que calcule as parcelas de um empréstimo para os seguintes valores:\n* `S`: 200\n* `N`: 5\n* `J`: 1%","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exercício Parte 2 - Escrevendo um Módulo (Função)\n\nReescreva o código acima de forma que seu programa faça uso de uma função `proximaParcela` que seja responsável pelo cálculo de uma única parcela X do empréstimo. Utilize as boas práticas de modularização que você aprendeu, evitando dependências do módulo com o programa principal. A função deve apenas calcular uma única parcela, portanto, ficará a cargo da função principal que chama `proximaParcela` realizar o restante do processo, para que sejam apresentadas todas as parcelas do financiamento.","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exercício Parte 3 - Mantendo o Estado\n\nModifique a função (módulo) `proximaParcela` acima de modo que ela tenha uma memória da situação em que estão as coisas, sem que o `main` precise ficar informando novamente coisas que já informou no início. Para isso serão permitidas as seguintes modificações:\n\n1. você pode desmembrar a função em mais de uma, por exemplo, uma você chama no começo do empréstimo e outra a cada parcela;\n\n2. você pode usar técnicas de uso de variáveis não recomendadas que geram dependência dos módulos com o programa principal.\n\nVocê deve organizar o código de tal maneira que o `main` informe para as funções os dados do financiamento apenas uma única vez e depois possa solicitar o cálculo da parcela subsequente sem informar tudo novamente.","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exercício Parte 4 - Minimizando os Parâmetros\n\nRetomando a solução da `Parte 2`, em que a função `main` deve ter usado vários parâmetros para a comunicação com a função `proximaParcela`, modifique a forma como você representa o empréstimo, de forma que a função `proximaParcela` receba sempre um único parâmetro capaz de representar o estado completo do empréstimo.","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exercício Parte 5 - Múltiplos Empréstimos\n\nConsidere que há múltiplos empréstimos que podem ser controlados em paralelo. A sua função `main` deve ser capaz de apresentar no console as parcelas de mais de um empréstimo de modo paralelo, mantendo um controle para cada empréstimo separadamente. Você deve decidir qual das soluções tomará como ponto de partida, se deve modificar a função `main`, a função `proximaParcela` ou ambas para atender esse requisito da melhor forma possível.\n\nAdote uma solução compacta e generalizável, de tal modo que, cada novo empréstimo só exija a informação dos parâmetros de partida, sem expansão do código.\n\nPor exemplo, suponha os seguintes dois empréstimos em paralelo:\n\n### Empréstimo 1\n* `S`: 200\n* `N`: 5\n* `J`: 1%\n\n### Empréstimo 2\n* `S`: 500\n* `N`: 7\n* `J`: 2%\n\nA saída esperada é:\n~~~\nEmprestimo 1: parcela 1 eh 200.00\nEmprestimo 2: parcela 1 eh 500.00\nEmprestimo 1: parcela 2 eh 202.00\nEmprestimo 2: parcela 2 eh 510.00\nEmprestimo 1: parcela 3 eh 204.02\nEmprestimo 2: parcela 3 eh 520.20\nEmprestimo 1: parcela 4 eh 206.06\nEmprestimo 2: parcela 4 eh 530.60\nEmprestimo 1: parcela 5 eh 208.12\nEmprestimo 2: parcela 5 eh 541.22\nEmprestimo 2: parcela 6 eh 552.04\nEmprestimo 2: parcela 7 eh 563.08\n~~~\n\nO exemplo mostra dois empréstimos, mas a estrutura deve ser genérica o suficiente para controlar N empréstimos em paralelo.","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]} \ No newline at end of file diff --git a/notebook/pt/c51oo/s01emprestimo/s02resolucao/emprestimo01-resolucao.ipynb b/notebook/pt/c51oo/s01emprestimo/s02resolucao/emprestimo01-resolucao.ipynb index 430bf79..a778642 100644 --- a/notebook/pt/c51oo/s01emprestimo/s02resolucao/emprestimo01-resolucao.ipynb +++ b/notebook/pt/c51oo/s01emprestimo/s02resolucao/emprestimo01-resolucao.ipynb @@ -1,410 +1 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Exercício do Empréstimo (resolução)\n", - "\n", - "![Enunciado](poo01-orientacao-objetos-exercicio-financiamento.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Versão sem modularização" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "O valor da parcela 1 eh 200.00\n", - "O valor da parcela 2 eh 202.00\n", - "O valor da parcela 3 eh 204.02\n", - "O valor da parcela 4 eh 206.06\n", - "O valor da parcela 5 eh 208.12\n" - ] - } - ], - "source": [ - "#include \n", - "\n", - "int main() {\n", - " float s = 200;\n", - " int n = 5;\n", - " float j = 1;\n", - " \n", - " float p = s;\n", - " for (int i = 1; i <= n; i++) {\n", - " printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n", - " p = p + (p * (j/100));\n", - " } \n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Escrevendo um Módulo (parte 2)\n", - "\n", - "Resolução da parte 2 (invertida propositalmente para manter uma linha de raciocícinio).\n", - "\n", - "Dado um empréstimo X, escreva um módulo que ao ser chamado retorne a próxima parcela a ser paga. Use o mínimo de parâmetros possíveis:\n", - "* evite informar recorrentemente dados sobre as características do empréstimo;\n", - "* evite usar informações de controle (e.g., parcela corrente) como parâmetro." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "O valor da parcela 1 eh 200.00\n", - "O valor da parcela 2 eh 202.00\n", - "O valor da parcela 3 eh 204.02\n", - "O valor da parcela 4 eh 206.06\n", - "O valor da parcela 5 eh 208.12\n" - ] - } - ], - "source": [ - "#include \n", - "\n", - "float es;\n", - "int en;\n", - "float ej;\n", - "int corrente;\n", - "float p;\n", - "\n", - "void novoEmprestimo(float s, int n, float j) {\n", - " es = s;\n", - " en = n;\n", - " ej = j;\n", - " corrente = 1;\n", - " p = s;\n", - "}\n", - "\n", - "float proximaParcela() {\n", - " float retorno = p;\n", - " corrente++;\n", - " if (corrente <= en)\n", - " p = p + (p * (ej/100));\n", - " else\n", - " p = 0;\n", - " return retorno;\n", - "}\n", - "\n", - "int main() {\n", - " novoEmprestimo(200, 5, 1);\n", - " \n", - " int i = 1;\n", - " float p = proximaParcela();\n", - " while (p > 0) {\n", - " printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n", - " p = proximaParcela();\n", - " i++;\n", - " } \n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Removendo variáveis globais (parte 1)\n", - "\n", - "Resolução da parte 1." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "O valor da parcela 1 eh 200.00\n", - "O valor da parcela 2 eh 202.00\n", - "O valor da parcela 3 eh 204.02\n", - "O valor da parcela 4 eh 206.06\n", - "O valor da parcela 5 eh 208.12\n" - ] - } - ], - "source": [ - "#include \n", - "\n", - "void novoEmprestimo(float s, int n, float j, int *corrente, float *p) {\n", - " *corrente = 1;\n", - " *p = s;\n", - "}\n", - "\n", - "void proximaParcela(float s, int n, float j, int *corrente, float *p) {\n", - " (*corrente)++;\n", - " if (*corrente <= n)\n", - " *p = *p + (*p * (j/100));\n", - " else\n", - " *p = 0;\n", - "}\n", - "\n", - "int main() {\n", - " int corrente;\n", - " float p;\n", - " \n", - " novoEmprestimo(200, 5, 1, &corrente, &p);\n", - " \n", - " int i = 1;\n", - " while (p > 0) {\n", - " printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n", - " proximaParcela(200, 5, 1, &corrente, &p);\n", - " i++;\n", - " } \n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Variáveis estáticas para a manutenção do estado (parte 2)\n", - "\n", - "Retomando aspectos da parte 2 de redução de parâmetros." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "O valor da parcela 1 eh 200.00\n", - "O valor da parcela 2 eh 202.00\n", - "O valor da parcela 3 eh 204.02\n", - "O valor da parcela 4 eh 206.06\n", - "O valor da parcela 5 eh 208.12\n" - ] - } - ], - "source": [ - "#include \n", - "\n", - "float proximaParcela(float s, int n, float j) {\n", - " static int corrente = 1;\n", - " static float p;\n", - " if (corrente == 1)\n", - " p = s;\n", - " else if (corrente <= n)\n", - " p = p + (p * (j/100));\n", - " else\n", - " p = 0;\n", - " corrente++;\n", - " return p;\n", - "}\n", - "\n", - "int main() {\n", - " int corrente;\n", - " \n", - " float p = proximaParcela(200, 5, 1);\n", - " \n", - " int i = 1;\n", - " while (p > 0) {\n", - " printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n", - " p = proximaParcela(200, 5, 1);\n", - " i++;\n", - " } \n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Agrupando variáveis de estado em uma estrutura (parte 3)\n", - "\n", - "Preparação para a parte 3." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "O valor da parcela 1 eh 200.00\n", - "O valor da parcela 2 eh 202.00\n", - "O valor da parcela 3 eh 204.02\n", - "O valor da parcela 4 eh 206.06\n", - "O valor da parcela 5 eh 208.12\n" - ] - } - ], - "source": [ - "#include \n", - "\n", - "typedef struct {\n", - " float s;\n", - " int n;\n", - " float j;\n", - " int corrente;\n", - " float p;\n", - "} Emprestimo;\n", - "\n", - "void novoEmprestimo(Emprestimo *umEmprestimo) {\n", - " umEmprestimo->corrente = 1;\n", - " umEmprestimo->p = umEmprestimo->s;\n", - "}\n", - "\n", - "float proximaParcela(Emprestimo *umEmprestimo) {\n", - " float retorno = umEmprestimo->p;\n", - " if (umEmprestimo->corrente < umEmprestimo->n)\n", - " umEmprestimo->p = umEmprestimo->p + (umEmprestimo->p * (umEmprestimo->j/100));\n", - " else\n", - " umEmprestimo->p = 0;\n", - " (umEmprestimo->corrente)++;\n", - " return retorno;\n", - "}\n", - "\n", - "int main() {\n", - " Emprestimo umEmprestimo;\n", - " \n", - " umEmprestimo.s = 200;\n", - " umEmprestimo.n = 5;\n", - " umEmprestimo.j = 1;\n", - " \n", - " novoEmprestimo(&umEmprestimo);\n", - " \n", - " int i = 1;\n", - " float p = proximaParcela(&umEmprestimo);\n", - " while (p > 0) {\n", - " printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n", - " i++;\n", - " p = proximaParcela(&umEmprestimo);\n", - " } \n", - "}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Múltiplos Empréstimos (parte 4)\n", - "\n", - "Considere que há múltiplos empréstimos que podem ser controlados em paralelo. O seu módulo deve sempre ser capaz de informar a pŕoxima parcela de qualquer um dele, mantendo um controle para cada empréstimos separadamente.\n", - "\n", - "Para esta resolução, a função `novoEmprestimo` passou a montar a estrutura de dados." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Emprestimo 1: parcela 1 eh 200.00\n", - "Emprestimo 2: parcela 1 eh 500.00\n", - "Emprestimo 1: parcela 2 eh 202.00\n", - "Emprestimo 2: parcela 2 eh 510.00\n", - "Emprestimo 1: parcela 3 eh 204.02\n", - "Emprestimo 2: parcela 3 eh 520.20\n", - "Emprestimo 1: parcela 4 eh 206.06\n", - "Emprestimo 2: parcela 4 eh 530.60\n", - "Emprestimo 1: parcela 5 eh 208.12\n", - "Emprestimo 2: parcela 5 eh 541.22\n", - "Emprestimo 2: parcela 6 eh 552.04\n", - "Emprestimo 2: parcela 7 eh 563.08\n" - ] - } - ], - "source": [ - "#include \n", - "\n", - "typedef struct {\n", - " float s;\n", - " int n;\n", - " float j;\n", - " int corrente;\n", - " float p;\n", - "} Emprestimo;\n", - "\n", - "Emprestimo novoEmprestimo(float s, int n, float j) {\n", - " Emprestimo umEmprestimo;\n", - " umEmprestimo.s = s;\n", - " umEmprestimo.n = n;\n", - " umEmprestimo.j = j;\n", - " umEmprestimo.corrente = 1;\n", - " umEmprestimo.p = s;\n", - " return umEmprestimo;\n", - "}\n", - "\n", - "float proximaParcela(Emprestimo *umEmprestimo) {\n", - " float retorno = umEmprestimo->p;\n", - " if (umEmprestimo->corrente < umEmprestimo->n)\n", - " umEmprestimo->p = umEmprestimo->p + (umEmprestimo->p * (umEmprestimo->j/100));\n", - " else\n", - " umEmprestimo->p = 0;\n", - " (umEmprestimo->corrente)++;\n", - " return retorno;\n", - "}\n", - "\n", - "int main() {\n", - " Emprestimo emprestimo1,\n", - " emprestimo2;\n", - " \n", - " emprestimo1 = novoEmprestimo(200, 5, 1);\n", - " emprestimo2 = novoEmprestimo(500, 7, 2);\n", - " \n", - " float p1 = proximaParcela(&emprestimo1),\n", - " p2 = proximaParcela(&emprestimo2);\n", - " \n", - " int i = 1;\n", - " while (p1 > 0 || p2 > 0) {\n", - " if (p1 > 0)\n", - " printf(\"Emprestimo 1: parcela %d eh %3.2f\\n\", i, p1);\n", - " if (p2 > 0)\n", - " printf(\"Emprestimo 2: parcela %d eh %3.2f\\n\", i, p2);\n", - " p1 = proximaParcela(&emprestimo1);\n", - " p2 = proximaParcela(&emprestimo2);\n", - " i++;\n", - " } \n", - "}" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "C", - "language": "c", - "name": "c" - }, - "language_info": { - "file_extension": ".c", - "mimetype": "text/plain", - "name": "c" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} +{"metadata":{"kernelspec":{"display_name":"C","language":"c","name":"c"},"language_info":{"file_extension":".c","mimetype":"text/plain","name":"c"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Memória, Variáveis, Comunicação e Estado de um Programa\n\nHá várias possíveis estratégias para usar a memória de um computador para se realizar a comunicação entre partes dele -- por exemplo, entre duas funções -- e para se manter o **estado atual** de execução de um programa. Dentre elas, podemos destacar o uso de variáveis locais, globais e parâmetros entre funções.\n\nVamos fazer aqui um exercício nesse contexto e você será conduzido a experimentar cada uma dessas estratégias, mesmo que em algumas ocasiões não seja a forma recomendada de se desenvolver um programa.\n\n\n# Exercício do Empréstimo\n\nEm um financiamento com juros compostos e número de parcelas fixas parte-se dos seguintes parâmetros:\n* `S` - valor da primeira parcela\n* `N` - número de parcelas\n* `J` - percentual de juros mensal\n\nA primeira parcela a ser paga do financiamento é sempre igual a `S`. A partir daí é feita uma atualização mensal da parcela, em que cada nova parcela é calculada a partir da parcela do mês anterior, conforme a fórmula:\n\n> Parcelamês = Parcelamês-1 * (1 + `J` / 100)\n\nO financiamento encerra quando as `N` parcelas são pagas.\n\nExemplo:\n* `S`: 200\n* `N`: 5\n* `J`: 1%\n\nParcelas do financiamento:\n`200`; `202`; `204.02`; `206.06`; `208.12`","metadata":{}},{"cell_type":"markdown","source":"## Exercício Parte 1 - Escrevendo um Módulo\n\nDado o problema descrito, escreva um programa que calcule as parcelas de um empréstimo para os seguintes valores:\n* `S`: 200\n* `N`: 5\n* `J`: 1%","metadata":{}},{"cell_type":"code","source":"#include \n\nint main() {\n float s = 200;\n int n = 5;\n float j = 1;\n \n float p = s;\n for (int i = 1; i <= n; i++) {\n printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n p = p + (p * (j/100));\n } \n}","metadata":{"trusted":true},"execution_count":15,"outputs":[{"name":"stdout","text":"O valor da parcela 1 eh 200.00\nO valor da parcela 2 eh 202.00\nO valor da parcela 3 eh 204.02\nO valor da parcela 4 eh 206.06\nO valor da parcela 5 eh 208.12\n","output_type":"stream"}]},{"cell_type":"markdown","source":"## Exercício Parte 2 - Escrevendo um Módulo (Função)\n\nReescreva o código acima de forma que seu programa faça uso de uma função `proximaParcela` que seja responsável pelo cálculo de uma única parcela X do empréstimo. Utilize as boas práticas de modularização que você aprendeu, evitando dependências do módulo com o programa principal. A função deve apenas calcular uma única parcela, portanto, ficará a cargo da função principal que chama `proximaParcela` realizar o restante do processo, para que sejam apresentadas todas as parcelas do financiamento.","metadata":{}},{"cell_type":"code","source":"#include \n\nfloat proximaParcela(float s, int n, float j, int *corrente, float *p) {\n if (*corrente == 0) // primeira parcela\n *p = s;\n else if (*corrente <= n)\n *p = *p + (*p * (j/100));\n else\n *p = 0; // não há mais parcelas\n (*corrente)++;\n return *p;\n}\n\nint main() {\n float s = 200;\n int n = 5;\n float j = 1;\n int corrente = 0; // controla parcela corrente\n float p = s; // controla valor da parcela corrente\n\n for (int i = 1; i <= n; i++) {\n p = proximaParcela(s, n, j, &corrente, &p);\n printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n } \n}","metadata":{"trusted":true},"execution_count":9,"outputs":[{"name":"stdout","text":"O valor da parcela 1 eh 200.00\nO valor da parcela 2 eh 202.00\nO valor da parcela 3 eh 204.02\nO valor da parcela 4 eh 206.06\nO valor da parcela 5 eh 208.12\n","output_type":"stream"}]},{"cell_type":"markdown","source":"## Exercício Parte 3 - Mantendo o Estado\n\nModifique a função (módulo) `proximaParcela` acima de modo que ela tenha uma memória da situação em que estão as coisas, sem que o `main` precise ficar informando novamente coisas que já informou no início. Para isso serão permitidas as seguintes modificações:\n\n1. você pode desmembrar a função em mais de uma, por exemplo, uma você chama no começo do empréstimo e outra a cada parcela;\n\n2. você pode usar técnicas de uso de variáveis não recomendadas que geram dependência dos módulos com o programa principal.\n\nVocê deve organizar o código de tal maneira que o `main` informe para as funções os dados do financiamento apenas uma única vez e depois possa solicitar o cálculo da parcela subsequente sem informar tudo novamente.","metadata":{}},{"cell_type":"code","source":"#include \n\nfloat es;\nint en;\nfloat ej;\nint corrente;\nfloat p;\n\nvoid novoEmprestimo(float s, int n, float j) {\n es = s;\n en = n;\n ej = j;\n corrente = 1;\n p = s;\n}\n\nfloat proximaParcela() {\n float retorno = p;\n corrente++;\n if (corrente <= en)\n p = p + (p * (ej/100));\n else\n p = 0;\n return retorno;\n}\n\nint main() {\n novoEmprestimo(200, 5, 1);\n \n int i = 1;\n float p = proximaParcela();\n while (p > 0) {\n printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n p = proximaParcela();\n i++;\n } \n}","metadata":{"trusted":true},"execution_count":10,"outputs":[{"name":"stdout","text":"O valor da parcela 1 eh 200.00\nO valor da parcela 2 eh 202.00\nO valor da parcela 3 eh 204.02\nO valor da parcela 4 eh 206.06\nO valor da parcela 5 eh 208.12\n","output_type":"stream"}]},{"cell_type":"markdown","source":"### Removendo variáveis globais (parte 1)\n\nResolução da parte 1.","metadata":{}},{"cell_type":"code","source":"#include \n\nvoid novoEmprestimo(float s, int n, float j, int *corrente, float *p) {\n *corrente = 1;\n *p = s;\n}\n\nvoid proximaParcela(float s, int n, float j, int *corrente, float *p) {\n (*corrente)++;\n if (*corrente <= n)\n *p = *p + (*p * (j/100));\n else\n *p = 0;\n}\n\nint main() {\n int corrente;\n float p;\n \n novoEmprestimo(200, 5, 1, &corrente, &p);\n \n int i = 1;\n while (p > 0) {\n printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n proximaParcela(200, 5, 1, &corrente, &p);\n i++;\n } \n}","metadata":{"trusted":true},"execution_count":11,"outputs":[{"name":"stdout","text":"O valor da parcela 1 eh 200.00\nO valor da parcela 2 eh 202.00\nO valor da parcela 3 eh 204.02\nO valor da parcela 4 eh 206.06\nO valor da parcela 5 eh 208.12\n","output_type":"stream"}]},{"cell_type":"markdown","source":"### Variáveis estáticas para a manutenção do estado (parte 2)\n\nRetomando aspectos da parte 2 de redução de parâmetros.","metadata":{}},{"cell_type":"code","source":"#include \n\nfloat proximaParcela(float s, int n, float j) {\n static int corrente = 1;\n static float p;\n if (corrente == 1)\n p = s;\n else if (corrente <= n)\n p = p + (p * (j/100));\n else\n p = 0;\n corrente++;\n return p;\n}\n\nint main() {\n int corrente;\n \n float p = proximaParcela(200, 5, 1);\n \n int i = 1;\n while (p > 0) {\n printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n p = proximaParcela(200, 5, 1);\n i++;\n } \n}","metadata":{"trusted":true},"execution_count":12,"outputs":[{"name":"stdout","text":"O valor da parcela 1 eh 200.00\nO valor da parcela 2 eh 202.00\nO valor da parcela 3 eh 204.02\nO valor da parcela 4 eh 206.06\nO valor da parcela 5 eh 208.12\n","output_type":"stream"}]},{"cell_type":"markdown","source":"## Exercício Parte 4 - Minimizando os Parâmetros\n\nRetomando a solução da `Parte 2`, em que a função `main` deve ter usado vários parâmetros para a comunicação com a função `proximaParcela`, modifique a forma como você representa o empréstimo, de forma que a função `proximaParcela` receba sempre um único parâmetro capaz de representar o estado completo do empréstimo.\n\n### Agrupando variáveis de estado em uma estrutura","metadata":{}},{"cell_type":"code","source":"#include \n\ntypedef struct {\n float s;\n int n;\n float j;\n int corrente;\n float p;\n} Emprestimo;\n\nvoid novoEmprestimo(Emprestimo *umEmprestimo) {\n umEmprestimo->corrente = 1;\n umEmprestimo->p = umEmprestimo->s;\n}\n\nfloat proximaParcela(Emprestimo *umEmprestimo) {\n float retorno = umEmprestimo->p;\n if (umEmprestimo->corrente < umEmprestimo->n)\n umEmprestimo->p = umEmprestimo->p + (umEmprestimo->p * (umEmprestimo->j/100));\n else\n umEmprestimo->p = 0;\n (umEmprestimo->corrente)++;\n return retorno;\n}\n\nint main() {\n Emprestimo umEmprestimo;\n \n umEmprestimo.s = 200;\n umEmprestimo.n = 5;\n umEmprestimo.j = 1;\n \n novoEmprestimo(&umEmprestimo);\n \n int i = 1;\n float p = proximaParcela(&umEmprestimo);\n while (p > 0) {\n printf(\"O valor da parcela %d eh %3.2f\\n\", i, p);\n i++;\n p = proximaParcela(&umEmprestimo);\n } \n}","metadata":{"trusted":true},"execution_count":13,"outputs":[{"name":"stdout","text":"O valor da parcela 1 eh 200.00\nO valor da parcela 2 eh 202.00\nO valor da parcela 3 eh 204.02\nO valor da parcela 4 eh 206.06\nO valor da parcela 5 eh 208.12\n","output_type":"stream"}]},{"cell_type":"markdown","source":"## Exercício Parte 5 - Múltiplos Empréstimos\n\nConsidere que há múltiplos empréstimos que podem ser controlados em paralelo. A sua função `main` deve ser capaz de apresentar no console as parcelas de mais de um empréstimo de modo paralelo, mantendo um controle para cada empréstimo separadamente. Você deve decidir qual das soluções tomará como ponto de partida, se deve modificar a função `main`, a função `proximaParcela` ou ambas para atender esse requisito da melhor forma possível.\n\nAdote uma solução compacta e generalizável, de tal modo que, cada novo empréstimo só exija a informação dos parâmetros de partida, sem expansão do código.\n\nPor exemplo, suponha os seguintes dois empréstimos em paralelo:\n\n### Empréstimo 1\n* `S`: 200\n* `N`: 5\n* `J`: 1%\n\n### Empréstimo 2\n* `S`: 500\n* `N`: 7\n* `J`: 2%\n\nA saída esperada é:\n~~~\nEmprestimo 1: parcela 1 eh 200.00\nEmprestimo 2: parcela 1 eh 500.00\nEmprestimo 1: parcela 2 eh 202.00\nEmprestimo 2: parcela 2 eh 510.00\nEmprestimo 1: parcela 3 eh 204.02\nEmprestimo 2: parcela 3 eh 520.20\nEmprestimo 1: parcela 4 eh 206.06\nEmprestimo 2: parcela 4 eh 530.60\nEmprestimo 1: parcela 5 eh 208.12\nEmprestimo 2: parcela 5 eh 541.22\nEmprestimo 2: parcela 6 eh 552.04\nEmprestimo 2: parcela 7 eh 563.08\n~~~\n\nO exemplo mostra dois empréstimos, mas a estrutura deve ser genérica o suficiente para controlar N empréstimos em paralelo.","metadata":{}},{"cell_type":"code","source":"#include \n\ntypedef struct {\n float s;\n int n;\n float j;\n int corrente;\n float p;\n} Emprestimo;\n\nEmprestimo novoEmprestimo(float s, int n, float j) {\n Emprestimo umEmprestimo;\n umEmprestimo.s = s;\n umEmprestimo.n = n;\n umEmprestimo.j = j;\n umEmprestimo.corrente = 1;\n umEmprestimo.p = s;\n return umEmprestimo;\n}\n\nfloat proximaParcela(Emprestimo *umEmprestimo) {\n float retorno = umEmprestimo->p;\n if (umEmprestimo->corrente < umEmprestimo->n)\n umEmprestimo->p = umEmprestimo->p + (umEmprestimo->p * (umEmprestimo->j/100));\n else\n umEmprestimo->p = 0;\n (umEmprestimo->corrente)++;\n return retorno;\n}\n\nint main() {\n Emprestimo emprestimo1,\n emprestimo2;\n \n emprestimo1 = novoEmprestimo(200, 5, 1);\n emprestimo2 = novoEmprestimo(500, 7, 2);\n \n float p1 = proximaParcela(&emprestimo1),\n p2 = proximaParcela(&emprestimo2);\n \n int i = 1;\n while (p1 > 0 || p2 > 0) {\n if (p1 > 0)\n printf(\"Emprestimo 1: parcela %d eh %3.2f\\n\", i, p1);\n if (p2 > 0)\n printf(\"Emprestimo 2: parcela %d eh %3.2f\\n\", i, p2);\n p1 = proximaParcela(&emprestimo1);\n p2 = proximaParcela(&emprestimo2);\n i++;\n } \n}","metadata":{"trusted":true},"execution_count":14,"outputs":[{"name":"stdout","text":"Emprestimo 1: parcela 1 eh 200.00\nEmprestimo 2: parcela 1 eh 500.00\nEmprestimo 1: parcela 2 eh 202.00\nEmprestimo 2: parcela 2 eh 510.00\nEmprestimo 1: parcela 3 eh 204.02\nEmprestimo 2: parcela 3 eh 520.20\nEmprestimo 1: parcela 4 eh 206.06\nEmprestimo 2: parcela 4 eh 530.60\nEmprestimo 1: parcela 5 eh 208.12\nEmprestimo 2: parcela 5 eh 541.22\nEmprestimo 2: parcela 6 eh 552.04\nEmprestimo 2: parcela 7 eh 563.08\n","output_type":"stream"}]}]} \ No newline at end of file