Sign in to follow this  

help with arrays?!?

This topic is 4355 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hello, I am trying to recode this small program that I made in java to c++ so I can have a .exe file. I have never taken c++ class, so I need help with the errors that i am getting. Most of my errors occur when i try to declare 2D array. what am i doing wrong here? GradeCalculator.cpp
#include<iostream>
using namespace std;

int main()
{
	cout <<"This program computes your percentage out of a 100 for weighted grades"<< endl;
	cout <<"----------------------------------------------------------------------"<< endl;
	cout <<"\nHow many sections of 100%: ";
	int rows;
	cin >> rows;
	double [][] list = new double[rows][3];

	int i = 0;
	int sec= 1;
	while (i < rows)
	{
		cout << "\nValues for Section " << sec << endl;
		cout << "What is this section's weight out of 100%: " << endl;
		cin >> list[i][0];
		cout << "What is your actual points: ";
		cin >> list[i][1];
		cout << "What are the total points possible: ";
		cin >> list[i][2];

		sec++;
		i++;
	}

	double [] toSum = new double[rows];
	for(int r = 0;r<rows; r++)
	{
		double weight;
		double actual;
		double outOf;
		weight = list[r][0];
		actual = list[r][1];
		outOf  = list[r][2];
		toSum[r] = ((actual/outOf)*weight);
	}
	double total=0.0;
	
	for (int s=0; s < rows; s++)
	{
		total = total + toSum[s];
	}

	cout << total;
	system ("pause");
	return 0;

}//end main


thanks

Share this post


Link to post
Share on other sites
In C++ arrays are declared as type name[element count]. So change from

Java: double [][] list = new double[x][y];

to

C++: double list[x][y];

Hope that helps ;)

EDIT: In addition, I'd recommend you look at using std::vector, which behaves almost exactly like Java's vector container. It is essentially a dynamic array, and is much nicer to use (and supports a lot of neato features, like sorting and element finding and iterating and coffee-making :D)

Share this post


Link to post
Share on other sites
I made the necessary changes to make it compile:


#include<iostream>
using namespace std;

int main()
{
cout <<"This program computes your percentage out of a 100 for weighted grades"<< endl;
cout <<"----------------------------------------------------------------------"<< endl;
cout <<"\nHow many sections of 100%: ";
int rows;
cin >> rows;
double* list = new double[rows * 3];

int i = 0;
int sec= 1;
while (i < rows)
{
cout << "\nValues for Section " << sec << endl;
cout << "What is this section's weight out of 100%: " << endl;
cin >> list[i * rows + 0];
cout << "What is your actual points: ";
cin >> list[i * rows + 1];
cout << "What are the total points possible: ";
cin >> list[i * rows + 2];

sec++;
i++;
}

double* toSum = new double[rows];
for(int r = 0;r<rows; r++)
{
double weight;
double actual;
double outOf;
weight = list[r * rows + 0];
actual = list[r * rows + 1];
outOf = list[r * rows + 2];
toSum[r] = ((actual/outOf)*weight);
}
double total=0.0;

for (int s=0; s < rows; s++)
{
total = total + toSum[s];
}

cout << total;
system ("pause");

delete [] toSum;
delete [] list;

return 0;

}//end main







As you can see I am using a 1-dimetional array rather than 2-dimentional.
It is possible to make a 2-dimentional dynamic array (as you are trying to do),but you will have to do it either using malloc (or something similar), or by creating each row in turn (typically using a loop)

double **array = new double*[nrows];
for(int i=0; i<nrows; i++)
array[i] = new double[3];

...

for(int i=0; i<nrows; i++)
delete array[i]; // dont forget to release the memory when you are done with it
delete [] array;


I dont dare to try to explain why you cant create the 2-dimentional array in a one liner. It gets technical. Maybe someone else can explain this better than me.

[Edited by - pulpfist on January 10, 2006 12:49:13 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by pulpfist
It is possible to make a 2-dimentional dynamic array (as you are trying to do),but you will have to do it either using malloc (or something similar), or by creating each row in turn


You could also take a look at boost::multi_array.

If you want to stick with standard C++ (and the array is one dimensional), in most cases I would recommend using std::vector over a C style array. There's a tutorial here.

While it's also possible to create a multidimensional vector (for example, std::vector<std::vector<int> > ), you'll probably be happier with the boost solution for multi arrays.

Share this post


Link to post
Share on other sites
Arrays in C++ are handled a *lot* differently.

In Java, arrays are objects (or at least, have *most* of the properties of proper objects). So a 2-dimensional array is an array of array objects, each of which in turn is an array of whatever normal things. The Java array objects "know" (remember) their length, and since each array is self-contained, a 2-dimensional array does not have to be rectangular: you could make an array of five arrays, and each of the one-dimensional arrays could be a different length.

In C++, arrays are just chunks of memory that correspond to a sequence of elements. They don't know their length, and the array name used by itself just makes a pointer to the beginning of that chunk. Also, while you could make an array of arrays manually (by making an array of pointers, and having each pointer point to an array somewhere else), by default a 2-dimensional array is rectangular - if you write float foo[5][5], or float foo[][5], then "foo" is a pointer to float, NOT a pointer to pointer to float (like it basically would be in Java, notwithstanding that you normally don't think in terms of pointers when you write Java code because the language does that part for you).

