Two dimension array dereferencing not working - arrays

Hello I am learning c in school and having a little confusion on this problem.
That is,
b is two d array, and I am trying to implement around printing values and the adress,
but why is *(b+1) giving the same thing as b+1?
I thought *(b+1) would give the value of the first element of the second row.
and if I change printf("%p\n", *(b+1)) to printf("%d\n", *(b+1)), it just gives a garbage value.
Why is it working like this?
I appriciate any feedback! thank you
int main()
{
int b[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
printf("b:\n");
print_2d_array(3, 4, b);
printf("\n");
printf("%p\n", b);
printf("%p\n", *(b+1));
printf("%p\n", b+1);
return 0;
}
Output is like this,
b:
0 1 2 3
4 5 6 7
8 9 10 11
0x7ffeecee6730
0x7ffeecee6740
0x7ffeecee6740

The question you have asked essentially boils down to a question about the nature of an array and the address of an array, which is a fairly well covered topic (see this for example). However, you likely confused yourself with the pointer arithmetic, so this answer tries to clarify some of that.
In C, when array object is used in an expression, its value and type becomes the same as the pointer to its first element.
In your case, you have:
int b[3][4] = { /* ... */ };
/* ... */
printf("%p\n", *(b+1));
printf("%p\n", b+1);
If we consider the last print statement,b in the expression b + 1 becomes the same as &b[0] + 1, and this would be the same as &b[1].
When we consider the print statement before the last one, we note that *(b+1) is defined to be the value b[1]. However, the result of that expression is an array of 4 int. That array now takes on the value and type of its first element, which would be &b[1][0].
Since you need to be able to find the address of the first element of an array from the array itself, the address of an array, &b[1], has the same pointer value as the address of its first element &b[1][0].
However, &b[1] and &b[1][0] have different types. The former is a pointer to an array, while the later is a pointer to an int.
For additional information, I encourage you to read the linked question at the top of this answer for more about arrays and the address of arrays.

*why is (b+1) giving the same thing as b+1?
The output address is numerically same but their type is different.
The type of *(b+1) is int [4] whereas the type of b+1 is int (*)[4].
*(b+1), when used in an expression, will convert to address of first element of second row1):
*(b + 1) -> b[1] -> ((b[1]) + (0)) -> &(*((b[1]) + (0))) -> &b[1][0]
and b+1 will give address of second row.
Address of an array and address of first element of that array are numerically same but their type are different.
*I thought (b+1) would give the value of the first element of the second row.
*(b+1) will give the second element of 2D array b which is nothing but a 1D array of 4 integers.
To access the first element of second row using *(b+1), you can do:
(*(b+1))[0]
To access the second element of second row using *(b+1), you can do:
(*(b+1))[1]
third element ....
(*(b+1))[2]
and so on .....
Note that *(b+1) is equivalent to b[1]1). So,
(*(b+1))[0] is equivalent to b[1][0]
(*(b+1))[1] is equivalent to b[1][1] .. and so on
Hope this clarifies your doubt.
1 ) From C Standards#6.5.2.1
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))..

Related

Confusion with referencing items in a array of pointers

I'm having a little bit of trouble understanding how this code outputs 10. I understand that p is the address of the first element in the pointer array, meaning p+1 is the address of the second element of the list. Meaning *(p+1) is the address of the first element of array n. Consequently * (*(p+1) + 1) evaluated to the 2nd element of array n. However, I'm getting confused as to how the below code prints the value 10, meaning the first element of array r. Help is greatly appreciated.
int m[4]={-2,3,6,8,9}, n[4]={7,6,4,3}, r[4]={10,-3,5};
int *p[3]={m,n,r};
printf("%d", *((p+1)[1]));
Starting at p:
p: {m, n, r}
p+1: {n, r}
(p+1): {n, r}
(p+1)[1]: r
((p+1)[1]): r
((p+1)[1]): {10, -3, 5}
*((p+1)[1]): 10
Note that (p+1)[1] means *((p+1)+1), not (*(p+1))+1.
You have an array of pointers, so p is the pointer to -2 (beginning of the m array) and p+1 is the pointer to 7 (beginning of the n array).
So p is the pointer to the beginning of the array that contains 3 pointers and p+1 is the pointer to the beginning of an array that contains 2 pointers and when you write (p+1)[1] you get the same result as p[2].
*p[2] == *(p+1)[1] == *(p+2)

What does this array function do? - C programming

