C++ Storing Array in Separate File - c++

I am working on a c++ program in which I have to pass an array to multiple sorting functions and compare the running times of the functions. For example, I have an array with 100 elements containing random numbers from 1 to 10. I have a bubble sort, merge sort, and quick sort function, and I have to pass the array to each function. However when I pass the array, the first sorting function changes the original array so that when it is passed to the next function it is already sorted. This is expected, but I was wondering how I would store this array in a separate file, perhaps a header file, to keep the original array unsorted for each function call.
Here is a layout of my code:
#include <iostream>
using namespace std;
//void bubblesort, mergesort, quicksort function prototypes
int main()
{
int a[100];
for (int i = 0; i < 100; i++)
a[i] = rand() % 10 + 1;
bubblesort(a);
mergesort(a);
quicksort(a);
return 0;
}
//void bubblesort, mergesort, quicksort function definitions
This code is obviously just a layout and the sorting functions aren't relevant for this question other than the fact that a call to a sorting function changes the original array. Thanks for your help.

You do not need files for this. Even though usual file systems on operating systems these days are rather nicely mapped to memory (in many cases this will be their cache) with delayed swapping to disk, interacting with the file system may make your code much more inefficient since you are writing to the disk.
Since you tagged this question with C++ I will answer this question the C++ way (or at least the C++ standard library way). What you want is to make a copy of the array when you pass it to the functions. At the moment you are passing in the raw address of the array so you are not making any copies (only possibly a copy of the pointer). This process is made easy if you use vectors. So the program could be
#include <iostream>
#include <vector>
using namespace std;
// The declarations would just need to change to this, I am assuming
// they print to stdout
void bubblesort(vector<int> vec);
void mergesort(vector<int> vec);
void quicksort(vector<int> vec);
int main()
{
vector<int> a;
for (int i = 0; i < 100; i++)
a.push_back(rand() % 10 + 1);
bubblesort(a);
mergesort(a);
quicksort(a);
return 0;
}
Here the vectors will be passed in by value so the vector that the function accesses is a copy of the original. The thing with vectors is that they are much more flexible and should usually be preferred over arrays in most high level programming scenarios.
If however your application demanded a use of low level arrays you could use memcpy to achieve this copying effect.
#include <iostream>
#include <vector>
using namespace std;
//void bubblesort, mergesort, quicksort function prototypes
int main()
{
int a[100];
for (int i = 0; i < 100; i++)
a[i] = rand() % 10 + 1);
int for_bubble_sort[100];
memcpy(for_bubble_sort, a, 100);
bubblesort(for_bubble_sort);
int for_merge_sort[100];
memcpy(for_merge_sort, a, 100);
mergesort(for_merge_sort);
int for_quick_sort[100];
memcpy(for_quick_sort, a, 100);
quicksort(for_quick_sort);
return 0;
}

Well, you should make an another array. Copy the contents of original array to this one using memcpy() or use a loop.

You can declare your array as const so it preserves it initial value and the functions don't change it.

Related

Why does my array say write access violation partially through?

