1

More than once I have seen the sizeof operator used on index 0 of an array act as the denominator when storing the number of elements of an array. My question is why use the sizeof operator instead of just dividing by 1 or not dividing at all?

See an example of this phenomenon below in some sample code from https://www.bravegnu.org/gnu-eprog/c-startup.html.

static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
static const int n = sizeof(arr) / sizeof(arr[0]);  //RIGHT HERE!!!!!

int main()
{
        int i;

        for (i = 0; i < n; i++)
                sum += arr[i];
}
  • Do you understand what the `sizeof` operator returns? You would not get the length of the array if you didn't divide by the size of array element – UnholySheep Jul 10 '20 at 15:13
  • If an array has elements of size > 1 why would you suggest to not divide? An array clearly has less or equel elements than bytes. – Gerhardh Jul 10 '20 at 15:13
  • 1
    Commonly seen in code: `#define COUNTOF(arr) ( sizeof(arr) / sizeof((arr)[0]) )` – Steve Friedl Jul 10 '20 at 15:20
  • 2
    Not very related, but `sizeof` is an operator (a unitary one), not a function. This distinction has some significant implications in certain circumstances. – Eugene Sh. Jul 10 '20 at 15:30
  • 1
    @EugeneSh. I'd say `sizeof()` being an operator instead of a function is related to this question. An operator can be used in global variable initializations such as `static const int n = ...` in this question. An executable function can not be called there. – Andrew Henle Jul 10 '20 at 15:40
  • @AndrewHenle Related indeed. I guess I covered myself with the "very" word :) – Eugene Sh. Jul 10 '20 at 15:42

3 Answers3

5
static int arr[] = { 1, 10, 4, 5, 6, 7 };

Array arr is a bunch of integers, six of them to be precise. Each integer takes up some number of bytes (let's assume four for the purposes of this answer - on some systems it can be more or less).

So, sizeof(arr) is 24 bytes, six integers times four bytes each.

If you want to know how many elements (rather than bytes) are in the array, divide the size of the entire array by the size of a single member, one of:

static const int n = sizeof(arr) / sizeof(arr[0]);
static const int n = sizeof(arr) / sizeof(*arr);

// sizeof(arr) / sizeof(arr[0]) == 24 / 4 == 6 elements
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
abelenky
  • 63,815
  • 23
  • 109
  • 159
0

This is because the size of an array (which is in bytes) is the size of one element times the number of elements. Be aware that sizeof doesn't work on pointers to heap variables allocated with malloc().

Gedobbles
  • 46
  • 5
  • `sizeof` does not to determine the size of an array given only a pointer to an element. It is irrelevant whether this pointer comes from `malloc` or elsewhere. Also, `sizeof` is an operator, not a function, and does not need parenthesis when applied to objects (rather than types). – Eric Postpischil Jul 10 '20 at 15:31
  • 1
    It works perfectly for pointers. You just need to know what the result means. – klutt Jul 10 '20 at 15:45
  • @EricPostpischil "`sizeof` does not to determine the size of an array given only a pointer to an element" thats what I meant to say, I didn't know this wasn't clear. "Also, `sizeof` is an operator, not a function, and does not need parenthesis when applied to objects (rather than types)." is off topic here. @klutt depends on the definition of "works". Is this how you welcome new members around here? – Gedobbles Jul 10 '20 at 16:07
  • 2
    The fact that `sizeof` is an operator is relevant because this answer refers to it as `sizeof()`, giving the misleading impression that parentheses are part of it. This unfortunately prevalent notion leads to people cluttering code with unnecessary parentheses. Comments give you an opportunity to improve an answer. – Eric Postpischil Jul 10 '20 at 17:15
  • @Eric, I use parentheses all the time because I couldn't be bothered trying to remember whether `sizeof(variableName)` or `sizeof(typeName)` needs them. I'm certain one needs them, I just have no spare capacity in my wet-ware :-) – paxdiablo Aug 18 '20 at 12:48
-2

Why is this done? This is done so changes to the array can be made without making other changes, reducing the chances of introducing bugs and/or outright failures from incorrect code.

TLDR answer:

This construct automates the counting of the elements of the array so that it doesn't depend on a human typing in a number - a number that can be wrong...

Full Answer

If the code were

static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;

int main()
{
        int i;

        for (i = 0; i < 6; i++)
                sum += arr[i];
}

instead, if the array is changed by removing an element to

static int arr[] = { 1, 10, 4, 5, 6 };

the code would be broken.

This code

static const int n = sizeof(arr) / sizeof(arr[0]);

would work with all of the following definitions of arr:

static int arr[] = { 1, 10, 4, 5, 6, 7 };

or

unsigned long long arr[ NUM_ELEMENTS ];

or

static float arr[] = { 12.4, 54.2 };

Your original code

static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
static const int n = sizeof(arr) / sizeof(arr[0]);  //RIGHT HERE!!!!!

int main()
{
        int i;

        for (i = 0; i < n; i++)
                sum += arr[i];
}

would (mostly) work with any of those definitions of arr.

(Undefined behavior from signed integer overflow could be more likely to happen for some of those definitions, but that's not addressed in the original code either)

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • 1
    You seem to have missed the point of the question. It is not asking why an expression is used to calculate the array size. It is asking why there is a division by the size of an element. – Eric Postpischil Jul 10 '20 at 17:05
  • @EricPostpischil [Forest, trees.](https://www.dictionary.com/browse/can-t-see-the-forest-for-the-trees) – Andrew Henle Jul 10 '20 at 17:11