-
Notifications
You must be signed in to change notification settings - Fork 0
/
pointers.c
117 lines (91 loc) · 2.76 KB
/
pointers.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "pointers.h"
void pain()
{
void* g;
// pointers can be void and general-purpose, but that limits your
// ability to do pointer arithmatic and you'll have to typecast them with
// (type*) p when attempting to use em in type-specific shit like printf
int* p; // pointers take the same type as their variable
int x; // init the variable
p = &x; // to point at x, you need to use the address operator &
x = 5;
// note: address operator can never be used lhs, as so: &x = 0xdeadbeef
g = p; // will this work? yes. *g = *p won't. (not without type casting)
// to disallow pointer aliasing, add the keyword `restrict` to the pointer
// declaration.
printf("x's value:\t%d\n", x);
printf("x's address:\t%p\n", &x);
printf("p's value:\t%p\n", p); // prints x's address
printf("p's deref val:\t%d\n", *p); // prints x's value
// printf("x's deref val:\t%d\n", *x); // shouldn't work
/*
* at compile time:
* error: invalid type argument of unary ‘*’ (have ‘int’)
* because x isn't a pointer
*/
printf("p's address:\t%p\n", &p); // prints p's address!!
printf("g's value :\t%p\n", g);
printf("g's deref val:\t%d\n", *((int*)g) ); //won't work without casting
// let's have fun:
puts("=========================");
puts("*p = 10;");
*p = 10;
printf("x's value:\t%d\n", x);
//printf("x's address:\t%d\n", &x);
//printf("p's value:\t%d\n", p);
//printf("p's deref val:\t%d\n", *p);
//printf("p's address:\t%d\n", &p);
/*
puts("=========================");
puts("p = 10;");
p = 10; // compiles with a warning
printf("x's value:\t%d\n", x);
//printf("x's address:\t%d\n", &x);
printf("p's value (no longer x's addr):\t%d\n", p);
printf("p's deref val:\t");
//printf("%d", *p); // this segfaults.
// cause p points at addr 0x00000000000a
printf("\n");
//printf("p's address:\t%d\n", &p);
*/
}
/*
* C's functions are called by value, not reference. And the function scope is
* private and has no effect over global scope.
* To get around this and introduce mutability, we build the function to handle
* pointers instead of values.
* In this example I'll construct two functions, swap and pswap, and we'll try
* to see the difference in their effect
*/
void swap(int a, int b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
void pswap(int* a, int* b)
{
int tmp;
tmp = *a;
*a = *b; // remember *p = *g and how it didn't work?
*b = tmp;
}
void swaptest()
{
puts("===============================");
int a, b;
a = 10;
b = 69;
printf("before swapping: a = %d, b = %d\n", a, b);
swap(a, b);
printf("after swap: a = %d, b = %d\n", a, b);
pswap(&a, &b); // another way is to pass a,b pointers instead of addresses
printf("after pswap: a = %d, b = %d\n", a, b);
}
int main()
{
pain();
swaptest();
return 0;
}