What does this array function do? - C programming - c

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

Related

In C, is it possible to store value in the last position of the array?

i only would know how to store value in the last position of the array, with the code below:
int main(int argc, char *argv[]){
int x[2][2];
int i, j;
x[2][0] = 1;
printf("%d", x[2][2]);
}
Thanks!
The last element in your matrix is in x[1][1]; just put in this position. Your vector has only four positions indexed starting in 0 going to 1 twice (for each dimension); that is, neither x[2][0] nor x[2][2] is valid — they access out of the bounds of the array.
The first element of an array in C is numbered as 0, and when creating an array, the size inputted will represent the number of elements in the said array. Hence, the first element of an array of 2 would be labelled as 0 and the second as 1, the third(2) not being allocated.
So, for example, making an array of 4 variables:
int i[4]
Would allocate four ints int memory,
i[0]
i[1]
i[2]
i[3]
these being the valid spots of the array. Of course this applies to 2D arrays like yours.
If you wish a 3-large array(Like I suppose from your use of the array element zero and two), you simply need to, as you probably understood, declare an array with a size of [3].
Keep in mind accessing invalid spots in an array might not cause a crash of your program if it had allocated some memory at the emplacement it tried to access, sometimes yielding to funny results caused by these unexpected values.
Hope this helps.

Last element of a struct array - C

I'm a bit confused about a thing :
If I have an array of structs: table whith a length of X and I want to access the last element of it: table[X] or table[X-1]. If it's table[X-1], what table[X] contains ?
The indexing of array in C starts with zero, i.e. the first element will be in table[0], the second in table[1], the third in table[2] ... and the last on in table[X-1].
table[X] is outside of the arrays bounds. C does not have bounds checking, so compiler allows accessing it, but this is an undefined behaviour, i.e. you will never know what happens. Reading it can give back memory garbage or can lead to an OS exception like segmentation fault.
The answer is the same for any kind of array. If you have one with the size
X :
int a[5];
struct my_struct ms[10];
...
you specify the amount of elements in that array. Because the 1st element is element 0, the last element is always X - 1.
If you try to access the element a[X] you will get undefined behavior.
Structs work in memory the same way that an integer or some other basic data type would in this instances. Your array would just be separated by sizeof(struct) instead of sizeof(the basic data type).
It'd still start at 0, and end at X - 1. The type of arrays usually just really defined 2 things:
The amount of bytes per index, and how to treat the data.
Picture an array of size 3 with structs that contain 5 bytes of data. Your array would just be set as follows:
-----|-----|-----|????|
s1 |s2 |s3 |????|
Just because it exists, doesn't mean our program knows what it is. the 4th [3] index (????) would be an index out of bounds of our array. It is possible however you could get some meaningful value here, but very unlikely. Most of the time it will either be garbage, or cause an error.
Arrays in C use zero indexing, meaning they start with 0 and end with n-1. Not to be confused with array declarations, where you write the size expressed in number of items. The syntax for accessing an array and declaring one looks similar, which is why this can be confusing for beginners.
Example:
int main (void)
{
int array[5]; // allocate an array with 5 elements
array[0] = 0; // access first element
array[4] = 0; // access last element (index 4)
array[5] = 0; // BAD, accessing the array out of bounds: index 5 gives item number 6
}
And this is why the canonical way to write for loops in C is this:
for(int i=0; i<n; i++)
where n is the size of the array, and the iterator i will have the values from 0 to n-1.

pointer and multidimensional array

i want to print the value which contain in the multidimensional array.I know that if we write something like arr[3][4] then arr[0] is the pointer to the first element in the that multidimensional array.
I want to ask why this code give me garbage value after the program print the number containing in the multidimensional array?
this is the code:
#include <stdio.h>
#define ROW 3
#define COLL 4
int main(void) {
int arr[ROW][COLL]={{1,2,3,4},
{5,6,7,8},
{9,10,11,12}};
int *ptr;
for(ptr=arr[0];ptr<arr[ROW]+COLL;ptr++){
printf("%d ",*ptr);
}
printf("\n");
return 0;
}
this is the result when i compile the above code:
1 2 3 4 5 6 7 8 9 10 11 12 -1079481492 134513936 0 -1079481352
but after changing the for loop to the following:
for(ptr=arr[0];ptr<=arr[ROW-1]+COLL-1;ptr++)
the code work and give the exact number which contain in the multidimensional array.
Because arr[ROW] is an out-of-bounds access. The last valid position in arr is arr[ROW-1]. Thus the first version of your code invokes undefined behaviour.
The pointer to the last element is
arr[ROW-1] + COLL - 1
So you loop should be
for (ptr = arr; ptr < arr[ROW-1] + COLL; ptr++) {
Elements of an array are indexed from 0 so the last element in your matrix is arr[ROW-1][COLL-1].
When your pointer reaches arr[2] + COLL there is no such element because the second coordinate of the last element in last row is [COLL-1].
Elements of an array are stored in 1D so arr[0] + 4 is acctualy arr[1][0].
When you increment ptr++ it tells the compiler to access the next memory location after the current. So, when ptr points to a[0] + 4 it works because the compiler access the fifth value after a[0][0] which is actually the first value in the next row, arr[1][0], because their memory locations are next to each other.
When your ptr points to arr[4] + i, i = 0, 1, 2, 3 you get bad output because those elements are not in your array.
Because your first element, 1, is at arr[0]+0,
5 is at arr[1]+0,
9 is at arr[2]+0,
10 is at arr[2]+1,
11 is at arr[2]+2,
and 12, which is the last element of your array is at arr[2]+3.
but your for loop keeps moving even after the array ends, that is, until the memory location arr[3]+4 is reached. Giving you four garbage values because we have stored nothing in the memory after arr[2]+3.
so the for loop should be like:
for (ptr=arr; ptr <= arr[ROW-1]+COLL-1; ptr++);
which is equivalent to:
for (ptr=arr[0]; ptr <= arr[ROW-1]+COLL-1; ptr++);
as arr[0] and arr point to the same location in memory.
NOTE- try reading how memory is allocated in arrays of multiple dimensions.

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.

For an X dimensional array where X is greater than 1,is only the first dimension optional,rest are mandatory?

I am trying to get my head around this but since I am new to C I just can't imagine how it will be at or beyond 3D arrays.I know we have to mention the size of static 1D arrays,but in 2D arrays,the first dimension is optional in a declaration as in:
int arr[][2]={{2,3},{4,8},{5,3}};
But what about X dimensional arrays?Are the following OK or is only the first dimension optional to be mentioned and rest necessary?
int arr[][][2]= blah blah;
int arr[][][][8]= blah blah;
I know that in the above case of the 2D array,the second dimension is necessary to perform pointer arithmetic using arr,but I can't imagine how things would or wouldn't work out for array whose dimension is greater than 2.
Only one can be left blank. In order to know how to get to a particular value, it needs to be able to compute the offset of everything but the first value.
For example:
char array[][3]
The system knows to go three bytes (assuming 1-byte chars) * the first part of the array index + 1 for each part in the second.
char array[][2][3]
The system knows to go 6 bytes (2*3) bytes * the first part of the array index + 3 * the second part + 1 * the last part.
If the 2 weren't there, you couldn't figure out how far to offset based on the value of the first index.

Resources