Updated to be copy/pasted and run. My bad.
I know I'm probably going to get the whole "this question was asked already" but I spent sometime looking and couldn't find a matching problem. It's very possible I just don't know enough to look in the right place.
When I call InitSortedArray() it runs through a seemingly random number of elements before throwing exception: write access violation. Everytime I run it it stops at a different element number. Any ideas?
#include <array>
#include <iostream>
using namespace std;
int * toSort;
const int SIZE = 100000;
void InitSortedArray()
{
srand(0);
toSort[0] = rand() % 5;
cout << toSort[0];
for (int i = 1; i < SIZE - 1; i++)
{
srand(0);
toSort[i] = toSort[i - 1] + rand() % 5;
cout << toSort[i] << endl;
}
}
void Search()
{
toSort[SIZE];
InitSortedArray();
}
int main()
{
Search();
}
int * toSort;
allocates a pointer to some data yet to be assigned to it. No data is ever assigned. You could
int * toSort = new int[100000];
but that picks up some memory management work you don't need. Any time you use new[] sooner or later you must delete[]. Instead use
const int SIZE = 100000; // place first so we can use it below
int toSort[SIZE];
or the more modern
const int SIZE = 100000; // place first so we can use it below
std::array<int, SIZE> toSort;
to declare an array.
toSort[100000];
in Search does nothing helpful (and is in fact harmful as it invokes Undefined Behaviour by accessing outside the bounds of toSort) and should be removed.
Extra stuff:
srand reseeds and restarts the random number generator. It is only in truly rare circumstances that you want to call it more than once, and in those cases there are many better options than srand and rand.
Place a single call to srand at the top of main and make absolutely certain you want srand(0) as this will always generate the exact same numbers on a given computer. It's great for testing, but not so good if you want a different sequence every time. Typical use is srand(time(NULL)) to seed the generator based on the ever-changing flow of time. That's still not all that good, but good enough for most cases where rand is in use.
It looks like you're using an uninitialized pointer that points to random space, and trying to store elements and access elements in it. Also, your inclusion of "array" doesn't make any sense here. I believe what you want to do here is initialize your toSort array to actually point to a section of memory that you intend to point it to:
int toSort[SIZE];
instead of
int * toSort;
If you're looking to use the STL array (which is likely highly recommendable) then you need to explicitly use it:
std::array<int, SIZE> toSort;
The nice thing about using the STL is it takes care of a lot of the memory access issues you can run into like memory access violation. Another helpful thing from the STL would be vector:
#include <vector>
std::vector<int> toSort;
then later: (this adds an item to the back of the vector)
toSort.push_back(<some number>);
and to access:
int somethingElse = toSort[<index number>];
Arrays: http://en.cppreference.com/w/cpp/container/array
Vectors: http://en.cppreference.com/w/cpp/container/vector

Using arrays and structures within functions in c++

I am trying to create a program that randomly generates the position of "ships". I'd like a structure to keep track of multiple aspects of the ships including their positions and an array to keep track of multiple ships.
The error I'm getting seems to be occurring in the first for loop within "main" at the line fleet[i] = ship_position (fleet[i], i); The error reads:
error: cannot convert 'ship_stats' to 'ship_stats*' for argument '1' to 'ship_stats ship_position(ship_stats*, int)'
Also, previously, I did not think the second "i" within the brackets of that line was necessary, but when I tried compiling without it the error I received was:
error: expected primary-expression before ']' token
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std;
int rand_range (int low, int high) {
return rand() % (high - low + 1) + low;
}
struct ship_stats {
int x_coordinate;
int y_coordinate;
int weapon_power;
};
ship_stats fleet[5]; // Create fleet of 5 ships linked to the structure
ship_stats ship_position (ship_stats fleet[], int ship_num) {
//Randomly generate a starting position for each ship
int low_x = 0; //Set max and min ranges for ship position
int high_x = 1024;
int low_y = 0;
int high_y = 768;
fleet[ship_num].x_coordinate = rand_range (low_x, high_x);
fleet[ship_num].y_coordinate = rand_range (low_y, high_y);
return fleet[ship_num];
}
int main () {
int num_ships = 5;
for (int i = 0; i < num_ships; i++)
fleet[i] = ship_position (fleet[i], i); // <-- error is here
}
The mechanical point you have been given is that if you want to pass "raw" arrays as parameters in C++ (or C), you can't say fleet[]. That will not compile, as you noted. But don't just put a random index value in the brackets--that gets you an array element, not the array itself.
It's a somewhat gross oversimplification to say you pass the "whole raw array" just by saying fleet. You're really passing the address of the first element, e.g. fleet ends up being equivalent to &fleet[0]. Crude though that is, it comes from C's heritage...and it means that if the function you're calling knows the size of the "raw" array, then that address can be meaningfully used as a means of accessing any subsequent value in it.
But in "idiomatic" C++, one rarely wants to use a "raw" C-style array. The std::vector solves several weak points of raw arrays, and is a good choice for beginners.
You can choose to pass vectors "by value" (which makes a copy) or "by reference" (which is a bit like passing by pointer, the only choice for a raw array). Vectors don't have to know their size in advance, and their size can change over the course of your program. Not only that, the size comes along with the vector when it's passed as a parameter. And very importantly, vectors speak an abstract "collection protocol", which means they're usable with #include <algorithm>.
But there are several other points. You have made a ship_position() function that "constructs" a ship. This oddly shaped function returns a value (the instance of a constructed ship), yet also mutates your "fleet" so that the ship is in that position. Why would you need to return the value and assign it to the location in the fleet...if that mutation of the fleet was already part of the function?
And in C++, the best mechanism for "constructing" something is...a constructor. ship_position() is what we would call a "free function"--it doesn't live within ship_stat's definition, yet it seems to have an eerie knowledge of how to manipulate ships.
(Supporting Note: Where does weapon_power fit into all this? Whose job is it to initialize it, or not? This is where a single point of responsibility of a "constructor" comes into place, to say that a constructed ship has all its fields covered.)
If this is to be a proper C++ program, you shouldn't think of ship_stats as a struct that is operated on by "free functions". Instead, you need to think of Ship as a class with some data, and some code. The randomization of a ship should be inside your class... the act of putting a random ship into a collection should be using push_back into a vector (or emplace_back, but that's very much skipping ahead).
Try not to use raw C arrays in C++ programs unless you really know what you're doing. (Or don't use C++ features and instead tag your question C, the answers will be very different.)
Like already stated in the comments you are trying to pass one ship_stats to function thats waiting for an array of them , so for the function to work it should look like this
ship_stats ship_position (ship_stats fleet, int ship_num) {
//Randomly generate a starting position for each ship
int low_x = 0; //Set max and min ranges for ship position
int high_x = 1024;
int low_y = 0;
int high_y = 768;
fleet.x_coordinate = rand_range (low_x, high_x);
fleet.y_coordinate = rand_range (low_y, high_y);
return fleet;
}
Try
#include <string>
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
int rand_range(int low, int high) {
return rand() % (high - low + 1) + low;
}
struct ship_stats {
int x_coordinate;
int y_coordinate;
int weapon_power;
};
ship_stats fleet[5]; // Create fleet of 5 ships linked to the structure
ship_stats ship_position(ship_stats IndividualShip, int ship_num) {
//Randomly generate a starting position for each ship
int low_x = 0; //Set max and min ranges for ship position
int high_x = 1024;
int low_y = 0;
int high_y = 768;
IndividualShip.x_coordinate = rand_range(low_x, high_x);
IndividualShip.y_coordinate = rand_range(low_y, high_y);
return IndividualShip;
}
int main() {
int num_ships = 5;
for (int i = 0; i < num_ships; i++) {
fleet[i] = ship_position(fleet[i], i); // <-- error is here
}
}
In the above code, I've changed the function parameters of ship_position to accept an individual ship rather than the array as a whole. Your code should compile. Also, if this is C++ rather than C, consider using the for loop
for (ship_stats& j : fleet)
std::cout << j.x_coordinate << " " << j.y_coordinate << endl;
to output the results of your program, using < iostream > of course.

