CS Atlas GATE 2027
PDS course
0 / 103 complete

PDS/Phase 1 · Programming in C

Lesson 1.4.3 · Item 23 of 103

Pointer arithmetic and why it scales by type size

Read at your own pace. Try the questions before opening the answers.

On this page

0 · Recall Warm-up

Answer from memory first. Answers are in the Answer Vault at the bottom.

  • After void f(int *p, int *q) { p = q; *p = 2; } is called with &i, &j, which variable becomes 2? from Lesson 1.4.2
  • What is kept in a stack frame? from Lesson 1.3.3
  • In a switch with no breaks, entering at case 2 runs which cases? from Lesson 1.2.1

1 · The Hook

🎣

Houses on a street are numbered by plot, not by step: walking “one house further” is 1 house, however wide the house is. In memory, an int occupies 4 byte-boxes and a double 8. So moving a pointer “one int further” must jump 4 bytes, and “one double further” 8 bytes. C does this scaling for you.

2 · Predict First

🤔

An int *p holds the address 2000. What address does p + 3 hold? And if p were a double *? Make a guess in your head. The answer opens Section 3.

3 · Core Concept

💡

Predict First — the answer

2012 for int (3 × 4 bytes) and 2024 for double (3 × 8). p + k moves k elements, not k bytes.

p + k scales by the element size

If p points to type T, p + k is the address k elements further: address(p) + k × sizeof(T). Likewise p − k, p++ (move to the next element) and p--.

p holds 2000, typesizeofp + 3
char *12003
short *22006
int *42012
double *82024

Measured on our machine by converting to char * (which steps one byte):

int x;
double d;
char c;
int *pi = &x;
double *pd = &d;
char *pc = &c;
printf("%d %d %d\n", (int)((char *)(pi + 1) - (char *)pi),
                     (int)((char *)(pd + 1) - (char *)pd),
                     (int)((char *)(pc + 1) - (char *)pc));

Output

4 8 1

Subtracting and comparing pointers

For two pointers into the same block of consecutive elements, q − p is the number of elements between them (not bytes), and <, >, == compare positions.

int x;
int *p = &x;
int *q = p + 1;          /* one past x: allowed to compute and compare */
printf("%d %d\n", (int)(q - p), q > p);

Output

1 1

A pointer may point one element past an object (to compare), but must not be dereferenced there. Arithmetic is meaningful only inside a row of consecutive elements; the next chapter gives you such rows.

No meaningless arithmetic

Adding two pointers, multiplying or dividing them is not allowed. Only pointer ± integer, pointer − pointer, and comparisons.

* together with ++

Post-increment p++ binds tighter than *; pre-increment ++p and * share a level and group right to left:

ExpressionMeansEffect
*p++*(p++)value at p, then p moves to the next element
*++p*(++p)p moves first, then the value at the new place
++*p++(*p)the pointed-to value grows by 1; p stays
(*p)++(*p)++gives the old value, then the pointed-to value grows; p stays
int x = 5;
int *p = &x;
int y = ++*p;      /* ++(*p): x becomes 6, y = 6 */
int z = (*p)++;    /* z = 6, then x becomes 7 */
printf("%d %d %d\n", x, y, z);

Output

7 6 6

4 · Visual

Diagram: memory · int · 2000 · int · 2004 · int · 2008 · int · 2012 · p · p + 1 · p + 3

int *p = 2000: each step of +1 jumps one 4-byte element, so p + 3 is 2012.

