Em C++, podemos criar uma função na qual podemos otimir o argumento, mesmo tendo um argumento de entrada.
Crie no código-fonte, uma função com entrada em string, assim:
void imp(string txt) {
cout << "\n" << txt << "\n";
}
E chame a função no método principal, da mesma forma:
#include <iostream>
using namespace std;
void imp(string txt);
int main() {
imp("Teste");
return 0;
}
void imp(string txt) {
cout << txt << "\n";
}
Até o momento, nada de novidade. Mas se tirar o argumento, vai dar erro. Para resolver isso, basta colocar na indicação um valor default (apenas na indicação, não na função em si, exceto quando ela vir antes do main), assim:
void imp(string txt = "");
PS: O valor pode ser qualquer um, desde que seja do mesmo tipo da variável.
Se passarmos outro argumento, ele será exibido normalmente.
A recursividade é quando uma função chama a si mesma, para entendermos, crie um programa com uma função normalmente, dessa forma:
#include <iostream>
using namespace std;
void contador(int num);
int main() {
contador(10);
return 0;
}
void contador(int num) {
for(int i = 1; i <= num; i++) {
cout << i << "\n";
}
}
Como no caso, a função vai chamar ela mesmo, não vamos usar laço for, no caso. Vamos alterar para ela receber dois parâmetros também. Esse é o código da função:
void contador(int num, int cont) {
cout << cont << "\n";
if(num > cont) {
contador(num, ++cont);
}
}
PS: Não esqueça de alterar a indicação também, o cont pode até ser inicializado:
void contador(int num, int cont = 1);
Como exercício, propomos a criação de fatoriais e fibonacci em C++.
Fatorial em C++:
#include <iostream>
using namespace std;
int fatorial(int n);
int main() {
int val, res;
cout << "Insira o número do fatorial: ";
cin >> val;
res = fatorial(val);
cout << endl << "Fatorial de " << val << ": " << res << endl << endl;
for(int f = val; f >= 1; f--) {
if(f > 1) {
cout << f << " x ";
}
else {
cout << f << " = ";
}
}
cout << res << endl;
return 0;
}
int fatorial(int n) {
if(n == 0) {
return 1;
}
return n * fatorial(n - 1); // Função chamando ela mesma (recursividade).
}
E a de fibonacci:
#include <iostream>
using namespace std;
int fibonacci(int n);
int main() {
int val, res;
cout << "Insira o número de valores desejados no fibonacci: ";
cin >> val;
cout << endl << "Fibonacci com " << val << " valores: ";
for(int i = 0; i < val; i++) {
cout << fibonacci(i + 1) << "... ";
}
cout << endl;
return 0;
}
int fibonacci(int n) {
if(n == 1 || n == 2) {
return 1;
}
else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
Enum é um conjunto de constantes inteiras que definem os valores que elas podem ter. Apesar de inserirmos identificadores com nomes, elas só armazenam números inteiros.
Veja um exemplo que pode ser usada para jogos, com uma munição de arma:
#include <iostream>
using namespace std;
enum Armas {fuzil, revolver, rifle, escopeta};
int main() {
Armas armaSel; // Essa é uma variável do tipo definido pelo enum.
int num;
armaSel = fuzil;
cout << armaSel; // Imprime o valor definido no enum.
return 0;
}
Por padrão, cada valor do enum adiciona um valor inteiro para cada item, contado a partir do zero (tal como os arrays).
Mas no caso de nós colocarmos um valor (por exemplo, 100 em fuzil), ele vai contar a partir do número pré-definido (101, 102, etc.):
enum Armas {fuzil = 100, revolver, rifle, escopeta};
Podemos também correr os dados de um enum num vetor, assim:
for(int i = fuzil; i <= escopeta; i++) {
cout << i << endl;
}
As pilhas em C++ são como um vetor, só que ele tem controles específicos, imagine ela como um tubo de um lado aberto e outro fechado onde inserimos "bolinhas", onde o primeiro elemento a ser inserido é o último a ser trabalhado e o último é o primeiro. Vamos supor os elementos 0, 1 e 2, colocados nessa ordem, o primeiro a ser retirado é o 2, depois o 1 e por último o 0.
Alguns dos exemplos em que uma pilha pode ser usada é em mecanismos de desfazer/refazer de editores, navegação entre páginas web, etc.
Para trabalharmos com pilhas, precisamos importar a biblioteca stack
.
Veja um exemplo básico de criação de pilhas, no caso, pilhas de strings:
#include <iostream>
#include <stack> // Importe para trabalharmos com pilhas
using namespace std;
int main() {
stack<string> cartas;
return 0;
}
PS: As pilhas tem tamanhos dinâmicos, que se alteram ao adicionar ou remover, por isso não precisa ser informado.
Para adicionar elementos na pilha, usamos o método push (vindo de POO), e para exibir a quantidade elementos, o método size, dessa forma:
#include <iostream>
#include <stack> // Importe para trabalharmos com pilhas
using namespace std;
int main() {
stack<string> cartas;
cartas.push("Rei de Copas"); // Isso é uma chamada de objeto, que adiciona elementos.
cartas.push("Rei de Espadas");
cartas.push("Rei de Ouros");
cartas.push("Rei de Paus");
cout << "Tamanho da pilha: " << cartas.size() << endl; // Isso exibe o tamanho da pilha
return 0;
}
No caso, o último elemento a ser adicionado foi o Rei de Paus, e o primeiro, é o Rei de Copas.
Para retirar o último elemento de uma pilha, usamos o método pop, dessa forma:
#include <iostream>
#include <stack> // Importe para trabalharmos com pilhas
using namespace std;
int main() {
stack<string> cartas;
cartas.push("Rei de Copas"); // Isso é uma chamada de objeto, que adiciona elementos.
cartas.push("Rei de Espadas");
cartas.push("Rei de Ouros");
cartas.push("Rei de Paus");
cout << "Tamanho da pilha: " << cartas.size() << endl; // Isso exibe os dados da pilha
cout << "Última carta da pilha: " << cartas.top() << endl; // Isso mostra o último elemento da pilha.
cartas.pop();
cout << "Tamanho da pilha: " << cartas.size() << endl;
cout << "Última carta da pilha: " << cartas.top() << endl
return 0;
}
Como visto acima, o método top mostra o elemento do topo da pilha (o último adicionado).
Para trabalharmos com pilhas, também temos o método empty, que verifica se a pilha está vazia, caso esteja, ele retorna true, senão retorna false.
Veja um exemplo abaixo:
#include <iostream>
#include <stack> // Importe para trabalharmos com pilhas
using namespace std;
int main() {
stack<string> cartas;
if(cartas.empty()) {
cout << "Pilha vazia!" << endl;
}
else {
cout << "Pilha com cartas!" << endl;
}
cartas.push("Rei de Copas"); // Isso é uma chamada de objeto, que adiciona elementos.
cartas.push("Rei de Espadas");
cartas.push("Rei de Ouros");
cartas.push("Rei de Paus");
if(cartas.empty()) {
cout << "Pilha vazia!" << endl;
}
else {
cout << "Pilha com cartas!" << endl;
}
cout << "Tamanho da pilha: " << cartas.size() << endl; // Isso exibe os dados da pilha
cout << "Última carta da pilha: " << cartas.top() << endl; // Isso mostra o último elemento da pilha.
cartas.pop();
cout << "Tamanho da pilha: " << cartas.size() << endl;
cout << "Última carta da pilha: " << cartas.top() << endl;
return 0;
}
No código acima, no primeiro condicional com empty, ele retorna vazio, já que a pilha não teve conteúdos adicionados, já no segundo, retorna que tem cartas.
Em vez do empty, podemos usar o size também, dessa forma:
if(cartas.size() == 0) {
cout << "Pilha vazia!" << endl;
}
else {
cout << "Pilha com cartas!" << endl;
}
Dessa forma, podemos usar um while para excluir todos os elementos da pilha, assim:
while(!cartas.empty()) {
cartas.pop();
}
Código completo abaixo:
#include <iostream>
#include <stack> // Importe para trabalharmos com pilhas
using namespace std;
int main() {
stack<string> cartas;
if(cartas.size() == 0) {
cout << "Pilha vazia!" << endl;
}
else {
cout << "Pilha com cartas!" << endl;
}
cartas.push("Rei de Copas"); // Isso é uma chamada de objeto, que adiciona elementos.
cartas.push("Rei de Espadas");
cartas.push("Rei de Ouros");
cartas.push("Rei de Paus");
while(!cartas.empty()) {
cartas.pop();
}
if(cartas.empty()) {
cout << "Pilha vazia!" << endl;
}
else {
cout << "Pilha com cartas!" << endl;
}
return 0;
}
Esses são os métodos básicos das pilhas:
Método | Funcionalidade |
---|---|
push() | Adiciona um elemento à pilha |
pop() | Remove um elemento da pilha |
size() | Exibe o tamanho da pilha |
top() | Exibe o último elemento da pilha |
empty() | Verifica se a pilha está vazia |