-2

Do the conditions of the for-loop always need constant? How can I put sizeof function there to run an output showing all the elements of an array?

#include<iostream>
using namespace std;

void array_output(int a[])
{
    for (int i = 0; i < (sizeof(a)) / (sizeof(a[0])); i++)
    {
        cout << a[i] << endl;
    }
}

int main()
{
    int a[] = { 22, 53, 13, 65, 80, 31, 46 };
    array_output(a);
    return 0;
}
  • i<(sizeof(a) output shows first 4 elements
  • i<(sizeof(a))/(sizeof(a[0])) output shows only the first element
  • instead of sizeof when 7 is directly used as a condition, it gives
    the right output, showing all the elements.
JeJo
  • 30,635
  • 6
  • 49
  • 88
  • 7
    Please post code that [**actually reproduces the problem**](https://stackoverflow.com/help/mcve). Not some code you *assumed* would reproduce the problem. The second option works properly [here](http://coliru.stacked-crooked.com/a/f4c75852790b64ba). – HolyBlackCat May 14 '19 at 10:05
  • 1
    Possible duplicate of [When a function has a specific-size array parameter, why is it replaced with a pointer?](https://stackoverflow.com/questions/1328223/when-a-function-has-a-specific-size-array-parameter-why-is-it-replaced-with-a-p) – Timo May 14 '19 at 10:40

3 Answers3

4

(This answer is for users...)

where no need of using sizeof operator at all. Use instead std::size() function which will get you the size of the given container or array.

#include <iostream>
#include <iterator>  // std::size
#include <cstddef>   // std::size_t

int main()
{
    int a[]{ 22,53,13,65,80,31,46 };
    for (std::size_t i = 0; i < std::size(a); i++)
    {
        std::cout << a[i] << `\n`;
    }
}

Update

The OP has edited the question after posting this answer, where the std::size can not be applied.

When the array a passed to void array_output(int a[]), it deduced to void array_output(int* a) instead if of the its actual type int a[7].

  • i<(sizeof(a) output shows first 4 elements

    Here, you are doing size of(int*) (pointer to int), depending up on the architecture it could be efferent. In your case it is 32 bit machine which is why you got sizeof(a) = 4.

  • i < sizeof(a)/ sizeof(a[0]) output shows only the first element

    Dividing sizeof(a)(which is sizeof(int*) equal to 4 bytes in your machine) by sizeof(a[0])(which is sizeof(int), also 4 bytes), is nothing but one and loops only once.

The @Timo's answer, provide a templated function where size will be a non-type template parameter, which can be accessed directly, without going for sizeof.


How can I put sizeof in function and run an output showing all the elements of an array?

This is possible only when passing the array a of actual type as it is. For that, let the array to deduce to its int [7], by forwarding it perfectly.

#include<iostream>

template<typename Type>
void array_output(Type&& a) // deduced to `int a[7]`
{
    for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { // or std::size(a)
        std::cout << a[i] << '\n';
    }
}

int main()
{
    int a[] = { 22, 53, 13, 65, 80, 31, 46 };
    array_output(a);
    return 0;
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
2

If you use the actual array in the sizeof operator you will get the size of the array in bytes, meaning you can calculate the number of elements like you expected it using sizeof(array) / sizeof(array_type).

int x[] = {1, 1, 1, 1, 1, 1};    
int sum = 0;

for (int i = 0; i < sizeof(x) / sizeof(int); i++)
    sum += x[i];

// sum == 6

However if you pass the array as a function parameter you will encounter pointer decay. This means that the array size information is lost and you get the pointer size instead, which is the behavior that you described.

int sum(int arr[])  // arr decays to int*
{
    int sum = 0;

    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
        sum += arr[i];

    return sum;
}

int main() 
{   
    int x[] = {1, 1, 1, 1, 1, 1};    
    return sum(x);  // will return 1 or 2, depending on architecture
}

You can still get the array size in the function if you use a template function for it.

#include <cstddef>

template <std::size_t N>
int sum(int (&arr)[N])
{
    int sum = 0;

    for (int i = 0; i < N; i++)
        sum += arr[i];

    return sum;
}

int main() 
{   
    int x[] = {1, 1, 1, 1, 1, 1};    
    return sum(x);  // will return 6
}
Timo
  • 9,269
  • 2
  • 28
  • 58
  • @JeJo That statement was written after I posted this answer. And tbh I don't know what OP's trying to say with that sentence. – Timo May 14 '19 at 19:09
  • Well OP can also do `sizeof(arr)` in my last example instead of `N`. Doesn't make any difference. – Timo May 14 '19 at 19:13
  • true... But in your answer `N` makes more sense. What I meant is, you could have mentioned it in your answer. – JeJo May 14 '19 at 19:16
1

You can use vector for this.

vector<int> nums{1,2,3,4};
for(std::size_t i = 0; i < nums.size(); ++i)
  cout<<nums[i]<<endl;

If you insist on using int a[], you should be aware of the size before traversing it. By the way, on GCC

sizeof(nums) = sizeof(int) * total number of element

it's not the total number of element.

asap diablo
  • 178
  • 2
  • 13
  • 1) Don't use `int` for `i`: `size()` returns `std::size_t` and then you're comparing a signed type `int` to an unsigned one `std::size_t` that is a bad thing to do; 2) in C++11 you can do this: `for (auto& x : nums) std::cout << x << std::endl;`. – Evg May 14 '19 at 10:12
  • @Evg you are right – asap diablo May 14 '19 at 12:10