Desenvolvimento - C#

Uso de Array no C# - parte 1

Gostaria de compartilhar com vocês o uso de Array no C#: Como declarar, onde ficam, qual o melhor método a ser usado e quais são os métodos e funções existentes para seu tratamento e o mais importante o que não fazer com os arrays.

por Claudenir Andrade



Na linguagem C, além de ponteiros, seu principal potencial é a capacidade de tratamento que a linguagem possibilita quando necessário uso de Arrays sejam eles de caracteres ou de inteiros. Independente disso, os Arrays (ou a Array como você desejar) sempre será útil em sua codificação mesmo com a existência dos poderosos tipos de dados como o String. Talvez você pode se perguntar, mas porque necessitarei de um array de caracteres, por exemplo, quando tenho o tipo String (ou cString no VC++) que já efetua todo tratamento de alocação de memória, valores nulos, etc.? Bem, existe vários argumentos e diferentes necessidades, que poderíamos chegar no "Bit" da questão e provar que o uso de Array é muito mais rápido e econômico que os tipos strings pré definidos nas linguagens de alto nível. Prometo em um próximo artigo estar mostrando isso, mas hoje, gostaria de compartilhar com vocês o uso de Array no C#. Como declarar, onde ficam, qual o melhor método a ser usado e quais são os métodos e funções existentes para seu tratamento e o mais importante o que não fazer com os arrays.

Antes de entrar na questão, vale aqui a explicação rápida de dois tipos de memória onde nossas variáveis, sejam elas array ou não, são alocadas quando utilizadas ou declaradas - o Stack e o Heap. A diferença entre eles está basicamente na maneira em como eles tratam, por assim dizer, as variáveis. Uma vez declarado uma variável local ou chamado funções com parâmetros - que por sua vez são locais sejam eles passados por valor ou referência - estes valores ficam armazenados em uma área de Memória chamada STACK, quando acontece a saída de uma função, seja pelo próprio return ou não, esta área é automaticamente limpa. Já o HEAP é o encarregado de ter os valores de objetos em sua área de armazenamento, ou seja, quando você declara um objeto, instancia uma classe, usa a palavra reservada new estes objetos - através de seus contrutores - ficam alocados no HEAP, porém se as funções que o utilizam são finalizadas ou acontece um exception o mesmo não é retirado do HEAP automaticamente - aqui entra o nosso valoroso "Coletor de Lixo" que faz isso por nós, caso não seja acionado de forma automática ou manual o destrutor deste objeto.

Para entendermos bem este conceito, vamos imaginar que estamos trabalhando com uma função que calcula o imposto devido por um produto:

fImposto(120);
void  fImposto( int iVr_Produto)
{
//Neste Momento é colocado no STACK o vr 120
objCalcula iValor_Imposto
//Neste Momento é colocado 0 Valor 120 no Heap e 
//declarado o iValor_Imposto no Stack
iValor_Imposto = new objCalcula(iVr_Produto)
}

A melhor definição para um array seria a seguinte: Uma Seqüência de elementos. Elementos de um mesmo tipo, sendo assim, array é um conjunto de Inteiros ou caracteres ou booleans...por isso afirmamos que um array é uma referência para um conjunto de valores de um tipo e não um tipo de dado.

Diferenças do C# para o C

Aqui começamos a entrar mais a fundo no elemento array, onde uma das grandes diferenças, e ao mesmo tempo facilidade é a forma de declaração, no C a declaração de um Array é dado pelo "Abre e Fecha" de colchetes após o nome da variável, exemplo char Nome[10]; já no c#.net a declaração é muito parecida mas o tipo ao qual o array faz referencia deve se antecedido pelos colchetes juntamente com o tipo, por exemplo char[] nome;

A definição do tamanho de um array pode ser definido em tempo de execução ou de compilação, por exemplo, no código abaixo temos os seguintes elementos:

  • Um controle TextBox chamado bt_texto
  • Um controle Botão chamado button1
  • Um listbox chamado ListArray

Nossa tela terá a seguinte aparência após a execução e a inserção do código abaixo no evento Click de nosso botão:

Layout da tela
private void button1_Click_1(object sender, System.EventArgs e)
 {
  char[ ] aMyArray;
  int Count;

 aMyArray = bt_Texto.Text.ToCharArray(0,bt_Texto.Text.Length);

 ListArray.Items.Add("Tamanho de aMyArray = " + aMyArray.Length.ToString());

for (Count=0;Count!=aMyArray.Length;Count++)
ListArray.Items.Add("Indice[" + (Count.ToString()) + "]= " +  aMyArray[Count]);
}

Observe então que a inicialização aconteceu em tempo de execução pois você não indicou em principio a quantidade de elementos que seu array teria. Porém você poderá fazê-lo, por segurança dentro de seu próprio código, limitando assim a quantidade de itens que seu array terá, basta declarar seu array da seguinte maneira char[] aMyArray = new char[100]; //100 elementos de um caracter. Uma forma abreviada da declaração anterior seria:

char[] aMyArray = "Teste de Array".ToCharArray();

Com isso, observe que o tratamento dado a um array nao é o mesmo dado a um string

string nome = "teste"; //Isso não dá erro de compilação e é válido
char[] aMyArray = "Teste de Array" //Isso dá erro de compilação sendo obrigatório o uso do 
//ToCharArray() que distribui em cada índice do array cada caracter do 
//texto em que está sendo inicializado nossa variável aMyArray.

