Reputation: 25
I do not know the value of V before. It is found within a file I open in the program. It cannot be defined as such #DEFINE V __
. It does not work as a global variable. The input file changes V based on the contents. Expected the parameters to pass and use the djisktra's algorithm found on Geeks for Geeks.
I have tried declaring V globally, but I am given an error saying "variable must have constant value."
void dijkstra(int graph[V][V], int src, int V)
//array function being pasted, error is the V in graph[V]
//V is defined at beginning of main as
int V;
//where V is changed
while(std::getline(file2,newstr))
{
if(newstr.find(check) != std::string::npos)
{
V++;
}
}
//where it is passed in main
for(int i = 0; i < V; i++)
{
size = V;
dijkstra(array[size][size], i, V);
}
Upvotes: 0
Views: 1578
Reputation: 5566
Is it possible to pass a variable length array as a parameter in C++.
No.
Variable length arrays are not supported in std C++, But read on, they have an alternative that is surprisingly better.
I do not know the value of V before it is found within a file I open in the program.
A 1d vector is trivial to create, after your code has found V, no compile time constant required.
Early in the startup in one of my programs, the gBoard vector is built using argv[3] and argv[4]. Here is a snippet:
aTermPFN += argv[1]; // ouput tty, /dev/pts/<argv[1]>
fillPatternChoiceLetter = argv[2][0];
aMaxRow = stoi(argv[3]);
aMaxCol = stoi(argv[4]);
userDim = true;
Clearly, the program has already started ... and V size is easily computed from (aMaxRow * aMaxCol).
I find it easy to access a 1d vector (or 1d array), in row major order, as if it is a 2d matrix, with the following function:
// game-board-index: computes index into the single dimension vector
// from 2d (row, col) matrix coordinates
size_t gbIndx(int r, int c) { return static_cast<size_t>((r * maxCol) + c); }
// a 2d game board of cells
// 2d access (row major order) implemented using 1d access
Cell_t* getCell( int r, int c ) { return (gBoard [gbIndx(r,c)]); }
// 1d access is surprisingly convenient for many functions
Cell_t* getCell( uint gbIndex ) { return (gBoard [gbIndex]); }
Sample initialization usage:
// vvvvvvvvvvvvvvvvvvv_-- 2d matrix access
gBoard [ gbIndx((midRow+1), midCol) ] -> setOptionX();
// ^^^^^^--1d row-major order index
A randomized gGoard is trivial in 1d:
void GOLUtil_t::setRandom() { CellVec_t myVec(gBoard); // copy cell vector
random_device rd; mt19937_64 gen(rd()); shuffle (myVec.begin(), myVec.end(), gen); // shuffle order
int count = 1; for ( auto it : myVec ) // randomly mark half the cells { if(count++ & 1) it->setAlive(); // every odd cell } }
Note from https://en.cppreference.com/w/cpp/container/vector:
"The elements are stored contiguously, which means that elements can be accessed not only through iterators, but also using offsets to regular pointers to elements. This means that a pointer to an element of a vector may be passed to any function that expects a pointer to an element of an array."
I was surprised how often the 1d access enabled simpler code.
for (auto it : gBoard)
it->init(); // command each cell to init
Summary:
Despite variable-length-arrays (vla) not being supported in std C++, I believe you will find std::vector a better alternative. And you will find that passing the vector within your code works.
Upvotes: 0
Reputation: 41770
For c style arrays, you need to know the size at compile time. A variable like int N;
is a runtime value. A variable like constexpr int N = 9;
is usable at compile time and cannot be mutated.
If you need an array sizeable at runtime, you need some sort of dynamic array. The most common one is std::vector
.
void dijkstra(std::vector<int> graph, int src, int V)
std::vector<int> graph;
graph.resize(V * V); // vector are resizable
for(int i = 0; i < V; i++)
{
size = V;
dijkstra(graph, i, V);
}
Upvotes: 1
Reputation: 211670
Don't use C-style arrays. Use std::vector
and friends from the Standard Library where you can ask for the size if you want to know.
Converted:
void dijkstra(const std::vector<std::vector<int>>& graph, int src) {
auto v = graph.size();
// ... Other code.
}
For inserting you can use push_back
:
std::vector<std::vector<int>> graph;
while(std::getline(file2,newstr)) {
if(newstr.find(check) != std::string::npos) {
std::vector<int> row;
row.push_back(...);
graph.push_back(row);
}
}
Then pass it in like a regular variable:
dijkstra(graph, src);
If all that vector stuff looks really ugly, typedef
it to something more friendly looking.
Upvotes: 1