Equations of Structure Single Pointer
In this section, you are going to learn
What are the different ways of declarations ?
How to dervie equations ?
What are the Properties of Variable ?
What are the Properties of Expression ?
1. Equations of Single Pointer
In this section, you are going to learn
How to derive pointer equations for single pointer ?
How to apply these equations to understand C statements ?
You can derive equations looking at C declarations !
There are many methods in C, using which a single pointer can be declared. See below
1#include <stdio.h> 2 3struct ABC 4{ 5 int a; 6 int b; 7 int c; 8}; 9 10int main(void) 11{ 12 struct ABC x = {.a = 1, .b = 2, .c = 3}, *p = &x; 13 14 p->a = 10; 15 p->b = 20; 16 p->c = 30; 17 18 printf("x.a = %d\n", x.a); 19 printf("x.b = %d\n", x.b); 20 printf("x.c = %d\n", x.c); 21 22 // Use "p->" notation to access contents of "x" 23 printf("p->a = %d\n", p->a); 24 printf("p->b = %d\n", p->b); 25 printf("p->c = %d\n", p->c); 26 27 // Use "p[0]" notation to access contents of "x" 28 printf("p[0].a = %d\n", p[0].a); 29 printf("p[0].b = %d\n", p[0].b); 30 printf("p[0].c = %d\n", p[0].c); 31 32 // Use "(*p)." notation to access contents of "x" 33 printf("(*p).a = %d\n", (*p).a); 34 printf("(*p).b = %d\n", (*p).b); 35 printf("(*p).c = %d\n", (*p).c); 36 37 return 0; 38}Output is as below
x.a = 10 x.b = 20 x.c = 30 p->a = 10 p->b = 20 p->c = 30 p[0].a = 10 p[0].b = 20 p[0].c = 30 (*p).a = 10 (*p).b = 20 (*p).c = 30
- In this example,
x
is a structure
p
is a structure pointer
x
andp
are declared in one Single Line
x
andp
are assigned in one Single Line
x
is assigned with value 10
p
is assigned with address ofx
1#include <stdio.h> 2 3struct ABC 4{ 5 int a; 6 int b; 7 int c; 8}; 9 10int main(void) 11{ 12 struct ABC x = {.a = 1, .b = 2, .c = 3}; 13 14 struct ABC *p = &x; 15 16 p->a = 10; 17 p->b = 20; 18 p->c = 30; 19 20 printf("x.a = %d\n", x.a); 21 printf("x.b = %d\n", x.b); 22 printf("x.c = %d\n", x.c); 23 24 // Use "p->" notation to access contents of "x" 25 printf("p->a = %d\n", p->a); 26 printf("p->b = %d\n", p->b); 27 printf("p->c = %d\n", p->c); 28 29 // Use "p[0]" notation to access contents of "x" 30 printf("p[0].a = %d\n", p[0].a); 31 printf("p[0].b = %d\n", p[0].b); 32 printf("p[0].c = %d\n", p[0].c); 33 34 // Use "(*p)." notation to access contents of "x" 35 printf("(*p).a = %d\n", (*p).a); 36 printf("(*p).b = %d\n", (*p).b); 37 printf("(*p).c = %d\n", (*p).c); 38 39 return 0; 40}Output is as below
x.a = 10 x.b = 20 x.c = 30 p->a = 10 p->b = 20 p->c = 30 p[0].a = 10 p[0].b = 20 p[0].c = 30 (*p).a = 10 (*p).b = 20 (*p).c = 30
- In this example,
x
is a structure
p
is a structure pointer
x
is declared in a separate line
p
is declared in a separate line
x
is assigned in the same line of declaration
p
is assigned in the same line of declaration
x
is assigned with value 10
p
is assigned with address ofx
1#include <stdio.h> 2 3struct ABC 4{ 5 int a; 6 int b; 7 int c; 8}; 9 10int main(void) 11{ 12 struct ABC x; 13 14 x.a = 10; 15 x.b = 20; 16 x.c = 30; 17 18 struct ABC *p; 19 p = &x; 20 21 p->a = 10; 22 p->b = 20; 23 p->c = 30; 24 25 printf("x.a = %d\n", x.a); 26 printf("x.b = %d\n", x.b); 27 printf("x.c = %d\n", x.c); 28 29 // Use "p->" notation to access contents of "x" 30 printf("p->a = %d\n", p->a); 31 printf("p->b = %d\n", p->b); 32 printf("p->c = %d\n", p->c); 33 34 // Use "p[0]" notation to access contents of "x" 35 printf("p[0].a = %d\n", p[0].a); 36 printf("p[0].b = %d\n", p[0].b); 37 printf("p[0].c = %d\n", p[0].c); 38 39 // Use "(*p)." notation to access contents of "x" 40 printf("(*p).a = %d\n", (*p).a); 41 printf("(*p).b = %d\n", (*p).b); 42 printf("(*p).c = %d\n", (*p).c); 43 44 return 0; 45}Output is as below
x.a = 10 x.b = 20 x.c = 30 p->a = 10 p->b = 20 p->c = 30 p[0].a = 10 p[0].b = 20 p[0].c = 30 (*p).a = 10 (*p).b = 20 (*p).c = 30
- In this example,
x
is a structure
p
is a structure pointer
x
is declared in a separate line
p
is declared in a separate line
x
is assigned and is not part of declaration
p
is assigned and is not part of declaration
x
is assigned with value 10
p
is assigned with address ofx
Decl #
Declaration
Description
Decl 1
struct ABC x, *p = &x;
struct ABC x, Pointer p are declared and assigned in same line
Decl 2
struct ABC x;
struct ABC *p = &x;
struct ABC x, Pointer p are declared and assigned in separate lines
Decl 3
- struct ABC x;
x.a = 10;
x.b = 20;
x.c = 30;
struct ABC *p;
p = &x;
struct ABC x, Pointer p are declared in one line and assigned in another line
Whenever we see any of the above methods of declarations, we need to rewrite them such that, declarations and assignments are not in same line. Similar to Declaration 3
Equation 1 : Obtained from
Step 2
p = &x;Implication :
p
holds the address ofx
Equation 2 : Move
&
to the left of First Equation. It turns in to*
*p = x;Implication :
x
and*p
are one and the same !
Equation 3 :
*p
has an aliasp[0]
. Means*p
andp[0]
are one and the same !p[0] = x;Implication :
x
andp[0]
are one and the same !
Equation 4 : From Equation 2, Equation 3, we can derive that
x
,*p
,p[0]
all are same !*p = p[0] = x;
(*p).a = 10; (*p).b = 20; (*p).c = 30; printf("(*p).a = %d\n", (*p).a); printf("(*p).b = %d\n", (*p).b); printf("(*p).c = %d\n", (*p).c);Output is as below
(*p).a = 10 (*p).b = 20 (*p).c = 30p[0].a = 10; p[0].b = 20; p[0].c = 30; printf("p[0].a = %d\n", p[0].a); printf("p[0].b = %d\n", p[0].b); printf("p[0].c = %d\n", p[0].c);Output is as below
p[0].a = 10 p[0].b = 20 p[0].c = 30p->a = 10; p->b = 20; p->c = 30; printf("p->a = %d\n", p->a); printf("p->b = %d\n", p->b); printf("p->c = %d\n", p->c);Output is as below
p->a = 10 p->b = 20 p->c = 30x.a = 100; printf("x.a = %d\n", x.a); printf("(*p).a = %d\n", (*p).a); printf("p[0].a = %d\n", p[0].a); printf("p->a = %d\n", p->a);Output is as below
x.a = 100 (*p).a = 100 p[0].a = 100 p->a = 1001#include <stdio.h> 2 3struct ABC 4{ 5 int a; 6 int b; 7 int c; 8}; 9 10int main(void) 11{ 12 struct ABC x; 13 14 struct ABC *p; 15 16 x.a = 10; 17 18 p = &x; 19 20 printf("x.a = %d, (*p).a = %d, p[0].a = %d, p->a = %d\n", x.a, (*p).a, p[0].a, p->a); 21 22 x.a = 20; 23 24 printf("x.a = %d, (*p).a = %d, p[0].a = %d, p->a = %d\n", x.a, (*p).a, p[0].a, p->a); 25 26 (*p).a = 30; 27 28 printf("x.a = %d, (*p).a = %d, p[0].a = %d, p->a = %d\n", x.a, (*p).a, p[0].a, p->a); 29 30 p[0].a = 40; 31 32 printf("x.a = %d, (*p).a = %d, p[0].a = %d, p->a = %d\n", x.a, (*p).a, p[0].a, p->a); 33 34 p->a = 50; 35 36 printf("x.a = %d, (*p).a = %d, p[0].a = %d, p->a = %d\n", x.a, (*p).a, p[0].a, p->a); 37 38 return 0; 39}
Output is as below
x.a = 10, (*p).a = 10, p[0].a = 10, p->a = 10 x.a = 20, (*p).a = 20, p[0].a = 20, p->a = 20 x.a = 30, (*p).a = 30, p[0].a = 30, p->a = 30 x.a = 40, (*p).a = 40, p[0].a = 40, p->a = 40 x.a = 50, (*p).a = 50, p[0].a = 50, p->a = 50
Equation #
Equation
Description
Equation 1
p = &x
Base condition
Equation 2
*p = x
From Equation 1, Move & from RHS to LHS to get * on LHS
Equation 3
p[0] = x
*p and p[0] are synonyms
Equation 4
*p = p[0] = x
From Equation 2, 3 we can conclude *p, p[0], x are synonyms
2. Properties of a variable
In this section, you are going to learn
Properties of a variable
Type of a variable ?
Size of a variable ?
Scope, Lifetime and Memory of a variable ?
1struct ABC x; 2 3struct ABC *p; 4 5p = &x; 6 7p->a = 10;
In above code snippet, there are two variables
x
,p
Variable
Type
Description
type_of(x)
struct ABC
See Line 1
type_of(p)
struct ABC *
See Line 3
Adress of variable must be stored in next level pointer type always
1struct ABC x; 2 3struct ABC *p; 4 5p = &x; 6 7p->a = 10;
In above code snippet, there are two variables
x
,p
Variable
Type
Description
type_of(&x)
struct ABC *
type_of(x)
isstruct ABC
Hence,
type_of(&x)
isstruct ABC *
type_of(&p)
struct ABC **
type_of(p)
isstruct ABC *
Hence,
type_of(&p)
isstruct ABC **
Sizeof(type)
Size
sizeof(char)
1 Byte
sizeof(int)
4 Bytes
sizeof(float)
4 Bytes
sizeof(double)
8 Bytes
sizeof(pointer types)
is always 8 Bytes, where pointer is single, double, triple etc.,:
Sizeof(type *)
Size
sizeof(char *)
8 Bytes
sizeof(int *)
8 Bytes
sizeof(float *)
8 Bytes
sizeof(double *)
8 Bytes
sizeof(struct xyz *)
8 Bytes
sizeof(union xyz *)
8 Bytes
Sizeof(type **)
Size
sizeof(char **)
8 Bytes
sizeof(int **)
8 Bytes
sizeof(float **)
8 Bytes
sizeof(double **)
8 Bytes
sizeof(struct xyz **)
8 Bytes
sizeof(union xyz **)
8 Bytes
etc.,
sizeof(&variable)
is always 8 Bytes, wheretype_of(variable)
can be anything
Sizeof(&variable)
Size
Declaration
sizeof(&x)
8 Bytes
char x;
sizeof(&x)
8 Bytes
int x;
sizeof(&x)
8 Bytes
float x;
sizeof(&x)
8 Bytes
double x;
sizeof(&x)
8 Bytes
struct xyz x;
sizeof(&x)
8 Bytes
union xyz x;
Sizeof(&variable)
Size
Declaration
sizeof(&x)
8 Bytes
char *x;
sizeof(&x)
8 Bytes
int *x;
sizeof(&x)
8 Bytes
float *x;
sizeof(&x)
8 Bytes
double *x;
sizeof(&x)
8 Bytes
struct xyz *x;
sizeof(&x)
8 Bytes
union xyz *x;
sizeof(variable)
equalssizeof(typeof(variable))
1struct ABC 2{ 3 int a; 4 int b; 5 int c; 6}; 7 8struct ABC x; 9 10struct ABC *p; 11 12p = &x; 13 14p->a = 10;
In above code snippet, there are two variables
x
,p
Sizeof(Variable)
Size
Description
sizeof(x)
12 Bytes
- How ?
Step 1 :
sizeof(x)
equalssizeof(typeof(x))
Step 2 :
type_of(x)
isstruct ABC
Step 3 :
sizeof(struct ABC)
is12 Bytes
Hence,
sizeof(x)
is12 Bytes
sizeof(p)
8 Bytes
- How ?
Step 1 :
sizeof(p)
equalssizeof(typeof(p))
Step 2 :
type_of(p)
isstruct ABC *
Step 3 :
sizeof(struct ABC *)
is8 Bytes
Hence,
sizeof(p)
is8 Bytes
Global Scope and Lifetime
1struct ABC 2{ 3 int a; 4 int b; 5 int c; 6}; 7 8struct ABC x; 9 10struct ABC *p; 11 12int main(void) 13{ 14 p = &x; 15 16 p->a = 10; 17 p->b = 20; 18 p->c = 30; 19 20 return 0; 21}
In above code snippet,
- Scope
Two variables
x
,p
are defined in Global Scope at Lines 8, 10Which means, they can be accessed in any function defined in current file
Which means, they can be accessed in any function defined in other files using extern keyword
1extern struct ABC x; 2 3extern struct ABC *p; 4 5void display(void) 6{ 7 printf("x.a = %d, p->a = %d\n", x.a, p->a ); 8 printf("x.b = %d, p->b = %d\n", x.a, p->b ); 9 printf("x.c = %d, p->c = %d\n", x.a, p->c ); 10}
- Lifetime
Lifetime of variables
x
,p
is same as Lifetime of Process(Program)
- Memory
Memory of
12 Bytes
for variablex
is reserved/allocated on Data Segment of the ProcessMemory of
8 Bytes
for variablep
is reserved/allocated on Data Segment of the ProcessLocal Scope and Lifetime
1struct ABC 2{ 3 int a; 4 int b; 5 int c; 6}; 7 8int do_calc(void) 9{ 10 struct ABC x; 11 12 struct ABC *p; 13 14 p = &x; 15 16 p->a = 10; 17 18 return 0; 19} 20 21int main(void) 22{ 23 do_calc(); 24 25 return 0; 26}
In above code snippet,
- Scope
Two variables
x
,p
are defined in Local Scope at Lines 10, 12 inside functiondo_calc
Which means, they can be accessed only inside a function
do_calc
and not anywhere else
- Lifetime
Lifetime of variables
x
,p
is same as Lifetime of functiondo_calc
- Memory
When a function call is made for
do_calc
, stack frame for functiondo_calc
is createdMemory of
12 Bytes
for variablex
is reserved/allocated on stack frame of functiondo_calc
Memory of
8 Bytes
for variablep
is reserved/allocated on stack frame of functiondo_calc
When a function
do_calc
returns at Line 18, stack frame for functiondo_calc
is deletedWith this memory of variables
x
,p
are also deleted
3. Properties of Expressions
In this section, you are going to learn
Properties of Expressions
What is an Expression ?
Table of Expressions
Table of Size (for Expressions)
Table of Type (for Expressions)
Table of Address/Value (for Expression)
Table of Function Prototype (for Expression)
Let us consider an example program as below
1#include <stdio.h>
2
3struct ABC
4{
5 int a;
6 int b;
7 int c;
8};
9
10int main(void)
11{
12 struct ABC x;
13
14 struct ABC *p, *q;
15
16 int sum;
17
18 //Write to x
19 x.a = 10;
20 x.b = 20;
21 x.c = 30;
22
23 //Read from x
24 sum = x.a + x.b + x.c;
25
26 //Write to p
27 p = &x;
28
29 //Read from p
30 q = p;
31
32 //Write to *p or Write to x
33 p->a = 100;
34 p->b = 200;
35 p->c = 300;
36
37 //Read from *p or Read from x
38 sum = p->a + p->b + p->c;
39
40 printf("sum = %d\n", sum);
41
42 return 0;
43}
Output is as below
sum = 600
Expressions must be understood always in a non-declaration C statement
Expressions are the valid operations on a given variable - (I am defining this for simplicity !)
- Write of
x
At Line 19, 20, 21,
Write
operation is done on variablex
- Write of
- Read of
x
At Line 24,
Read
operation is done on variablex
which is reading content of variablex
- Read of
- Fetch Address of
x
(&x) At Line 27, Address of variable
x
is being fetched and assigned to pointer variablep
- Fetch Address of
- Write of
p
At Line 33, 34, 35,
Write
operation is done on variablep
which is storing address ofx
intop
- Write of
- Read of
p
At Line 38,
Read
operation is done on variablep
which is reading content ofp
p
contains address ofx
- Read of
1struct ABC x;
2
3struct ABC *p;
4
5p = &x;
6
7p->a = 10;
Expression
Description
x
x
is a structure&x
&x
is address of a structure
&x
is a single pointerp
p
is a pointer to a structure
p
is a single pointer&p
&p
is address of a pointer
&p
is a double pointer*p
*p
is a structure, because*p = x
. See Equation 2p[0]
p[0]
is a structure, becausep[0] = x
. See Equation 3
Expression
Size
Description
sizeof(x)
12 Bytes
sizeof(&x)
8 Bytes
sizeof(p)
8 Bytes
sizeof(&p)
8 Bytes
sizeof(*p)
12 Bytes
Step 1 :
sizeof(*p)
equalssizeof(x)
See Equation 2Step 2 :
sizeof(x)
equalssizeof(type_of(x))
See Property 2.4Step 3 :
sizeof(type_of(x))
equalssizeof(struct ABC)
See Property 1.1Step 4 :
sizeof(struct ABC)
equals 12 Bytessizeof(p[0])
12 Bytes
Step 1 :
sizeof(p[0])
equalssizeof(x)``= x
See Equation 3Step 2 :
sizeof(x)
equalssizeof(type_of(x))
See Property 2.4Step 3 :
sizeof(type_of(x))
equalssizeof(struct ABC)
See Property 1.1Step 4 :
sizeof(struct ABC)
equals 12 Bytes
Expression
Type
Description
type_of(x)
struct ABC
type_of(&x)
struct ABC *
type_of(p)
struct ABC *
type_of(&p)
struct ABC **
type_of(*p)
struct ABC
Step 1 :
type_of(*p)
equalstype_of(x)
, because*p = x
. See Equation 2Step 2 :
type_of(x)
equalsstruct ABC
type_of(p[0])
struct ABC
Step 1 :
type_of(p[0])
equalstype_of(x)
, becausep[0] = x
. See Equation 3Step 2 :
type_of(x)
equalsstruct ABC
Expression
Address/Value
Description
x
Value
Step 1 :
x
is a structureStep 2 : Hence
x
is a value&x
Address
& operator indicates address
p
Address
Step 1 :
p = &x
See Equation 1Step 2 : & operator indicates address
&p
Address
& operator indicates address
*p
Value
Step 1 :
*p
is a structure.*p = x
See Equation 2Step 2 : Hence
*p
is a valuep[0]
Value
Step 1 :
p[0]
is a structure.p[0] = x
See Equation 3Step 2 : Hence
p[0]
is a value
If
fun(v)
is function call then,fun(type_of(v))
is the prototype
Function call
Function Prototype
Description
fun(x)
void fun(struct ABC x);
fun(&x)
void fun(struct ABC *p);
fun(p)
void fun(struct ABC *p);
fun(&p)
void fun(struct ABC **p);
fun(*p)
void fun(struct ABC x);
Step 1 :
fun(*p)
equalsfun(x)
See Equation 2Step 2 :
fun(x)
equalsfun(type_of(x))
Step 3 :
fun(type_of(x))
equalsfun(struct ABC)
fun(p[0])
void fun(struct ABC x);
Step 1 :
fun(p[0])
equalsfun(x)
See Equation 2Step 2 :
fun(x)
equalsfun(type_of(x))
Step 3 :
fun(type_of(x))
equalsfun(struct ABC)
4. Summary
# |
? |
Size in Bytes |
Type |
Address or Value |
Function call |
Function Prototype |
---|---|---|---|---|---|---|
x |
struct ABC |
12 |
struct ABC |
Value |
fun(x) |
void fun(struct ABC x); |
&x |
Single Pointer |
8 |
struct ABC * |
Address |
fun(&x) |
void fun(struct ABC *p); |
p |
Single Pointer |
8 |
struct ABC * |
Address |
fun(p) |
void fun(struct ABC *p); |
&p |
Double Pointer |
8 |
struct ABC ** |
Address |
fun(&p) |
void fun(struct ABC **q); |
*p |
struct ABC |
12 |
struct ABC |
Value |
fun(*p) |
void fun(struct ABC x); |
p[0] |
struct ABC |
12 |
struct ABC |
Value |
fun(p[0]) |
void fun(struct ABC x); |
Current Module
Next Module
Other Modules