Pointer Array in C? [duplicate] - c

This question already has answers here:
Are negative array indexes allowed in C?
(9 answers)
Closed 7 years ago.
Pointers are a difficult topic for sure, but I have come across this snippet and I just can't figure out what the p[-1] is:
#include <stdio.h>
int main(void) {
int t[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, *p = t;
p += 2;
p += p[-1];
printf("%d",*p);
return 0;
}

Any time you see an expression like a[b] in C, you can mentally think that *(a + b) is happening.
So, it's just "the contents of the element before the one p is pointing at right now".
Since p is at t + 2, p[-1] refers to t[2 + (-1)] i.e. t[1].

p += p[-1];
can be written as
p = p + *(p-1);
At that point, p points to the 3rd element of the array (value 3) and *(p-1) is 2.
So, it's equivalent to
p = p+2;
and printing *p would print 5.

Related

C: order of evaluation in a conditional expression [duplicate]

This question already has answers here:
Post-increment and Pre-increment concept?
(14 answers)
Closed 5 years ago.
There is the following C code:
#include <stdio.h>
int main ()
{
int a[5] = {0, 1, 2, 3, 4};
int* a_p = a;
float x = 1.5;
while(x > (*a_p++))
{
printf("*a_p = %d\n", *a_p);
}
printf("*a_p = %d", *a_p);
return 0;
}
The question would be which is the result of the final printf statement?
I would judge that the order is:
1) inside while, a_p address is incremented => *a_p is 1 (a[1])
2) 1.5 is compared with 1
3) inside while, a_p address is incremented again => *a_p is 2 (a[2])
4) 1.5 is compared with 2
5) 2 is printed for *a_p
I have tried with 3 compilers and the result is 3.
Why 3 is the correct result? Is first done the comparison and then the pointer is incremented meaning that at step 4 from above, after the comparison is done, *a_p is 3?
Is this always the behavior (is this behavior defined) or is compiler dependent?
Yes that's how post increment works. The while condition is true for 0th and 1th index but when it evaluates to false - the pointer value is already increased as a result it points to index 4 having value 3.
*p++ the value of it will be *p where this p is the old one which is not incremented. Same happens with a_p is here - last time when it is compared the value *a_p++ is 2 but the new value of a_p is pointing to the 4th index. Loop ends and 3 is printed.

Retrieval of values in reverse order using pointers [duplicate]

This question already has answers here:
Are negative array indexes allowed in C?
(9 answers)
Closed 5 years ago.
I understand working of *(p+i), but, what actually is happening at memory level when retrieving values with *(p-i) or p[-i] through printf() function ?
#include <stdio.h>
int main() {
int i, arr[5] = {1, 2, 3, 4, 5}, *p;
p = &arr[4];
for (i = 0; i < 5; i++)
printf("%d\t%d\t", *(p - i), p[-i]);
// why does this prints in reverse order?
return 0;
}
It's simple, *(p - i) and p[-i] are exactly the same with different syntax. It's interesting that you can also write, -i[p] with exactly the same meaning *(p - i).
It prints in the reverse order because you start at arr[4] and then subtract i from the pointer, which subtracts 0, 1, 2 one by one until it reaches 4, so it prints p[4], p[3], p[2], p[1], p[0] which is the array arr from the last element to the first.
You have assigned last element address in the pointer and subtracting address one by one and hence it prints in reverse order

How does *(array + 3) work?

