Pergunta

Como determino o tamanho do meu array em C?

Ou seja, o número de elementos que o array pode conter?

Foi útil?

Solução

Sumário executivo:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Resposta completa:

Para determinar o tamanho do seu array em bytes, você pode usar o sizeofoperador:

int a[17];
size_t n = sizeof(a);

No meu computador, os inteiros têm 4 bytes, então n é 68.

Para determinar o número de elementos na matriz, podemos dividir o tamanho total da matriz pelo tamanho do elemento da matriz.Você poderia fazer isso com o tipo, assim:

int a[17];
size_t n = sizeof(a) / sizeof(int);

e obter a resposta correta (68/4 = 17), mas se o tipo dea mudou, você teria um inseto desagradável se esquecesse de mudar o sizeof(int) também.

Portanto, o divisor preferido é sizeof(a[0]), o tamanho do elemento zeroth da matriz.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Outra vantagem é que agora você pode facilmente parametrizar o nome da matriz em uma macro e obter:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

Outras dicas

O sizeof caminho é o caminho certo se você está lidando com matrizes não recebidas como parâmetros.Um array enviado como parâmetro para uma função é tratado como um ponteiro, então sizeof retornará o tamanho do ponteiro, em vez do array.

Assim, dentro de funções este método não funciona.Em vez disso, sempre passe um parâmetro adicional size_t size indicando o número de elementos na matriz.

Teste:

#include <stdio.h>
#include <stdlib.h>

void printSizeOf(int intArray[]);
void printLength(int intArray[]);

int main(int argc, char* argv[])
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };

    printf("sizeof of array: %d\n", (int) sizeof(array));
    printSizeOf(array);

    printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
    printLength(array);
}

void printSizeOf(int intArray[])
{
    printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}

void printLength(int intArray[])
{
    printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}

Saída (em um sistema operacional Linux de 64 bits):

sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2

Saída (em um sistema operacional Windows de 32 bits):

sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1

Vale a pena notar que sizeof não ajuda ao lidar com um valor de array que decaiu para um ponteiro:mesmo que aponte para o início de um array, para o compilador é o mesmo que um ponteiro para um único elemento desse array.Um ponteiro não "lembra" de mais nada sobre o array que foi usado para inicializá-lo.

int a[10];
int* p = a;

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));

O tamanho do "truque" é a melhor maneira que conheço, com uma mudança pequena, mas (para mim, isso é uma grande implicância) importante no uso de parênteses.

Como a entrada da Wikipedia deixa claro, C's sizeof não é uma função;é um operador.Assim, não requer parênteses em torno do seu argumento, a menos que o argumento seja um nome de tipo.Isso é fácil de lembrar, pois faz com que o argumento pareça uma expressão convertida, que também usa parênteses.

Então:Se você tiver o seguinte:

int myArray[10];

Você pode encontrar o número de elementos com código como este:

size_t n = sizeof myArray / sizeof *myArray;

Isso, para mim, é muito mais fácil do que a alternativa entre parênteses.Também sou a favor do uso do asterisco à direita da divisão, pois é mais conciso que a indexação.

Claro, tudo isso também é tempo de compilação, então não há necessidade de se preocupar com a divisão que afeta o desempenho do programa.Portanto, use este formulário sempre que puder.

É sempre melhor usar sizeof em um objeto real quando você tiver um, em vez de em um tipo, pois assim você não precisa se preocupar em cometer um erro e indicar o tipo errado.

Por exemplo, digamos que você tenha uma função que gera alguns dados como um fluxo de bytes, por exemplo, através de uma rede.Vamos chamar a função send(), e faça com que ele receba como argumentos um ponteiro para o objeto a ser enviado e o número de bytes no objeto.Então, o protótipo fica:

void send(const void *object, size_t size);

E então você precisa enviar um número inteiro, então codifique-o assim:

int foo = 4711;
send(&foo, sizeof (int));

Agora, você introduziu uma maneira sutil de dar um tiro no próprio pé, especificando o tipo de foo em dois lugares.Se um mudar, mas o outro não, o código será quebrado.Portanto, faça sempre assim:

send(&foo, sizeof foo);

Agora você está protegido.Claro, você duplica o nome da variável, mas isso tem uma grande probabilidade de quebrar de uma forma que o compilador possa detectar, se você alterá-la.

int size = (&arr)[1] - arr;

Confira esse link para explicação

Você pode usar o SizeoOf Operator, mas ele não funcionará para funções, pois ele aceitará a referência do ponteiro que você pode fazer o seguinte para encontrar a duração de uma matriz:

len = sizeof(arr)/sizeof(arr[0])

Código originalmente encontrado aqui:Programa C para encontrar o número de elementos em uma matriz

Se você conhece o tipo de dados do array, pode usar algo como:

int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};

