I'm an ICT student, studying C++, and I find it very interesting. However, while experimenting, I came up to something I can't fix myself nor find on the net.
This is the code:
#include <iostream>
using namespace std;
float average(float array[10], float &average){
int i = 0;
for( i = 0; i != 10; i++ ){
cout << "Vett ("<<i<<") = ";
cin >> array[i];
while(cin.fail())
{
cin.clear();
cin.ignore();
system("Color 5C");
cout << "\nPlease insert a number: ";
cin >> array[i];
}
average = average + array[i];
}
average = average / 10;
return array[10];
return average;
}
main(void){
float vett[10], media;
int i;
char loop;
vett[10] = 0;
media = 0;
do{
system("cls");
system("Color 00");
cout<<"****************************************"<<endl;
cout<<"*** INSER THE DATA TO COMPUTE ***"<<endl;
cout<<"****************************************\n"<<endl;
/* for( i = 0; i != 10; i++ ){
cout << "Vett ("<<i<<") = ";
cin >> vett[i];
while(cin.fail())
{
cin.clear();
cin.ignore();
system("Color 5C");
cout << "\nPlease insert a number: ";
cin >> vett[i];
}
media = media + vett[i];
}
media = media / 10;
*/
average(vett[10],media);
for( i = 0; i != 10; i++ ){
cout << vett[i]<<" ";
}
if(media == 0){
cout << "\nATTENTION the average equals to = "<<media<<endl;
}
else{
cout << "\nThe average is"<<media<<endl;
}
printf("\n");
cout << "\nDo You want to continue? Y/N";
cin >> loop;
}
while(loop == 'Y' || loop == 'y');
system("pause");
}
For some reason I couldn't set in the 'average' function the array as a pointer (&array), perhaps because the array is already a pointer. Nonetheless, removing it gives me the following error:
"Cannot convert 'float' to 'float*' for argument '1' to 'float average(float*,float&)'
If I call the function this way
average(&vett[10],media);
it works, but returns weird values in the array.
As you can see, I commented the same thing I put in the function, which works perfectly, unless..I put it in a function. I assume I've done something wrong with the function call, can anybody help me understand?
First of all, note that main(void){ is not a valid signature for main.
It should be:
int main(void){
Then:
float vett[10];
vett[10] = 0;
This is not valid. Array indices start at 0, so index 10 is out of bounds, as it would require an array with size 11.
Also, as your average function takes as first argument a float array, you'll need to pass it this way:
average(vett,media);
Using:
average(&vett[10],media);
Will pass a pointer to the data located right after the array, so obviously you'll get junk values.
Don't use func(void) in C++, it's some sort of deprecated. Use func() instead.
If you have float vett[10];, then vett[10] is invalid. You must use only vett[0 .. 9]
float average(float array[10], float &average) actually means float average(float *array, float &average). (Second form is more common way to declare pointer arguments.) If you want to call it with vett as argument, just use average(vett, media);Names of an arrays, when used as pointers, are automatically converted to pointer to first element of an array. So hereaverage(vett, media);vett means &vett[0].
The number in the square brackets has two meanings:
In a declaration like float vett[10]; it is the size of the array
When not in a declaration, like average(&vett[10],media); it means the eleventh element of the array.
average(&vett[10],media); is passing the address of the eleventh element to the function. The function interprets it as the beginning of the array, which is wrong and causes undefined behaviour when the elements outside of the array are accessed.
Because you want to pass the whole array, you should use
average(vett,media);
I'll add a little more to the help...
Your average method has two return statements at the end of it. The final one (the one you will be wanting) will never be reached, because the method will return on the first one...
In the function instead of this
float average(float array[10], float &average){
you have to put this :
float average(float *array, float &average){
Related
I'm writing two functions: one of them is for "filling" array with random values and int the second function I have to use the same array, choose one row and find the min element of that row.
But the problem is that I don't know how to pass values from one function to another.
Here is my code:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
void fillarray(int arr[5][5], int rows, int cols) {
cout << "Static Array elements = \n\n" << flush;
for(int i = 0; i < rows; ++i) {
cout << "Row " << i << " ";
for(int j = 0; j < cols; ++j) {
arr[i][j] = rand() % 10;
cout << arr[i][j] << " " << flush;
}
cout << endl;
}
cout << " \n\n";
}
void minarray(int a, void fillarray) { // don't know what to write here
there:
int min = INT_MAX; // Value of INT_MAX is 2147483648.
if(a > 4) {
cout << "Invalid input! " << endl;
goto there;
}
for(int counter = 0; counter < 5; ++counter) {
if(arr[a][counter] < min) min = arr[a][counter];
}
cout << "Minimum element is " << min << endl;
}
int main() {
int z;
srand(time(NULL));
const int rows = 5;
const int cols = 5;
int arr[rows][cols];
fillarray(arr, rows, cols);
cout << "Enter the number of row: ";
cin >> z;
minarray(z, fillarray)
system("PAUSE");
}
For starters the function fillarray has redundant parameter cols because this number is known from the declaration of the first parameter int arr[5][5].
Th function can be declared like
void fillarray(int arr[5][5], int rows )
You could supply the parameter cols in case when not the whole array is filled in the function.
You already filled the array by this call
fillarray ( arr, rows, cols );
The function performed its task. So there is no need to reference the function one more time as you are trying
minarray(z, fillarray)
The function minarray can be declared either like
void minarray( const int arr[], size_t n );
and called like
minarray( arr[z], cols );
with a preliminary check that z is less than 5.
Or it can be declared like
void minarray( const int arr[][5], size_t n, size_t row );
and called like
minarray( arr, rows, z );
Pay attention to that there is the standard algorithm std::min_element that allows to find minimum element in an array. And to fill an array with values you can use the standard algorithm std::generate.
And each function should do only one task. For example the function fillarray should silently fill the array with values. To output the array you could write a separate function.
I'm not sure this even compiles, but i'm guessing you want to pass int arr[x][y] from the fill Array function to the minArray function. To do that you first need to include arr as a parameter of minArray. From there you need to pass it by reference. Then, you can call minArray from fillArray.
What you need to do is call fillarray to fill your array. So it would look like
fillarray(arr, rows, cols);
Just like you have so far. Now, you have array arr all filled in. minarray doesn't care how that happened. So don't pass it your filler method. Pass it the array.
minarray(cols, arr[z]);
You don't need to pass the entire array -- just the row in question. You're also passing the width.
And change the definition of minarray:
void minarray(int length, int[] array)
Now, your minarray itself needs changes. First, get rid of the if-check. You don't need to pass a row number now, but you do need the number of columns passed as length.
Then your for loop looks like:
for (int index = 0; index < length; ++index) {
if (array[index] < min) {
min = array[index];
}
}
So, to summarize:
Main declares the data and calls your two methods.
fillarray populates the array. It is called from main the way you already have.
minarray prints the minimum on a single line. It is also called from main, passing in the array, not the method that filled it.
You have one more issue, however. fillarray hardcodes the array size as 5x5, but main uses constants defined. I'd move those contents to the top of the file and use them in both places.
Move to the top, below any #includes:
const int rows = 5;
const int cols = 5;
Define fillarray:
void fillarray(int arr[rows][cols]) {
And when you call it from main:
fillarray(arr);
I'll let the other answers answer your question and concentrate on the code around your goto that you asked about in the comments.
In main you have this:
cout << "Enter the number of row: ";
cin >> z;
minarray(z, fillarray)
In minarray you have this:
void minarray(int a, void fillarray) { // don't know what to write here
there:
int min = INT_MAX; // Value of INT_MAX is 2147483648.
if(a > 4) {
cout << "Invalid input! " << endl;
goto there;
}
First, there's absolutely no reason to use goto. You could do this:
void minarray(int a, void fillarray) { // don't know what to write here
int min = INT_MAX; // Value of INT_MAX is 2147483648.
while(a > 4) { // loop for as long as "a > 4"
cout << "Invalid input! " << endl;
}
Removing the goto made the bug rather apparent. a will never change inside the loop, so it'll just print Invalid input! forever if you give it invalid input. An alternative would be to validate the input when you actually get the input from the user (in main):
while(true) { // loop forever
cout << "Enter the number of row: ";
if(cin >> z) { // check that the user inputs an int
if(z<0 || z>4) // validate the input
cout << "Invalid input!\n";
else
break; // we got valid input, break out of the while loop
} else { // user did not input an int
std::cout << "input failed - aborting\n";
return 1; // return from main to exit the program
}
} // if the program reaches this point, it'll ask the user for input again
// and that will only happen if the user gives it an int that is <0 or >4
This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
The goal of this code is to pass an array through a function (which I'm already having a difficult time understanding). I went through with a pen and paper and traced the code and I think I just don't know enough to understand what's going wrong. All the test scores I throw in just push back a ridiculously large negative number. I'm not asking for you guys to do my homework because I really want to try and understand what I'm doing, but any help would really be appreciated right now.
#include <iostream>
//function prototype
double average(int studentScores[], int size);
double studentScores[4];
bool runAgain(void);
int main() {
do {
int studentScores[4], size = 4, result;
string score;
cout << "This program will calculate the average of four diffrent exam scores." << endl;
for (int i = 0; i < size; i++) {
studentScores[i] = 0;
cout << "Please Enter Exam Score " << i + 1 << ": ";
getline(cin, score);
}
for (int i = 0; i < size; i++) {
result = (studentScores[1] + studentScores[2] + studentScores[3] + studentScores[4]) / size;
studentScores[i]++;
}
cout << "The Average Exam score is " << result << endl;
} while (runAgain());
system("pause");
return 0;
}
//function implementation
double average(int studentScores[], int size) {
for (int i = 0; i < size; i++) {
return (studentScores[i]++ / size);
}
}
bool runAgain(void) {
char userResponse;
cout << "\nWould you like to run again (y or n): ";
cin >> userResponse;
if (userResponse == 'y' || userResponse == 'Y')
return(true);
return(false);
}
First obvious bug:
int studentScores[4]
studentScores has 4 elements, numbered studentScores[0] through studentScores[3].
But your code accesses studentScores[4] in
result = (... + studentScores[4]) / ...
which doesn't exist (and doesn't access studentScores[0], which does).
Glad to try to help ya out without giving you the answer.
I'm gonna sprinkle some questions throughout your code that you should be asking yourself in future programs whenever you get unexpected output.
#include <iostream>
//function prototype
double average(int studentScores[], int size);
double studentScores[4];
bool runAgain(void);
int main() {
do {
int studentScores[4], size = 4, result;
string score;
/* Above, you declared a string to store the user's input in.
In C++, the string "4" DOES NOT equal the integer 4.
How will you handle the fact that the variable 'score' is of type
string, but you want to work with integers?
Is there an easy way to get rid of this issue? (hint: use cin)
*/
cout << "This program will calculate the average of four diffrent exam scores." << endl;
/* In the below for-loop, think about what the value of 'score' will be
after each iteration. (Hint, getline replaces the existing value of score).
Also, where is the code that saves the user's inputted numbers to an array?
Learn how to write values to an array http://www.cplusplus.com/doc/tutorial/arrays/
*/
for (int i = 0; i < size; i++) {
studentScores[i] = 0;
cout << "Please Enter Exam Score " << i + 1 << ": ";
getline(cin, score);
}
/* In the for-loop below, you already noticed that your array has random
values in it. The comment about the above for-loop should address that issue.
Equally important though is understanding what the heck is happening in this
loop below. After you fix the bug in the for-loop above (which will
get the values in the array to equal the user's inputs), you'll be faced
with issues in this loop below.
My advice is to understand what happens when the program
executes "studentScores[i]++". First, it gets the number in the array at
the ith+1 position, then it increments that number by 1. Cool, but what
are you doing with the result of that? It's not being put to use anywhere.
Also, note that because the array is never being updated,
the line above it just calculates the same number and stores it in 'result'
every iteration of the loop.
*/
for (int i = 0; i < size; i++) {
result = (studentScores[1] + studentScores[2] + studentScores[3] + studentScores[4]) / size;
studentScores[i]++;
}
cout << "The Average Exam score is " << result << endl;
} while (runAgain());
system("pause");
return 0;
}
// this function doesn't seem to be used, but understanding what
// is wrong with it will help you understand how to code.
// First, note that once a function hits 'return', it will
// never execute any more code in that function.
// So here, your return statement in the for-loop will prevent an
// actual loop from occuring (since the function will exit as soon as the first loop iteration is entered)
// Second, note that you are just getting the value in the array and adding 1 to it
// before dividing it by 'size', which is not the formula for an average.
double average(int studentScores[], int size) {
for (int i = 0; i < size; i++) {
return (studentScores[i]++ / size);
}
}
bool runAgain(void) {
char userResponse;
cout << "\nWould you like to run again (y or n): ";
cin >> userResponse;
if (userResponse == 'y' || userResponse == 'Y')
return(true);
return(false);
}
I hope these comments helped :) Keep at it!
Don't forget that arrays start at index 0. Trying to access studentScores[4]
will give you an unexpected number.
#include <iostream>
using namespace std;
// prototype functions
void DisplayResult(float MaxOrMin);
float FindMinimum(float Array[5]);
float FindMaximum(float Array[5]);
//Global Variables
float Array[5];
float MaxOrMin = 3;
float FindMin;
float FindMax;
//Main Function
int main()
{
cout << "Please enter 5 numbers: " << endl;
for (int i=0; i<5; i++)
{
cin >> Array[i]; // input for array
}
cout << "Please enter '0' for minimum or '9' for maximum:" << endl;
cin >> MaxOrMin; // input 0 or 9 for min or max
//Calling Functions
FindMinimum(Array);
FindMaximum(Array);
DisplayResult(MaxOrMin);
return 0;
}
//Function to find Minimum
float FindMinimum(float Array[5])
{
float FindMin = Array[0];
for (int y=1;y<5;y++)
{
if(Array[y] < FindMin)
FindMin = Array[y];
}
return FindMin;
}
//Function to find Maximum
float FindMaximum(float Array[5])
{
float FindMax = Array[0];
for (int x=1;x<5;x++)
{
if(Array[x] > FindMax)
FindMax = Array[x];
}
return FindMax;
}
This last part is my if, else if, else funtion:
//Function to display minimum or maximum result
void DisplayResult(float MaxOrMin)
{
if (MaxOrMin == 0)
cout << "Minimum is: " << FindMin << endl;
else if (MaxOrMin == 9)
cout << "Maximum is: " << FindMax << endl;
else
cout << "Invalid Input" << endl;
}
My project is to create a program using functions to take user input on a 5 float array. Then find the max and min and display whichever the user asks for.
Here is where my problem comes in. For both max(input 9) and min(input 0) I am getting "0". However any other input correctly returns my "Invalid Input" message.
I'm not getting any errors or warnings or errors at all on eclipse. My professor has told me that my problem was likely with my void function for displaying results. I am hoping someone could point me in the right direction here.
Apologies for my formatting and/or if this question is too basic for this site.
You misunderstand how local and global variables work. Your Find* functions shadow the globals with locals and thus they don't appear to do anything.
The problem is that your FindMinimum() (and the same with FindMaximum()) function compute the minimum (maximum) in a local variable and return it but you, in main() don't receive they in correct variables
So the computed value is lost.
I mean... instead of
FindMinimum(Array);
FindMaximum(Array);
you should write
FindMin = FindMinimum(Array);
FindMax = FindMaximum(Array);
I am currently trying to fill a double array with a while loop with a terminating condition (entered>0). The array is getting filled and the loop appears to be working however when a -1 is entered the program does not seem to exit the loop. I've been trying to debug this with cout statements for hours and I really appreciate any help.
double calc(double a[],double dev[], int n,double *mean);
void letter(double a[],char letg[],double std,double *mean);
int main(void)
{double a[6],dev[6],mean, std;
int i,n;
int entered;
char letg[6];
cout<<"Please enter the test grades one at a time (max 6)\n";
cout<<"enter a -1 when you are done entering scores\n";
//based off class notes
i=0;
cin>>entered;
while (entered>0 && i<=6)
{a[i]=entered;
i++;
cin>>entered;
}
i=n
cout<<"out of loop";
std=calc(a,dev,n,&mean);
letter(a,letg,std,&mean);
cout<<"the corresponding scores and letter grades are:\n";
cout<<a;
cout<<letg;
return 0;
}
double calc(double a[],double dev[],int n,double *mean)
{int c,i;
cout<<"in calc";
double sum,sqdif,std;
c=0;
sum=0;
while (c<=n)
{sum=sum+a[c];
c++;
}
*mean=sum/(n+1);
for (i=0;i<=n;i++)
dev[n]=pow((a[n]-*mean),2);
for(i=0;i<=n;i++)
sqdif=dev[i]+sqdif;
std=sqrt(sqdif/c);
return std;
}
Problem could be negative numbers (sizing problem). try another positive number for exit e.g. 99
also try the same code with an exit controlled loop i.e. do..while
What is the input sequence you have given. Its getting out of the loop when I tried
After you'll have solved the problem with i<6 (instead of i<=6 which causes the segfault as Borgleader pointed out 1), correct this one:
double entered; // should be double and not int
With entered declared at int int, if you enter a floating point number, for example 0.5, it will stop reading at the dot (because dot is not valid for an integer), and never be able to read all the other numbers that you'll type.
Suggestion: It could be a good practice to check for valid input, for example by replacing the cin>entered; with:
// cin>>entered; => if wrong input, you'll not do anything about it
while (!(cin >> test) && cin.fail() && ! cin.eof()) { // check if input failed, and for another reason that an eof.
cout << "Wrong input. Enter again ! ";
cin.clear(); // reset error flag
cin.ignore(SIZE_MAX, '\n'); // discard faulty input
}
Perhaps move away from arrays and instead use a vector:
int main(void)
{
std::vector<double> scoreList;
double score;
// Intro msg
std::cout << "Please enter the test grades one at a time (max 6)" << std::endl;
std::cout << "enter a -1 when you are done entering scores" << std::endl;
// Loop for up to 6 scores, exit loop when 6 entered.
while (scoreList.size() < 6)
{
std::cin >> score;
// Exit loop if -1 entered
if (score == -1.0)
break;
scoreList.push_back(score);
}
// Access scores and display
for (std::vector<double>::iterator v = scoreList.begin(); v != scoreList.end(); v++)
std::cout << "Score entered: " << *v << std::endl;
return 0;
}
The result is no buffer overrun and all that is needed is to iterate through the list of entered numbers.
You have to initialize variables before assigning them.
i=n //n = ?
and
sqdif=dev[i]+sqdif; //sqdif = ?
Consider this example about Uninitialized variables error -
int main() {
int i;
return i; // C4700
}
I'm trying to write a program that simulates darts being thrown at a standard curve. Whenever I get close to debugging the entire thing something else pops up. So far I am getting a lot of errors like:
Error: variable is not declared in this scope
Also there's an error I have no idea how to fix which has to do with C++ comparing pointers and integers
I'm pretty new to C++ so any pointers would be greatly appreciated.
Here's what I got so far.
note: errors are on lines 67, 70, 72, and 75.
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
double seed(int darts, int x);
int main ()
{
int darts, x_max;
double area;
char again = 'y';
char giveDarts;
while (again == 'y' || again == 'Y');
cout << "Run program (y/n)?";
cin >> giveDarts;
switch (giveDarts) {
case 'y':
case 'Y':
cout << "Enter the ammount of darts to be thrown: "; //since we are simulating DARTS I will use the varible darts instead of "NumberOfSamples"
cin >> darts;
srand(darts);
default:
break;
}
cout << "Enter maximum value of x: ";
cin >> x_max;
while (x_max < 0);
cout << "Please enter a positive value of x: ";
cin >> x_max;
cout << endl;
srand(time(NULL));
area = seed(darts, x_max);
cout << "Estimate of area under curve is: " << area << endl;
cout << "Go again? ";
cin >> again;
return 0;
}
double seed(int darts, int x_max)
{
int i, num_darts=0; //num_darts instead of SamplesInsideArea.
double area;
for(i=1; i<=darts; i++) // for loop
{
double x, y;
double pi = 3.14;
double n (double t);
return 1/sqrt(2*pi)*exp(-pow(t,2)/2); //error:'t' was not declared in this scope
x = rand() / static_cast<double>(RAND_MAX);
y = rand() / static_cast<double>(RAND_MAX);
n(0) = (x*x_max + y*y_max); //error: y_max was not declared in this scope
if(num_darts <= n) //error: ISO C++ forbids comparison between pointer and integer
num_darts++;
area*n(0)+0.5 = static_cast<double>(num_darts)/darts; //error: invalid Ivalue in assignment.
}
return area;
}
This line:
double n (double t);
is prototyping a function n that takes one parameter double t. This is causing two of the errors:
error: 't' was not declared in this scope (because function prototypes don't declare variables)
error: ISO C++ forbids comparison between pointer and integer (because n is a pointer to a function)
Did you mean this to be a function prototype? If not, what did you mean?
The error error: y_max was not declared in this scope is straight-forward. y_max isn't declared anywhere.
This line:
area*n(0)+0.5 = static_cast<double>(num_darts)/darts; //error: invalid Ivalue in assignment.
The error error: invalid Ivalue in assignment is because you can't assign a value to an expression. What did you intend to do here?
Additionally, there are some other problems:
This line:
while (again == 'y' || again == 'Y');
will cause your program to go into an infinite loop, since you set again = 'y' just before it, and the semicolon tells the compiler this:
while (again == 'y' || again == 'Y')
{
// do nothing
}
To fix this, remove the semicolon and put braces around the code that needs to be inside the while loop. The same issue exists later too (while (x_max < 0);).
Someone else pointed out this one:
return 1/sqrt(2*pi)*exp(-pow(t,2)/2);
which occurs in the middle of the function. This will cause that function to finish immediately and return the calculated value. Is this what you intended? The code after this line will never run.
More problems:
This code doesn't handle the N/n case. The program will not stop when you type 'n', and will probably crash.
switch (giveDarts) {
case 'y':
case 'Y':
cout << "Enter the ammount of darts to be thrown: "; //since we are simulating DARTS I will use the varible darts instead of "NumberOfSamples"
cin >> darts;
srand(darts);
default:
break;
}
cout << "Enter maximum value of x: ";
Use braces to control loops, not whitespace. Instead of this:
while (x_max < 0);
cout << "Please enter a positive value of x: ";
cin >> x_max;
cout << endl;
You want this:
while (x_max < 0)
{
cout << "Please enter a positive value of x: ";
cin >> x_max;
cout << endl;
}
This line:
area*n(0)+0.5 = static_cast<double>(num_darts)/darts;
If you're trying to set area, this needs to be in the form:
area = static_cast<double>(num_darts)/darts; // n(0)+0.5 goes where??
When you are first learning to program C++, I suggest that you declare and define all of your functions at the global level. This means that lines like double n (double t); should never appear inside any braces. So to fix part of the problem with your code, move these two lines of code:
double n (double t);
return 1/sqrt(2*pi)*exp(-pow(t,2)/2);
outside of the seed() function and make a few minor modifications so it looks like this:
double n (double t) {
return 1/sqrt(2*pi)*exp(-pow(t,2)/2)
}
This should help you in the right direction. (Just be sure that pi is declared either as a global constant.)