I'm new to using C++ for complicated programming. I've been sifting through some leftover, uncommented, academic code handed down through my department, and I've stumbled across something I have no real idea how to google for. I don't understand the syntax in referencing an array of structs.
Here is a trimmed version of what I'm struggling with:
typedef struct
{
double x0,y0;
double r;
} circle;
double foo()
{
int N = 3;
double mtt;
circle circles[N];
for (int i = 0; i < N; i++)
{
mtt += mtt_call_func((circles+i), N);
}
return mtt;
}
What does (circles+i) mean in this case?
EDIT: the function should have (circles + i), not (circle + i).
circles+i is equivalent to &circles[i]. That's how pointer arithmetic works in C++.
Why is there a pointer? Well, when you give the name of an array, in a context other than &circles or sizeof circles, a temporary pointer is created that points to the first member of the array; that's what your code works with. Arrays are second-class citizens in C++; they don't behave like objects.
(I'm assuming your circle+i was a typo for circles+i as the others suggested)
circle+i means "take a pointer circle and move it i times by the size of the object pointed to by it". Pointer is involved because the name of the array is a pointer to it's first element.
Apart from this you should initialize an integer counter variable that is used in loop:
for (int i = 0; i < N; i++)
^^^^
{
mtt += mtt_call_func( ( circles + i), N);
^ // typo
}
In C, as in C++, it is legal to treat an array as a pointer. So circles+i adds i times the size of circle to the address of circles.
It might be clearer to write &circles[i]; in this form, it is more obvious that the expression produces a pointer to the ith struct in the array.
Each vector you declare in stack it's actually a pointer to the first index, 0, of the vector. Using i you move from index to index. As result, (circles+i) it's the equivalent of &circles[i].
& means the address of the variable. As in your function call, you send a pointer which stores an address of a variable, therefore & is required in front of circles[i] if you were to change to that, as you need the address of the i index of the vector circles to run your function.
For more about pointers, vectors and structures check this out: http://pw1.netcom.com/~tjensen/ptr/pointers.htm
It should cover you through ground basics.
Related
I'm new to c++,
I'm trying to find main diagonal matrix using pointer array like
int * ProblemSolution :: solution(int *A,int N)
{
//write your code here
for (int m=0;m<N;m++){
for (int x=0;x<N;x++){
if(m=x)
cout<<*(*(A+m)+x)<<",";
}
}
return 0;
}
but i'm getting some kind of error:
can anyone help me?
You have a few problems
if(m=x)
is an assignment, you probably want,
if(m==x)
Square bracket syntax is a lot clearer than pointer arithmetic,
A[m]
instead of,
*(A+m)
Also *(A+m) is an integer, so *(A+m)+x is also an integer which you can't dereference.
Your index should be something like:
A[m*N+x]
A is an int*
A+m is also an int*
*(A+m) is an int
(*(A+m) + x) is also an int
Instead of cout<<*(*(A+m)+x)<<","; you could write int tmp = (*(A+m)+x); cout << *tmp << ",";.
You are trying to derefence a pointer.
To make things easier you should rather use appropriate types (e.g. std::array, std::vector) instead of using raw-pointers.
*(*(A+m) + x) is an int,So try to store it in some variable then print it. Also you are mixing up 2D matrix(pointer to pointer) with 1D array(pointer).
try to do like-
*(A+m)=A[m] ,
*(*(A+m)+x) =A[m][x]
You mixed up 2D matrix represented by pointer to pointer and 1D array represented by pointer, your case is the latter.
*(*(A+m)+x) is legal only if A is a pointer to array decayed to a pointer to pointer, instead it should be *(A + N*m +x)
I'm mostly just documenting this question as someone may stumble upon it, and may find it useful. And also, I'm very curios with, how does std::swap works on a 2D array like: Arr[10][10].
My question arised because as to my understanding an array like this is just a 1D array with some reindexing.
For reference:
How are 2-Dimensional Arrays stored in memory?
int main()
{
const int x = 10;
const int y = 10;
int Arr[y][x];
// fill the array with some elements...
for (int i = 0; i < x*y; i++)
{
Arr[i / y][i % x] = i;
}
// swap 'row 5 & 2'
// ??? how does swap know how many elements to swap?
// if it is in fact stored in a 1D array, just the
// compiler will reindex it for us
std::swap(Arr[5], Arr[2]);
return 0;
}
I could understand swapping two 'rows' if our data type is, say a pointer to a pointer like int** Arr2D then swap with std::swap(Arr2D[2], Arr2D[5]) as we do not need to know the length here, we just need to swap the two pointers, pointing to '1D arrays'.
But how does std::swap work with Arr[y][x]?
Is it using a loop maybe, to swap all elements within x length?
std::swap has an overload for arrays that effectively swaps each two elements, again, using std::swap.
As for the size information, it is embedded within the array type (Arr[i] is int[x]), so the compiler knows to deduce T2 as int and N as 10.
OT: Why aren't variable-length arrays part of the C++ standard? (but this particular case is OK)
I'm looking at some source code and within the code it has some code I don't fully understand. Below is a basic pseudo example that mimics the part I'm having trouble understanding:
float *myArray;
object(){
myArray = new float[20];
}
~object(){
}
void reset(){
delete [] myArray;
}
void myMethod(float *array){
for (int i = 0; i < 20; i++){
array[i] = 0.5f;
}
}
Now in another method body there's:
void mySecondMethod(){
myMethod(myArray + 10);
}
It's the second method I don't get: What does it mean when you pass an array pointer and an int into a parameter that wants an array pointer? I'm just trying to bolster my knowledge, I've been trying to search about it but have found no information.
It simply means "the address of the 11th element in this array".
This is an example of pointer arithmetic, a core feature of C (and also of C++ although it's perhaps considered a bit "low-level" there).
The expression means "take the address of the first element of myArray, and add the size of 10 elements to that".
It works the same as myArray[10], since the indexing operator is really sugar for *(myArray + 10).
myArray[10] == *(myArray + 10)
&myArray[10] == myArray + 10
Can anyone hint on how to pass by reference an array of the kind
int array[2][3][4];
so that I may save his pointer in order to use and modify the array?
Like, if I were speaking about a single integer:
// Scope 1
int a = 3;
increment(&a);
// End Scope 1
// Scope 2
int *pa;
void increment(int *tpa) {
pa = tpa; *pa++;
}
// End Scope 2
Thanks a lot and best regards.
If you really want to pass the array by reference, you can do so:
void f(int (&a)[2][3][4]) { }
In C, which doesn't have references, you can pass the array by pointer (this works in C++ too, of course):
void f(int (*a)[2][3][4]) { }
C++:
void f(int (&array)[2][3][4])
{
}
C: There are no references in C
Note that no matter how you pass the array, via reference or not, the array is not going to be copied, so you'll get the original pointer. You can pass this array also like this:
void f(int array[][3][4])
{
}
Thanks to everyone who participated in this! sskuce provided a very good solution, taking advantage of a "container". I had thought about this but didn't really like the extra stuff.
I realized after a little jumbling that James McNellis had given the answer all along. So... here's the solution I prefer with no containers and no indexes arithmetic (mind the parenthesis):
void Scope1()
{
int array[2][3][4];
Scope2(&array);
}
int (*pArray)[2][3][4];
void Scope2(int (*tpArray)[2][3][4]))
{
pArray = tpArray;
(*pArray)[0][0][0] = 3;
}
Thanks again to everyone.
Edit: I'm keeping my original answer below, as I believe it's necessary for folks to understand how arrays are actually passed to functions and how they're layed out in memory, but on further reflection I think there is a simple and correct way to get what you want done.
Encapsulate the array within a struct, e.g.
typedef struct ArrayHolderStruct{
int array[2][3][4];
} ArrayHolder
//...
//scope 1
ArrayHolder thingy;
thingy.array[0] = something;
//other initialization.
F( &thingy );
//...
//scope 2
ArrayHolder *pa;
void F ( ArrayHolder *p ){
pa = p;
p->array[0][1][2] = 42;
}
//Call F first to set pa.
void G(){
pa->array[0][1][2] = 6 * 9; // if pa = &thingy, thingy will be modified.
}
The struct will allow you to maintain layout information about the encapsulated array, and you don't have to worry about nasty index arithmetic.
-----OLD ANSWER-----
Passing a reference to an array is not useful, unless you want to change the size or layout of the array (which you can't do with statically sized arrays anyway). You'll get a reference (or pointer) to the elements of the array even if you pass the array by "value". That is to say, if you declare your function:
void f ( int a[2][3][4] ){
a[0][1][2] = 42;
}
and call it like f( array ) when f exits, array[0][2][2] will have been set to 42, even though you didn't pass a "reference" to array into the function.
If you want to save a pointer to the array for later use in a library function, etc, you could do something like:
//scope 2
int * pa;
void f ( int a[2][3][4] ){
pa = &a[0][0][0];
}
It gets tricky at this point - you have to know how pa is layed (laid?) out in memory. I think C has standardized on 'row major order', so the array should be layed out in memory like:
a[0][0][0] a[0][0][1] a[0][0][2] a[0][0][3] a[0][1][0] ... a[0][2][3] a[1][0][0] a[1][0][1]... a[1][2][3]
So, to get at an element at index [n][j][k], you have to do something like:
pa[n * 12 + j * 4 + k] = something;
Basically, multiply each index by the number of elements that can be referenced by an index of that order, e.g. each k index points to exactly one element given a fixed j and n index, each j index can point to 4 elements given a fixed n index, and each n index can point to one of 12 (because 12 = 3 * 4) elements.
Like I said, it's tricky. See the wikipedia articles on Array Data Structures and Row-major order to get a better understanding of how these things are layed out.
In using Dev C++, I a m trying to insert a smaller 2D array object into a larger 2D array object. While attempting to achieve that, I came into compilers errors which I do not know how to solve.
I attempt to insert the smaller Object by making it returning the array's name. Then I attempt to change the values inside the large array with the values of the smaller array.
There two line of code that I have problems with:
int result = smallerArray.extractPiece();
largerArray.extractArray(result);
And within these two lines of codes:
int Piece::extractPiece()
{
return **pieceArray;
}
and
void Grid::extractArray( int** arr )
{
for(int i = 0; i < xGrid ; ++i)
{
for (int j = 0; j < yGrid ; ++j)
{
squares[i][j] = arr[i][j];
}
}
}
The two of the problems is that "int result" will not hold smallerArray.extractPiece(),
and if i just put "smallerArray.extractPiece()" in largerArray.extractArray(), i still get problems. I attempted to make "int result" a pointer pointer, as "int** result", i still have the same errors.
These are the errors that i get when i try to compile in Dev C++:
In function `int main()';
invalid conversion from `int' to `int**'
initlizing argument 1 of 'void Grid::extractArray(int**)'
[Build Error] [grid test.o] Error 1
Does anyone know whats wrong?
It's precisely this bunch of code:
int result = smallerArray.extractPiece();
largerArray.extractArray(result);
// ...
int Piece::extractPiece() {
return **pieceArray;
}
Trying to pass an int to extractArray, which wants a pointer to a pointer, presumable your dynamic array, and not an int. Try changing it to
int **result = smallerArray.extractPiece();
largerArray.extractArray(result);
// ...
int ** Piece::extractPiece() {
return pieceArray;
}
Only changing result to a pointer to pointer won't work. You of course also have to change what extractPiece returns (changing from int to int**)
Look, always at least for me it was easier to manage 2D arrays internally as 1D arrays where M[i,j]=A[i*N+j] where N is the number of cols (or rows, if the 2D arrays is row-column type). Users may get elements with the i,j indices but my class always store A[M * N] as private data. Passing 1-D pointer arrays is easier than managing 2-D pointer arrays (you can't fall in the pointer-to-pointer syntax which can get messy in some code).,
This is not related to this question, but since I don't know about specific compiler optimization instrinsics, I wonder if M[i,j] gets transformed to A[i] internally to use simpler addressing modes in the generated code.