I'm trying to write code that has a pointer point to a 2-dimensional array.
My main purpose is for not just one asd array, like I would like to point 5 array each of which is 2 dimensional.
int asd1[2][2];
int asd2[2][2];
int *se;
se[0] = asd1;
se[1] = asd2;
Use se = asd[0];
The reason is that the symbol asd yields not a pointer to an int but rather a pointer to a one-dimensional array of ints.
#Mig's solution may be good, too. It depends on what you want. In my experience, it tends to work better when you treat a two-dimensional array of a basic type like int as though it were a one-dimensional of length n*n. (This is expecially true in numerical work, where you are likely to call BLAS and LAPACK, but may be true elsewhere, as well. You probably aren't doing numerical work here, but, well, try #Mig's and mine both, and see which you don't prefer. Good luck.)
You can do this:
#include<stdio.h>
int main()
{
int asd[2][2] = {{0,1},{2,3}};
int (*se)[2]; // a pointer (*se) to an array (2-element array, but only you know it, not the compiler) of array-of-two-integers [2]
se = asd;
printf("%d %d\n%d %d\n", se[0][0], se[0][1], se[1][0], se[1][1]);
return 0;
}
or:
#include<stdio.h>
int main()
{
int asd[2][2] = {{0,1},{2,3}};
int (*se)[2][2]; // a pointer (*se) to a 2-element array (first [2]) of two element array (second [2]) of ints
se = &asd;
printf("%d %d\n%d %d\n", (*se)[0][0], (*se)[0][1], (*se)[1][0], (*se)[1][1]);
return 0;
}
You want something like this:
int asd[2][2];
int (*se)[2] = asd;
This is equivalent to
int (*se)[2] = &asd[0];
because asd decays to a pointer to its first element in this context.
The key thing to bear in mind is that the type of asd[0] is int[2], not int*, so you need a pointer to an int[2] (i.e. int (*)[2]) and not a pointer to an int* (i.e. int**).
Incidentally, you can make an int* point to the first element of the asd[0] if you like:
int *p = &asd[0][0]; // or just = asd[0];, because it decays to &asd[0][0];
but accessing the other elements of the 2D array as if it were a 1D array, e.g. p[2], would be undefined behaviour.
As a more general point, it's often better to eschew using raw C-style arrays altogether if you can help it. You might want to investigate std::array or std::vector, depending on your needs.
If you were allocating that array dynamically, you could do something like this:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int main() {
int i;
int **asd;
asd = (int **)malloc(sizeof(int *) * SIZE);
for (i = 0; i < SIZE; i++) {
asd[i] = (int*)malloc(sizeof(int) * SIZE);
}
int **se;
se = asd;
se[0][1] = 10;
printf("%d %d\n", se[0][1], asd[0][1]);
for (i = 0; i < SIZE; i++) {
free(asd[i]);
}
free(asd);
return 0;
}
EDIT: My first answer was wrong, here's what I had said:
You need a pointer to a pointer, since your array is 2-dimensional:
int asd[2][2];
int **se;
se = asd;
Now you should be able to:
se[0][1] = 10;
Related
I recently learned about pointers, and have been working hard to really understand them. However, I have run into trouble. For class we had to write a function that would double an array x amount of times. I was able to write the function without any real problems, but I'm trying to implement it into an actual code and I continue to get invalid pointer errors. Here's the code:
#include <iostream>
using namespace std;
int *ArrayDoubling(int inputArray[], int initialSize, int numberToDouble);
int main(){
int arr[2] = {0,1};
int array_size = 2;
int number = 3;
ArrayDoubling(arr, array_size, number);
}
int *ArrayDoubling(int inputArray[], int initialSize, int numberToDouble){
for(int i=0;i<numberToDouble;i++){
int *array2 = new int[initialSize*2];
for(int i=0;i<initialSize;i++){
array2[i] = inputArray[i];
array2[i+initialSize] = inputArray[i]*2;
}
initialSize = initialSize*2;
delete []inputArray;
inputArray = array2;
}
return inputArray;
}
So what exactly is causing the problem, and how can I fix it? Also not sure if this will actually print the output of the Array, but I'm also trying to get that to happen. Thanks for any and all help!
The ArrayDoubling function calls delete[] on the inputArray argument. But you pass a pointer to an automatic array when you call it in main. Calling delete[] with a pointer that you didn't get from new[] has undefined behaviour.
To fix it, only use the function with dynamically allocated arrays.
Your inner loop is looping by the number of times to double, not the size of the array. For inputs where the size of the array is less than the number of times to double, you will be accessing out of range indices.
I am not quite sure what your intension is, but I think your second for loop should look like this:
for(int i=0;i<initialSize;i++)
The biggest problem with your code is this line: delete []inputArray;
inputArray was originally declared as int arr[2] = {0,1}; which should not be deleted. You can only delete variables which were created using keyword new.
Broadly speaking, your program is going to need to look something like this. Note that new[] happens outside of the population loops in ArrayRepeat so it is only called once and similarly delete[] will only be called once, on the same pointer that was created through new[].
// dynamically allocate an array which contains the first `N` elements of
// `array` repeated `repeats` times.
int * ArrayRepeat (int * array, size_t N, int repeats) {
int * result = new int[N * repeats];
assert(result); // Error check
// Loops to populate result goes here
return result;
}
int main (void) {
int arr[] = {0, 1};
int * repeated = ArrayRepeat(arr, 2, 3);
// Print the result
for (int i = 0; i < 2 * 3; ++i) {
printf("%d\n", repeated[i]);
}
delete[] (repeated);
return 0;
}
Now the question is about typedef and c styles strings.
Here is the code.
#include <stdio.h>
#define C "BTP300", "BTD310", "BTI320", "BTS330"
typedef char* Course;// Line 1
#define CMP(a,b,c,d) ((a[(c)])d(b[(c)]))
int main(void) {
Course reference, test[] = {C}; //Line 2
sort(test,4,2);
reference=test[0];
difference(test, reference, 4);
return 0;
}
void sort(Course a[], int n, int k) {
int i, j;
Course temp;
for (i = n - 1; i > 0; i--) {
for (j = 0; j < i; j++) {
if (CMP(a[j],a[j+1],k,>)) {
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
void difference(Course a[], Course reference, int n) {
int i;
for (i = 0; i < n; i++)
printf("%d ", ABS(a[i] - reference));
printf("\n");
}
This is what I understood:
-Course is an alias for a pointer of char type.
-reference is a pointer of char type.
What I dont know or need to know the theory behind the code is:
1- What is test[] ??? I think its an array of pointers of type char in other words test[1] contains char*="btd310" .(I dont know the reasoning of it.)
2- how do i access the "d" in "btd310"?
3- using typedef int* how do i create a 2 dimensional int array? I was looking for something like
typedef int* arr;
void main(){
arr foo[]={{1,2},{3,4}}
}
Obviously above code didnt work for me so which way it will work i.e. i will get 2d int array.
Thanks guys in advance. And by the way, there might be better other ways to do it but i have to learn this way.
How the two macros in above code work?
1- What is test[] ??? I think its an array of pointers of type char in
other words test[1] contains char*="btd310" .
test is an array of type Course.
2- how do i access the "d" in "btd310"?
test[1][2]
3- using typedef int* how do i create a 2 dimensional int array?
why not just making it:
int foo[][2]={{1,2},{3,4}}
test is an array of Course, i. e. an array of char pointers. The type of course would be written as char *()[]. As to the contents of that array, the preprocessor will simply substitute "BTP300", "BTD310", "BTI320", "BTS330" for C, so the initialization of test reads test[] = {"BTP300", "BTD310", "BTI320", "BTS330"}.
You get the 'D' with test[1][2]. Please note that C is case sensitive everywhere, so 'D' is something very different than 'd'.
The use of strings in the initialization of char* and char ()[] is a bit special, so better not think about that. To declare a two dimensional array of int, you simply use int foo[2][2] = {{1, 2}, {3, 4}}; If you must use a typedef, you can use typedef int arr[2]; to define an array type for a one dimensional array of 2 integers, and you can then make a one dimensional array of two one dimensional array of 2 integers with arr foo[2] = {{1, 2}, {3, 4}};.
I have a 3x3 array that I'm trying to create a pointer to and I keep getting this array, what gives?
How do I have to define the pointer? I've tried every combination of [] and *.
Is it possible to do this?
int tempSec[3][3];
int* pTemp = tempSec;
You can do int *pTemp = &tempSec[0][0];
If you want to treat a 3x3 array as an int*, you should probably declare it as an int[9], and use tempSec[3*x+y] instead of tempSec[x][y].
Alternatively, perhaps what you wanted was int (*pTemp)[3] = tempSec? That would then be a pointer to the first element of tempSec, that first element itself being an array.
You can in fact take a pointer to a 2D array:
int (*pTemp)[3][3] = &tempSex;
You'd then use it like this:
(*pTemp)[1][2] = 12;
That's almost certainly not what you want, but in your comment you did ask for it...
Its easyier to use a typedef
typedef int ThreeArray[3];
typedef int ThreeByThree[3][3];
int main(int argc, char* argv[])
{
int data[3][3];
ThreeArray* dPoint = data;
dPoint[0][2] = 5;
dPoint[2][1] = 6;
// Doing it without the typedef makes the syntax very hard to read.
//
int(*xxPointer)[3] = data;
xxPointer[0][1] = 7;
// Building a pointer to a three by Three array directly.
//
ThreeByThree* p1 = &data;
(*p1)[1][2] = 10;
// Building a pointer to a three by Three array directly (without typedef)
//
int(*p2)[3][3] = &data;
(*p2)[1][2] = 11;
// Building a reference to a 3 by 3 array.
//
ThreeByThree& ref1 = data;
ref1[0][0] = 8;
// Building a reference to a 3 by 3 array (Without the typedef)
//
int(&ref2)[3][3] = data;
ref2[1][1] = 9;
return 0;
}
Oh. That's easy!
int aai[3][3];
int* pi = reinterpret_cast<int*>(aai);
You can actually use this awesome technique to cast it into other wonderful types. For example:
int aai[3][3];
int (__stdcall *pfi_lds)(long, double, char*) = reinterpret_cast<int (__stdcall *)(long, double, char*)>(aai);
Isn't that just swell? The question is whether it's meaningful.
You're asking how to lie to your compiler. So the first thing to know is: Why do you want to lie?
int a[20][30];
int* b=&a[0][0];
As Steve pointed out, the proper form is int *pTemp = &tempSec[0][0];. int** pTemp2 = tempSec; does not work. The error given is:
cannot convert 'int (*)[3]' to 'int**' in initialization
It's not stored as an array of pointers to arrays. It's stored as one big vector, and the compiler hides the [a][b] = [a*rowLength+b] from you.
#include <iostream>
using namespace std;
int main()
{
// Allocate on stack and initialize.
int tempSec[3][3];
int n = 0;
for(int x = 0; x < 3; ++x)
for(int y = 0; y < 3; ++y)
tempSec[x][y] = n++;
// Print some addresses.
cout << "Array base: " << size_t(tempSec) << endl;
for(int x = 0; x < 3; ++x)
cout << "Row " << x << " base: " << size_t(tempSec[x]) << endl;
// Print contents.
cout << "As a 1-D vector:" << endl;
int *pTemp = &tempSec[0][0];
for(int k = 0; k < 9; ++k)
cout << "pTemp[" << k << "] = " << pTemp[k] << endl;
return 0;
}
Output:
Array base: 140734799802384
Row 0 base: 140734799802384
Row 1 base: 140734799802396
Row 2 base: 140734799802408
As a 1-D vector:
pTemp[0] = 0
pTemp[1] = 1
pTemp[2] = 2
pTemp[3] = 3
pTemp[4] = 4
pTemp[5] = 5
pTemp[6] = 6
pTemp[7] = 7
pTemp[8] = 8
Note that the Row 0 address is the same as the full array address, and consecutive rows are offset by sizeof(int) * 3 = 12.
Another way to go about doing this, is to first create an array of pointers:
int* pa[3] = { temp[0], temp[1], temp[2] };
Then create a pointer pointer to point to that:
int** pp = pa;
You can then use normal array syntax on that pointer pointer to get the element you're looking for:
int x = pp[1][0]; // gets the first element of the second array
Also, if the only reason you're trying to convert it to a pointer is so you can pass it to a function, you can do this:
void f(int v[3][3]);
As long as the size of the arrays are fixed, you can pass a two-dimensional array to a function like this. It's much more specific than passing a pointer.
Original post follows - please disregard, it is misinformed. Leaving it for posterity's sake ;)
However, here is a link I found regarding memory allocation of 2-dimensional arrays in c++. Perhaps it may be of more value.
Not sure it's what you want, and it's been a while since I've written c++, but the reason your cast fails is because you are going from an array of arrays to a pointer of ints. If, on the other hand, you tried from array to array to a pointer of pointers, it would likely work
int tempSec[3][3];
int** pTemp = tempSec;
remember, your array of arrays is really a contiguous block of memory holding pointers to other contiguous blocks of memory - which is why casting an array of arrays to an array of ints will get you an array of what looks like garbage [that garbage is really memory addresses!].
Again, depends on what you want. If you want it in pointer format, pointer of pointers is the way to go. If you want all 9 elements as one contiguous array, you will have to perform a linearization of your double array.
Let's ask cdecl.org to translate your declaration for us:
int tempSec[3][3]
returns
declare tempSec as array 3 of array 3 of int
Ok, so how do we create a pointer to that? Let's ask cdecl again:
declare pTemp as pointer to array 3 of array 3 of int
returns
int (*pTemp)[3][3]
Since we already have the array 3 of array 3 of int, we can just do:
int (*pTemp)[3][3] = &tempSec;
int tempSec[3][3];
int* pTemp = tempSec[0];
I have a problem with two dimensional arrays :( I feel very stupid and Visual C does not help me :( and I also think that my mistake is very stupid but still I can't find it :( I have this code:
double matrix[100][100]; //which is full with a matrix 3x4
double nVector[10000]; // for negative doubles
//I wanted to see if there are negative doubles in each row and column
//and I want this to happen with function
And this is my function:
double* negativeVector(double*nVector, double*fromVector, int m, int n){
int position = 0;
double *myNegArray = nVector;
double *myMatrix = fromVector;
for(int i = 0; i < m*n; i++)
if(*(*(myMatrix+i)) < 0){
*(myNegArray+position) = *(*(myMatrix+i));
position++;
}
return myNegArray;
}
//for double*nVector I'm passing nVector
//for double*fromVector I'm passing *matrix
Visual C tells me that I have an error C2100: illegal indirection here: *(*(myMatrix+i)) I hope someone can help me (happy)
Thanks in advance!
*(*(myMatrix+i)) is wrong. This is a common mistake.
2D matrix does not create an array of pointers which you can access this way. It is a different structure. Even though an array is a pointer, 2D array is not a pointer to pointer, and it cannot be dereferrenced twice. Nor you have any other way to access element at coordinates (x,y) without knowing the layout in memory, because pointers to every line are nowhere to be found. For instance, char **argv parameter of main() is not a 2D array. This is an array of pointers to arrays, which is something else.
There're two ways to fix it.
One is replace
double *myMatrix = fromVector;
by
double *myMatrix[100] = (appropriate cast)fromVector;
and index it as myMatrix[i/n][i%n]
But then remember that 100 is a constant expression, and it cannot be passed as a parameter. Alternatively, you can implement the indexing operation yourself:
Pass additional parameter: matrix line size (100)
Instead of *(*(myMatrix+i)), write:
int row = i/n;
int col = i%n;
*(myMatrix+row*line_size+col) is your element.
first you might wanna start a small struct like
struct tmp {
bool negative;
double value;
};
and make your own way up to the
tmp *myvars [100][100];
.
instead try using that struct and try the std::vectors instead of arrays if that's possible then try using pointers on decalring the variable "1 time only" when declaring the variable as i said above
then pass arguments
( tmp *mystructpointer )
mystructpointer->.......
access your matrix directly ... peice of cake :D
If you are passing *matrix, you are actually passing a double[100] (an array of 100 doubles), that happens to be passed as a pointer to its first element. If you advance further than those 100 doubles using i added to that pointer, you advance into the next array of 100 doubles, since the 100 arrays of 100 doubles are stored next to each other.
Background: A multi-dimensional array is an array whose element type is itself an array. An array like double a[100][100]; can be declared equivalently as typedef double aT[100]; aT a[100];. If you use an array like a pointer, a temporary pointer is created to the array's first element (which might be an array). The * operator is such an operation, and doing *a creates a pointer of type double(*)[100] (which is a pointer to an array of 100 doubles), and dereferences it. So what you end up with *matrix is a double[100]. Passing it to the negativeVector function will create a pointer to its first element, which is of type double*.
Your pointer parameters point to the start of each of two arrays of 100 doubles each. So you should rewrite the function as
double* negativeVector(double*nVector, double*fromVector, int m, int n){
int position = 0;
double *myNegArray = nVector;
double *myMatrix = fromVector;
for(int i = 0; i < m*n; i++)
if(*(myMatrix + i) < 0){
*(myNegArray + position) = *(myMatrix + i);
position++;
}
return myNegArray;
}
Notice that since your i iterates beyond the first of the 100 arrays stored in the 2d array, you will formally not be correct with this. But as it happens those arrays must be allocated next to each other, it will work in practice (and in fact, is recommended as a good enough work around for passing multi-dimensional arrays around as pointers to their first scalar element).
I have no clue why you are copying the arrays twice (once in the parameters of the function and a second time by declaring some new arrays)... You should also think of using the STL... std::vector will make the your life way easier ;)
double* negativeVector(double*nVector, double*fromVector, int m, int n){
int position = 0;
double *myNegArray = nVector;
double *myMatrix = fromVector;
for(int i = 0; i < m*n; i++)
if(*((myMatrix+i)) < 0){
*(myNegArray+position) = *((myMatrix+i));
position++;
}
return myNegArray;
}
is that homework? some templates - just for fun ;-)
double matrix[100][100];
double nVector[10000];
template< const int m, const int n >
double* negativeVector( double* myNegArray, const double (&myMatrix)[m][n] )
{
int position = 0;
for( int i = 0; i < m; ++i )
{
for( int j = 0; j < n; ++j )
{
const double value = myMatrix[ i ][ j ];
if ( value < 0 )
{
myNegArray[ position ] = value;
++position;
}
}
}
return myNegArray;
}
int main()
{
//...initialize matrix here...
negativeVector( nVector, matrix );
}
Perhaps rewrite this using std::vector to increase readability? (#):
#include <vector>
std::vector< std::vector<double> > matrix; //which is full with a matrix 3x4
std::vector<double> row;
row.resize(100,0);
matrix.resize(100,row);
std::vector<double> nVector; // for negative doubles, no size, we'll "push_back"
//I wanted to see if there are negative doubles in each row and column
//and I want this to happen with function
This is the stl enabled version of the function:
//I'm returning void because nvector contains the result,
//so I don't feel the need to return anything. vectors contain their
//own size so n and m are also not needed. Alsom pass in references
void negativeVector(std::vector<double>& nVector,
std::vector< std::vector<double> >& fromVector){
nVector.clear();
int i,j;
for(i = 0; i < fromVector.size(); i++) {
for(j = 0; j < fromVector[i].size(); j++) {
if(fromVector[i][j] < 0){
nVector.push_back(fromVector[i][j]);
}
}
}
}
call with:
negativeVector(nVector, matrix);
Once the function completes, nVector contains all negative numbers in matrix.
Read more about std::vector here.
(#) for people like me who are too lazy/stupid to comprehend code containing pointers.
Take a look at C++ Faq site:
How do I allocate multidimensional arrays using new?
link
And read until point [16.20] summarize all the answers you are getting and at the end you get a very useful Matrix template class.
Have a good read.
There is a pointer-to-an-Array of Arrays i.e. NameList in the code. I want the contents of each of the Arrays in the Pointer(NameList) to get printed one by one. The below code is not able do the task. Pls. help.
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
main()
{ Function(NameList); }
Function(int *ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 2; j++)
{
//It does not print the data
printf("\nName: %s", ArrayPointer[index++]);
}
index=0; //Counter reset to 0
ArrayPointer++; //Pointer is incremented by one to pick next array in the pointer
}
}
print("code sample");
Another note from the original poster of the question:
I have completed a pacman game in Turbo C. I was polishing some graphics routines so that it can be reused again easily. This is only a small sample created for the purpose of help and understanding the concept. All data in the code actually are char arrays for sprites. Now i simply want to call a function passing the pointer so that each arrays in the pointer are drawn to the screen. How can this code be modified to handle this? Im actually stuck up here.
Darn it litb, once again you beat me to the punch by mere minutes. (If only I didn't have kids who keep waking up...)
Ahh, what the hell. Perhaps this will still be useful to somebody.
Oh, and just to nail this thing down:
Arrays, such as int a[4] allocate memory space for their data.
Pointers, such as int * p allocate just enouch memory space for a pointer to another spot in memory.
That's why we can use sizeof on arrays and get the full memory footprint, but not on pointers.
Other than that little distinction, there really isn't a big difference between int[] and int*. (Consider how many folks declare *main(int argc, char **argv) vs main(int argc, char * argv[]).)
ATTENTION: All memory addresses here are fictional. I'm just making them up to illustrate a point.
Given:
int Data1[] = {10,11};
int Data2[] = {20,22};
int Data3[] = {30,33};
We now have 3 blocks of memory. Say:
0xffff0000-0xffff0003 with a value of (int)(10)
0xffff0004-0xffff0007 with a value of (int)(11)
0xffff0008-0xffff000b with a value of (int)(20)
0xffff000c-0xffff000f with a value of (int)(22)
0xffff0010-0xffff0013 with a value of (int)(30)
0xffff0014-0xffff0017 with a value of (int)(33)
Where:
Data1 == & Data1 [0] == 0xffff0000
Data2 == & Data2 [0] == 0xffff0008
Data3 == & Data3 [0] == 0xffff0010
NO, I'm not going to get into big-endian vs little-endian byte ordering here!
Yes, in this case, Data1[2] == Data2[0]. But you can't rely on your compiler laying things out in memory the same way I've laid them out here.
Next:
int *NameList[] = {Data1, Data2, Data3};
So we now have another block of memory. Say:
0xffff0018-0xffff001b with a value of (int*)(0xffff0000)
0xffff001c-0xffff001f with a value of (int*)(0xffff0008)
0xffff0020-0xffff0023 with a value of (int*)(0xffff0010)
Where:
NameList == & NameList [0] == 0xffff0018
Note that NameList is of int ** type, and NOT int* type!
We can then write:
void Function(int **ArrayPointer)
{
for ( int i=0; i < 3; i++ )
for ( int j=0; j < 2; j++)
printf("Name: %d\n", ArrayPointer[i][j] );
}
int main() { Function(NameList); }
ArrayPointer resolves to (int**)0xffff0018.
ArrayPointer[0] == *( (int**) 0xffff0018 ) == (int*)(0xffff0000) == Data1.
ArrayPointer[0][1] == *( ( * (int**) 0xffff0018 ) + 1 ) == (int) * ( (int*)0xffff0000 + 1 ) == (int) * (int*) 0xffff0004 == Data1[1].
You may want to review pointer arithmetic: array[N] == *( array + N )
main has to return a type. You forget to put "int" as a return type (implicit int in C++ is banned).
Having said that, i'm not sure what you mean by
// It does not print the data
printf("\nName: %s", ArrayPointer[index++]);
ArrayPointer[index++] would, as it is defined in the parameter list, return an int. How is that supposed to store a name ? It will store an integer!
Once again, that said, you can't call that Function (pun intended) with that particular argument. Let's view your types:
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
Data1 Data2 Data3 NameList
int[2] int[2] int[2] int*[3]
Contrary to what you said, NameList is not a pointer to an array of arrays. I feel i need to show you what that would be:
int (*NameList)[N][M] = Some3DimensionalArray;
That wouldn't make sense at all. So what do you have?
Data1 = array of 2 int
Data2 = array of 2 int
Data3 = array of 2 int
NameList = array of poiners to int
That is what you got. And you pass NameList to a Function that wants a pointer to an int. It must fail already at the time you call Function in main! I've got no idea what you mean by name in that line in Function. But if you want to print out the integers that are stored in the arrays pointed to (by pointers to their first element), you can do it like this (keeping your code as much as i can):
// don't forget the return type, mate. Also see below
void Function(int **ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 2; j++)
{
// It does not print the data. It is not a string,
// but an int!
printf("\nName: %d\n", ArrayPointer[i][index++]);
}
index=0; //Counter reset to 0
// no need to increment the pointer. that's what the indexing by i
// above does
// ArrayPointer++;
}
}
I keep preaching people asking questions the difference between a pointer and an array. It's crucial to write correct code. I hope i could help. At the end, just a little though about the difference between int[] and int*. The first is an incomplete array type, while the second is a complete type (pointer to int):
typedef int Single[]; // array of indeterminate size.
typedef int *Pointer; // pointer to int
Single s1 = { 1, 2, 3, 4 }; // works!
Pointer s2 = { 1, 2, 3, 4 }; // no no, doesn't work. s2 wants an address
s2's type now has a type different from int[], because you initialized the array which would have incomplete type, the array s1 become complete after defined. It has type of int[4]. In parameter lists, however, there exist a special rule, which will cause any array type (even complete ones!) to be equivalent to a pointer to their first argument. Thus:
void f(int *a) <=> void f(int a[]) <=> void f(int a[42]);
void f(int (*a)[42]) <=> void f(int a[][42]) <=> void f(int a[13][42])
// ...
That's because you can't pass arrays by value. The compiler abuses that to make array types equivalent to pointers to their first element. Same deal with functions:
void f(int a()) <=> void f(int (*a)())
Because you can't pass functions by value (huh, doesn't even make sense at all to me), the compiler abuses it to make a function type in a parameter list equivalent to a pointer to that function type.
int Data1[]
has the type of
int *
and
int *NameList[]
has the type of
int **
You have a two-dimensional array there. Most likely you meant:
Function(int **ArrayPointer)
On that note, ANSI C/C89/C99 functions have an explicit return type (or void), e.g.
int main() { ... }
void Function() { ... }
The value pointed to by ArrayPointer is an int, not a string. Thus
printf("\nName: %s", ArrayPointer[index++]);
Should be written as something else.
A third thing: index == j in your code. Thus index can be removed in favor of j.
i and j are probably not good variable names here because ArrayPointer is not name describing a list of something.
If you need more help, please post what you're looking to do, because you code has several bugs (and oddities) in it.
Judging by your "answer" (you really should have edited your original post and added this information), you probably want something like this:
void draw_all_sprites(Sprite *sprites, size_t num_sprites)
{
Sprite *cur_sprite;
size_t i;
for(i = 0; i < num_sprites; ++i)
{
draw_sprite(cur_sprite);
++cur_sprite;
}
}
A fairly simple for loop to iterate through elements in an array.
Paramod,
is there a function you need to call that takes something along the lines of
void drawSprite(int *data, int rows, int cols)
?
Then you need to have all data in a single chunk of memory. In your example, the compiler allocates a separate chunk for every row, and then another chunk to hold the three pointers to rows. Thus, the array is kept in 4 different places.
What you need is a multidimensional array rather than array of arrays. Initialize your data like this:
int data[3,2] = {{10,10},{20,20},{30,30}};
Then you can call your function like this:
drawSprite(&data[0,0], 3, 2);
Using multidimensional array places all elements in one block of memory. The advantage is, you can pass the piointer to first element, and you know where all other elements are. The disadvantage - all rows are allocated the same size.
I made some corrections in your program please find them and compare. I know its too late for the response. But I saw this today itself.
int Data1[] = {10,10};
int Data2[] = {20,20};
int Data3[] = {30,30};
int *NameList[] = {Data1, Data2, Data3};
main()
{
Function(NameList);
}
Function(int *ArrayPointer)
{
int i, j, index=0;
for (i=0; i < 3; i++)
{
for (j=0; j < 5; j++)
{
//It does not print the data
printf("\nName: %d\n", *((int *)ArrayPointer[i] + index));
index++;
}
index=0; //Counter reset to 0
}
}
Explanation:
When you pass NameList to Function as a pointer to an integer, what gets passed is the address of the first element of the array, which happens to be Data1 (an address to an array). But since this address is held in an array of ints, it will be considered as an integer. To make it behave like an address to an array(or, for that matter pointer to an int) you need to cast it to (int *). Thats what I did in :
printf("\nName: %d\n", *((int *)ArrayPointer[i] + index));