Click here to Skip to main content
15,888,136 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
C++
#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); 
        getch(); 
    }

i understand p contains the the addresses of respective elements in t array but the arithmetic i cant understand especially p+=p[-1] and in the printf expression what will be printed and how
Posted
Updated 20-Jul-15 22:02pm
v2
Comments
Mohibur Rashid 20-Jul-15 21:19pm    
Its a bad practice.
But

t[1] would be (address of t[0])+1, and so on.
Now, p is holding the address of t, i.e. t[0].
So, p +=2 would be t[2]. i.e. (Address of t[2])
at this point p[0] holds 3; and p[-1] holds 2
p += p[-1] is p += 2; which would be value 5.

Some issues:
1. you are not returning anything from your void function.
2. My guess is your compiler is TC3.0, suggestion. drop it. get something new. compiler has been improved a lot in past 20 years.
3. learn how to debug. Debugging is as important as learning programming. If you miss that part, you will go no where with your development skill. Because, there will be none.

All the solution are correct, but they don't highlight enough the magic word: "Pointers arithmetic in C".
Google for it and you'll get all answers you need.
To understand why you can assign an array name to a pointer to array element types just consider that an array name is a pointer to its 0th element, so:
C++
int arr[10];    //An array of 10 integers
int *p = arr;   //p is a pointer to int initialized with arr
                //Is equivalent to p=&arr[0];

Each time the compiler sees an array name creates a pointer to 0th element of the array, then use it to access the array.

Pointers Arithmetic allow sum and subtraction, and the operand must be a number. As special case you can subtract 2 pointers, pointing to same type, to get a number as result.
C language try to implement an abstract handling for pointers in the sense that they are managed as virtually accessing next value each increment or decrement. Of course real objects have a size that spans over many bytes so that to access adjacent values requires a memory displacement bigger that 1 for some types. This is silently handled by the compiler, that adds for each increment the required displacement.
I.e.
 Type    Start Address  After increment
char      0x0021000      0x0021001    //Char   is 1 byte
int       0x0021000      0x0021004    //int    is 4 bytes
float     0x0021000      0x0021004    //float  is 4 bytes
double    0x0021000      0x0021008    //double is 8 bytes
....

A pointer arithmetic operation can be described as:
C++
address = (<type pointed> *)(((char *)p)+(number * sizeof(<type pointed>)))

Where the pointer p is casted to a char pointer to get 1 byte addressing, then we add our number multiplied by the size of the type pointed, than recast to point to our type.
This is valid for any kind of type, structures, unions, etc. In that case incrementing by one we will point to next structure.
Subtraction works the same way as sum, only the number is negative.

The special case of subtraction of two pointers gives the integral number of objects of type pointed to between the two addresses.

You cannot sum two pointers. It is illegal.

Now the index operator, [], is equivalent to retrieve of value pointed by pointer after incrementing the pointer by the number in braces:
p[n] ==> *(p + N)

And this operation is conform to use of an array or a pointer on the basis of what we already said before about an array name (replaced by compiler with a pointer to its 0th element).

If you understood this you will understand your code... ;)
 
Share this answer
 
v8
If we look here: http://c-faq.com/aryptr/aryptrequiv.html[^]
we read "in spite of the fact that the underlying arrays and pointers are quite different, the compiler doesn't apply the array subscripting operator [] that differently to arrays and pointers, after all".

C++
#include <stdio.h>
#include <conio.h>

  int main(void) { 

  int t[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

  int  *p = t;  // Assigns address of array t to p. This is also address of t[0].

  p += 2;  // Increment p by 2 - now points to t[2] == 3

  printf("%d\n", *p); 

  printf("%d\n", p[-1]);  // From link above p[-1] is the value -1 from where pointer currently points and thus is actually *(p+2-1) or t[1]  

   p += p[-1];  //  p is now t + 2 + 2 thus t[4]

   printf("%d\n", *p); 


   getch(); 

   return 0;
 }
 
Share this answer
 
v3
Comments
CPallini 21-Jul-15 4:22am    
5
[no name] 21-Jul-15 22:37pm    
Thanks.
Allow me to explain line by line.

Line #1: #include
This line missing a include file or header file. I believe you need to include stdio.h since printf is used, and conio.h since getch is used.

Line #2: int main(void) {
Line #3: int t[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, *p = t;
t is an integer array, and p is a pointer to integer.
In this line, pointer p is assigned to array t, so it points to first integer in t array. Variable t can be used as pointer to integer as well.

Line #4:
Line #5: p += 2;
Adding 2 integer spaces to the pointer p. Now, pointer p is pointing to third integer in array t.

Line #6: p += p[-1];
In C, pointer can also used as an array.
p[0] is same as *p.
p[1] is same as *(p + 1).
so p[-1] is same as *(p - 1)
Since pointer p is pointing to third integer, so pointer (p - 1) is pointing to second integer. The value pointed by (p - 1) is 2.
Therefore, p += p[-1] is same as p += 2, which mean adding 2 to the pointer p. Now, pointer p is pointing to fifth integer in array t.

Line #7: printf("%d",*p);
Line #8: getch();
Line #9: }
"5" will be printed here.
a return statement is recommended to silent compiler warning.
 
Share this answer
 
Comments
Mohibur Rashid 20-Jul-15 21:34pm    
include thing is just a bug of Codeproject
CPallini 21-Jul-15 4:23am    
5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900