Passing an array as argument to a function
-
Hi What is the syntax when you want to pass an array as argument? I`m looking for syntax for both function call and function definition.
You can do either of these, depending on what you want to do:
// pass read only array of ints
void process_Carray(int const* values, int n_values);
template // caution: this will create a separate function for each array size!
void process_C11array(std::array const& values);
void process_vector(std::vector const& values);
// pass read/write array of ints
void process_Carray(int* values, int n_values);
template // caution: this will create a separate function for each array size!
void process_C11array(std::array& values);
void process_vector(std::vector& values);The first variant is deprecated in C++, it should be restricted to pure C code. The second variant is useful if you know the size of your arrays at compile time (and it's always the same) The third variant is the most flexible as you don't need to know the array size, and you can even add more values within your function if you desire.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
-
The leading '_' indicates it's a system level macro, i. e. Windows specific.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
-
You can do either of these, depending on what you want to do:
// pass read only array of ints
void process_Carray(int const* values, int n_values);
template // caution: this will create a separate function for each array size!
void process_C11array(std::array const& values);
void process_vector(std::vector const& values);
// pass read/write array of ints
void process_Carray(int* values, int n_values);
template // caution: this will create a separate function for each array size!
void process_C11array(std::array& values);
void process_vector(std::vector& values);The first variant is deprecated in C++, it should be restricted to pure C code. The second variant is useful if you know the size of your arrays at compile time (and it's always the same) The third variant is the most flexible as you don't need to know the array size, and you can even add more values within your function if you desire.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
thanks, I also understand `defensive programming` now.
-
Much the same syntax as when passing anything, in this case a pointer is the norm:
int myFunction(char* anArrayOfChars) // a pointer to the array
{
// function code ...
}...
// calling code
char anArray[32];
// fill the array
int value = myFunction(anArray) // name of the array is a pointer to its contentSo is this pointer a save of the physical address of the real thing or just an artifice done by the compiler which matches the data behind the scenes to achieve the desired result?
-
So is this pointer a save of the physical address of the real thing or just an artifice done by the compiler which matches the data behind the scenes to achieve the desired result?
It is the actual address in the pointer. In that way you can address any array, or any structure just by passing the real address to the function.
void myFunc(char* someData, int length)
{
for (int i = 0; i < length; ++i)
{
char c = toUpper(someData[i]);
someData[i] = c; // comnvert the string to upper case
}
}You can now call that function with any array of any length and get it converted. In every case the function receives the physical address of the array and accesses each character by using the index value
i
, where0 <= i < length
. -
It is the actual address in the pointer. In that way you can address any array, or any structure just by passing the real address to the function.
void myFunc(char* someData, int length)
{
for (int i = 0; i < length; ++i)
{
char c = toUpper(someData[i]);
someData[i] = c; // comnvert the string to upper case
}
}You can now call that function with any array of any length and get it converted. In every case the function receives the physical address of the array and accesses each character by using the index value
i
, where0 <= i < length
.thank you Richard
-
In that case you'd use another level of indirection: e.g.
#include <iostream>
void myfn(int **data, size_t len)
{
for(size_t i = 0; i < len; ++i)
*data[i] = i * 2; // assign value to address pointed to by data[i]// alternatively : // for(size\_t i = 0; i < len; ++i) // \*\*data++ = i\*2; // Note: use double de-reference and post increment!
}
int main)_
{
int data[5] = { 1, 2, 3, 4, 5 }; // our original data
const size_t ndata = sizeof(data)/sizeof(data[0]);
int** pdata = new int*[ndata]; // double indirection used for definition of pdata// assign each element of pdata the address of element of data for(size\_t i = 0; i < ndata; ++i) pdata\[i\] = &data\[i\]; // or could use pdata\[i\] = data+i; std::cout << "Before:\\n"; for(size\_t i = 0; i < ndata; ++i) std::cout <^lt; \*pdata\[i\] << std::endl; myfn(pdata, 5); std::cout <\*lt; "\\nAfter:\\n"; for(size\_t i = 0; i < ndata; ++i) std::cout << \*pdata\[i\] << std::endl; delete\[\] pdata; return 0;
}
Keep Calm and Carry On
This array of pointers thing is above trivial. Here is my old code:
CUSTOMVERTEX* ScreenLetters;
ScreenTextBuffers[0]->Lock( 0, 0, (void**)&ScreenLetters, 0 );
int LetterVertexDataincrement = 0;
int letterwidth = 12;
int letterheight = 12;for(int ii = 0; ii < ScreenLetterGroups\[0\].height;ii++) { for(int i = 0; i < ScreenLetterGroups\[0\].width;i++) { //. . //\_ . ScreenLetters\[LetterVertexDataincrement\].position.x = i \* letterwidth + ScreenLetterGroups\[0\].x; ScreenLetters\[LetterVertexDataincrement\].position.y = ii \* letterheight + ScreenLetterGroups\[0\].y; ScreenLetters\[LetterVertexDataincrement\].position.z = 20; ScreenLetters\[LetterVertexDataincrement\].color = 0xffffffff;
// ... filling the array ...
}
}ScreenTextBuffers[0]->Unlock();
I have this piece of code repeating for every ScreenTextBuffers element. I want to place it in a `for` loop so what I`m doing is:
CUSTOMVERTEX ** ScreenLettersP_s = new CUSTOMVERTEX* [NumberOfTextBuffers];
int LetterVertexDataincrement = 0;
int letterwidth = 12;
int letterheight = 12;
for(int iii =0; iii < NumberOfTextBuffers; iii++)
{
ScreenTextBuffers[iii]->Lock( 0, 0, (void**)&ScreenLettersP_s[iii], 0 );for(int ii = 0; ii < ScreenLetterGroups\[iii\].height;ii++) { for(int i = 0; i < ScreenLetterGroups\[iii\].width;i++) { //. . //\_ . \*ScreenLettersP\_s\[LetterVertexDataincrement\]->position.x = i \* letterwidth + ScreenLetterGroups\[iii\].x; // \`illegal indirection\` \*ScreenLettersP\_s\[LetterVertexDataincrement\]->position.y = ii \* letterheight + ScreenLetterGroups\[iii\].y; \*ScreenLettersP\_s\[LetterVertexDataincrement\]->position.z = 20; \*ScreenLettersP\_s\[LetterVertexDataincrement\]->color = 0xffffffff;
// ... filling the array ...
}
}
ScreenTextBuffers[i]->Unlock();
}but it doesn`t compile, I`m getting an `illegal indirection` error
struct CUSTOMVERTEX
{
D3DXVECTOR3 position; // The position
D3DCOLOR color; // The color
FLOAT tu, tv; // The texture coordinates
}; -
This array of pointers thing is above trivial. Here is my old code:
CUSTOMVERTEX* ScreenLetters;
ScreenTextBuffers[0]->Lock( 0, 0, (void**)&ScreenLetters, 0 );
int LetterVertexDataincrement = 0;
int letterwidth = 12;
int letterheight = 12;for(int ii = 0; ii < ScreenLetterGroups\[0\].height;ii++) { for(int i = 0; i < ScreenLetterGroups\[0\].width;i++) { //. . //\_ . ScreenLetters\[LetterVertexDataincrement\].position.x = i \* letterwidth + ScreenLetterGroups\[0\].x; ScreenLetters\[LetterVertexDataincrement\].position.y = ii \* letterheight + ScreenLetterGroups\[0\].y; ScreenLetters\[LetterVertexDataincrement\].position.z = 20; ScreenLetters\[LetterVertexDataincrement\].color = 0xffffffff;
// ... filling the array ...
}
}ScreenTextBuffers[0]->Unlock();
I have this piece of code repeating for every ScreenTextBuffers element. I want to place it in a `for` loop so what I`m doing is:
CUSTOMVERTEX ** ScreenLettersP_s = new CUSTOMVERTEX* [NumberOfTextBuffers];
int LetterVertexDataincrement = 0;
int letterwidth = 12;
int letterheight = 12;
for(int iii =0; iii < NumberOfTextBuffers; iii++)
{
ScreenTextBuffers[iii]->Lock( 0, 0, (void**)&ScreenLettersP_s[iii], 0 );for(int ii = 0; ii < ScreenLetterGroups\[iii\].height;ii++) { for(int i = 0; i < ScreenLetterGroups\[iii\].width;i++) { //. . //\_ . \*ScreenLettersP\_s\[LetterVertexDataincrement\]->position.x = i \* letterwidth + ScreenLetterGroups\[iii\].x; // \`illegal indirection\` \*ScreenLettersP\_s\[LetterVertexDataincrement\]->position.y = ii \* letterheight + ScreenLetterGroups\[iii\].y; \*ScreenLettersP\_s\[LetterVertexDataincrement\]->position.z = 20; \*ScreenLettersP\_s\[LetterVertexDataincrement\]->color = 0xffffffff;
// ... filling the array ...
}
}
ScreenTextBuffers[i]->Unlock();
}but it doesn`t compile, I`m getting an `illegal indirection` error
struct CUSTOMVERTEX
{
D3DXVECTOR3 position; // The position
D3DCOLOR color; // The color
FLOAT tu, tv; // The texture coordinates
};Arrays of pointers are just as trivial as arrays of anything, if you understand how to address them.
fearless_ wrote:
I`m getting an `illegal indirection` error
Since we cannot see your screen we also cannot guess where that occurs. Please format your code properly and explain exactly where the error occurs.
-
Arrays of pointers are just as trivial as arrays of anything, if you understand how to address them.
fearless_ wrote:
I`m getting an `illegal indirection` error
Since we cannot see your screen we also cannot guess where that occurs. Please format your code properly and explain exactly where the error occurs.
I get illegal indirection at this spot
*ScreenLettersP_s[LetterVertexDataincrement]->position.x = i * letterwidth + ScreenLetterGroups[i].x
-
I get illegal indirection at this spot
*ScreenLettersP_s[LetterVertexDataincrement]->position.x = i * letterwidth + ScreenLetterGroups[i].x
The variable
ScreenLettersP_s
is an array of pointers, so the referenceScreenLettersP_s[LetterVertexDataincrement]
is one of the actual pointers. The leading asterisk onScreenLettersP_s
means an extra level of indirection which is not required (or valid). -
The variable
ScreenLettersP_s
is an array of pointers, so the referenceScreenLettersP_s[LetterVertexDataincrement]
is one of the actual pointers. The leading asterisk onScreenLettersP_s
means an extra level of indirection which is not required (or valid).so this is specific for structures only. because if I change *data[i] = i * 2; to data[i] = i * 2; in the k5054s example I will be editing the save entry rather than the save data.
-
so this is specific for structures only. because if I change *data[i] = i * 2; to data[i] = i * 2; in the k5054s example I will be editing the save entry rather than the save data.
No. Pointers are pointers whatever they point at, be it an array or a structure. Think about a piece of memory as a sequence of cells. So a pointer to any cell allows you to access all the following cells in order, by using an index (pointer plus offset). If you (the programmer) have decided that the area you point to should be treated as if it contains different sized blocks (aka a structure), that does not affect the physical properties of the memory. It merely allows the compiler to calculate the distance between the elements of the structure. And an array of pointers is much the same thing. If you have trouble visualising multi levels of indirection, then always go for a single level. If you have an array of pointers, then create a temporary one and allocate an array entry to it like:
CUSTOMVERTEX ** ScreenLettersP_s = new CUSTOMVERTEX* [NumberOfTextBuffers]; // an array of struct pointers
CUSTOMVERTEX* pTemp = ScreenLettersP_s[0]; // get the first pointer in the array
pTemp-> // now access the struct items. -
No. Pointers are pointers whatever they point at, be it an array or a structure. Think about a piece of memory as a sequence of cells. So a pointer to any cell allows you to access all the following cells in order, by using an index (pointer plus offset). If you (the programmer) have decided that the area you point to should be treated as if it contains different sized blocks (aka a structure), that does not affect the physical properties of the memory. It merely allows the compiler to calculate the distance between the elements of the structure. And an array of pointers is much the same thing. If you have trouble visualising multi levels of indirection, then always go for a single level. If you have an array of pointers, then create a temporary one and allocate an array entry to it like:
CUSTOMVERTEX ** ScreenLettersP_s = new CUSTOMVERTEX* [NumberOfTextBuffers]; // an array of struct pointers
CUSTOMVERTEX* pTemp = ScreenLettersP_s[0]; // get the first pointer in the array
pTemp-> // now access the struct items.I understand. for the record that`s directx 9.
-
I understand. for the record that`s directx 9.
fearless_ wrote:
directx 9
I have not used DirectX, but I have used plenty of other Windows' functions that use structures, arrays of structures, and even arrays of structures that contain other unstructured structures. In the latter case, the presence or absence of certain items depends on settings elsewhere.
-
fearless_ wrote:
directx 9
I have not used DirectX, but I have used plenty of other Windows' functions that use structures, arrays of structures, and even arrays of structures that contain other unstructured structures. In the latter case, the presence or absence of certain items depends on settings elsewhere.
You have a vast experience, I appreciate all your help.
-
You have a vast experience, I appreciate all your help.
-
Hi What is the syntax when you want to pass an array as argument? I`m looking for syntax for both function call and function definition.
Just as a conclusion to everything that has been said in this thread, if you want to pass an array as argument you have to declare it as pointer in the function definition.
-
Just as a conclusion to everything that has been said in this thread, if you want to pass an array as argument you have to declare it as pointer in the function definition.