0
int array[] = {23,34,12,17,204,99,16};
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
printf("%d",sizeof(TOTAL_ELEMENTS));

here is my some piece of sample code. the array is an integer type. so, the array[0] is also an integer. division of an integer by an integer should yield an integer. But, when I try to find the size of TOTAL_ELEMENTS by using sizeof() operator, it shows 8 bytes. why??

Yash Karanke
  • 764
  • 1
  • 15
  • 29

4 Answers4

7

Your use of the macro expands to something like sizeof (sizeof ....). Since the result of sizeof is a size_t, you're getting sizeof (size_t), which is evidently 8 on your platform.

You probably wanted

printf("%zu\n", TOTAL_ELEMENTS);

(Note that %d is the wrong conversion specifier for a size_t, and a good compiler will at least warn about your version.)


Here's a complete program that works:

#include <stdio.h>

int main()
{
    int array[] = {23,34,12,17,204,99,16};
    size_t const TOTAL_ELEMENTS = (sizeof array) / (sizeof array[0]);

    printf("%zu\n", TOTAL_ELEMENTS);
}

Output:

7

Note that I made TOTAL_ELEMENTS be an ordinary object, as there's no need for it to be a macro here. You may need it as a macro if you want a version that will substitute the array name, like this:

#define TOTAL_ELEMENTS(a) (sizeof (a) / sizeof (a)[0])

You'd then write:

printf("%zu\n", TOTAL_ELEMENTS(array));
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • I would say "Note that I made TOTAL_ELEMENTS be an ordinary object" or "variable" as `TOTAL_ELEMENTS` in `size_t TOTAL_ELEMENTS = ...` is not a _constant_ in C. `const size_t TOTAL_ELEMENTS = ..` is closer, to a wannabe _constant_. Otherwise, good answer. – chux - Reinstate Monica Jun 20 '17 at 18:03
  • 1
    @chux, I thought I *had* written `const` there when I wrote that - now fixed (and I like your suggestion of "object" as a better descriptive term). – Toby Speight Jun 21 '17 at 09:36
3

When you use the #define the pre-processor replaces TOTAL_ELEMENTS with (sizeof(array) / sizeof(array[0])).

The result type of (sizeof(array) / sizeof(array[0])) is a size_t. When you use sizeof operator on a size_t it will return its size. In your case 8 bytes.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
2

sizeof returns a size as type size_t, as per 6.5.3.4p5

Your platform's sizeof(size_t) is 8.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
0

sizeof returns the size of an item, in bytes. Since a lot of types are larger than a single byte, if you have an array, one way to determine its size in elements is to take the total size in bytes of the array, then divide it by the size of the type of element it's composed of - and that type will be in the first element of the array, at index 0.

For example, if I have an array of ints, and an int is 4 bytes on my platform, it would look like this in memory

Item 0 | Item 1 | Item 2
4bytes | 4bytes | 4bytes

sizeof(array) would be 12, the array's total size in bytes. sizeof(array)/sizeof(array[0]) would be 3, the array's total size in elements.

You're using the macro wrong in your code. You should be using:

printf("%zu", TOTAL_ELEMENTS);

Otherwise the code expands to sizeof(sizeof ...) which is not what you want if you're actually after the length of elements in the array. sizeof(sizeof(something)) will return the size of a size_t type on your platform, which is why you're seeing 8.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
  • 1
    The first few paragraphs just restate what the asker already knows - the actual useful answer is hidden in the "By the way..." edit. – Toby Speight Jun 20 '17 at 16:01