This rectangularity can be quite useful, if you know how to make use of it. It avoids adding extra pointers and so forth under the hood - which is not a big deal in Java, but is a huge deal in C++ because you have to do the memory management yourself.

C++ objects are handled differently as well. In Java, all object variables actually hold handles (basically pointers, but it can be more complicated) to some chunk of memory where the actual data is held (this is why you can alias objects with '=' rather than copying them, and why you sometimes need .equals() methods instead of using '=='). In C++, you get that behaviour by asking for a variable of some pointer type (e.g. "float*"), and then pointing it at a "new" memory allocation (which must then later be "delete"d exactly once at run-time - the above-mentioned memory management). This is tricky and often not useful, so instead you normally try to declare local, non-pointer variables as often as possible. That is to say, objects that are "on the stack", and cease to exist at the end of the current scope.

There's one extra complication there: C++ arrays are on the stack as well. The variable name is usable as a pointer, but it *points into the stack*.

Anyway. Enough theory. Practically, you have two options:

1) Use std::vector, a container in the C++ standard library (#include <vector> to get at it). The philosophy behind it is similar to that of the container objects in the Java standard library, and std::vector is most similar to java.util.Vector.

std::vector knows its size, like a Java array or vector. It can also be resized, and will over-allocate a local memory pool, like java.util.Vector. It does *not* however allow for holding different sorts of objects (for polymorphism) unless you do it explicitly (by holding a vector of pointers and doing the appropriate memory management); it holds a specific type of thing (so it is more like the plain Java array in that respect).

2) Make a typedef or struct to represent the array "rows", and then make a dynamically allocated array of rows. pulpfist illustrated allocating the array as a single chunk and then doing the math to simulate the array dimensions. That works too, but is not quite as clean.


#include <iostream>
using namespace std;

// First, our 'row'. I will make it as a struct, just to show how you can
// do this sort of thing in C++ (including operator overloads).

struct Row {
double data[3];
double& operator[] (int index) { return data[index]; }
const double& operator[] (int index) const { return data[index]; }
};

// Now when we make a dynamic array of Rows (we allocate it dynamically with
// a pointer so that we can control its size, a la Java), we can use a
// subscript on the array to refer to a Row object, and then subscript that
// to get an element.

int main() {
cout << "This program computes your percentage out of a 100 for weighted grades"<< endl;
cout << "----------------------------------------------------------------------" << endl;
cout <<"\nHow many sections of 100%: " << flush;
// You should "flush" output streams to make sure that the data appears -
// otherwise it can stick around in an internal buffer. "endl" is really
// a combination of a \n and a flush.
int rows;
cin >> rows;
Row* list = new Row[rows];
// Use for loops instead of while loops where it makes sense.
// You'd do the same in Java, right?
// Also, don't create an update a "sec" separately. Instead, make
// use of the mathematical relationship:
for (int i = 0; i < rows; ++i) {
cout << "\nValues for Section " << (i + 1) << endl;
// parentheses should not be necessary; just there for clarity
cout << "What is this section's weight out of 100%: " << endl;
cin >> list[i][0];
cout << "What is your actual points: ";
cin >> list[i][1];
cout << "What are the total points possible: ";
cin >> list[i][2];
}
double* sums = new double[rows]; // what kind of name is "toSum"? That's
// a function name, if anything, not a variable name.
for(int r = 0; r < rows; r++) {
// You should (in Java too!) initialize variables with their first value
// when you know where it will come from.
double weight = list[r][0];
double actual = list[r][1];
double outOf = list[r][2];
sums[r] = ((actual/outOf)*weight);
}
double total=0.0;
for (int s=0; s < rows; s++) {
total += toSum[s]; // Again, something valid in Java.
// Try not to repeat stuff. Which sounds more natural?
// "this is now this plus that"
// "increase this by that"
}
cout << total << endl;
system ("pause"); // I don't advise using this, btw
delete [] toSum;
delete [] list;
// You don't need to return 0 from main; as a special case, the return
// at the end of main() is implicit in C++ (yes, standard-guaranteed).
}






BUT. That's all just so that you learn how to do this stuff. There really isn't a reason to bother with the arrays at all:


#include <iostream>
using namespace std;

int main() {
cout << "This program computes your percentage out of a 100 for weighted grades"<< endl;
cout << "----------------------------------------------------------------------" << endl;
cout <<"\nHow many sections of 100%: " << flush;
double total;
int rows;
cin >> rows;

for (int i = 0; i < rows; ++i) {
cout << "\nValues for Section " << (i + 1) << endl;
// get the values
double weight, actual, outOf;
cout << "What is this section's weight out of 100%: " << endl;
cin >> weight;
cout << "What is your actual points: ";
cin >> actual;
cout << "What are the total points possible: ";
cin >> outOf;

// Determine the amount of marks awarded for this section, and
// increment the total by that much
total += ((actual/outOf)*weight);
}
cout << total << endl;
}


See how much shorter, too. Don't complicate things :)

Share this post


Link to post
Share on other sites

This topic is 4355 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this