byte addresses:  2000 2001 2002 2003 | 2004 ... 2007 | 2008 ... 2011 | 2012 ...
                 [   int #0          ][  int #1     ][  int #2     ][  int #3 ...
                  ^p                   ^p+1                          ^p+3

as char *:  p + 3 = 2003  (one byte per step)
as int *:   p + 3 = 2012  (four bytes per step)
as double*: p + 3 = 2024  (eight bytes per step)

The same “+3” means a different number of bytes for each pointer type.

5 · Worked Examples

Example 1 Easy

A short *s holds 3000 and a long long *t holds 3000 (sizes 2 and 8). What do s + 5 and t + 5 hold?

Solution

3000 + 5 × 2 = 3010; 3000 + 5 × 8 = 3040.

Example 2 Medium

int *p holds 4000 and int *q holds 4020, both inside the same row of ints. What is q − p? What address is p + (q − p)/2?

Solution

The difference counts elements: (4020 − 4000)/4 = 5. Then (q − p)/2 = 2 (integer division), and p + 2 = 4008.

Example 3 GATE

What does this print?

int x = 5;
int *p = &x;
int y = ++*p;      /* ++(*p): x becomes 6, y = 6 */
int z = (*p)++;    /* z = 6, then x becomes 7 */
printf("%d %d %d\n", x, y, z);

Solution

++*p is ++(*p): x becomes 6 and y = 6. (*p)++ gives the old value 6 to z and then x becomes 7. p never moves.

Output

7 6 6

6 · GATE Traps

⚠️

  • p + 1 adds sizeof(*p) bytes, not 1 byte (except for char *).
  • q − p counts elements, not bytes.
  • *p++ moves the pointer; (*p)++ changes the value.
  • Adding two pointers is not allowed; subtracting them is.
  • Pointer arithmetic outside one row of elements (other than one past the end) is undefined.

8 · Memory Hook

🧠

“Pointers count houses, not bricks.” +1 always means “next house of my kind”, whatever its width.

9 · Connect the Dots

Lessons 1.4.1–1.4.3 covered addresses, passing them, and stepping them by element size. Stepping only makes sense when many values of one type sit side by side. Next lesson answers: how do we declare a whole row of values at once and walk through it with an index or a pointer?

10 · Self-Test

GATE format. Try every question before opening the vault.

Q1NAT1 markScaling

A double *d holds 1000. What address does d + 4 hold? (double = 8 bytes)

Numerical answer: ________

Q2NAT1 markDifference

Two int * pointers into one row of ints hold 2016 and 2040. What is their difference (larger − smaller)?

Numerical answer: ________

Q3MCQ2 marksOutput

What does this print?

int x = 10;
int *p = &x;
int a = (*p)++;
int b = ++*p;
printf("%d %d %d\n", a, b, x);
  • (A) 11 11 12
  • (B) 10 11 11
  • (C) 11 12 12
  • (D) 10 12 12

Q4MCQ1 markPrecedence

*p++ means:

  • (A) *(p++)
  • (B) *(++p)
  • (C) ++(*p)
  • (D) (*p)++

Q5MSQ1 markRules

Which pointer operations are allowed in C (pointers into the same row of ints)?

  • (A) p + q
  • (B) p + 3
  • (C) q − p
  • (D) p < q

11 · Rule Card

  • p + k = address + k × sizeof(*p); p++ moves one element.
  • q − p = number of elements between (same row).
  • Allowed: ptr ± int, ptr − ptr, comparisons. Not: ptr + ptr, ×, ÷.
  • *p++ = *(p++); *++p = *(++p); ++*p = ++(*p); (*p)++ changes the value, p stays.
  • One past the end may be computed/compared, never dereferenced.

12 · Concept Ledger

Unlocked in this lesson. From here on, these terms may be used.

pointer arithmeticscaling by sizeofpointer differencepointer comparison*p++ vs (*p)++ vs ++*p vs *++p

13 · Answer Vault

Answer Vault

Try the questions first. Open when you are ready to check.

Recall Warm-up

  • j.
  • Parameters, automatic locals, the return address and bookkeeping.
  • Case 2 and every case and default written below it.

Self-Test

Q1 Answer: 10321 mark

1000 + 4 × 8 = 1032.

Re-read: Lesson 1.4.3 — Pointer arithmetic and why it scales by type size

Q2 Answer: 61 mark

(2040 − 2016)/4 = 6 elements.

Re-read: Lesson 1.4.3 — Pointer arithmetic and why it scales by type size

Q3 Answer: (D)2 marks

(*p)++ gives 10, x → 11; ++*p makes x 12 and gives 12.

Output

10 12 12
  • (A) is wrong: a gets the old value.
  • (B) is wrong: x is incremented twice.
  • (C) is wrong: Post-increment gives the old value 10.

Re-read: Lesson 1.4.3 — Pointer arithmetic and why it scales by type size

Q4 Answer: (A)1 mark

Post-increment ++ binds tighter than *.

  • (B) is wrong: That is *++p.
  • (C) is wrong: That is ++*p.
  • (D) is wrong: That increments the value.

Re-read: Lesson 1.4.3 — Pointer arithmetic and why it scales by type size

Q5 Answer: (B) (C) (D)1 mark

Adding two pointers has no meaning.

  • (A) is wrong: Pointer + pointer is not allowed.

Re-read: Lesson 1.4.3 — Pointer arithmetic and why it scales by type size

Ready for the next idea?

Mark this item complete when you’ve finished reading and working through it.