Enunciado:
Escrever um programa que leia um número inteiro A e uma matriz M(2,3) de inteiros.
Contar quantos elementos iguais a A estão na matriz e criar um vetor V contendo todos os elementos de M diferentes de A.
Imprimir os resultados.
Variação
Para tornar o exercício mais interessante, implementamos a solução fazendo que o vetor V seja um "vetor de ponteiros", e não um "vetor de valores".
O código está comentado - abundantemente, prolixamente, espero que não excessivamente! :-)
Bom divertimento!
Screenshot:
Código-Fonte (use o "anexo" para fazer download, se achar mais prático...:
#include <cstdlib>
#include <iostream>
using namespace std;
// Escrever um programa que leia um número inteiro A e uma matriz M(2,3) de inteiros.
// Contar quantos elementos iguais a A estão na matriz
// e criar um vetor V contendo todos os elementos de M diferentes de A.
// Imprimir os resultados.
// Vamos fazer uma coisinha para tornar o exercício mais interessante:
// O vetor V vai conter ponteiros para os elementos de M
// Constantes para definir o tamanho da Matriz M
int const cstNroLinhas = 2;
int const cstNroColunas = 3;
int const cstNroElementosVetor = cstNroLinhas * cstNroColunas; // Note que chique: uma constante depende das outras duas!
// Variaveis 'Globais' - usadas por mais de uma rotina ao longo do programa
// (há outras variáveis que poderiam ser globais, mas optei por passá-las como parâmetros... afinal, isto é um exercício!)
int indLinha = 0;
int indColuna = 0;
int indVetor = 0;
// Leitura da Matriz M
// Recebe como parâmetro a própria matriz
void LerMatriz(int MatrizM[cstNroLinhas][cstNroColunas])
{
printf("\n");
for (indLinha=0; indLinha<cstNroLinhas; indLinha++)
for (indColuna=0; indColuna<cstNroColunas; indColuna++)
{
printf("Digite o elemento da linha %i, coluna %i da Matriz M: ", indLinha+1, indColuna+1);
scanf("%i",&MatrizM[indLinha][indColuna]);
}
printf("\n");
}
// Contar elementos na Matriz M iguais ao valor A
// Parâmetros:
// Matriz "M", aqui chamada "Matriz" - estou usando outro nome, só para salientar que o nome da variável não importa!
// Valor "A" - passado como "inteiro", portanto "por valor"
// ptrNroElementosIguaisA - ESTE PARÂMETRO É UM "PONTEIRO PARA INTEIRO" (int *) - é um "parâmetro passado 'por referência'"!
// O que eu passo é &NroElementosIguaisA - o ENDEREÇO de NroElementosIguaisA
// Dentro desta subrotina faço "*ptrNroElementosIguaisA = 0;" e depois "*ptrNroElementosIguaisA += 1", ou seja,
// primeiro zero o valor endereçado pelo ponteiro e depois incremento o valor endereçado pelo ponteiro
// - desta forma, estou alterando a variável "original", da rotina principal!
// Claro que eu poderia ter feito a subrotina retornar este valor, mas - você já sabe - isto é um exercício, vamos nos divertir!
void ContarElementosIguaisA(int Matriz[cstNroLinhas][cstNroColunas], int ValorA, int * ptrNroElementosIguaisA)
{
*ptrNroElementosIguaisA = 0; // Aqui inicializo o parâmetro passado "por referência"
for (indLinha=0; indLinha<cstNroLinhas; indLinha++)
for (indColuna=0; indColuna<cstNroColunas; indColuna++)
if (Matriz[indLinha][indColuna] == ValorA)
*ptrNroElementosIguaisA += 1; // Note que se usar *ptrNroElementosIguaisA ++ não funciona... :-(
}
// Preenchimento do Vetor V
// Os parâmetros são a "Matriz de Inteiros M" e o "inteiro A", e o "Vetor de Ponteiros para Inteiros V".
// Os dois primeiros parâmetros não tem nada de novo.
// Já no terceiro, estou usando um "Vetor de Ponteiros para Inteiros", em lugar de um "Vetor de Inteiros".
// Ou seja, não armazeno em V cópias dos valores dos elementos de A,
// e sim o endereço dos valores dos elementos de A!
// Qual a vantagem? Ora, isto é um exercício, vamos inventar, gente boa!
// Mas se eu estivesse trabalhando com valores "float", e não "int", por exemplo, eu estaria "economizando" memória...
//
// Ah, note também que a função retorna um inteiro - "return indVetor".
// Isto informa à função "chamadora" quantos elementos do vetor foram preenchidos.
int PreencherVetor(int M[cstNroLinhas][cstNroColunas], int A, int * V[cstNroElementosVetor])
{
indVetor = 0;
for (indLinha=0; indLinha<cstNroLinhas; indLinha++)
for (indColuna=0; indColuna<cstNroColunas; indColuna++)
if (M[indLinha][indColuna] != A)
{
// Note que faço V igual a &M, não a M.
// Estou armazenando o ENDEREÇO, não o conteúdo...
V[indVetor] = &M[indLinha][indColuna];
indVetor ++;
}
return indVetor;
}
int main(int argc, char *argv[])
{
// "Pego" o valor de A
int A;
printf("Digite o valor 'A': ");
scanf("%i", &A);
// Defino a Matriz M
int M[cstNroLinhas][cstNroColunas];
// Chamo a função que preenche a matriz a partir da digitação
LerMatriz(M);
// Chamo a função que conta os elementos da matriz que são iguais a A
int NroElementosIguaisA; // Note que não estou inicializando a variável, a função "Contar..." já faz isto!
ContarElementosIguaisA(M, A, &NroElementosIguaisA); // E note que estou passando &NroElementosIguais - passo o ENDEREÇO!
// Defino o vetor V e chamo a função que o preenche
int * V[cstNroElementosVetor]; // Note que charmoso: V é um vetor de "ponteiros para inteiros", não um "vetor de inteiros"...
int NroElementosPreenchidosVetor = PreencherVetor(M, A, V);
// Imprimo os resultados
printf("Quantidade de Elementos na Matriz iguais a A: %i\n\n",NroElementosIguaisA);
printf("Vetor de Elementos na Matriz diferentes de A: \n");
for (indVetor=0; indVetor<NroElementosPreenchidosVetor; indVetor++)
// Veja: imprimo "*V[indVetor]", não "V[indVetor]
// pois preciso "buscar" o conteúdo endereçado pelo ponteiro para imprimir...
printf("V [%i]: %i\n", indVetor, *V[indVetor]);
system("PAUSE");
return EXIT_SUCCESS;
}