int noofele = sizeof(arr)/sizeof(int);

Ou se você não conhece o tipo de dados do array, pode usar algo como:

noofele = sizeof(arr)/sizeof(arr[0]);

Observação:Isso só funciona se o array não for definido em tempo de execução (como malloc) e o array não for passado em uma função.Em ambos os casos, arr (nome da matriz) é um ponteiro.

A macro ARRAYELEMENTCOUNT(x) que todo mundo está fazendo uso de avaliações incorretamente.Isso, realisticamente, é apenas um assunto delicado, porque você não pode ter expressões que resultem em um tipo 'array'.

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0]))

ARRAYELEMENTCOUNT(p + 1);

Na verdade avalia como:

(sizeof (p + 1) / sizeof (p + 1[0]));

Enquanto

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])

ARRAYELEMENTCOUNT(p + 1);

Ele avalia corretamente como:

(sizeof (p + 1) / sizeof (p + 1)[0]);

Isso realmente não tem muito a ver explicitamente com o tamanho dos arrays.Acabei de notar muitos erros por não observar verdadeiramente como o pré-processador C funciona.Você sempre envolve o parâmetro macro, e nenhuma expressão pode estar envolvida.


Isto está certo;meu exemplo foi ruim.Mas isso é exatamente o que deveria acontecer.Como mencionei anteriormente p + 1 terminará como um tipo de ponteiro e invalidará a macro inteira (como se você tentasse usar a macro em uma função com um parâmetro de ponteiro).

No final das contas, neste especial por exemplo, a culpa realmente não importa (então estou apenas desperdiçando o tempo de todos;huzzah!), porque você não tem expressões com um tipo de 'array'.Mas realmente acho que o ponto sobre as sutilezas da avaliação do pré-processador é importante.

Para matrizes multidimensionais é um pouco mais complicado.Freqüentemente, as pessoas definem constantes macro explícitas, ou seja,

#define g_rgDialogRows   2
#define g_rgDialogCols   7

static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] =
{
    { " ",  " ",    " ",    " 494", " 210", " Generic Sample Dialog", " " },
    { " 1", " 330", " 174", " 88",  " ",    " OK",        " " },
};

Mas essas constantes também podem ser avaliadas em tempo de compilação com tamanho de:

#define rows_of_array(name)       \
    (sizeof(name   ) / sizeof(name[0][0]) / columns_of_array(name))
#define columns_of_array(name)    \
    (sizeof(name[0]) / sizeof(name[0][0]))

static char* g_rgDialog[][7] = { /* ... */ };

assert(   rows_of_array(g_rgDialog) == 2);
assert(columns_of_array(g_rgDialog) == 7);

Observe que este código funciona em C e C++.Para arrays com mais de duas dimensões use

sizeof(name[0][0][0])
sizeof(name[0][0][0][0])

etc., ad infinitum.

Tamanho de um array em C:

int a[10];
size_t size_of_array = sizeof(a);      // Size of array a
int n = sizeof (a) / sizeof (a[0]);    // Number of elements in array a
size_t size_of_element = sizeof(a[0]); // Size of each element in array a                                          
                                       // Size of each element = size of type
sizeof(array) / sizeof(array[0])
#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))

"você introduziu uma maneira sutil de dar um tiro no próprio pé"

Matrizes 'nativas' C não armazenam seu tamanho.Portanto, é recomendado salvar o comprimento do array em uma variável/const separada e passá-lo sempre que passar o array, ou seja:

#define MY_ARRAY_LENGTH   15
int myArray[MY_ARRAY_LENGTH];

Você DEVE sempre evitar arrays nativos (a menos que não consiga, nesse caso, cuidado com o pé).Se você estiver escrevendo C++, use o STL'vetor' do contêiner.“Comparados aos arrays, eles oferecem quase o mesmo desempenho” e são muito mais úteis!

// vector is a template, the <int> means it is a vector of ints
vector<int> numbers;  

// push_back() puts a new value at the end (or back) of the vector
for (int i = 0; i < 10; i++)
    numbers.push_back(i);

// Determine the size of the array
cout << numbers.size();

Ver:http://www.cplusplus.com/reference/stl/vector/

@ Magno:O padrão define sizeof como o número de bytes no objeto e que sizeof (char) é sempre um.O número de bits em um byte é específico da implementação.

Editar:Seção 5.3.3 do padrão ANSI C++ Tamanho de:

O operador sizeof produz o número de bytes na representação do objeto de seu operando.[...] sizeof (char), sizeof (signed char) e sizeof (unsigned char) são 1;o resultado de sizeof aplicado a qualquer outro tipo fundamental é definido pela implementação.

Seção 1.6 O modelo de memória C++:

A unidade de armazenamento fundamental no modelo de memória C++ é o byte.Um byte é pelo menos grande o suficiente para conter qualquer membro do conjunto básico de caracteres de execução e é composto por uma sequência contígua de bits, cujo número é definido pela implementação.