I am studying for my midterm. this was an example code
#include <stdio.h>
void doubleArray(int array[], int length)
{
for (int i = 0; i < length-2; i++) {
array[i] += array[i];
}
length += 5;
printf(“%d\n”, length); // Question 29
}
int main(int argc,char *argv[]) {
int integers[6] = { 3, 4, 5, 6, 7, 8};
int length = 6;
printf(“%d\n”, integers[4]); // Question 28
doubleArray(integers, length);
printf(“%d\n”, *(integers + 3)); // Question 30
printf(“%d\n”, *(integers + 4)); // Question 31
printf(“%d\n”, length); // Question 32
}
for questions 30 and 31
the answer is that it prints 12 (30) and 7 (31)
can someone explain to me why and what that "*(integers + 3)" means?
* is a dereference operator on a pointer.
This means that it will "get" the value that's stored at the pointer address of the item right after it ((integers + 3)).
It will interpret this value as the dereferenced type of the item after it (int since (integers + 3) is of type int*)
(integers + 3)
integers is a pointer to the address of the first element of the integers array.
That means that if integers contained [1, 2, 3, 4, 5] then it would point to where 1 is stored in memory.
integers + 3 takes the address of integers (i.e. where 1 is stored in memory) and adds the amount of address space required to store 3 ints (since the pointer is of type int*). Advancing it by one space would give you the address of 2 in memory, advancing it by two spaces would give you the address of 3 in memory, and advancing it by three spaces gives you the address of 4 in memory.
How this applies to your example
(integers + 3) gives you the address of the 4th item in the integers array since it's the first element's address plus the size of three elements.
Dereferencing that with the * operator, gives you the value of the 4th element, 12 (since the value of 6 was doubled by doubleArray)
The same applies to *(integers + 4) except that doubleArray didn't double the 5th element so it gives you 7.
How doubleArray works
for (int i = 0; i < length-2; i++) means start the variable i at 0 and advance it until it is length - 2.
This means it takes the value of everything from 0 to the value of length - 2 but executes the body of the loop for values from 0 to length - 3 since the < is exclusive (the conditional is evaluated BEFORE executing the body of the loop so when i == length - 2 the condition is false and the loop terminates without further execution.
So, for each element, excluding the last two, the element in array is added to itself.

C programming recursion

I was into C today and I bumped into this example of using recursive calls and I don't understand how it works. Can someone explain?
#include <stdio.h>
#define SIZE 10
int sample(const int b[], int p); //function prototype
void main(void){
int x;
int a[SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
x = sample(a, SIZE); //call
printf("Result is X: %d\n", x);
}
int sample(const int b[], int p){
if (p == 1){
return b[0];
}
else{
return b[p - 1] + sample(b, p - 1); //recursive calls until p is 1
}
}
My question is: Why the output is 55? Does x save the previous value and then add next from next call of the sample? Why the value of x is not just b[0] which is 1?
What might help is to write out a table of the value of p at the first call of sample:
p b[p - 1]
-------- --------
SIZE 10
Since p is not 1, the function sample returns the calculation:
b[SIZE - 1] + sample(b, SIZE - 1)
Or:
10 + sample(b, SIZE - 1)
To calculate sample(b, SIZE - 1), we write out the next value in the table:
p b[p - 1]
-------- --------
SIZE - 1 9
Again, p is not 1, so we ultimately return the following value:
(10 + (9 + sample (b, (SIZE - 1) - 1)))
If you repeat these steps, you can see how this eventually terminates, because we get to a state where p is 1:
(10 + (9 + (8 + ... + (1)))
This results in the answer 55.
The answer is 55 as that's the sum of all 10 terms.
What it's doing is summing the last term with the sum of the others. When presented with the first term it returns that, ending recursion and popping the whole stack.
It happen because when you execute the above code then a memory stack of recursive function call outputs is formed till there is a controlling condition like in this case we have
if (p == 1){
return b[0];
}
so the values you get at every level of recursion are as follows
10 9 8 7 6 5 4 3 2 1
Adding all of them you get 55.
The value of x is not just 1 because the return value of each recursive function calls for decremented values of P is added to calculate the return value of previous call at each call till it reaches 1 (the condition in the parent call).
ie return b[p - 1] + sample(b, p - 1);
For brief explanation refer : http://www.programiz.com/c-programming/c-recursion

pointer movement what is difference between cs[1], and *cs++

I am trying to understand how the pointers are moving.
Following is the program and I am aware that
if
int cs={1,2,3};
then cs points to cs[0]
what I am not clear is what is *cs pointing to.
#include<stdio.h>
int main()
{
int array[] = { 1, 2, 3, 4, 5 };
int *arrptr1 = array;
int *arrptr = array;
int i;
for (i = 0; i < sizeof(array) / sizeof(int); i++) {
printf("%d, %d, %d\n", array[i], *arrptr1++, *arrptr + i);
}
}
the output of above program is
1, 1, 1
2, 2, 2
3, 3, 3
4, 4, 4
5, 5, 5
then my understanding *arrptr should increase the value stored at
*arrptr
should get incremented by 1.
Where as what I observe is the pointer is moving to next location.So just want to know what is wrong in my understanding?
UPDATE
As per the replies below I understand that
print("%d", *arrptr1++);
in such a statement evaluation of operators is from right to left.
Hence in *arrptr1++ the ++ will get evaluated first and then arrptr and then *
So to confirm the same I wrote another program
#include<stdio.h>
int main()
{
int array[] = { 10, 20, 30, 40, 50 };
int *q1 = array;
printf("q1 = %p\n",q1);
printf("*q1++ = %d\n",*q1++);
printf("q1 = %p\n",q1);
printf("*q1++ = %d\n",*q1);
}
The output of above program is different than the expected operator precedence by above logic.
The output I got is
q1 = 0x7ffffcff02e0
*q1++ = 10
q1 = 0x7ffffcff02e4
*q1++ = 20
So I was expecting in the 2nd line of output instead of *q1++ = 10 following *q1++ = 20
so did the operator precedence not happened right to left?
*arrptr1++ is parsed as *(arrptr1++), not (*arrptr1)++.
Whenever you use dereference operator * and pre-increment(pre-decrement) or post-increment(post-decrement) operator on a variable simultaneously ,the order of operation is from right to left (if parenthesis are not used).
What you want to do is
(*arrptr)++
because of higher precedence of (), it will force the compiler to first access the element pointed to by arrptr and then increment its value.
When you do this *arrptr++ , as I've said it first operates rightmost operator (i.e. ++)
and then the dereference operator.
If you will write
EDITED (only the comment): *++arrptr // increment the pointer then access
it will first advance the pointer and then access the value
stored in the address now pointed to by arrptr.
One more thing,The comma used for separation of function argument is not the comma operator so the order of evaluation of the arguments is undefined. (already been told)
What happens is that *arrptr1++ is interpreted as *(arrptr1++), which means that the pointer to the array is increased by one each time in the loop, and hence it will point to the same element as array[i]. *arrptr + i on the other hand is interpreted as "the value of the array element pointed to by arrptr plus the integer i". In this loop it means it will display the same thing as array[i], but it is not pointing at the same element (arrptr is always pointing to the first element in your array). If you change the values in the array to something more random, it should be obvious when you run the program again.
cs = &cs[0] ( cs is equal to the address of cs sub 0) ; *cs = cs[0] (cs pointer is equal to cs sub 0) ; You should remember that *'s hide the [].
// here is a print function with a pointer
int foo[5] = { 2, 9, 1, 3, 6};
int *walker, count;
walker = foo;
for (count = 0; count < 5; walker++, count++)
printf("Array[%d]: %d\n", count, *walker);
Recap: walker is equal to &foo[0], so when you increment walker (eg. walker++) you're moving the pointer to the next address which is foo[1]. And when we are printing the value we can't say ..., walker); since walker( &foo[whatever] ) is pointing to an address, we need to dereference the pointer to get the value. Again, the most important thing to remember
array = &array[0] AND *array = array[0]

Resources