Como faço para determinar o tamanho da minha matriz em C?

Como faço para determinar o tamanho da minha matriz em C?

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

Sumário executivo:

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

Para determinar o tamanho da sua matriz em bytes, você pode usar o operador sizeof :

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

No meu computador, os ints têm 4 bytes, portanto, 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 obtenha a resposta apropriada (68/4 = 17), mas se o tipo de mudança for alterado, você terá um erro desagradável se esqueceu de alterar o sizeof(int) também.

Portanto, o divisor preferido é sizeof(a[0]) , o tamanho do elemento zeroeth 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); 

O sizeof maneira é o caminho certo, se você estiver lidando com matrizes não recebidas como parâmetros. Uma matriz enviada como um parâmetro para uma function é tratada como um ponteiro, portanto, sizeof retornará o tamanho do ponteiro, em vez do tamanho da matriz.

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  #include  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 quando se lida com um valor de matriz 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 daquele 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 eu conheço, com uma pequena, mas (para mim, essa é uma grande preocupação) uma mudança importante no uso de parênteses.

Como a input da Wikipedia deixa claro, o sizeof de C não é uma function; é um operador . Assim, não requer parênteses em torno de 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 de casting, que também usa parênteses.

Então: Se você tem 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 que a alternativa com parênteses. Eu também sou a favor do uso do asterisco na parte direita da divisão, já que é mais conciso que a indexação.

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

É sempre melhor usar sizeof em um object real quando você tem um, em vez de um tipo, desde então, você não precisa se preocupar em cometer um erro e declarar o tipo errado.

Por exemplo, digamos que você tenha uma function que produza alguns dados como um stream de bytes, por exemplo, através de uma rede. Vamos chamar a function send() e torná-la como um ponteiro para o object a ser enviado e o número de bytes no object. Então, o protótipo se torna:

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

E então você precisa enviar um inteiro, então você o codifica assim:

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

Agora, você introduziu uma maneira sutil de atirar no próprio pé, especificando o tipo de foo em dois lugares. Se uma muda mas a outra não, o código quebra. Assim, faça sempre assim:

 send(&foo, sizeof foo); 

Agora você está protegido. Claro, você duplica o nome da variável, mas tem uma alta probabilidade de quebrar de uma maneira que o compilador possa detectar, se você a alterar.

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

Confira este link para explicação

Você pode usar o operador sizeof, mas ele não funcionará para funções porque ele pegará a referência do ponteiro, você pode fazer o seguinte para encontrar o tamanho de um array:

 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 da matriz, 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 souber o tipo de dados da matriz, poderá usar algo como:

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

Nota: Essa coisa só funciona se a matriz não estiver definida em tempo de execução (como malloc) e a matriz não for passada em uma function. Em ambos os casos, arr (nome da matriz) é um ponteiro.

A macro ARRAYELEMENTCOUNT(x) que todos estão fazendo uso de avalia incorretamente . Isso, realisticamente, é apenas uma questão delicada, 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); 

Realmente avalia como:

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

Enquanto que

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

Ele avalia corretamente para:

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

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


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

No final do dia, neste caso em particular , a falha 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 o ponto sobre subtração de avaliação do pré-processador eu acho que é importante.

Para matrizes multidimensionais é um pouco mais complicado. Muitas vezes 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 podem ser avaliadas em tempo de compilation também com sizeof :

 #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); 

Note que este código funciona em C e C ++. Para matrizes 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 atirar-se no pé”

C arrays ‘nativos’ não armazenam seu tamanho. Portanto, é recomendável salvar o tamanho da matriz em uma variável / const separada e passá-la sempre que você passar a matriz, ou seja:

 #define MY_ARRAY_LENGTH 15 int myArray[MY_ARRAY_LENGTH]; 

Você DEVE sempre evitar matrizes nativas (a menos que você não possa, nesse caso, cuidar do seu pé). Se você estiver escrevendo C ++, use o contêiner ‘vector’ do STL . “Comparado aos arrays, eles fornecem quase o mesmo desempenho”, e eles são muito mais úteis!

 // vector is a template, the  means it is a vector of ints vector 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(); 

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

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

Editar: seção padrão ANSI C ++ 5.3.3 Sizeof:

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

Seção 1.6 O modelo de memory C ++:

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

@Skizz: Tenho certeza de que estou certo, embora a melhor “fonte” que eu possa lhe dar no momento seja a Wikipedia, do artigo sobre sizeof:

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

Quero dizer, apenas leia a input da Wikipedia bem de perto para ver que está errado. “múltiplos de char”. sizeof(char) nunca pode ser outra coisa senão “1”. Se fosse, digamos, 2, isso significaria que sizeof(char) tinha o dobro do tamanho de char!

Se você realmente quiser fazer isso para passar em sua matriz, sugiro implementar uma estrutura para armazenar um ponteiro para o tipo que você deseja uma matriz e um inteiro representando o tamanho da matriz. Então você pode passar isso para suas funções. Basta atribuir o valor da variável de matriz (ponteiro ao 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í alguns códigos para você. Não é muito útil, mas você pode ampliá-lo com mais resources. Para ser honesto, se estas são as coisas que você quer, você deve parar de usar C e usar outro idioma com esses resources incorporados.

 /* 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  #include  /* #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 maneira é 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 o mais que você precisa. É mais fácil passar como parâmetro.

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

 #include #include 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 

A function sizeof retorna o número de bytes que é usado por sua matriz na memory. Se você quiser calcular o número de elementos em sua matriz, você deve dividir esse número com o sizeof tipo de variável da matriz. Vamos dizer int array[10]; , se o inteiro de tipo de variável no seu computador é de 32 bits (ou 4 bytes), a fim de obter o tamanho da sua matriz, você deve fazer o seguinte:

 int array[10]; int sizeOfArray = sizeof(array)/sizeof(int); 
 int a[10]; int size = (*(&a+1)-a) ; 

para mais detalhes: https://aticleworld.com/how-to-find-sizeof-array-in-cc-without-using-sizeof/ https://www.geeksforgeeks.org/how-to-find-size- of-array-in-cc-sem-usar-sizeof-operator /

Usar:

 int a=[10] = {1, 2, 3, 4, 5}; int n = sizeof(a); printf("%d", n); 

Saída:

 5 

Razão: calcula o número de elementos contidos na matriz, em vez do número de espaços livres alocados a ela.