0
#include <iostream>

using namespace std;
int main()
{
    int arr,i=0,frequancy,y,X,l;
    
    int V[arr];
    cout<<"Enter the size of an array: ";
    cin>>arr;
    
    cout<<"Enter all "<<arr<<" elements in array: ";
    for(i=0;i<=arr-1;i++)
    cin>>V[i];
    
    int a[arr]={0};
    
    cout<<"Frequency of all "<<arr<<" elements in array:"<<endl;
        
    for(i=0;i<arr;i++)
    {
        int count=0;
        if (a[i]!=1)
        {
            for (int j=0;j<arr;j++)
            {
                if(V[i]==V[j])
                {
                    count++;
                    a[j]=1;
                }
            }
            if (count>1||count==1)
            {
                cout<<V[i]<<" occurs "<<count<<" times "<<endl;
            }
        }
    }
return 0;
}

//this is the answer
Enter the size of an array: 9
Enter all 9 elements in array: 1
1
2
3
1
5
3
12
1
Frequency of all 9 elements in array:
1 occurs 4 times
2 occurs 1 times
3 occurs 2 times
5 occurs 1 times
12 occurs 1 times

So there are a few questions that I don't understand that well and I need someone to explain what is going on with it, please.

  1. I don't understand why we have to initialize this(int a[arr]={0}) to 0, I asked my prof about it be he said it has to be like that. which doesn't answer my question:'C.

  2. I have a problem with the bottom part of the code, I kinda understand a bit but if someone can help me that would help a lot Thank you!!!!

given159
  • 7
  • 1
  • `int a[arr]={0};` sets the values to 0. And then you have a loop with `if (a[i]!=1)` but reading from a variable that hasn't been assigned a value is not allowed so you must put something into the array before reading the values in the loop - and that's why `int a[arr]={0};` is done. – Jerry Jeremiah Jun 04 '21 at 00:32
  • If you don't initialize a stack variable (or array), then it will contain whatever was in the stack memory before, which is almost never useful. Globals are different. – Tim Roberts Jun 04 '21 at 00:38
  • This is a terrible way to count the frequencies - it is quadratic with the number of array items and there is a linear way to do it. Basically, for each frequency that we haven't already counted we count the number of items that match that same index in V, mark it as counted and write the result. – Jerry Jeremiah Jun 04 '21 at 00:38
  • @TimRoberts I thought that in C++ reading from an uninitialized variable was undefined behaviour (which is worse than just getting a random value) https://stackoverflow.com/questions/30180417/what-happens-when-i-print-an-uninitialized-variable-in-c https://stackoverflow.com/questions/30542801/reading-uninitialized-variable – Jerry Jeremiah Jun 04 '21 at 00:40
  • Well, "undefined behavior" just means there are no promises. The compiler is allowed to do anything it wants without violating the spec. What literally happens in this case is that the variable just inherits the previous contents of that memory. – Tim Roberts Jun 04 '21 at 00:42
  • Unrelated, you should also be aware that `V` is pointless. You can build a frequency table of values being streamed in without having to store said-same values in an intermediate array first. – WhozCraig Jun 04 '21 at 00:52
  • `V` is pointless AND Crom only knows how big it is. The value of `arr` hasn't been defined yet. Could be a billion. Could be minus billion. – user4581301 Jun 04 '21 at 00:54
  • Removed a comment above. It seems the behaviour I described was changed back in GCC 4.9. Shows you how long it's been since I used a VLA – user4581301 Jun 04 '21 at 01:11

1 Answers1

2
int arr/*...*/;
int V[arr];
cin>>V[i];

This program is badly broken.

Problem 1: The size of an array variable must be a compile time constant in C++. arr is not a compile time constant value. Violating this rule makes the program ill-formed, which means that compilers aren't required to compile it. You should avoid this.

Solution: If you need an array whose size is determined at runtime, then you should allocate the array dynamically. Simplest way to achieve that is to use the std::vector template from the standard library.


Problem 2: The behaviour of a program that reads an indeterminate value is undefined. Undefined behaviour means that there are no guarantees about the behaviour of the program whatsoever. This is very bad and should be avoided.

arr has an indeterminate value when you use it. The behaviour of the program is undefined. I repeat: This is very bad.

C++ is not a "data-flow" language. You cannot simply use a variable and initialise it after the usage. The program won't automatically stop, create a thread and wait for the later initialisation to proceed further.

Solution: Initialise before use.


I don't understand why we have to initialize this(int a[arr]={0}) to 0

Later on in the program, the values of that array are read (a[i]!=1). If you don't initialise the values before using them, then the behaviour of the program is undefined. See the previous paragraph.

Presumably, the elements of the array are initialised to zero in order to avoid that undefined behaviour.

Note that it is redundant to initialise the first element of the array explicitly to zero, and value initialise the rest, because those achieve the same thing. Thus, a simpler way to achieve the same is to value initialise all of the elements by not providing an initialiser for any of them:

constexpr int arr = 42;
int a[arr] {};

I have a problem with the bottom part of the code

The first step to solve that problem is to figure out why you think that you have a problem, and what kind of problem it could be.

eerorika
  • 232,697
  • 12
  • 197
  • 326