I was given this function and I need to explain what it does without other context.
What my interpretation is: The address of the first element of an array is inputted into arrFunc with some length L1, and an integer pointer p is declared and initialized to point to the first element of arr1.
The while loop is what confuses me. My interpretation is (and I'm a beginner when it comes to programming) is that if the contents of p (which I believe contains the address of the first element of arr1) is less than the address of the last element of arr1, then increment the value inside the first element by 5, then increment p to go on to the next element of the array. The biggest thing that confuses me about the while loop is the comparison of two addresses (p<arr1+L1).
I guess my other question is, is the condition in the while loop comparing the two addresses, or is it comparing the values stored in those addresses?
void arrFunc(int *arr1, int L1)
{
int *p = arr1;
while(p< arr1 + L1)
{
*p+=5;
p++;
}
}
The function adds 5 to the elements of the provided array, but only to the first L1 elements (might not be the whole array).
To answer the second question, about adding an int to a pointer, in terms of memory C will manage to add the right amount based on an element size ; meaning it doesn't simply add the int to the address, it adds
sizeof(*array) * intValue
It actually adds the size of an array element multiplied by that integer value. Here it adds sizeof(int) * L1 to get
arr1 + L1
to be compared with p. (p++, similarly, is incremented, in terms of addresses, by sizeof(int)).
This function takes an array of size L1 and add 5 to each of the element. So if an array of size 4 like following is inputted
10 20 30 40
After executing this function the output will be
15 25 35 45

Passing an array into a function in C

Consider the following C program:
#include <stdio.h>
void swap(int []);
int main(void) {
int a[3] = {1, 2, 3};
swap(a);
printf("%d %d %d\n", a[0], a[1], a[2]);
swap(&a[1]);
printf("%d %d %d\n", a[0], a[1], a[2]);
return 0;
}
void swap(int x[]) {
int temp = x[0];
x[0] = x[1];
x[1] = temp;
}
Can anyone explain why the following code gives an output
2 1 3
2 3 1
rather than
2 1 3
1 2 3
I understand that swap(a) swaps a[0] and a[1]. But I'm not so sure how swap(&a[1]) works. In both cases we are passing the array a into the function swap, are we not? So my hypothesis was that swap(&a[1]) should again swap a[0] and a[1], giving us back the original order 2 3 1.
EDIT: This code was written as intended. I just wanted to see what happens if we pass an address of an element other than the first element into the function. Apparently if I pass &a[n] into the function, it disregards all elements before a[n] and treats a[n] as the first element?
Your swap function takes and address of an integer as input and swaps element at that address with element at next address.
swap(a) is same as swap(&a[0])
It will swap element at index 0 with element at index 1.
Now your array becomes {2,1,3}
swap(&a[1]) swaps element at index 1 with element at index 2.
So your array now becomes {2,3,1}
Remember when you pass an array actually you are passing address of element at index 0 (&a[0]).
Because when you swap first time you sent an array starting with 0 index then it exchanges 0th and 1st index values means at first swap, array becomes {2,1,3} then again you sent this array starting with 1 index means you sent only two values {1,3}, then that values gets exchanges. In this case x[0] = 1 & x[1] = 3, that is why the output came as {2,3,1} here 2 remains as it is.
In the first call swap(a); you are passing the entire array (actually a pointer to the first element.) So you are swapping elements 0 and 1, which are 1 and 2, respectively, therefore your first output is 2 1 3.
In the second call swap(&a[1]); you are passing the address of the second element in the array, and in your swap function you are therefore swapping the second and third elements, at indices 1 and 2, which are 1 and 3, respectively. That's why your answer after the second iteration is 2 3 1.
Possibly what you meant was
swap(&a[0]);
This will swap the values at indices 0 and 1, which will give you the desired output of 1 2 3.
In your code before the first println statement you are passing a complete array to the parameter of the fuction but in the next you are just passing a single value of location of a[1] which make bit confusing for the function because it has only a single value to swap or it might be as first you passed a zero(0) index or the array to swap with the next time you pass first 1 index of array to swap with which means [1,3 to swap] so pass complete in next statment as this
swap(a);
printf("%d %d %d\n", a[0], a[1], a[2]);
swap(a);
printf("%d %d %d\n", a[0], a[1], a[2]);
return 0;
this will generate your desire answer

Meaning of arr +1, *arr+1 , **arr+1 in 3D array

I have this question:
say starting address is 100.
int arr[2][3][2] = {{{2,4},{7,8},{3,4}},{{2,2},{2,3},{3,4}}};
printf(“%u %u %u %d \n”,arr,*arr,**arr,***arr); // Line 2
printf(“%u %u %u %d \n”,arr+1,*arr+1,**arr+1,***arr+1); // Line 3
}
Answer:
100, 100, 100, 2
114, 104, 102, 3
Explanation:
For Line 3: arr+1 increases in the third dimension thus points to value
at 114, *a+1 increments in second dimension thus points to 104, **arr +1
increments the first dimension thus points to 102 and ***arr+1 first gets the
value at first location and then increments it by 1. Hence is the output of second line.
My Question - I tried my best. but i could get what explanation meant for Line 3 ! please explain
What is type of int arr[2][3][2]? It is array of 2 elements of type int [3][2]. This is 3rd dimension.
What is int [3][2]? It is array of 3 elements of type int [2]. This is 2nd dimension.
What is int [2]? It is array of 2 elements of type int. This is 1st dimension.
Here's diagram
In line 2:
arr points to first element of 3rd dimension,
*arr points to first element of 2nd dimension,
**arr points to first element of 1st dimension,
***arr takes the value of first element of 1st dimension.
You can see from diagram that all dimensions start from address 100. Hence the output of line 2: "100, 100, 100, 2".
In line 3:
arr + 1 points to second element of 3rd dimension,
*arr + 1 points to second element of 2nd dimension,
**arr + 1 points to second element of 1st dimension,
***arr + 1 takes the value of first element of 1st dimension and increments it.
You can see from diagram that second element of 3rd dimension has address 112 (not 114!), second element of 2nd dimension has address 104, second element of 1st dimension has address 102. Hence the output of line 3 must be: "112, 104, 102, 3"
Your answer is wrong. The first value for line 3 should be 112, not 114.
When you use arithmetic on a pointer, it changes the address by some number of elements (of whatever size the array stores). When you use an array as if it were a pointer, C will manage that for you.
When you use arr, the compiler will say you have a pointer to an array holding two elements of type int[3][2]. So adding one to that means adding sizeof(int[3][2]) which is 12. Here is a table to show this:
code element type ints per element bytes per element array length
-----------------------------------------------------------------------------
arr int[3][2] 6 12 2
*arr int[2] 2 4 3
**arr int 1 2 2
there isn't much value in any "explanation" within your example. See, you're mixing things up. That's because your multi--ing (**arr and the like) only is sensible, if you're allocating with C's malloc. Then the rows of a 2D array are arr[i] of type (int *), and within any row a column value is arr[i][j] of type (int), and the whole 2D matrix is *arr of type (int *). In 3D you have arr[i][j][k] of type (int) down to **arr for the whole 3D structure. But using int arr[2][3][2] = {...}, just use arr[i][j][k] to get a matrix element and i.e. arr[0], arr[1] for the rows. Pointers aren't really useful with those compile-time allocated 2-3D matrices. Always remember **arr is a pointer to a pointer to a pointer, if and only if someone came along and did all the C-malloc-ing. Regards, M.

