# Vetores e Matrizes

Façamos uma pequena revisão de conceitos:
* Vetores e matrizes são variáveis compostas homogêneas, ou seja, são agrupamentos de dados que individualmente ocupam o mesmo tamanho na memória e são referenciados pelo mesmo nome, geralmente são individualizadas usando-se índices.
* Vetores distinguem-se das matrizes apenas pela característica de ter dimensão (1 x n) ou (n x 1), essencialmente vetores são matrizes linha ou matrizes coluna.
Em linguagem "C" vetores e matrizes são usados abundantemente para compor estruturas de dados necessárias para composição de diversos recursos. Esta usa, mais explicitamente, vetores de caracteres para definir cadeias de texto, o que é conhecido como o mais trivial uso de vetores. Além deste recurso, o "C" também define meio de criação de matrizes tipo (n x m), provendo, desta forma os recursos necessários para criação destes conjuntos de dados.
A linguagem "C++" suporta os mesmos recursos e permite a criação de matrizes de objetos. Uma vez que um objeto é essencialmente um tipo de dado criado pelo programador, todas as características básicas legadas aos "tipos" em geral são observados nos tipos criados (classes de objetos).

## Vetores

Os vetores em C++ seguem a mesma notação da linguagem "C", via de regra declara-se o tipo seguido de um asterisco. Para acessar o valor apontado pela variável usa-se um asterisco de forma semelhante, como pode ser visto no trecho de código abaixo:

## Matrizes

Podemos imaginar que uma matriz é um conjunto de vetores que ocupam uma determinada área de memória referenciada por um nome comum. Matrizes de tipos primitivos são conseguidas através de associações do operador [ ], como por exemplo:
Definindo nossas classes de objetos poderemos declarar matrizes de objetos:
Ou seja, podemos adotar a mesma sintaxe para criar matrizes de objetos. Este procedimento pode ser usado com o cuidado de se avaliar antes a quantidade de memória disponível para que a matriz não ultrapasse esse limite físico, muitas vezes delimitada pelo hardware ou pelo sistema operacional. Lembremos que, um objeto precisa do espaço equivalente a soma de suas variáveis internas para ser alocado na memória.

## Declarando arranjo

Os arrays permitem fazer o seguinte:
Ou seja permite declarar muitas variáveis de uma forma bem simples, poupa escrita e é bastante compreensível.
* O número que está dentro de brackets é o size declarator. Ele é que vai permitir ao computador dizer quantas variáveis a serem geradas e logo quanta memória deverá ser reservada. A memória reservada para as variáveis vão ser todas seguidas, um int a seguir ao outro
* Há uma forma para não dizer o valor deste size declarator, mas isso apenas acontece antes da compilação, ou seja o compilador é que vai fazer esse preenchimento por nós, visualizando o nosso código e contanto os membros que colocámos. Isto é um automatismo dos compiladores recentes. chama-se a isto iniciação implícita que vamos ver nesta secção.
* As variáveis geradas pelos arrays vão ser todos do mesmo tipo.
* Reparem que o valor do size declarator é um número. É literal, ele não vai mudar quando o programa estiver a correr. Por isso quando não soubermos o número de elementos o que fazemos?
Veja uma tentativa:
Isto vai dar um erro de compilação, porque o array está a espera de uma constante e não uma variável. Há uma maneira de contornar isto que é através da memória dinâmica que vamos dar mais tarde, num capitulo próprio, pois isto vai envolver muitos conceitos.

## Constantes

Reparem que há uma diferença entre literais e constantes, apesar de em ambos os casos o valor não é alterado durante a execução do programa, a constant é um nome que representa o valor, o literal é o valor.

## Declarar constantes