Boundless Arrays?

I'm having some trouble. I wrote a code to find prime numbers up to a number, but for some reason, it gives me the error that I didn't define the number of elements in the array that I will be using. Is it possible to have an array where the number of elements isn't limited? Thanks :)
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
using namespace std;
int primer(int max);
int main()
{
system("pause");
return 0;
primer(1000);
}
int primer(int max){
int a[]=2;
for (int i=2;i<=max;i++){
prime=true;
for (int ii=1;ii<=#a;ii++) {
if i/a[ii]==math.floor(i/a[ii]) {
prime=false;
}
}
if prime==true {
a[#a+1]=i;
}
}
for (i=1;i<=#a;i++) {
print(a[i]);
}
}
}
Yes. Use a std::vector or std::deque.
What is this # symbol that you're using everywhere?
Your line int a[]=2 is incorrect.
You need to specify how big your array is going to be. For example, int a[100], or
int a[] = {Values here}.
That being said, you probably want a flexibly sized array like the vector class.
The compiler needs to know how much space to allocate, and therefore requires you to state how many elements you have.
You could try using the STL vector instead of an array. This allows you to add as many elements as you want, without declaring the number right at the beginning.
http://www.cplusplus.com/reference/stl/vector/vector/
You are always 'limited', if only by the amount of memory which can allocate for the array.
Having said that, you will probably be fine using a std::vector.

elegant way to create&pass multi-dimensional array in c++?