Please explain the difference

i have a program about 2-D arrays
base adress is 8678
#include<stdio.h>
#include<conio.h>
main()
{
int arr[3][3]={
{83,8,43},
{73,45,6},
{34,67,9}
};
printf("%d ",&arr+1); //points to 8696
printf("%d ",arr+1); //points to 8684
return 0;
}
what is the difference between arr+1 and &arr+1?
Well, they're different things. arr decays in most contexts to a pointer to the first element of your array - that means a pointer to the first 3-element row in your 2D array: type int (*)[3]. arr + 1, then, points to the second row in the array.
&arr is the address of the array itself (type int (*)[3][3]), so &arr + 1 points to memory just past the end of the entirety of your 2D array.
You can confirm this behaviour easily by printing differently. Specifically, printing the offsets to the new pointers rather than the values themselves will help clear things up. The output from your program from these print statements:
printf("%ld\n",(intptr_t)(&arr+1) - (intptr_t)arr);
printf("%ld\n",(intptr_t)(arr+1) - (intptr_t)arr);
Will be the decimal offsets to &arr+1 and arr+1 respectively. Here's the output from a test run I just made:
36
12
36 matches up: 3 rows × 3 columns × 4 bytes per entry = 36 bytes. So does the 12: 1 row × 3 columns × 4 bytes per entry = 12 bytes.
Note - you're also printing pointers using %d, which is wrong. You should probably be using %p for that.
You can figure this out with the help of this equivalence: X[Y] === *(X+Y)
Since *(arr+1) === arr[1], arr+1 === &arr[1]
Similarly, &arr+1 === &((&arr)[1])
What is (&arr)[1]? Well, (&arr)[0] === *&arr === arr,
that is, the 3x3 array itself, so (&arr)[1] is the 3x3 array following that,
and &arr+1 === &((&arr)[1]) is the address of the 3x3 array following &arr ... a pointer to the byte just past the entire array.
Arr+1 gives the next element in an array while &arr +1 gives the address of next array of integers
array + 1 means the array[1] 's address and it costs 3 int memory.
&array + 1 means the address of array[0] add 1;

Resources