A brief review on operators:
|
Example:
The integer addition operator +: (1) + operates on 2 int operands (binary operator) (2) + returns the sum of its operands (3) + returns a result of the type int 3 + 4 = 7 (result) |
The reference operator &:
|
Example:
int a; float b; &a returns the address of the int typed variable a &b returns the address of the float typed variable b |
Note: the data type of &a and &b are different !!!
In C, the programmer can use the & operator to find the address of any variable in the program:
#include <stdio.h> int i = 4; short s = 5; float f = 6.0; double d = 7.0; int main(int argc, char *argv[]) { printf("Address of i = %p\n", &i ); // %p = pointer printf("Address of s = %p\n", &s ); printf("Address of f = %p\n", &f ); printf("Address of d = %p\n", &d ); } |
This feature is not available in any other programming language (except C++)
|
Example: storing addresses into reference typed variables
#include <stdio.h> int i = 4, *p; // p stores addresses of int typed vars short s = 5, *q; // q stores addresses of short typed vars int main(int argc, char *argv[]) { } |
|
Example: storing addresses into reference typed variables
#include <stdio.h> int i = 4, *p; // p stores addresses of int typed vars short s = 5, *q; // q stores addresses of short typed vars int main(int argc, char *argv[]) { &i; // this is the address of an int typed var &s; // this is the address of a short typed var } |
|
Example: storing addresses into reference typed variables
#include <stdio.h> int i = 4, *p; // p stores addresses of int typed vars short s = 5, *q; // q stores addresses of short typed vars int main(int argc, char *argv[]) { p = &i; // stores the address of var i in p q = &s; // stores the address of var s in q } |
|
Example: DEMO
#include <stdio.h> int i = 4, *p; short s = 5, *q; int main(int argc, char *argv[]) { p = &i; q = &s; printf("address of i = %p\n", p); printf("address of s = %p\n", q); } |
This is how the C compiler translates p = &i:
C: ARM assembler ================== ============================ int i, *p; .data i: .skip 4 p: .skip 4 // an address is 4 bytes p = &i; .text movw r0, #:lower16:i movt r0, #:upper16:i // r0 = &i movw r1, #:lower16:p movt r1, #:upper16:p str r0, [r1] // p = &i |
The mechanism to find the address of any variable is a powerful feature - it's only available in assembler programming languages !
Note: you cannot find out the address of a variable in Java !
|
These assignments are illegal due to type conflicts:
int i = 4, *p; // p must store an addr of an int typed var short s = 5, *q; // q must store an addr of an short var int main(int argc, char *argv[]) { p = &s; // Illegal: stores addr of a short type var in p q = &i; // Illegal: stores addr of a int type var in q } |
The de-reference operator *:
|
Important note:
|
Before I show you an example of the * operator, you need to know that:
|
The precedence of the operators will help you understand how the expression is evaluated.
int *p, a, b; // p stores address of int typed variables |
int *p, a, b; // p stores address of int typed variables
After this assignment:
p = &a; // p will store the address of
// the int type variable a
|
int *p, a, b; // p stores address of int typed variables After this assignment: p = &a; // p will store the address of // the int type variable a Then the expression: *p // is equivalent to a anywhere in the program |
int *p, a, b; // p stores address of int typed variables
After this assignment:
p = &a; // p will store the address of
// the int type variable a
Then the expression:
*p // is equivalent to a anywhere in the program
And after this assignment:
p = &b; // p will store the address of
// the int type variable b
|
int *p, a, b; // p stores address of int typed variables After this assignment: p = &a; // p will store the address of // the int type variable a Then the expression: *p // is equivalent to a anywhere in the program And after this assignment: p = &b; // p will store the address of // the int type variable b Now the expression: *p // is equivalent to b anywhere in the program |
Reference variables in C are often used as aliases (= another name) for variables.
Example:
#include <stdio.h> int main(int argc, char *argv[]) { int a = 4, b = 8, *p; p = &a; // Now *p is an alias for a *p = *p + 100; // ≡ a = a + 100 printf("a = %d, b = %d\n", a, b); p = &b; // Now *p is an alias for b *p = *p + 200; // ≡ b = b + 200 printf("a = %d, b = %d\n", a, b); } |
This is how the C compiler translates *p = *p + 99:
// *p = *p + 99 movw r0, #:lower16:p movw r0, #:upper16:p ldr r0, [r0] // r0 = p (= addr of some int typed var) ldr r0, [r0] // Use addr to load value from variable // *p = *p + 99 add r1, r0, #99 // r1 = RHS // *p = *p + 99 movw r0, #:lower16:p movw r0, #:upper16:p ldr r0, [r0] // r0 = p str r1, [r0] // Use p to write value to variable |
So when p contains the address of variable a , *p = *p + 99 will add 99 to the a
And when p contains the address of variable b , *p = *p + 99 will add 99 to the b
|
The * operator is the inverse operator for the & operator
This is valid for any variable x: *(&x) ≡ x // Their data types are same too ! |
Example:
#include <stdio.h> int main(int argc, char *argv[]) { int i; i = 4; printf("i = %d\n", i ); *(&i) = 9999; // Equiv to: i = 9999; printf("i = %d\n", i ); } |