Embora estamos tratando basicamente de tipos char o mesmo se dá com array de inteiros, que podem ser declarados de duas formas, sempre lembrando que independente disso nossas arrays sempre começam pelo índice 0(zero):

int[ ] numeros = new int[3]; OU int[ ] numeros = {1,2,3};

Uma observação interessante do trecho de código acima é que utilizamos as funções ToString() e ToCharArray(); que efetuam uma conversão para texto, porém de duas formas diferentes, uma para um Tipo string esperado pela função MessageBox e outra de um Texto tipo string para um conjunto de caracteres. Observe também que utilizamos um FOR( ; ;) para varrer nossa string até que o índice da mesma seja o seu final, ou seja, até que o contador que esta sendo incrementado a cada pasagem do FOR seja != de tamanho de nossa string, porém se em alguma parte de nosso código nos descuidamos e erramos o contador e sem aviso ultrapassamos o numero de índices que nossa array possui, teremos um erro não muito interessante de IndexOutOfRangeexception. Para ao ter que quebrar muito a cabeça e controlar seu contador a cada vez que for varrer um array você pode utilizar a interação ForEach, da seguinte maneira:

Substitua no código anterior a instrução:

for (Count=0;Count!=aMyArray.Length;Count++)
ListArray.Items.Add("Indice[" + (Count.ToString()) + "]= " +  aMyArray[Count]);

foreach( char x in  aMyArray)
	ListArray.Items.Add(ToString + "["+ x +"]");

Você também estará varrendo a string e imprimindo seu valor índice por índice, sem ter que controlar diretamente o final, deixando isso a cargo do ForEach.

Mas se desejamos buscar uma letra dentro de nossa string, talvez para saber se uma data que foi inputad,a por exemplo, já foi digitada com barras ou não, para isso vale um passeio pelas classes e seus métodos fornecidos pelo .NET Framework, digite "System.Array." e verá os métodos fornecidos pela classe array para trabalharmos com tipos de dados como string e referencia de tipos Array. Insira o seguinte trecho de código que irá buscar uma letra na string digitada em nosso textbox e mostrar o resultado.

Intelisense para a classe Array
if( (Count = System.Array.BinarySearch(aMyArray,0,aMyArray.Length,"c"))<0)

  MessageBox.Show("Caracter Não Encontrado!!");
else
  MessageBox.Show("Caracter Encontrado na posicao aMyArray[" + Count.ToString() + "]");

Bem, assim começamos aqui um longo passeio pelos métodos oferecidos pelo .net para trabalharmos com strings e arrays, buscas, espaços, copias, etc.. Tudo isso pode ser facilmente controlados pelos métodos oferecidos pela Classe Array e pelos métodos incluídos nos tipos de dados, como o ToString() que vimos nos exemplos anteriores.

Uma outra forma interessante de inicializarmos uma array, é trabalhando com métodos ou funções dentro de sua inicialização, isso é perfeitamente possível no .net. No código abaixo estamos buscando de forma randômica, letras que irão compor, por exemplo, uma senha de quatro letras e as mesmas estão sendo designadas em tempo de declaração do array.

//Metodo Inicializando em tempo de Execucao
private void button3_Click(object sender, System.EventArgs e)
{
 Random rLetra = new Random();
 string Alfabeto = "ABCDEFGHIJKLMNOPQRSTUVXZ";
 int iPosicao;
 char[] aSenha = new char[4];

 iPosicao = rLetra.Next(0,23);aSenha[4]=Alfabeto[iPosicao];
 iPosicao = rLetra.Next(0,23);aSenha[4]=Alfabeto[iPosicao];
 iPosicao = rLetra.Next(0,23);aSenha[4]=Alfabeto[iPosicao];
 iPosicao = rLetra.Next(0,23);aSenha[4]=Alfabeto[iPosicao];

 MessageBox.Show("A Senha Gerada Foi:" + aSenha.ToString());

}

//Metodo Inicializando em Tempo de declaracao e criacao da Variavel
private void button3_Click(object sender, System.EventArgs e)
{
  Random rLetra = new Random();
  string Alfabeto = "ABCDEFGHIJKLMNOPQRSTUVXZ";
 
  char[] aSenha={ 
Alfabeto[ (rLetra.Next(0,23))], 
Alfabeto[ (rLetra.Next(0,23))], 
Alfabeto[ (rLetra.Next(0,23))], 
Alfabeto[ (rLetra.Next(0,23))]
};

  MessageBox.Show("A Senha Gerada Foi:" + aSenha.ToString());
}

OK, além de economizar uma variável, economizamos algumas linhas de código. Ficamos por aqui, no próximo artigo veremos mais sobre a Classe System.Array e Collection Classes.!!

Claudenir Andrade

Claudenir Andrade - Formado pela Academia de Sistemas Informáticos de Madrid, trabalha com automação comercial há nove anos, foi responsável pela Homologação e aprovação de ECFs brasileiros em países como Equador e Venezuela, gerencia a equipe de desenvolvimento da Daruma Automação. Autor do primeiro livro de automação comercial no Brasil - "Automação Comercial com VB.Net e C#", é também MVP da Microsoft e está criando e definindo o Modelo XML para Automação Comercial, escreve artigos também para o site MSDN e pode ser contatado pelo e-mail - claudenir@daruma.com.br