first question:
for known dimensions, we don't need new/malloc for the creation
const int row = 3;
const int col = 2;
int tst_matrix[row][col] ={{1,2},{3,4},{5,6}}
however, there is no easy to pass this two-dimensional array to another function, right? because
int matrix_process(int in_matrix[][])
is illegal, you have to specify all the dimensions except the first one. if I need to change the content of in_matrix, how could I easily pass tst_matrix to the function matrix_process?
second question:
what's the standard way to create 2-dimensional array in c++ with new? I dont wanna use std::vector etc.. here.
here is what I come up with, is it the best way?
int **tst_arr = new int*[5];
int i=0, j=0;
for (i=0;i<5;i++)
{
tst_arr[i] = new int[5];
for (j=0;j<5;j++)
{
tst_arr[i][j] = i*5+j;
}
}
In addition, if I pass tst_array to another function, like:
int change_row_col( int **a)
{
.....................
//check which element is 0
for (i=0; i<5; i++)
for(j=0;j<5;j++)
{
if (*(*(a+i)+j)==0) //why I can not use a[i][j] here?
{
row[i]=1;
col[j]=1;
}
}
.....................
}
In addition, if I use ((a+i)+j), the result is not what I want.
Here is the complete testing code I had:
#include <iostream>
using namespace std;
//Input Matrix--a: Array[M][N]
int change_row_col( int **a)
{
int i,j;
int* row = new int[5];
int* col = new int[5];
//initialization
for(i=0;i<5;i++)
{
row[i]=0;
}
for(j=0;j<5;i++)
{
col[j]=0;
}
//check which element is 0
for (i=0; i<5; i++)
for(j=0;j<5;j++)
{
if (*(*(a+i)+j)==0) //why I can not use a[i][j] here?
{
row[i]=1;
col[j]=1;
}
}
for(i=0;i<5;i++)
for (j=0;j<5;j++)
{
if (row[i] || col[j])
{
*(*(a+i)+j)=0;
}
}
return 1;
}
int main ()
{
int **tst_arr = new int*[5];
int i=0, j=0;
for (i=0;i<5;i++)
{
tst_arr[i] = new int[5];
for (j=0;j<5;j++)
{
tst_arr[i][j] = i*5+j;
}
}
for (i=0; i<5;i++)
{
for(j=0; j<5;j++)
{
cout<<" "<<tst_arr[i][j];
}
cout<<endl;
}
change_row_col(tst_arr);
for (i=0; i<5;i++)
{
for(j=0; j<5;j++)
{
cout<<" "<<tst_arr[i][j];
}
cout<<endl;
}
for (i=0;i<5;i++)
{
delete []tst_arr[i];
}
delete []tst_arr;
}
For multidimensional arrays were all the bounds are variable at run time, the most common approach that I know of is to use a dynamically allocated one dimensional array and do the index calculations "manually". In C++ you would normally use a class such as a std::vector specialization to manage the allocation and deallocation of this array.
This produces essentially the same layout as a multidimensional array with fixed bounds and doesn't have any real implied overhead as, without fixed bounds, any approach would require passing all bar one of the array dimensions around at run time.
I honestly think the best idea is to eschew raw C++ arrays in favor of a wrapper class like the boost::multi_array type. This eliminates all sorts of weirdness that arises with raw arrays (difficulty passing them S parameters to functions, issues keeping track of the sizes of the arrays, etc.)
Also, I strongly urge you to reconsider your stance on std::vector. It's so much safer than raw arrays that there really isn't a good reason to use dynamic arrays over vectors in most circumstances. If you have a C background, it's worth taking the time to make the switch.
My solution using function template:
template<size_t M,size_t N>
void Fun(int (&arr)[M][N])
{
for ( int i = 0 ; i < M ; i++ )
{
for ( int j = 0 ; j < N ; j++ )
{
/*................*/
}
}
}
1)
template < typename T, size_t Row_, size_t Col_>
class t_two_dim {
public:
static const size_t Row = Row_;
static const size_t Col = Col_;
/* ... */
T at[Row][Col];
};
template <typename T>
int matrix_process(T& in_matrix) {
return T::Row * T::Col + in_matrix.at[0][0];
}
2) use std::vector. you're adding a few function calls (which may be inlined in an optimized build) and may be exporting a few additional symbols. i suppose there are very good reasons to avoid this, but appropriate justifications are sooooo rare. do you have an appropriate justification?
The simple answer is that the elegant way of doing it in C++ (you tagged C and C++, but your code is C++ new/delete) is by creating a bidimensional matrix class and pass that around (by reference or const reference). After that, the next option should always be std::vector (and again, I would implement the matrix class in terms of a vector). Unless you have a very compelling reason for it, I would avoid dealing with raw arrays of arrays.
If you really need to, but only if you really need to, you can perfectly work with multidimensional arrays, it is just a little more cumbersome than with plain arrays. If all dimensions are known at compile time, as in your first block this are some of the options.
const unsigned int dimX = ...;
const unsigned int dimY = ...;
int array[dimY][dimX];
void foo( int *array[dimX], unsigned int dimy ); // [1]
void foo( int (&array)[dimY][dimX] ); // [2]
In [1], by using pass-by-value syntax the array decays into a pointer to the first element, which means a pointer into an int [dimX], and that is what you need to pass. Note that you should pass the other dimension in another argument, as that will be unknown by the code in the function. In [2], by passing a reference to the array, all dimensions can be fixed and known. The compiler will ensure that you call only with the proper size of array (both dimensions coincide), and thus no need to pass the extra parameter. The second option can be templated to accomodate for different sizes (all of them known at compile time):
template <unsigned int DimX, unsigned int DimY>
void foo( int (&array)[DimY][DimX] );
The compiler will deduct the sizes (if a real array is passed to the template) and you will be able to use it inside the template as DimX and DimY. This enables the use of the function with different array sizes as long as they are all known at compile time.
If dimensions are not known at compile time, then things get quite messy and the only sensible approach is encapsulating the matrix in a class. There are basically two approaches. The first is allocating a single contiguous block of memory (as the compiler would do in the previous cases) and then providing functions that index that block by two dimensions. Look at the link up in the first paragraph for a simple approach, even if I would use std::vector instead of a raw pointer internally. Note that with the raw pointer you need to manually manage deletion of the pointer at destruction or your program will leak memory.
The other approach, which is what you started in the second part of your question is the one I would avoid at all costs, and consists in keeping a pointer into a block of pointers into integers. This complicates memory management (you moved from having to delete a pointer into having to delete DimY+1 pointers --each array[i], plus array) and you also need to manually guarantee during allocation that all rows contain the same number of columns. There is a substantial increase in the number of things that can go wrong and no gain, but some actual loss (more memory required to hold the intermediate pointers, worse runtime performance as you have to double reference, probably worse locality of data...
Wrapping up: write a class that encapsulates the bidimensional object in terms of a contiguous block of memory (array if sizes are known at compile time --write a template for different compile time sizes--, std::vector if sizes are not known until runtime, pointer only if you have a compelling reason to do so), and pass that object around. Any other thing will more often than not just complicate your code and make it more error prone.
For your first question:
If you need to pass a ND array with variable size you can follow the following method to define such a function. So, in this way you can pass the required size arguments to the function.
I have tested this in gcc and it works.
Example for 2D case:
void editArray(int M,int N,int matrix[M][N]){
//do something here
}
int mat[4][5];
editArray(4,5,mat); //call in this way

can someone help me translate this c++ code to c?

this is a magic square generator, but do not know C++, I have some difficulties to convert this code:
#include <vector>
#include <iostream>
using namespace std;
//There two series will be on even in case of magic square
// One of even order will be for multiple of 4
void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order);
//Other of even order will be for multiple of 2
void SinglyEvenMagicSquare(vector<vector<int> > &mat, int order);
// For odd order
void BuildOddMagicSquare(vector<vector<int> > &mat, int Order);
// For odd order
void BuildOddMagicSquare(vector<vector<int> > &mat, int Order)
{
int SqrOfOrder = Order * Order;
int start=0, mid=Order/2; // start position
for (int loop=1; loop<=SqrOfOrder; ++loop)
{
mat[start--][mid++] = loop;
if (loop % Order == 0)
{
start += 2;
--mid;
}
else
{
if (mid==Order)
mid -= Order;
else if (start<0)
start += Order;
}
}
}
void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order)
{
vector<vector<int> > A(Order, vector<int> (Order, 0));
vector<vector<int> > B(Order, vector<int> (Order, 0));
int i, j;
//Building of matrixes I and J
int index=1;
for (i=0; i<Order; i++)
for (j=0; j<Order; j++)
{
A[i][j]=((i+1)%4)/2;
B[j][i]=((i+1)%4)/2;
mat[i][j]=index;
index++;
}
for (i=0; i<Order; i++)
for (j=0; j<Order; j++)
{
if (A[i][j]==B[i][j])
mat[i][j]=Order*Order+1-mat[i][j];
}
}
void BuildSinglyEvenMagicSquare(vector<vector<int> > &mat, int order)
{
int ho=order/2;
vector<vector<int> > C(ho, vector<int> (ho, 0));
// For Order is Odd
if (order%2==1)
BuildOddMagicSquare(C, order);
// For Order is Even
else
{
//For Order is Doubly Even Order
if (order % 4==0)
BuildDoublyEvenMagicSquare(C, order);
//For Order is Singly Even Order
else
BuildSinglyEvenMagicSquare(C, order);
}
int i, j, k;
for (i=0; i<ho; i++)
for (j=0; j<ho; j++)
{
mat[i][j]=C[i][j];
mat[i+ho][j]=C[i][j]+3*ho*ho;
mat[i][j+ho]=C[i][j]+2*ho*ho;
mat[i+ho][j+ho]=C[i][j]+ho*ho;
}
if (order==2)
return;
vector<int> A(ho, 0);
vector<int> B;
for (i=0; i<ho; i++)
A[i]=i+1;
k=(order-2)/4;
for (i=1; i<=k; i++)
B.push_back(i);
for (i=order-k+2; i<=order; i++)
B.push_back(i);
int temp;
for (i=1; i<=ho; i++)
for (j=1; j<=B.size(); j++)
{
temp=mat[i-1][B[j-1]-1];
mat[i-1][B[j-1]-1]=mat[i+ho-1][B[j-1]-1];
mat[i+ho-1][B[j-1]-1]=temp;
}
i=k;
j=0;
temp=mat[i][j]; mat[i][j]=mat[i+ho][j]; mat[i+ho][j]=temp;
j=i;
temp=mat[i+ho][j]; mat[i+ho][j]=mat[i][j]; mat[i][j]=temp;
}
int main()
{
int Order;
cout<<"Enter the order of square which you wanna: ";
cin>>Order;
vector<vector<int> > mat(Order, vector<int> (Order, 0));
// For order less than 3 is meaningless so printing error
if (Order<3)
{
cout<<" Order Of Square must be greater than 2";
return -1;
}
// For Order is Odd
if (Order%2==1)
BuildOddMagicSquare(mat, Order);
// For Order is Even
else
{
//For Order is Doubly Even Order
if (Order % 4==0)
BuildDoublyEvenMagicSquare(mat, Order);
//For Order is Singly Even Order
else
BuildSinglyEvenMagicSquare(mat, Order);
}
// Display Results
for (int i=0; i<Order; i++)
{
for (int j=0; j<Order; j++)
{
cout<< mat[i][j]<<" " ;
}
cout<<endl;
}
return 0;
}
for example, how can I write this function call in C?
void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order);
and what vector<vector<int> > &mat means?
#Omnifarious
can i use something like this?
int **mat:
*mat = (int **)malloc(sizeof(int*)*Order);
for (int i=0;i<Order;i++)
mat[i] = (int *)malloc(sizeof(int)*Order);
Are you restricted to building the project as a C project? If you're writing good C code (and it isn't C99), you can probably compile it as C++ with no difficulty. If you can then build it as a C++ program, you can use the function as is.
In that case, all you really need to know is that you've got vector<vector<int> > mat, and when you call your function it's got your result. Then you can put the preprocessor directive #include <vector> in your files that use it, and follow it with using std::vector, and everything will just work. In particular, you can read off the values with mat[i][j], just as you would with an array of array of int in C.
One thing to watch is that you write vector<vector<int> > rather than vector<vector<int>>, since in the latter the >> will be treated as a right-shift operator rather than angle bracket delimiters. This will be fixed in C++0x, when it comes out (the x digit is now strictly hex), and may be fixed in particular compilers.
Alternatively, write a wrapper function that takes the vector and changes it into an array of array of int. For convenience, you can find the number of elements in a vector with mat.size() or mat[i].size().
For the last part of the question, in C that function prototype would look like this if you follow the rest of my advice:
void BuildDoublyEvenMagicSquare(int *mat, int Order);
There are actually several ways you could do it. There are some things being done here that simply can't be done in C, so you'll have to sort of go for a slightly different approach. The biggest thing is the C++ vector's. A C++ vector is like a C array, but it does all the memory management for you. This means, for example, that it's fairly convenient to have an array of arrays where in C it would just add to your resource management headache.
The C++ declaration:
vector<int> varname(5);
is roughly equivalent to the C declaration:
int varname[5];
But in C++ you can do this:
int randominteger = 7;
vector<int> varname(randominteger);
and in C this is illegal unless you have a C99 compliant compiler (-std=c99 in gcc):
int randominteger = 7;
int varname[randominteger];
You can't have arrays with variable numbers of elements in C, so you have to resort to calloc or malloc and do your own memory management, like this:
/* Not that this is not necessary and shouldn't be done (as it's *
* prone to memory leaks) if you have a C99 compliant compiler. */
int randominteger = 7;
int *varname = calloc(randominteger, sizeof(int));
if (varname == NULL) {
/* Die horribly of running out of memory. */
}
In this case, I'm assuming that you're going to unfold your array of arrays into a single long C array of integers large enough to hold the answer so you can reduce the number of bits of memory you have to manage. To accomplish this, I would use a call like mat = calloc(order * order, sizeof(int)); in main, which also means you'll have to call free(mat) when you're finished with it at the end of main.
I'm also assuming that you're unfolding the array so that you no longer have an array of arrays. That means you'll have to be doing some math to turn a row,column index into a linear index into the array. Something like row * order + column.
You'll have to repeat the procedure I suggested for main in each of the functions that build a magic square because they each create temporary arrays to hold stuff in that go away at the end of the function.
I'll just answer the last part of the question.
vector is a container in the C++ standard library. It's like an array that can automatically resize itself when it gets full.
A vector<vector<int> > is a vector containing vector objects, and the latter holds int.
A vector<vector<int> >& is a reference to same. A reference is like a pointer, except that you do not use * to access the actual contents. So you treat mat "as if" it's a vector object directly, except that it's really aliased to another instance, so any changes you make to it will "reflect back" and affect what the caller can see.
Simple example of references:
void add1(int& n) {
++n;
}
int main() {
int num = 5;
add1(num);
// num is 6 here
}
A C++ vector is like a C array. It adds some nice features, like optional bounds checking, automatic reallocation when it needs its size increased, and so on.
A vector<int> is roughly analogous to an int[].
A vector<vector<int> > is like an int*[], where each int* points to an array. It's not like a two-dimensional array - each of the inner vectors can have different sizes.
Prefixing a variable with an & makes that variable a reference. A reference is like a pointer that you don't have to explicitly dereference. Passing parameters by reference is a common C++ idiom, which is used in many of the same situations as passing by pointer in C.
vector is an array which is resized automatically. So vector<vector<int>> would be an array of int-arrays, equivalent to the C int*[]. &mat is a reference to a mat, similiar to pointers (in fact I think C99 supports references). However, in this case since the value being passed in is already a pointer, it is not really needed.
So the equivalent in C would be
void BuildDoublyEvenMagicSquare(int*[] mat, int Order);
You can get rid of the #includes and the 'using namespace std' line. The only difficult bit now is your vector. What's being passed here is a two dimensional array of ints which is easy enough in C. The difficult bit is resizing it if you don't know the bounds at the outset. That's why vector is so nice - you don't need to care.
For more general C++ to C connversion I'd suggest you get a book like "C++ for C programmers" and work from the index back. Even better, work from the beginning to the end and learn C++. You'll probably find that if the program is in any way complicated, there's going to be some things which are pretty tricky to do in C from C++. Good luck!!
Vector is pretty much C++ for an array. There are ways to dynamicly resize vectors (without resorting to realloc()), but otherwise that is pretty much what you are looking at.
If you see & in a parameter list, it means "pass this parameter by reference". In C parameters inside a routine are a copy of what was passed in, so if you modify them that modificaion doesn't go outside the function. However, if you modify a C++ reference parameter, you are also modifying the variable the caller used for that parameter.
So to get the equivalent of <vector<vector<int>> & mat in C, you'd probably pass that parameter as something like int ** mat[], with the assumption that the user is passing in a pointer to an array of int arrays that they want you to work on. The difference is that inside the routine your C code would have to be doing a *mat to get at the array of int arrays, whereas in the C++ code they can just use mat directly.