I wrote a code that computes the sum of components of an array which is randomly filled with values between 0 and 1. I have to write two functions, one is iterative, and the other one is recursive. Both should do the same work. The two functions I wrote work fine when I call only one at the time. However, if i try to call the two functions in the main, I can see the result of one only, but cannot see the result from the other one. In addition, my recursive function tends to get called one extra time. I have noticed that if I put getch() as comment in recursive_function(). I know I am missing something, but I cannot figure that out. Thanks for your help. here is the code. i am using Dev-C++.
#include <iostream>
#include<conio.h>
#include <stdlib.h>
using namespace std;
//headers of the thre functions
int random_value(int array[], int size);
int iterative_function (int array[], int size, int sum);
int recursive_function ( int size, int array[], int index, int sum);
int main()
{
int size;int array[size]; int sum=0;
int index=0;
cout<<"enter the size of the array"<<endl;
cin>>size; //enter the size ofthe array...
random_value(array, size);
iterative_function (array, size, sum);
recursive_function ( size, array, index, sum);
getch();
return 0;
}
int random_value(int array[], int size)
{ cout<<"here is the value returned by rand()"<<endl;
for(int i=0;i<size;i++)
{ array[i]=( rand() % (0-2));
cout<<array[i]<<endl;
}
}
int iterative_function (int array[], int size, int sum)
{
int i,j, number, value; i=0;
cout<<"from the iterative function"<<endl;
cout<<"------"<<endl;
for(i=0;i<size;i++)
sum=sum+array[i];
cout<<"sum of the array="<<sum<<endl;
getch();
return 0; //exit the function. Program terminated succesfully.
}
int recursive_function ( int size, int array[], int index, int sum)
{
if(size>index)
{
sum=sum+array[index];
index++;
recursive_function( size, array, index, sum);
}
cout<<"from the recursive function"<<endl;
cout<<"------"<<endl;
cout<<"new sum= "<< sum<<endl;
getch();
return 0;
}
#include <iostream>
#include<conio.h>
<conio.h is not a standard header, i.e. it is not available with all compilers, and you don't need it.
To see the result output of your program:
run it from the command line, or
in Visual Studio run it via keypress [Ctrl F5] (no debugging), or
set a breakpoint on the closing brace of main, and run it under a debugger (in Visual Studio e.g. via keypress [F5]).
#include <stdlib.h>
As far as I can see you’re not using anything from this header. However, it does provide the symbolic constants EXIT_SUCCESS and EXIT_FAILURE, which are intended for return statement in main. E.g., it can be more clear to write EXIT_SUCCESS there than to write 0, because many folks misunderstand what 0 means in this context.
using namespace std;
This is OK for a short program or within a namespace.
However, keep in mind that short programs very often end up as not-so-short programs.
And then a using namespace std; can easily cause name collisions, in particular with the name std::distance.
//headers of the thre functions
int random_value(int array[], int size);
int iterative_function (int array[], int size, int sum);
int recursive_function ( int size, int array[], int index, int sum);
Although it is partly a matter of preference, there is no advantage in forward-declaring the functions before main, it is more work, and it sometimes causes problems when the forward declarations don’t quite match the definitions – as with any unnecessary redundancy, violations of the DRY principle (Don’t Repeat Yourself).
Instead, just place the function definitions before main.
That way it is also much easier to see what refers to what, because functions that are used by others then necessarily come before those other functions.
int main()
{
int size;int array[size]; int sum=0;
This should not compile, because in C++ only a dynamically allocated array can have a size that is unknown at compile time.
However, C99 supports “variable length arrays” a.k.a. VLAs with the above syntax, and as a language extension the g++ compiler supports that.
On the third and gripping hand, even with the g++ language extension the above declares an array of indeterminate length, because the size variable has not been initialized and has an indeterminate value.
With the g++ compiler that value is most likely 0, but it can easily be any other value.
To turn off the g++ VLA language extension, and some other language extensions, use the following g++ options:
-pedantic -std=c++0x -Wall
For standard C++, instead of a C99 VLA you should use a C++ std::vector<int>.
In order to get a declaration of the std::vector class template, include the standard library header <vector>.
int index=0;
cout<<"enter the size of the array"<<endl;
cin>>size; //enter the size ofthe array...
When you're using a std::vector, then here, knowing its size, would be the place to declare that vector.
Or, if declared earlier, here would be the place to resize it.
random_value(array, size);
This would better be a function that returned a vector of random values.
You would then use that to initialize the declared vector.
iterative_function (array, size, sum);
recursive_function ( size, array, index, sum);
getch();
Regarding the getch() call, see the above comments about <conio.h>.
return 0;
Regarding the value 0 here, see the above comments about <stdlib.h>.
}
int random_value(int array[], int size)
{ cout<<"here is the value returned by rand()"<<endl;
for(int i=0;i<size;i++)
{ array[i]=( rand() % (0-2));
Here you have Undefined Behavior, accessing elements of a possibly zero-size array.
cout<<array[i]<<endl;
}
}
int iterative_function (int array[], int size, int sum)
{
int i,j, number, value; i=0;
cout<<"from the iterative function"<<endl;
cout<<"------"<<endl;
for(i=0;i<size;i++)
sum=sum+array[i];
Here you are again invoking Undefined Behavior, often called just “UB”, by accessing non-existing array elements.
In addition, even if the array had been of non-zero size, it has not been initialized and so would contain just zeroes or arbitrary values (by the Holy Standard called “indeterminate values”).
cout<<"sum of the array="<<sum<<endl;
getch();
See the above comment about <conio.h>.
return 0; //exit the function. Program terminated succesfully.
}
There is no point in letting the above function always return the same value. From an information-theoretical perspective, that return value carries zero bits of information. Instead just let the function’s result value be void.
int recursive_function ( int size, int array[], int index, int sum)
{
if(size>index)
{
sum=sum+array[index];
index++;
recursive_function( size, array, index, sum);
}
Instead of incrementing the index, which is non-idiomatic and therefore difficult to spot for experienced readers, just use index + 1 in the recursive call.
It is a good idea to add const to just about every declaration where it is possible.
That would, for example, have forced you to use index + 1. :-)
cout<<"from the recursive function"<<endl;
cout<<"------"<<endl;
cout<<"new sum= "<< sum<<endl;
getch();
See the above comment about <conio.h>.
return 0;
See the above comment about function always returning the same value.
}
Summing up, with all the Undefined Behavior it is just happenstance if things appear to work.
Fix the UB's (in particular replace C99 VLA with std::vector) first of all, then perhaps ask new question if it still does not work as it should. ;-)
You create your array using size but it's initialized AFTER that. You simply get random stuffs...
Declare int pointer, read size, allocate the array with new then try again (do not forget to delete).
First of all the array that you've declared is of unknown size, declare the array after getting input for size
Remember that in recursive_function() it calls itself many times - and every time it is called (either by main() or by itself) it will run all commands in its body (since you never return early)... now can you see a problem with the getch() in there?
Related
I created an array of size N, where N is a variable and not initialized. arr[N] is of variable size. It should give an error but it runs fine.
#include<iostream>
using namespace std;
int time_calculator(int ,int *,int );
int main(){
int N,RN,i;
int arr[N];
cin>>N;
cin>>RN;
for(i=0; i<N ; i++)
cin>>arr[i];
int time=time_calculator(N,arr,RN);
cout<<"time required= "<<time<<" sec";
return 0;
}
int time_calculator(int n, int * s, int rn){
int sm=*s;
for(int i=0;i<n;i++)
if(sm>*(s+i)){
int t=sm;
sm=*(s+i);
*(s+i)=t;
}
return rn-sm;
}
Here I created an array of variable size, but the code runs fine.
The array is not created dynamically. sm is a variable for the smallest element of arr, initialized by arr[0]. s is a pointer to arr. Please tell me why an error is not thrown.
The problem is not it being uninitialized, but rather not being a compile-time constant.
The program is ill-formed (i.e. not valid C++) because of this.
Most compilers don't enforce strict standard compliance by default, but you can configure them to do it. For MinGW/GCC you could use following flags: -std=c++xx -pedantic-errors -Wall -Wextra, where xx is the language version (one of: 98, 11, 14, 17, 20). The last two flags are not strictly related to compliance (they merely enable the warnings), but it's a good idea to use them.
With those flags the code no longer compiles. I get error: ISO C++ forbids variable length array 'arr'.
N is uninitialized when creating arr. You don't know how big of an array arr is. It might be 0, in which case you are overwriting your array. Or it might be some large number and you have plenty of space to store your integers.
Either way, this is undefined behavior. I suggest looking at std::vector as a replacement.
I was able to fix some of the errors. Now I am just getting 3.
1. control reaches end of non-void function at } before the
void displayIntegerArray(int *arrayPtr,int arraySize) function.
2. expected expression at delete[];.
3. expected expression at return 0;.
#include <iostream>
#include <iomanip>
using namespace std;
// Function prototypes
void populateIntegerArray(int *arrayPtr, int arraySize);
void displayIntegerArray(int *arrayPtr, int arraySize);
void findMaximumInteger(int *arrayPtr, int arraySize);
//method to populate array
void populateIntegerArray(int *arrayPtr,int arraySize)
{
for(int i=0;i<arraySize;i++)
{
cout<<"Enter value for array element:"<<i<<":";
cin>>arrayPtr[i]; //reading value
}
}
void findMaximumInteger(int *arrayPtr,int arraySize)
{
int maximum = arrayPtr[0];
{
for(int i=0;i<arraySize;i++)
{
if(maximum<arrayPtr[i])maximum=arrayPtr[i];
}
cout<<"Maximum integer in array is: "<<maximum<<endl;
}
}
void displayIntegerArray(int *arrayPtr,int arraySize)
{
for(int i=0;i<arraySize;i++)
{
cout<<&arrayPtr[i]<<": arrayPtr["<<i<<"] = "<<setw(15)<<arrayPtr[i]<<endl;
}
}
int main()
{
int arraySize;
// Read array size
cout<<"Enter desired array size:";
cin>>arraySize;
// Print array
cout<<"arrayPtr = "<<arraySize<<endl;
populateIntegerArray( arrayPtr, arraySize);
displayIntegerArray(arrayPtr, arraySize);
findMaximumInteger( arrayPtr, arraySize);
cout<<"DELETING array at arrayPtr = "<<arrayPtr<<endl;
delete[];
return 0;
}
In main function:
There is undeclared variable; arrayPtr.
So you have to declare it and allocate memory for it dynamically.
int* arrPtr = new int[arraySize];
You also have to provide the delete [] operator the arrayPtr to free the memory allocated.
Finally main function will be like that:
int main()
{
int arraySize;
// Read array size
cout<<"Enter desired array size:";
cin>>arraySize;
int *arrayPtr=new int[arraySize];
// Print array
cout<<"arrayPtr = "<<arraySize<<endl;
populateIntegerArray( arrayPtr, arraySize);
displayIntegerArray(arrayPtr, arraySize);
findMaximumInteger( arrayPtr, arraySize);
cout<<"DELETING array at arrayPtr = "<<arrayPtr<<endl;
delete[] arrayPtr;
return 0;
}
So there are a couple of things that ain't quite right with your program my dude, but they mainly stem from you not creating a arrayPtr in main. If you don't create something to point to a chunk of memory then your program wont know where the array is.
https://www.cplusplus.com/doc/tutorial/pointers/
The next problem is that, because you never created the pointer to the memory, you also forgot to create the space for the memory. If the array was the same size every time your program ran and was reasonably small then you could just allocate the space on the stack. However you don't so you need to allocate the memory dynamically. This means that you need to ask your operating system for the memory and get back its location. This can be done with the new[] operator. Then when you are done using the memory you tell the program to de-allocate it with the delete[] operator. (If you don't then memory will keep being marked as used despite your program ending. This is called a memory leak.)
https://www.cplusplus.com/doc/tutorial/dynamic/
Next you aren't actually displaying the location of the array. You want to print the new arrayPtr variable to see the location.
Lastly your post is a bit hard to work with. The formatting is a bit inconstant and that makes it significantly harder to read. Luckily your program was simple enough that it isn't too time consuming to read through and figure out what is going wrong. However, as your programs get more complex and larger, many people won't be willing to look through your whole program and find your bugs for you. Try to narrow down where you think the error is coming from and post: some context, the relevant chunk of code, and the exact error messages.
i initialize the matrix and call the output like this in int main()
int array[a][b][c] = {0};
OMat3(a,b,c,(int*)array);
this is the output function
void OMat3(int rig,int col,int pro,int *mat){
for (int a=0;a<rig;a++){
printf("\n%da Materia:\n",a+1);
for (int b=0;b<col;b++){
printf("\n\t%d Giorno: ",b+1);
for (int c=0;c<pro;c++){
printf("%d ",mat[a*col*pro+b*pro+c]);
}
}
}
}
the problem is that in the output i don't get only 0s (there are mostly 0, but sometimes there are crazy high values).
Am I initializing it to 0 wrong or is there something wrong with my output function?
example program
void OMat3(int rig,int col,int pro,int *mat){
for (int a=0;a<rig;a++){
printf("\nRow %d:\n",a+1);
for (int b=0;b<col;b++){
printf("\n\tColumn %d: ",b+1);
for (int c=0;c<pro;c++){
printf("%d ",mat[a*col*pro+b*pro+c]);
}
}
}
}
int main(){
int a,b,c;
printf("Insert the array's dimensions: ");
scanf("%d %d %d",&a,&b,&c);
int array[a][b][c] = {0};
OMat3(a,b,c,(int*)array);
}
I'm using TDM-GCC 4.9.2 64-bit Release if that's important
First, this is not legal C++ syntax:
int a,b,c;
//...
int array[a][b][c] = {0};
The issue is that C++ does not allow declaring arrays with a variable being used as the number of items. So a, b, or c cannot be used in the array declaration. An array's size must be declared using a compile-time expression, not a value determined at runtime.
What you are using is an extension offered by GCC, namely Variable Length Arrays. If you compiled your code using -Wall -pedantic flags for g++, you will get the error that I am speaking of.
The way you can alleviate this is to use std::vector<int>.
#include <vector>
//..
int a, b, c;
//..assume a, b, and c have values
std::vector<int> array(a*b*c);
//... call the function
OMat3(a, b, c, array.data());
Using array[a][b][c]={} works as intended and initializes all of the values to 0
Thanks to #AndyG for finding out that.
So, I am trying to implement merge sort, which I conceptually understand but am obviously having great difficulty programming (I'm quite inexperienced). I have looked up previous posts which has helped, but I can't get past this point. I am currently having the following errors :
13:20: error: âSizeâ was not declared in this scope
mergesort(array[Size], low, mid);
41:20: error: invalid conversion from âintâ to âint*â [-fpermissive]
mergesort(data[size], 0, size-1);
6:6: error: initializing argument 1 of âvoid mergesort(int*, int,
int)â [-fpermissive] void mergesort(int array[], int low, int high)
I am also very confused on how to proceed in general. I really don't know how to merge everything back together either. This did not seem like it would be nearly this difficult, but recursion really confuses me :/ Thanks for your help in advance.
#include <iostream>
using namespace std;
void merge(int[], int, int, int);
void mergesort(int array[], int low, int high)
{
int mid;
if(low < high)
{
mid = low + (high-low)/2;
mergesort(array[Size], low, mid);
mergesort(array[Size], mid+1, high);
merge(array[Size], low, mid, high);
}
}
void merge(int array, int low, int mid, int high)
{
}
int main()
{
int size;
cin >> size;
int data[size];
for(int i = 0; i < size; i++)
{
cin >> data[i];
}
mergesort(data[size], 0, size-1);
}
data[Size] attempts to get the Sizeth value from the array data. Size doesn't exist, and I don't think this is what you want. If you want to refer to the array itself, just use it's name: data.
You have the same problem later on with data[size], except size does exist in this case. The error message is telling you that it can't convert an int to an int*. When you declare a function parameter like int array[], it is actually just syntactic sugar for int* array. You are passing data[size] to this parameter, which attempts to access an int from data (although size is outside the bounds). Hence, the compiler does not know how to convert an int to a int* - they're different types.
Note that the following code is not standard C++, because variable-length arrays are not supported:
int size;
cin >> size;
int data[size];
That is, the size of an array needs to be known at compile-time, which size is not. You could instead use std::vector<int> data(size);.
Also, your declaration and definition for merge don't match - one takes an int as its first parameter, while the other takes int[].
It seems you are having difficulties understanding static arrays vs dynamic arrays.
I would suggest using std::vector instead of your data[size] declaration .
Regarding your errors :
Note that inside your mergesort function you are referring to Size which isn't defined . If you want to go with static array, I would suggest the following :
#define SIZE 200
...
int data[SIZE];
This will allow you to use the same SIZE thorughout the code.
However your array won't be the size of your input .
If you want to allocate an array at runtime , you need to change your code from
int size;
cin >> size;
int data[size];
To
int size;
cin >> size;
int* data = new int[size];
Then , in your mergesort function, you will have to pass the size as parameter.
//function prototype at the top
void fillRandArray(int A[], int number, int maxNum);
//function declaration
void fillRandArray(int* A, int number, int maxNum) {
for(int i = 0; i < number; i++) {
A[i] = rand() % maxNum + 1;
}
}
int A[MAX_STUDENTS];
fillRandArray(A, number, 44);
I dont understand the code, so the prototype set int A[]
then the declaration set int* A
when we pass the argument, shouldn't we pass like this...
fillRandArray(A[MAX_STUDENTS], number, 44); <---- ???
The code below is passing the name of an array, which is an address.
void fillRandArray(int A[], int number, int maxNum);
The code below this is passing just the name of an address, which happens to be A in this case. They are basically doing the same thing.
void fillRandArray(int* A, int number, int maxNum)
You would not pass the argument like the following:
fillRandArray(A[MAX_STUDENTS],..., ...);
because you told the compiler to expect an address, not an element of the array. So you would just pass it A (i.e. the name of array, which is also the starting address). So it would look like this:
fillRandArray(A, number, 44);
Ask more questions, if I didn't explain it well enough.
The problem is that C-style arrays can't be passed as arguments
to a function. When you write int a[] as a parameter in
a function, the compiler translates it to int* a. In
addition, if you provide a dimension (e.g. int a[10]), it is
simply ignored.
Also, an array can convert to a pointer, and will do so in a lot
of contexts. This is what happens in fillRandArray(A, number,
44); the array A is implicitly converting to a pointer.
As for fillRandArray(a[MAX_STUDENTS], number, 44), this
indexes into the array for the first element; with your
declaration, it passes an int (not an array or a pointer),
except that it accesses one beyond the end of the array, so it's
undefined behavior.
In general, you want to avoid this (although with main, you
can't): the function should either take an std::vector<int>&
a, or in a few special cases, an int (&a)[N] (in which case,
the function should be a template, and N be a template
parameter). So you might write:
template <size_t N>
void fillRandArray( int (&a)[N], int maxNumber )
{
for ( int i = 0; i != N; ++ i ) {
a[i] = rand() % maxNum + 1;
}
}
(But for this sort of thing, std::vector is far preferrable.)