I'm having trouble in C with creating a pointer that points to an array of pointers where each pointer in the array points to an array. I'm having trouble setting this up and storing values in each array. The goal is to avoid array indexing and use pointer arithmetic only. An example of how to implement this idea correctly and storing the values for access later would help me greatly to understand pointers to functions, pointers to arrays, and pointer arithmetic. I do know how to use malloc and calloc. I know basic pointers but this problem is more advanced so some examples of how this is implemented would help greatly! Thanks! :)
From your description it sounds as if you need something like:
#include <stdio.h>
int main(void) {
// Make some arrays of ints
int a0[3] = {1, 2, 3};
int a1[3] = {4, 5, 6};
// To access element a1[2] do *(a1 + 2)
printf("%d\n", *(a1 + 2));
// Make an array of int pointers
int* b[2] = {a0, a1}; // Or: int* b[2];
// *(b + 0) = a0;
// *(b + 1) = a1;
// To access element a1 do *(b + 1)
// To access a1[1] through b just combine the two expressions
// so that you have *(*(b + 1) + 2)
printf("%d\n", *(*(b + 1) + 2));
return 0;
}
In general: To access b[i][j] do *(*(b + i) + j)
Related
I was wondering if it is possible to dereference a pointer to a two dimensional array in C:
int matrix1[2][2] = {{1,2},{3,4}};
int matrix2[2][2] = {{4,5},{6,7}};
I am trying to create an array of pointers, where the first pointer points to matrix1 and the second one to matrix2. I thought of
int *(pt[2]);
pt[0] = &matrix1
My goal would be to be able to access any element in one of the two array with something like:
pt[0][n][m];
Or for the second matrix:
pt[1][n][m]
But as far as I know this doesn't work. Is the pointer declaration wrong?
You have to declare pt as an array of pointers to array.
int (*pt[2])[2] = { matrix1, matrix2 };
Demo.
The answer provided is correct but lacks explanation. I think it is more helpful if you understand why your approach failed.
Using array indexes on pointers works by incrementing the pointer using the size of the data type.
For example if we define an array as follows:
int a[2] = {1,2};
and assume that the array was created in memory at location x
a[0]; // points at x
a[1]; //points at x + sizeof(int)
now lets take the example of two dimensional array
int a[2][2] = {{1,2},{3,4}}
again assume location x
a[0]; //points at x
a[1]; //points at x + sizeof(int [2]) because int[2] is the data type
a[0][1]; // points at x + sizeof(int)
a[1][1]; // points at x + sizeof(int[2]) + sizeof(int)
Now lets take your example
int matrix1[2][2] = {{1,2},{3,4}};
int matrix2[2][2] = {{4,5},{6,7}};
int *pt[2];
pt[0] = &matrix1; //doesn't compile
First, that won't really compile because the type of pt is pointer to int and matrix1 is a pointer to int[2]. However, you can force it by casting like this
pt[0] = (int*)&matrix1;
But it still won't work because the following is not valid either
pt[0][n][m]; //fails to compile
This is because pt is an array of pointer to int, so pt[0][n] points at an integer, not an array. As such you cannot use apply an index to it
However, if you define it as follows
int (*pt[2])[2] = {&matrix1,&matrix2}
pt is then an array of pointers to two dimensional arrays. As such, assuming matrix1 defined at x1 and matrix2 defined at x2,
pt[1][1][1]; //points to x2 + sizeof(int[2]) + sizeof(int)
I am working on C, specifically on creating a matrix using pointers, and one thing that confuses me is that in a 2D array that matrix[i][j] is equal to
*(*(matrix+i)+j)
Does this mean that the element located, in say, the position [3][3] is given by *(*(0+3)+3))?
More specifically, I'm coding a matrix in C by using the following code:
double** makeMatrix(unsigned int rows, unsigned int cols)
{
unsigned int i;
double** matrix;
matrix = (double** ) malloc(rows * sizeof(double *));
if (!matrix) { return NULL; }/* failed */
for (i = 0; i < rows; i++)
{
matrix[i] = (double *) malloc(cols*sizeof(double));
if (!matrix[i])
return NULL;
}
return matrix;
}
So, allocating memory to each i'th element within the array - is this the reason that we get ((matrix+i)+j) for the [i][j] - due to the fact that each element has its own memory block?
In C, there are no multidimensional arrays to the "true" sense (like in LISP, C# or C++/CLI). Rather than that, what you can declare is array of arrays (or array of pointers, where each pointer is assigned by malloc etc.). For instance:
int matrix[2][3];
defines two-elements array, where each element is of type array of three ints.
Now, when you refer to an ultimate array element, you need to first derefence into that inner array, then into the int object:
int value = matrix[2][3];
which is equivalent to:
int value = (*(*(matrix + 2) + 3));
a[i] is a syntactic sugar for *(a + i). That means that a[3][3] is equivalent to *(*(a + 3) + 3).
One other thing is notable, 3[a] is equivalent to *(3 + a) which is *(a + 3), which is a[3].
let consider the following fragment of Code:
#include<stdio.h>
main()
{
int count[100][10];
*(count + (44*10)+8)=99;
printf("%d",count[44][8]);
}
What is the wrong with it?
Array-to-pointer decay only works for one level; so int count[100][10]; decays to int (*)[100] (Why does int*[] decay into int** but not int[][]?).
You can either cast count to int* or use &count[0][0] to get an int* pointer to the first element of the 2D array.
count[44][8]
is not initialized and you are trying to print the value of it which is UB.
a[i][j] = *(a[i] + j);
a[i][j] = *(*(a+i) + j);
So if you want to initialize count[44][8] then do
*(count[44] + 8) = 10; /* or *(*(count + 44) + 8) = 10 */
printf("%d",count[44][8]);
*(count + (44*10)+8)=99; should be
*(count[0] + (44*10)+8)=99;
Type of countp[0] can be reinterpreted as int * as you want.
Live code here
Type of count is int [100][10] so adding some big number to it would go 10 times ahead as you want and access to that location would lead to UB.
Anopter way to write the same is:
*( *(count + 44) + 8 )=99;
I have a problem, I have a function and I do not understand a specific thing. The function is:
int F( int* x , int n ){
int i , m=0
for (i=0;i<n; i++){
m=x[ i ] + m;
}
return m * m ;
}
I call the function with a pointer and with an integer. Later I do a "for", but I do not understand the line:
m=x[ i ] + m;
Because x is a pointer not an array.
Could you please help me.
Then x points to the memory position then to +1. For example if i call the function with
n=10
x=&n
F(x,n)
the function returns somenthing strange.
X points to the position memory to n, later to the position memory to n+1??
Since x is a pointer, when you pass the array to the function, x points to the first element of the array. Since array is a contigous allocation of memory, The pointer can be made to point to consecutive elements of the array. Thats why
m=x[i]+m
x[i] implies to the ith index from the first element of the array
main()
{
int x[10]={1,2,3,4,5,6,7,8,9,10},sum;
sum=function(x,10);
return 0;
}
This function sends the array to the function, with 10, the size of the array
Arrays are represented as contiguous memory and the array variable gets interpreted as a pointer to the base of that memory (e.g. &(x[0])). Array offset syntax gets translated into pointer arithmetic.
See this post, which clarifies the difference between pointer and arrays:
[] - indexed dereference
a[b] is equivalent to *(a + b). This means a and b must be a pointer to an array element and an integer; not necessarily respectively, because a[b] == *(a + b) == *(b + a) == b[a]. Another important equivalence is p[0] == 0[p] == *p.
The function might be equivalently declared (with more clarity perhaps):
int F(int x[], int n);
and you would call it like so:
int data[3] = {1, 2, 3};
int value = F(data, 3);
So I have the following code snippet:
#include <stdio.h>
void pointer_shift(int *a, int n);
int main(void) {
int a[] = {100, 101, 102};
pointer_shift(a1, 3);
}
void pointer_shift(int *a, int n) {
int i;
for (i = 0; i != n - 1; i++) {
*(a + i) = *(a + i + 1);
}
}
I just want to clarify how the pointers work in this snippet. So pointer_shift takes in 'a', a pointer to an int, correct? a1 is passed in to this parameter, and since arrays decay to a pointer to their first element, it works.
First of all, hopefully what I said in the above paragraph is correct. Secondly, what does *(a + i) = *(a + i + 1); actually do? Say we're on the first iteration of the for loop, and i = 0. Then the left side, *a, accesses what, exactly? Does it represent a pointer? I thought * was the dereferencing operator, and accesses the object that a pointer points to... And so then it sets *a = *(a + 1). (a + 1) is the next element in the array, but what exactly does this assignment do, and why?
Thanks!
It is actually not pointer shift, but value shift, *(a+i) is of same effect as a[i], so what it does is a[i] = a[i+1]
*(a + i) = *(a + i + 1); is copying array elements within the array using a bit of pointer arithmetic.
*(a + i) is equivalent to a[i], so the statement is equivalent to a[i] = a[i + 1];. The loop is moving the array values "to the left" in the array: a[0] = a[1]; a[1] = a[2]; and so on.
Your understanding of the function call is correct.
I just want to clarify how the pointers work in this snippet. So pointer_shift takes in 'a', a pointer to an int, correct? a1 is passed in to this parameter, and since arrays decay to a pointer to their first element, it works.
Yes, when you pass an array to a function it degrades to a pointer. An array is not a pointer in an object sense, but it is a pointer in a value sense. When you pass it to a function its value is passed, i.e., a pointer to the first element.
array indexing is the same as pointer arithmetic, so the last two lines in this snippet are equivalent:
int arr[] = {1, 2, 3};
arr[0] = 10;
*arr = 10;
as are these:
arr[1] = 20;
*(arr + 1) = 20;
The expression a + i is pointer arithmetic, incrementing the memory address stored in a by i units of the pointer size of a. So if a pointer to an int takes four bytes on your system, and if the current memory address is, say, 0x1234 the value of a + 1 would be 0x1238.
What the asterisk does is dereference that address and access the actual value at that address. If you have 100 stored at a or a[0], and 101 stored at a + 1 or a[1], then *(a + i) = *(a + i + 1) replaces 100 with 101 at a[0], for i = 0.
Basically, you want to read this C tutorial on pointers and arrays.