@Skizz:Tenho quase certeza de que estou certo, embora a melhor "fonte" que posso fornecer no momento seja a Wikipedia, do artigo sobre sizeof:

A Wikipedia está errada, Skizz está certo.sizeof(char) é 1, por definição.

Quero dizer, basta ler a entrada da Wikipedia com muita atenção para ver que está errado."múltiplos de caracteres". sizeof(char) nunca pode ser nada outro do que "1".Se fosse, digamos, 2, isso significaria que sizeof(char) tinha o dobro do tamanho do char!

Se você realmente deseja fazer isso para transmitir seu array, sugiro implementar uma estrutura para armazenar um ponteiro para o tipo do qual você deseja um array e um número inteiro representando o tamanho do array.Então você pode passar isso para suas funções.Basta atribuir o valor da variável array (ponteiro para o primeiro elemento) a esse ponteiro.Então você pode ir Array.arr[i] para obter o i-ésimo elemento e usar Array.size para obter o número de elementos na matriz.

Eu incluí um código para você.Não é muito útil, mas você pode estendê-lo com mais recursos.Para ser honesto, se essas são as coisas que você deseja, você deve parar de usar C e usar outra linguagem com esses recursos integrados.

/* Absolutely no one should use this...
   By the time you're done implementing it you'll wish you just passed around
   an array and size to your functions */
/* This is a static implementation. You can get a dynamic implementation and 
   cut out the array in main by using the stdlib memory allocation methods,
   but it will work much slower since it will store your array on the heap */

#include <stdio.h>
#include <string.h>
/*
#include "MyTypeArray.h"
*/
/* MyTypeArray.h 
#ifndef MYTYPE_ARRAY
#define MYTYPE_ARRAY
*/
typedef struct MyType
{
   int age;
   char name[20];
} MyType;
typedef struct MyTypeArray
{
   int size;
   MyType *arr;
} MyTypeArray;

MyType new_MyType(int age, char *name);
MyTypeArray newMyTypeArray(int size, MyType *first);
/*
#endif
End MyTypeArray.h */

/* MyTypeArray.c */
MyType new_MyType(int age, char *name)
{
   MyType d;
   d.age = age;
   strcpy(d.name, name);
   return d;
}

MyTypeArray new_MyTypeArray(int size, MyType *first)
{
   MyTypeArray d;
   d.size = size;
   d.arr = first;
   return d;
}
/* End MyTypeArray.c */


void print_MyType_names(MyTypeArray d)
{
   int i;
   for (i = 0; i < d.size; i++)
   {
      printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age);
   }
}

int main()
{
   /* First create an array on the stack to store our elements in.
      Note we could create an empty array with a size instead and
      set the elements later. */
   MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")};
   /* Now create a "MyTypeArray" which will use the array we just
      created internally. Really it will just store the value of the pointer
      "arr". Here we are manually setting the size. You can use the sizeof
      trick here instead if you're sure it will work with your compiler. */
   MyTypeArray array = new_MyTypeArray(2, arr);
   /* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */
   print_MyType_names(array);
   return 0;
}

A melhor forma é você salvar essas informações, por exemplo, em uma estrutura:

typedef struct {
     int *array;
     int elements;
} list_s;

Implemente todas as funções necessárias, como criar, destruir, verificar igualdade e tudo mais que você precisar.É mais fácil passar como parâmetro.

A função sizeof retorna o número de bytes usados ​​pelo seu array na memória.Se você deseja calcular o número de elementos em sua matriz, você deve dividir esse número pelo sizeof tipo de variável da matriz.Digamos int array[10];, se o tipo de variável inteiro em seu computador for de 32 bits (ou 4 bytes), para obter o tamanho do seu array, você deve fazer o seguinte:

int array[10];
int sizeOfArray = sizeof(array)/sizeof(int);

Você pode usar o & operador.Aqui está o código fonte:

#include<stdio.h>
#include<stdlib.h>
int main(){

    int a[10];

    int *p; 

    printf("%p\n", (void *)a); 
    printf("%p\n", (void *)(&a+1));
    printf("---- diff----\n");
    printf("%zu\n", sizeof(a[0]));
    printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0])));


    return 0;
};

Aqui está o exemplo de saída

1549216672
1549216712
---- diff----
4
The size of array a is 10
int a[10];
int size = (*(&a+1)-a) ;

Para mais detalhes vejaaquie também aqui.

Exemplo

#include <stdio.h>

int main() {
    int size;
    scanf("%d", &size);
    int array[size];
    printf("%d\n", (int) (sizeof(array) / sizeof(int)));
    printf("%d\n", (int) (sizeof(array) / sizeof(array[0])));
    return 0;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top