4

I was trying to make a function for finding number of elements in an array. For this I approached for following code:

#include<iostream>
#include<stdlib>

int no_of_ele(A[])    //function to return size of array
{
    return (sizeof(A)/sizeof(A[0]);
}

void main()
{
    system("cls");
    int arr[5] = {1,2,3,4,5};

    cout<<"Number of elements in array are "<<no_of_ele(arr)<<endl;
    system("pause");
}

In this approach I got output as follows:
enter image description here

Then, I did this:

cout<<"Size of array is "<<sizeof(arr)<<endl;
cout<<"Size of data type is "<<sizeof(arr[0]);

Now I got absolutely correct output of size as follows:

enter image description here

Why is it?

Tony Tannous
  • 14,154
  • 10
  • 50
  • 86
Snigdh
  • 61
  • 11
  • Note: I'm using Turbo C++ IDE, is this a compiler problem? – Snigdh Aug 06 '17 at 06:07
  • But if I do it as I did in latter code the array does not decays and I got correct output size(i.e. 5). Why? – Snigdh Aug 06 '17 at 06:10
  • 6
    The array decays into a pointer, **when passed into a function**. The second example doesn't do that. – Algirdas Preidžius Aug 06 '17 at 06:12
  • This looks right to me. `main()` has an *array*; the length is known. But `no_of_ele()` only gets a *pointer*. Your output is what I would expect since the array has decayed to a pointer. – chrisaycock Aug 06 '17 at 06:13
  • So, what I should do to make a perfect function? – Snigdh Aug 06 '17 at 06:15
  • @Snigdh You can pass the size of locally declared array, into a templated function (not sure if Turbo C++ supports such templates). Or, macros, are another possibility. – Algirdas Preidžius Aug 06 '17 at 06:17
  • You can't pass an array to a function. It is received as a pointer. *Ergo* you cant write a method to return the size of an array. You will have to make it a macro. – user207421 Aug 06 '17 at 06:17
  • @AlgirdasPreidžius: The answer section is below. Comments are for requesting clarification or suggesting improvements to the question. – Benjamin Lindley Aug 06 '17 at 06:18
  • *"I'm using Turbo C++ ID"* - I suggest you switch to a compiler that was at least updated this decade instead. Turbo-C++ won't be able to support anything you try with *modern* C++. – StoryTeller - Unslander Monica Aug 06 '17 at 06:20
  • @AlgirdasPreidžius Please **provide me code** for this I'll try to run it. – Snigdh Aug 06 '17 at 06:20
  • @StoryTeller **Which compiler I should use?** – Snigdh Aug 06 '17 at 06:21
  • Wow, that must be an old compile, I now get `warning: ‘sizeof’ on array function parameter ‘A’ will return size of ‘int*’ [-Wsizeof-array-argument]` after some modifications. – alfC Aug 06 '17 at 06:21
  • @Snigdh - No need to **bolden** anything. I can see your comment just fine. GCC and Clang are two very good and well maintained toolchains. One is free software and the other open source (the difference not important to you) which you can download and use free of charge. – StoryTeller - Unslander Monica Aug 06 '17 at 06:23
  • @StoryTeller my book suggests me Turbo C++ or Code::Blocks are the compilers you suggesting won't make much difference or what? – Snigdh Aug 06 '17 at 06:27
  • 2
    @Snigdh - (1) Code::Blocks isn't a compiler, it's an IDE. At least you can setup another compiler to work with it, so I suggest to make the switch. (2) [Get a better book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) – StoryTeller - Unslander Monica Aug 06 '17 at 06:30
  • @StoryTeller Sorry I meant "Suggest me IDE" – Snigdh Aug 06 '17 at 06:34
  • @StoryTeller I can't alter my book It is my course book – Snigdh Aug 06 '17 at 06:34
  • @Snigdh - Then take everything that course teaches you with a grain of salt. Decent instructors should know better than suggest ancient tool-chains. Any way, I made my suggestions. Do what you will with them. – StoryTeller - Unslander Monica Aug 06 '17 at 06:36
  • @BenjaminLindley Well.. I am too lazy to write an actual answer at the moment (if I wasn't - I would have done so). My comment was hardly an answer, but a suggestion. – Algirdas Preidžius Aug 06 '17 at 06:38

2 Answers2

6

There are better ways these days, but the closest is:

#include<iostream>

template<std::size_t N>
int no_of_ele(int (&A)[N]){
    return sizeof(A)/sizeof(A[0]); // or just return N
}

int main(int argc, char* argv[]){

    int arr[5] = {1,2,3,4,5};

    std::cout<<"Number of elements in array are "<<no_of_ele(arr)<<std::endl;
    return 0;
}

Greetings to 1998. The question is, does Turbo C++ support templates?

See here for more: Is it possible to overload a function that can tell a fixed array from a pointer?

alfC
  • 14,261
  • 4
  • 67
  • 118
  • You can just "`return N;`" in `no_of_ele`. – 一二三 Aug 06 '17 at 06:27
  • @一二三, good point. I tried to change the original code the least possible. For that matter, it is not even necessary to have a function. – alfC Aug 06 '17 at 06:28
  • @StoryTeller, ok – alfC Aug 06 '17 at 06:36
  • @Snigdh, they are called non-class templates. Not sure if Turbo C++ was compliant with this feature at the time. http://en.cppreference.com/w/cpp/language/template_parameters#Template_non-type_arguments – alfC Aug 06 '17 at 06:43
  • @Snigdh what is the error? are you still using Turbo c++ ? Your compiler is outdated and doesn't follow standard c++. – alfC Aug 11 '17 at 16:09
2

The array decayed to pointer when passed to your function.

sizeof(int)/sizeof(int)... = 1

Reason for this, the parameters are pushed on stack to the function. The compiler as declared by your function declaration will just send the address of your array.


When passing an array as a parameter

int func(int arr[])

Is just as:

int func(int *arr)

Giving an array as a function argument you can't determine its size using the sizeof.

Tony Tannous
  • 14,154
  • 10
  • 50
  • 86