I'm practicing pointers and want to substitute pointer operations in place of the arrays to traverse through the elements of the array. I have read numerous articles and cannot grasp this concept. Can someone explain?
Here I made a 2D array and iterated through it using a basic nested for-loop, but want to use pointers;
int test[3][2] = {1,4,2,5,2,8};
for (int i = 0 ; i < 3; i++) {
for (int j = 0; j < 2; j++) {
printf("%d\n", test[i][j]);
}
}
int test[3][2] = {{1,4},{2,5},{2,8}};
// Define a pointer to walk the rows of the 2D array.
int (*p1)[2] = test;
// Define a pointer to walk the columns of each row of the 2D array.
int *p2 = NULL;
// There are three rows in the 2D array.
// p1 has been initialized to point to the first row of the 2D array.
// Make sure the iteration stops after the third row of the 2D array.
for (; p1 != test+3; ++p1) {
// Iterate over each column of the arrays.
// p2 is initialized to *p1, which points to the first column.
// Iteration must stop after two columns. Hence, the breaking
// condition of the loop is when p2 == *p1+2
for (p2 = *p1; p2 != *p1+2; ++p2 ) {
printf("%d\n", *p2);
}
}
In some compilers you can also use a single loop, treating a multidimensional array as a one-dimensional array read in row-major order.
This is mentioned in King's C Programming: A Modern Approach (2nd ed., p268).
#include <stdio.h>
int main(void)
{
int test[3][2] = {{1,4},{2,5},{2,8}}, *p;
for(p = &test[0][0]; p <= &test[2][1]; p++)
{
printf("%d\n", *p);
}
return 0;
}
Try the following and investigate
#include <stdio.h>
int main(void)
{
int test[3][2] = { { 1,4 }, { 2,5 }, { 2,8 } };
for ( int ( *p )[2] = test ; p != test + 3; ++p )
{
for ( int *q = *p; q != *p + 2; ++q ) printf( "%d ", *q );
puts( "" );
}
return 0;
}
The putput is
1 4
2 5
2 8
The first pointer is a pointer to an object of type int[2] that is it points to the first "row" of the array and then due to increments it points to other rows.. The second pointer is a pointer to an object of type int. It points to the first element of each row in the inner loop.
Treating a 2d array as 1d array is very easy using pointer arithmetic to iterate.
void print_2d_array(int *num, size) {
int counter = 0;
while (counter++ < size) {
printf("%i ", *num);
num++;
}
printf("\n");
}
int main() {
int matrix[2][3] = {{2, 11, 33},
{9, 8, 77}};
int matrix_size = sizeof(matrix) / sizeof(int); // 24 bytes / 4 (int size) = 6 itens
print_2d_array(matrix, matrix_size);
return 0;
}
If pointer declaration is the goal of your practice, use the following initialization:
int (*pTest)[rmax][cmax] = test;
Once you do that, the syntax of using pointer indexing mirrors that of array indexing, except that you have to use the * de-referencing operator.
for (int i= 0; i < 3; i++) {
for (int j= 0; j < 2; j++) {
printf ("%d ", *(pTest[i][j]));
}
printf ("\n");
}
However, if pointer arithmetic is the goal of your practice, then the following will work too:
int *res = &test;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
printf ("%d ", *(res + i*2 + j));
}
printf ("\n");
}
OUTPUT
1 4
2 5
2 8
Related
I just started to tinker with pointers in multidimensional arrays and was trying to pass and array into a void function. The compilator just threw an error. I need the array to be passed exactly as a pointer to maybe change it then by reference.
#include <stdio.h>
#include <stdlib.h>
void Func(int** matrix, int sizeFirst, int sizeSecond)
{
for (int i = 0; i < sizeFirst; i++)
{
for (int j = 0; j < sizeSecond; j++)
{
printf("%d\n", matrix[i][j]);
}
}
}
int main()
{
int array[2][3] = {
{5,8,2},
{1,3,6}
};
int sizeMain = sizeof(array)/sizeof(array[0]);
int sizeInner = sizeof(array[0])/sizeof(array[0][0]);
Func(array, sizeMain, sizeInner);
return 0;
}
2D array is not pointer to pointer. Your code is invalid as Func does not know how many columns every row has. Also, use the correct type for sizes & indexes
void Func(size_t sizeFirst, size_t sizeSecond, int (*matrix)[sizeSecond])
{
for (int i = 0; i < sizeFirst; i++)
{
for (int j = 0; j < sizeSecond; j++)
{
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int main()
{
int array[2][3] = {
{5,8,2},
{1,3,6}
};
size_t sizeMain = sizeof(array)/sizeof(array[0]);
size_t sizeInner = sizeof(array[0])/sizeof(array[0][0]);
Func(sizeMain, sizeInner, array);
return 0;
}
https://godbolt.org/z/Ejfrdd3nK
With pointers to VLAs, you can preserve all of the dimensions in the type of the argument and then let C do the multidimensional scaling for you.
In older versions of C you need to calculate the spot manually, remembering that
the first dimension from the right moves by 1 (scaled by sizeof(type), which C does for you), the second by first dimension from the right,
the third by first dimension from the right multiplied by second dimension from the right and so on.
It's sort of like digits in numbers (units, tens, hundreds, ...) except that the next scaling is the previous scaling multiplied by the previous dimension rather than by a constant radix.
(You could let C convert groups of decimal digits to decimal numbers by letting it subtract some &decdigits[a][b][c] and &decdigits[0][0][0] where decdigits is some decdigits[10][10][10], i.e.:
char decdigits[10][10][10]; printf("%d\n", (int)(&decdigits[1][2][3] - &decdigits[0][0][0])) /*prints 123*/;)
#include <stdio.h>
void Func( int sizeFirst, int sizeSecond, int (*matrix)[sizeFirst][sizeSecond])
{
for (int i = 0; i < sizeof((*matrix))/sizeof((*matrix)[0]) ; i++)
{
for (int j = 0; j < sizeof((*matrix)[0])/sizeof((*matrix)[0][0]) ; j++)
{
printf("%d ", (*matrix)[i][j]);
}
puts("");
}
}
void Func_89( int sizeFirst, int sizeSecond, int *matrix)
{
for (int i = 0; i < sizeFirst; i++)
{
for (int j = 0; j < sizeSecond; j++)
{
printf("%d ", matrix[i*sizeSecond + j]);
}
puts("");
}
}
int main()
{
int array[2][3] = {
{5,8,2},
{1,3,6}
};
int sizeMain = sizeof(array)/sizeof(array[0]);
int sizeInner = sizeof(array[0])/sizeof(array[0][0]);
Func(sizeMain, sizeInner,&array );
puts("===");
Func_89(sizeMain, sizeInner,&array[0][0] );
//char decdigits[10][10][10]; printf("%d\n", (int)(&decdigits[1][2][3] - &decdigits[0][0][0])); //123
return 0;
}
First of you have to understand what int ** represent, it represents pointer to integer pointer, here's an example:
int a = 10;
int *p = &a; // 'p' points to 'a`
int **pp = &p; // 'pp' points to 'p' (pointer to integer)
So because of this, you can't use int ** for an integer array. Now that's out of the way, let's see what can you do instead (solution)
You can simply add a pointer to an integer array in a function definition like this
void Func(int *matrix[], int rows, int cols)
Or you can simply do
void Func(int matrix[rows][cols])
Note: Array of strings or 2D character array (char array[][]) can be represented as char**
I have to create functions for print array, fill array witn descending numbers.
I created functions for printing array and creating descending array.But I faced with a problem.
If I use my own function printArray() it prints something unclear. Where is the problem, what i do wrong?
Please, help.
Here is the code in C. value - is value of array
Function for printing array:
void printArray (int arr[]){
int i;
printf("\n");
for(i = 0; i < value; i ++)
printf("%3d ", arr[i]);
}
Function for creating descending array:
int createDescendingArray(int a[])
{
int i;
printf("\nDescending array is created.\n");
for (i = value; i > 0; i--) {
a[i] = i;
}
printArray(a); // print of created array
}
Main function:
int main(){
int arr1[value]; //create new array
arr1[value] = createDescendingArray (arr1); //fill array with descending numbers
}
However when I don't use my print function in function createDescendingArray() and print it in Main funktion with standart method like this:
{int i;
for(i = 0; i < value; i++)
{
a[i]=i;
printf("%3d", a[i]);
}
}
It shows descending array as ascending (look at the picture)
How it works?
You have been using a variable named value in your function which prints array, without initializing it, hence the garbage value.
you should initialize it in the function or pass its start value as an argument to the function.
#include <stdio.h>
#include <stdlib.h>
void printArray(int *arr, int length)
{
int i;
printf("\n");
for (i = 0; i < length; i++)
{
printf("%3d ", arr[i]);
}
}
int *createDescendingArray(const int length)
{
if (length == 0)
return NULL;
int *a = malloc(length * sizeof(int));
;
printf("\nDescending array is created.\n");
for (int i = length-1; i >= 0; i--)
{
a[i] = i;
}
printArray(a, length); // print of created array
return a;
}
int main()
{
int *a = createDescendingArray(20);
printArray(a, 20);
return 0;
}
these changes should most probably do the trick but again, there is no initialization of value in the function that creates array as well
EDIT: stop creation of array if length is 0
EDIT2: fixed code to consider 0 as an element
EDIT3: Fixed code with suggestion from #CraigEstey in comments, tested and working
EDIT4: fixed for loop and removed cast on mallock
The function
int createDescendingArray(int a[])
{
int i;
printf("\nDescending array is created.\n");
for (i = value; i > 0; i--) {
a[i] = i;
}
printArray(a); // print of created array
}
is wrong.
According to the output in your question, it seems that you have defined value as 4 (you are not showing us the code with the definition). In that case, your code for the mentioned function is equivalent to the following:
int createDescendingArray(int a[])
{
printf("\nDescending array is created.\n");
a[4] = 4;
a[3] = 3;
a[2] = 2;
a[1] = 1;
printArray(a); // print of created array
}
I did nothing else to the code than unroll the loop.
Since the array a has a size of 4 elements, valid indices are from 0 to 3. Therefore, by writing to a[4], you are writing to the array out of bounds, causing undefined behavior.
If you had written
for (i = value - 1; i >= 0; i--)
instead of
for (i = value; i > 0; i--)
then the unrolled loop would be:
a[3] = 3;
a[2] = 2;
a[1] = 1;
a[0] = 0;
This is better, because now we have fixed the undefined behavior; you are no longer writing to the array out of bounds. However, this is still not what you want. If you want descending output, your unrolled loop must look like this instead:
a[0] = 3;
a[1] = 2;
a[2] = 1;
a[3] = 0;
This can be accomplished by changing your function to the following:
int createDescendingArray(int a[])
{
int i;
printf( "\nDescending array is created.\n" );
for ( i = 0; i < value; i++ ) {
a[i] = value - i - 1;
}
printArray(a); // print of created array
}
Here is a small test program:
#include <stdio.h>
//NOTE: It is customary for constants to be written upper-case,
//not lower-case, so the line below should normally not be used.
#define value 4
void printArray (int arr[]) {
int i;
printf( "\n" );
for( i = 0; i < value; i++ )
printf("%3d ", arr[i]);
}
int createDescendingArray(int a[])
{
int i;
printf( "\nDescending array is created.\n" );
for ( i = 0; i < value; i++ ) {
a[i] = value - i - 1;
}
printArray(a); // print of created array
}
int main( void )
{
int array[value];
createDescendingArray( array );
}
The output is:
Descending array is created.
3 2 1 0
In this test program, I took over most of your other code, but I did not take over the function main, because it was also causing undefined behavior:
int main(){
int arr1[value]; //create new array
arr1[value] = createDescendingArray (arr1); //fill array with descending numbers
}
In the line
arr1[value] = createDescendingArray (arr1);
you are assigning the return value of the function to a variable, although the function did not return a value. This causes undefined behavior. You may want to consider changing the return type to void in the function declaration, if it does not return a value.
Also, even if the function did return a value, arr1[value] would be writing to the array out of bounds, as valid indices are from 0 to value - 1.
Given array A[3][2] ={(1,2),(3,4),(5,6)}
I want to traverse through the first column elements i.e 1,3,5 and next column elements, 2,4,6. All this must be done using a single pointer. How to do this?
If you have 2 array indices, use two for loops.
uint32_t m, n, sum = 0U;
for(n = 0U; n < 2; ++n){ // For each column [n]
for(m = 0U; m < 3; ++m){ // For each row [m] in column [n]
sum += A[m][n];
}
}
Edit: There's not really a difference when using pointers (especially once passed into a function, when it decays). But you have to deal with dereferencing the pointer. This code is more type obfuscating, and could lead one to improperly type/reference, if you don't compile with sufficient warning flags.
uint32_t A[3][2] = {{1,2},{3,4},{5,6}};
uint32_t m, sum = 0U;
uint32_t (*pa2_n)[2];
uint32_t * p_m;
for(pa2_n = &A[0]; pa2_n < &A[3]; ++pa2_n){ // For each column [n]
for(m = 0U; m < 2U; ++m){ // For each row [m] in column [n]
sum += (*pa2_n)[m];
}
// Or
for(p_m = &(*pa2_n)[0]; p_m < &(*pa2_n)[2]; ++p_m){ // For each row [m] in column [n]
sum += *p_m;
}
}
printf("Hello World %u\n", sum);
//
// a method using only 1 pointer could rely on pointer math
//
#include <stdio.h>
#define ROWS 3
#define COLS 2
int
main(void)
{
int matrix[ROWS][COLS] = {
{ 1, 2 },
{ 3, 4 },
{ 5, 6 },
};
int *ptr = &matrix[0][0];
while (1) {
printf("%d,", *ptr);
// point into the next row, same col
ptr += COLS;
// now pointing at least 1 row too many?
if (ptr >= &matrix[ROWS][0]) {
printf("\n");
// at least 1 row too many, last col?
if (ptr >= &matrix[ROWS][COLS - 1])
break;
// backup by total element count - 1 (first row, next col)
ptr -= (ROWS * COLS) - 1;
}
}
return (0);
}
If you want to traverse in the given array int A[3][2] using single pointer you should look at this code:
#include <stdio.h>
int main(void)
{
int arr[3][2] = { 1, 2, 3, 4, 5, 6 };
int *ptr = arr[0], i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
{
printf("%4d", *(ptr+j*2+i));
}
putchar('\n');
}
return 0;
}
I assume you know about the memory representation of a 2D array. If you don't then I'll tell you in short.
A 2D array is stored in the computer's memory on consecutive locations, i.e. one row after another.
That is elements of arr in the above code, will be stored as first 1, second 2, and so on. Using this *(ptr+j*2+i) statement we are traversing through the array. In 1st iteration we are printing ptr+0 then ptr+2 and so on.
Or you can make it simple by declaring a pointer to an array
int (*ptr)[2]; ptr = arr;
and now you can access elements of arr using ptr just like a 2D array.
printf("%4d", ptr[j][i]); or printf("%4d", *(*(ptr+j)+i));
I hope you'll understand the answer.
I'm writing a C for which I need to create a 2D array. I've found a solution to my problem using double pointers (pointers to pointers) in the following way:
#include <stdio.h>
#include <stdlib.h>
int d = 3;
#define DIM_MAX 9
void changeArray(int d, int *array[d]);
int main()
{
//alocate array of 'd' colummns and 'd' row using malloc using array of pointers
int **array = malloc(d*sizeof(int *));
for(int count = 0; count < d; count++)
{
array[count] = malloc(d*sizeof(int *));
}
/* Call changeArray function */
changeArray(d, array);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
for(int count = 0; count < d; count++)
{
free(array[count]);
}
return 0;
}
void changeArray(int n, int *array[d])
{
for(int i =0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
array[i][j] = i*j;
}
}
return;
}
The code above works pretty well (it seems), but I've read in the web that using pointer to pointer is not the correct way to create 2D arrays. So I've come up with the following code, which also works:
#include <stdio.h>
#include <stdlib.h>
#define DIM_MAX 9
int d = 3;
void changeArray(int d, int *array[d]);
int main()
{
//alocate array of 'd' colummns and 'd' row using malloc using array of pointers
int *array[DIM_MAX] = {0};
for(int count = 0; count < d; count++)
{
array[count] = (int *)malloc(d*sizeof(int *));
}
/* Call changeArray function */
changeArray(d, array);
for(int i = 0; i < d; i++)
{
for(int j = 0; j < d; j++)
{
printf("%d ", array[i][j]);
}
printf("\n");
}
for(int count = 0; count < d; count++)
{
free(array[count]);
}
return 0;
}
void changeArray(int n, int *array[d])
{
for(int i =0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
array[i][j] = i*j;
}
}
return;
}
What is the difference in using any of the two ways above to write this code?
[Not an answer, but an alternative approach to achieve the desired result, namely defining a user-defined 2D array.]
Assuming the compiler in use supports VLAs you could do this:
#include <stddef.h> /* for size_t */
void init_a(size_t x, size_t y, int a[x][y]); /* Order matters here!
1st give the dimensions, then the array. */
{
for (size_t i = 0; i < x; ++i)
{
for (size_t j = 0; j < y; ++j)
{
a[i][j] = (int) (i * j); /* or whatever values you need ... */
}
}
}
int main(void)
{
size_t x, y;
/* Read in x and y from where ever ... */
{
int a[x][y]; /* Define array of user specified size. */
init_a(x, y, a); /* "Initialise" the array's elements. */
...
}
}
It is actually pretty simple. All you have to do is this:
int i[][];
You are overthinking it. Same as a normal array, but has two indexes.
Let's say you want to create a "table" of 4 x 4. You will need to malloc space for 4 pointers, first. Each of those index points will contain a pointer which references the location in memory where your [sub] array begins (in this case, let's say the first pointer points to the location in memory where your first of four arrays is). Now this array needs to be malloc for 4 "spaces" (in this case, let's assume of type INT). (so array[0] = the first array) If you wanted to set the values 1, 2, 3, 4 within that array, you'd be specifying array[0][0], array[0][1], array[0][2], array[0][3]. This would then be repeated for the other 3 arrays that create this table.
Hope this helps!
I was writing a code the other day and I found it rather strange, that int** and int[][] does not behave the same way. Can anyone point out the differences between them? Below is my sample code, which fails with a segmentation fault, if I pass constant size 2d array, while it does work fine when I pass a dinamically allocated 2d array.
I am confused mainly because ant int[] array works the same as int*.
#include<stdio.h>
#include<stdlib.h>
void sort_by_first_row(int **t, int n, int m)
{
int i, j;
for(i = m-1 ; i > 0 ; --i)
{
for(j = 0 ; j < i; ++j)
{
if(t[0][j] < t[0][j+1])
{
int k;
for(k = 0 ; k < n ;++k)
{
int swap;
swap = t[k][j];
t[k][j] = t[k][j+1];
t[k][j+1] = swap;
}
}
}
}
}
int main(void) {
int i, j;
/* Working version */
/*int **t;
t =(int**) malloc(3*sizeof(int*));
for(i = 0; i < 3; ++i)
{
t[i] = (int*) malloc(6*sizeof(int));
}*/
/*WRONG*/
int t[3][6];
t[0][0] = 121;
t[0][1] = 85;
t[0][2] = 54;
t[0][3] = 89;
t[0][4] = 879;
t[0][5] = 11;
for( i = 0; i < 6; ++i )
t[1][i] = i+1;
t[2][0] = 2;
t[2][1] = 4;
t[2][2] = 5;
t[2][3] = 3;
t[2][4] = 1;
t[2][5] = 6;
sort_by_first_row(t, 3, 6);
for(i = 0; i < 3; ++i)
{
for(j = 0; j < 6; ++j)
printf("%d ", t[i][j]);
printf("\n");
}
return 0;
}
So based on the below answers I realize, that a multidimensional array is stored continuously in a row major order. After some modification, the below code works:
#include<stdio.h>
#include<stdlib.h>
void sort_by_first_row(int *t, int n, int m)
{
int i, j;
for(i = m-1 ; i > 0 ; --i)
{
for(j = 0 ; j < i; ++j)
{
if(t[j] < t[j+1])
{
int k;
for(k = 0 ; k < n ;++k)
{
int swap;
swap = t[k*m + j];
t[k*m + j] = t[k*m + j+1];
t[k*m + j+1] = swap;
}
}
}
}
}
int main(void) {
int i, j;
/* Working version */
/*int **t;
t =(int**) malloc(3*sizeof(int*));
for(i = 0; i < 3; ++i)
{
t[i] = (int*) malloc(6*sizeof(int));
}*/
/*WRONG*/
int t[3][6];
t[0][0] = 121;
t[0][1] = 85;
t[0][2] = 54;
t[0][3] = 89;
t[0][4] = 879;
t[0][5] = 11;
for( i = 0; i < 6; ++i )
t[1][i] = i+1;
t[2][0] = 2;
t[2][1] = 4;
t[2][2] = 5;
t[2][3] = 3;
t[2][4] = 1;
t[2][5] = 6;
sort_by_first_row(t, 3, 6);
for(i = 0; i < 3; ++i)
{
for(j = 0; j < 6; ++j)
printf("%d ", t[i][j]);
printf("\n");
}
return 0;
}
My new question is this: How to modify the code, so that the procedure works with int[][] and int** also?
Realize that int **t makes t a pointer to a pointer, while int t[3][6] makes t an array of an array. In most cases, when an array is used in an expression, it will become the value of the address of its first member. So, for int t[3][6], when t is passed to a function, the function will actually be getting the value of &t[0], which has type pointer to an array (in this case, int (*)[6]).
The type of what is being pointed at is important for how the pointer behaves when indexed. When a pointer to an object is incremented by 5, it points to the 5th object following the current object. Thus, for int **t, t + 5 will point to the 5th pointer, while for int (*t)[M], t + 5 will point to the 5th array. That is, the result of t + 5 is the same as the result of &t[5].
In your case, you have implemented void sort_by_first_row(int **t, int n, int m), but you are passing it an incompatible pointer. That is, the type of &t[0] (which is what t will become in main) is not the same as what the function wants, a int **t. Thus, when the sorting function starts to use that address, it will think its indexing into pointers, when the underlying structure is an array of arrays.
int** is quite different from int[][]. int** is simply a pointer to a pointer and would appear like the following:
in reality, you can access the entire multidimensional array with simply int* pointing to the first element, and doing simple math from that.
Here is the result of the separate allocations (in your commented code):
However when you allocate a multidimensional array, all of the memory is contiguous, and therefore easy to do simple math to reach the desired element.
int t[3][6];
int *t = (int*) malloc((3 * 6) * sizeof(int)); // <-- similarly
This will result in a contiguous chunk of memory for all elements.
You certainly can use the separate allocations, however you will need to walk the memory differently.
Hope this helps.
int t[3][6] is very nearly the same thing as int t[18]. A single contiguous block of 18 integers is allocated in both cases. The variable t provides the address of the start of this block of integers, just like the one-dimensional case.
Contrast this with the case you have marked as "working", where t gives you the address of a block of 3 pointers, each of which points to a block of memory with 6 integers. It's a totally different animal.
The difference between t[3][6] and t[18] is that the compiler remembers the size of each dimension of the array, and automatically converts 2D indices into 1D offsets. For example, the compiler automatically converts t[1][2] into *(t + 1*6 + 2) (equivalent to t[8] if it were declared as a one-dimensional array).
When you pass a multi-dimensional array to a function, there are two ways to handle it. The first is to declare the function argument as an array with known dimension sizes. The second is to treat your array like a 1D array.
If you are going to declare the size of your array, you would declare your function like this:
void sort_by_first_row(int t[][6], int n)
or this
void sort_by_first_row(int t[3][6])
You either have to declare all array dimension sizes, or you can leave out the first size. In both cases, you access elements of t using t[i][j]; you've given the compiler enough information to do the offset math that converts from 2D notation to a 1D index offset.
If you treat it as a 1D array, you have to pass the array dimensions and then do the offset math yourself.
Here's a full working example, where f and f2 both generate the same output:
void f(int* t, int m, int n)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
std::cout << t[i * n + j] << " ";
std::cout << std::endl;
}
void f2(int t[][6], int m)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < 6; j++)
std::cout << t[i][j] << " ";
std::cout << std::endl;
}
int main()
{
int t[3][6];
int val = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 6; j++)
{
t[i][j] = val;
val++;
}
}
f(&(t[0][0]), 3, 6);
f2(t, 3);
return 0;
}
One thing to note is the hack-ish way I had to pass t to f. It's been a while since I wrote in C/C++, but I remember being able to pass t directly. Maybe somebody can fill me in on why my current compiler won't let me.
A int ** is a pointer to a pointer to an int, and can be a pointer to an array of pointers to arrays of ints. A int [][] is a 2-dimensional array of ints. A two-dimensional array is exactly the same as a one-dimensional array in C in one respect: It is fundamentally a pointer to the first object. The only difference is the accessing, a two-dimensional array is accessed with two different strides simultaneously.
Long story short, a int[][] is closer to an int* than an int**.