• Articles
  • Using Pointers 3 dfferent ways
Published by
Oct 22, 2012 (last update: Oct 22, 2012)

Using Pointers 3 dfferent ways

Score: 3.3/5 (123 votes)
*****
In this small article, I show you about pointers by performing the same task using pointers in 3 different way. I think for some one learning c++ this is a very good approach because you can see pointers from different angles and get a much better idea as to what they and how to use them.

the code uses 3 different approaches using pointers to create an array of strings. you can look at the it as a sparse matrix of characters or just an array of strings like
Aa01234
Bb012
Cc0123456
etc.

the 3 approaches are offset, indexes and increments
the codes uses the #define in order to be able to compile
easily the each aproach so by just commenting these 3 lines
you can see how each approach works.

for example now it is set to run using increments

1
2
3
//#define _use_offset_
//#define _use_array_
#define _use_increments_ 


the data structure I use is the char**
this is a pointer to a pointer to a character
like -> (-> character)
I initialize it to
 
char** array_of_strings = new char*[26];


so is basically an array of strings like
-> ->sssssssssssss
->sssssssssssss
->sssssssssssss

array_of_stringsis the main pointer -> which we move by either method
vertically (is better to think of it this way). at the moment
we dereference *array_of_strings we then have another pointer the one that
points to the actual string, the second -> above.
so array_of_strings++ moves to the next string (vertical) and
(*array_of_strings)++ points to the next character in the string horizontal.


the first approach using offsets, in this approach we don't modify
the pointers, instead we use some offset value to point to the data
like *(pointer+5) = something. because pointers hold address we can so this
so pointer+5 points to the address of the byte which is 5 bytes from pointer
in array terminology as you will see in the array approach this is equivalent to pointer[5]. In increments terminology this is equivalent to
++pointer;++pointer;++pointer;++pointer;++pointer, incrementing the pointer 5
times.

the second approach is the best and easiest, using array indexes
array[i][j].

the third approach is the increments. here we need to modify the pointer
because we move the pointer forward or backward using the ++ and -- operators.

so p[1], *(p+1) and *++p are 3 ways to do the same thing
point pointer to one byte after pointer.

in the increment method you will see i used 2 pointers
array_of_strings and new_string they are both pointers but they
behave differently. array_of_strings is a pointer to a pointer
it points to a pointer to a byte (character), while new_string
points to the actual data the string. when we do array_of_strings++
we move array_of_strings to point to the next string.

Aa01234
*array_of_strings++ -> Bb01234567

and when we do *++new_string we point to the next character in the string
Aa01234
^
|
*++new_pointer

notice i use the increment operator before *++p not *p++ because i wanted
to increment p first and then dereference. if i had done *p++ it would process
Aa012345 or which ever string twice

bellow is the code, it has comments and I think is not hard to follow
just comment two of the #define and leave the one you want to experiment with
uncommented, then set break points and see how it works.

to run the code just create a new windows console application if using
Microsoft visual studio. if using some other tool then just copy paste
the code in your Main function

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
	/************************************************************************/
	/*
	    this example shows the equivalence in pointer math between
	    array     p[i]
	    offset    *(p+i)
	    increment p++ p++ ..... i number of times

	    example p[3] = *(p+3) = p++ p++ p++
	*/
//#define _use_offset_
//#define _use_array_
#define _use_increments_

	#ifdef _use_offset_
		cout << "using offset\n";
	#endif
	#ifdef _use_array_
		cout << "using array\n";
	#endif
	#ifdef _use_increments_
		cout << "using increments\n";
	#endif

	int j;
	
	/*
	    declare and initialize the sparse matrix of characters
	    or the array of string, whichever fits.
	*/
	char** array_of_strings = new char*[26];

	for (int i = 0; i < 26 ; i++) 
	{
#ifdef _use_offset_		
		/*
		  using offsets
		  instead of changing the pointer, just use
		  and offset from it all the time. the i is the
	           vertical offset into the table of strings
		  while the j is the horizontal. j = x and y = i
		  in vector terminology.
		*/
		*(array_of_strings+i)      = new char(toascii(65+i));
		*(*(array_of_strings+i)+1) = char(toascii(97+i));
		for (j = 2; j < rand() % 16 + 2; j++)
			*(*(array_of_strings+i)+j) = char(toascii(48+j-2));
		*(*(array_of_strings+i)+j) = '\0';
#endif
#ifdef _use_array_
		/*
		   using arrays
		   the simplest and prefered way because is more
	            readable and cleaner. just use array indexes
		    [y][x] or [i][j]
		*/
		array_of_strings[i]    = new char(toascii(65+i));
		array_of_strings[i][1] = char(toascii(97+i));
		for (j = 2; j < rand() % 16 + 2; j++)
			array_of_strings[i][j] = char(toascii(48+j-2));
		array_of_strings[i][j] = '\0';
#endif
#ifdef _use_increments_
		/*
		   use increments
		   here we change the pointers instead of using offsets
		   like p+i we actuaqlly increment the pointers p++
		   two things we need a two pointers the vertical pointer
		   and the horizontal pointer which actually points to
		   each string. array_of_strings is the verticaal and
	            new_string is the horizontal and the one which
		   points to the string and we use to modify the strings.

		   before printing out the strings we need to reset 
	            the vertical pointer array_of_strings back to the
		   to the beginning so we simply subtract 26 from it
	            because we incremented it 26 times.
		*/ 
		char* new_string  = *array_of_strings++ = new char(toascii(65+i));
		*++new_string = char(toascii(97+i));
		for (j = 2; j < rand() % 16 + 2; j++)
			*++new_string = char(toascii(48+j-2));
		*++new_string = '\0';
#endif
	}

		#ifdef _use_increments_
			array_of_strings = array_of_strings - 26;
		#endif

	for (int i = 0; i < 26 ; i++) 
	{
		#ifdef _use_offset_
			cout << *(array_of_strings+i) << endl;
		#endif
		#ifdef _use_array_
			cout << array_of_strings[i] << endl;
		#endif
		#ifdef _use_increments_
			cout << *array_of_strings++ << endl;
		#endif
	}
	/************************************************************************/