sexta-feira, 15 de janeiro de 2016

Como descobrir o tamanho de um vetor - Linguagem C

Sabemos que para descobrirmos o tamanho de um vetor de char ou String, basta usar o strlen da biblioteca <string.h>. Veja o exemplo:

#include <stdio.h>
#include <string.h>

int main(){
 char palavra[10];
 strcpy(palavra, "ColaboraTI");
 int tamanho;
 tamanho = strlen(palavra);
 printf("Tamanho do vetor de string: %d", tamanho);
 getchar();
}


Tamanho do vetor de string: 10

Através do comando strcpy que também é da biblioteca <string.h> é possível copiar a String para o nosso vetor palavra. E o comando strlen fica responsável por descobrir o tamanho utilizado da string palavra.

Para descobrir o tamanho de um vetor do tipo inteiro declarado em uma mesma função, por exemplo, você precisa usar o comando sizeof da biblioteca <stdio.h> através do algoritmo:

#include <stdio.h>

int main()
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };
    printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
}


Entendendo este código... Temos um array com 7 posições { 0, 1, 2, 3, 4, 5, 6 }. Cada posição equivale a 4 bits, pois estamos trabalhando com inteiros. Inteiros suportam números de até 4 bits. Como há 7 posições em um vetor de inteiros, o nosso vetor possui 28 bits. Este algoritmo descobre através do tamanho do vetor (28 bits) dividido pelo tamanho de cada posição do vetor (4 bits) que dará 7.

Tamanho do vetor: 7

O problema de usar este método para descobrir o tamanho do vetor é que ele só funciona com vetores declarados na mesma função. Ele não funciona com vetores declarados em uma função local que são passados por parâmetro em outra função. Não funciona!

Com base nisto descobri alguns métodos que funcionam localmente e que não funcionam se passados por parâmetro em outra função e métodos que funcionam das duas formas. Na verdade são 4 métodos para descobrir o tamanho de um vetor que apresento aqui.

Vamos lá! Veja o código:

#include <stdio.h>
#include <stdlib.h>
void metodo1(int arr[]){
    printf("\nMetodo 1");
    int result = *(&arr+1)-arr;
    printf("\nMETODO 1 - Resultado *(&arr+1)-arr: %d",result);
}
void metodo2(int arr[]){
    printf("\n\nMetodo 2");
    int res = sizeof(*(&arr));
    printf("\nResultado sizeof(*(&arr)): %d",res);
    int resu = sizeof(*(&arr+1));
    printf("\nResultado sizeof(*(arr+1)): %d", resu);
    int tamanho = res/resu;
    printf("\nMETODO 2 - Resultado de res/resu: %d",tamanho);
    printf("Numero: %d",(arr));
}

void metodo3(int arr[]){
    printf("\n\nMetodo 3");
    int *inicio;
    int *fim;
    int count=0;
    for (inicio = *(&arr), fim = *(&arr+1); inicio<fim; inicio++){
        count++;
        printf("\ninicio: %d",inicio);
    }
    printf("\nMETODO 3 - Count eh igual a: %d",count);
}

void metodo4(int arr[]){
    printf("\n\nMetodo 4");
    int *n = *(&arr+1);
    printf("\n\nResultado &arr+1: %d",*n);
    int *n1 = *(&arr);
    printf("\nResultado &arr: %d",*n1);
    int g = n-n1;
    printf("\n\nMetodo 4- Resultado de n-n1: %d",g);
}

int main(){
    int arr[12] = {1};
    int opcao;
    do{

    printf("MENU: ");
    printf("\n\n1 - Metodo 1");
    printf("\n2 - Metodo 2");
    printf("\n3 - Metodo 3");
    printf("\n4 - Metodo 4");
    printf("\nOpcao: ");
    scanf("%d",&opcao);
  
    switch(opcao){
        case 1: metodo1(arr);
      
        break;
        case 2: metodo2(arr);
        break;
        case 3: metodo3(arr);
        break;
        case 4: metodo4(arr);
    }
    getchar();
    getchar();
    system("cls");
  
    }while(opcao!=5);
  
}


Bem! O método 1 foi proposto nesta página How to find size of an array in C without sizeof.

Arjun Sreedharan faz todo um estudo sobre como funciona a alocação de um
 vetor na memória. Você pode se aprofundar se quiser conferindo o artigo
 dele. O método 1 funciona perfeitamente.

Metodo 1
METODO 1 - Resultado de *(&arr+1)-arr: 12

O método 2 é aquele mesmo que já expliquei sobre o uso do sizeof. A
diferença é porque foi usado o conhecimento de ponteiros.
sizeof(*(&arr)) é equivalente a sizeof(array) e sizeof(*(&arr+1)
 é equivalente a sizeof(array[0]). O método 2 estamos trabalhando
diretamente com os endereços diferente do uso do sizeof que expliquei
anteriormente. Este método não funciona como desejado.

Metodo 2
Resultado sizeof(*(&arr+1):4
METODO 2 - Resultado de res/resu: 4

O método 3 usa do conhecimento de que se &arr é igual ao endereço da
 primeira posição do vetor(arr[0]) e &arr+1 é o endereço da primeira
 posição do próximo vetor que fica vizinho a ele na memória(digamos
arr1[0] que foi alocada pelo SO vizinho ao vetor arr). O método 3 usa um
 for para passar de posição em posição do vetor arr. Há uma variável
contadora que conta quantas posições foram encontradas no vetor. Ele dá
todos os endereços entre &arr e &arr+1. A última linha do
resultado é esta:

METODO 3 - Count eh igual a 12

O método 3 funciona perfeitamente. O método 4 é semelhante ao método 1 tanto que se baseia nele.



Valeu, galera! Testem o código!

Estou usando o Dev-C++ 5.5.3 com o compilador MinGW GCC. Até mais!
Related Posts Plugin for WordPress, Blogger...