É exatamente como declarar uma variável com duas diferenças:
* A declaração começa com a palavra const. Isto vai dizer ao compilador que é uma constante e não uma variável
* Teremos de atribuir logo o valor na declaração, ou seja, é fazer a iniciação
Exemplo:
Portanto se tentarmos colocar um outro valor ao numTest, isso vai dar um erro de compilação
Array index
Pergunta: Porque é que o índex começa em zero e não um? Ou seja temos as 100 posições que pedimos mas o índex começa no zero e não no 1. A razão disto tem a ver com offset – que refere ao valor adicionado para o endereço base para produzir a segunda address. Bem não entendi bem! Eu explico de novo: O endereço (address) do primeiro elemento do array, é o mesmo do que o endereço base do próprio array. ah espera aí, o que estão a dizer é que o endereço do array é igual ao do primeiro elemento do array. Assim o valor que teria de ser adicionado, ao endereço base do array, para conseguirmos o endereço do primeiro elemento seria zero. Agora sim, percebi!
Erro: Um erro comum é esquecer que o index começa no zero, e portanto quando se querem referir ao último elemento, esquecem-se que têm de subtrair uma unidade. O que advém desse esquecimento é que podem estar a alterar memória pertencente a uma variável, instrução,..de um outro programa. – Ou seja vai existir violação de dados.
Se o array for declarado globalmente em vez de ser localmente, então cada elemento é inicializado ao valor defaut que é zero.

## Iniciação

Iniciação, se bem se recordam é atribuir um valor a uma variável ao mesmo tempo que declaramos a variável. Podemos fazer a iniciação de um array de 2 maneiras:
1) explicit array sizing
Pergunta: O que é que acontece se dermos mais valores de atribuição do que elementos do array?
Isto vai dar um erro de compilação “too many initializers”
Pergunta: O que é que acontece se tivermos menos valores do que os elementos?
Não acontece nada simplesmente não temos valores para a[1] e a[2]. Porém em alguns compiladores os elementos não inicializados ficam com os valores defaut, que no caso dos ints é 0 no caso dos floats é 0.0 e nos caracteres é o caractere nulo ("\0"). No entanto se não inicializarmos um dos elementos, os restantes elementos terão de ser não inicializados pois caso contrário teremos um erro de compilação
2) implicit array sizing
Aqui o compilador faz o trabalho por nós, conta os elementos e preenche o número de elementos

## Caracter array

Ambas as inicializações são permitidas. Porém tomar atenção á ultima iniciação! Quando colocámos as aspas duplas o compilador acrescenta o "\0" na array que cria! Não tem!! Esta até costuma ser a preferida pelos programadores, é ao estilo de strings (Na verdade as strings são arrays de char mas vamos falar disso num capitulo próprio)
O char "\0" é o escape sequence para caracterer null. Este escape sequence sinaliza ao cout o fim do character array. É o último elemento do array preenchido!
Se não tivéssemos este carácter apareceriam estranhos caracteres a seguir ao "jeff", chamados "caracteres-lixo". (porquê?) Isto não significa que o último elemento deva ser sempre o null carácter

## Arrays de várias dimensões

Podemos ter duas dimensões
como também poderíamos ter infinitas

## Iniciando

Peguemos no exemplo:
Na memória teríamos as coisas assim. ou seja os elementos são seguidos e do mesmo tipo
| a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
| 1 | 2 | 3 | 4 | 5 | 6 |
Portanto ter int a [2][3] é equivalente a ter int a [6] o nome que se dá é que é diferente.
Pergunta: será pedido espaço par 6 ints ou antes um espaço com o tamanho de 6 ints? Como nós sabemos que os arrays os elementos têm endereços de memoria consecutivos, por isso, não podem ser pedidos 6 ints, pois se fosse esse o caso, poderia acontecer que eles não ficassem juntos.

## Const Constant arrays

Recordar que temos de inicializar quando queremos fazer uma constante array

## Atribuir valores ao array

Podemos atribuir o valor 1 a 1, mas para poupar escrita de programação é melhor utilizar as funções anteriormente revistas como o for
Ou melhor ainda podemos usar uma constante, para tornar o nosso código mais abstracto.
Lembram-se da história de termos o endereço do array igual ao endereço do 1º elemento do array?
Pois bem vemos que quando mandamos imprimir o array, ele dá um endereço. Pois o valor do nome do array é o endereço do array.

## Arrays como statements de funções

Pegando no programa
Vamos torná-lo mais modular, escrevendo uma função para atribuir valores ao array e outa função para mostrar os valores do array

## Arrays como argumentos de funções

Este exemplo por acaso está muito curioso
Pergunta: mas agora deveríamos perguntar se neste caso tínhamos uma passagem por valor ou referência.
Quando um array é passado para uma função, a função recebe não a cópia do array mas invés disso o endereço, address do primeiro elemento do array, que é igual ao valor do array (base).
Assim todas as modificações que se efectuarem na função que foi chamada irão repercutir-se no array passado.
Vamos confirmar: