Pointers (archived tutorial)

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Sep 2004
Posts: 185
Reputation: Stack Overflow is an unknown quantity at this point 
Solved Threads: 4
Stack Overflow's Avatar
Stack Overflow Stack Overflow is offline Offline
C Programmer

Pointers (archived tutorial)

 
1
  #1
Sep 2nd, 2004
Hello fellow programmers,

This is a tutorial about using pointers in the C environment. Please, don’t hit the back button; pointers aren’t as hard as you think. In fact without pointers, most of us would be lost in our latter programming years.

Even though pointers are for the experienced, as they say, I’m here to help programmers from consisting of all levels to help greater understand pointers, and why they are pertinent to your everyday programming needs.

Let me start off by stating, a pointer is a variable that contains the address of another variable. Pointers and arrays are closely related, though pointers are sometimes the only way to express a computation. Some also say pointers usually lead to more compact and efficient code. If you view the following example [1.1], it may confuse you or if not, you’ll see the incompleteness of it:

int main() {
	char c;
	char ch[2];
	char *pch;

	c = ‘a’;
	ch[0] = ‘a’
	*pch = ch[0];

	return 0;
}
Example 1.1: An incomplete look at pointers

Pointers and addresses need allocation to store its data. Unlike the char and char[] data types, which use locally stacked memory, pointers pass though existing memory stacks.

The unary operator “&� gives the memory address of an existing object. This assigns the address of one variable and “points to� another. Remember, pointers use existing memory, so we can either send an empty or freed block of memory to a pointer, or assign it another variables’ address. Let me lead this with an example:

#include <stdio.h>

int main() {
	int n = 3;
	int *ptr;

	ptr = &n;

	printf("%p\n", (void *)ptr);	// memory address
	printf("%d\n", *ptr);		// data

	return 0;
}
Example 1.2: A closer look into pointers and addresses

If you have tried to compile this piece of code, you may see that it did not result in a crash. As you might ask “why?� this is because we sent our memory address of the variable n to ptr which is results to giving ptr its memory block. Here, ptr does not receive its own block of memory, yet it points to an existing variable n. The same implementation applies for multiple situations, as arrays:

int main() {
	int n[5];
	int *ptr;

	ptr = &n[0];
	*ptr = 3;

	return 0;
}
Example 1.3: Sending a memory address to a pointer

As you are probably wondering how the same applies if you want to consistently move the pointers position to correspond with all 5 slots of the array {0, 1, 2, 3, 4}. This is called pointer arithmetic, and is very possible to do with ease. An example:

int main() {
	int n[5];
	int *ptr;

	ptr = &n[0];	// points to n[0]
	*(ptr+1);	// points to n[1]
	++*ptr;		// points to n[2]
	(*ptr)++;	// points to n[3]

	return 0;
}
Example 1.4: Pointer arithmetic

Pointer arithmetic may seem confusing, but it’s just like adding and subtracting. *ptr is the location of your pointer, not actually the value when working with arrays. As you may have already learned, “++� is an operator that remedies the choice of “+= 1�, or in other terms, “increments the variable by 1�. To move multiple positions at once, the recommended arithmetic would be “*(ptr+x)� as x represents your incrementing position.

Pointers are used in real programs. For example, take the following question and convert it to the C syntax:

There are 3 people in room A, and 5 in room B. If they were reversed, how many people would be in room A, and room B?

Note: This seems extremely easy and it would be best served if we used pointers in this situation. Let me explain, here, as logically explained above, we are to swap A and B, and produce an answer. With our current knowledge of pointers, this can be done feasibly:

#include <stdio.h>

void reverse(int *x, int *y);

int main() {
	int A = 3, B = 5; // represent room A and B

	reverse(&A, &B);

	printf(“Room A: %d\nRoom B: %d\n�, A, B);

	return 0;
}

void reverse(int *x, int *y) {
	int temp;	// temporary variable

	temp = *x;	// hold temporary variable that wont change
	*x = *y;	// set x to y
	*y = temp;	// set y to what x was temporarily before
}
Code 1.1: Reversing two numbers using pointer knowledge

As stated in code, void reverse(int *x, int *y) did a simple calculation and reversed A and B for us easily. The reason a temporary variable was needed, is because if we had set “*x = *y� and “*y = *x� it would have caused a problem no matter which we would call first. To break it down, we would literally state “1 [x] = 2 [y]�, then “2 [y] = 2 [x]�. Using a temporary variable should become clear since keeping the previous state of *x is very crucial at this point.

In order for this code to have worked so clearly, we would need to send our function void reverse(int *x, int *y) the memory addresses of A and B. That’s where the unary operator comes in handy. Send the addresses of A and B to *x and *y, swap out the two and we’re done. If we had not worked with pointers, we would have to create another set of variables, say, A0 and B0, then send A to B0, and B to A0 yet implementing a swap with unnecessary steps.


Pointers in the char data type realm
Above we discussed pointers in the realm of integers, and one-dimensional figures. As we may know, there are multiple dimensions in a programming environment, and we must take the appropriate steps to accommodate all surrounding aspects.

The character array realm is different from the integer, as we must deal with multiple instances in one variable. They both dwindle down to the fact of digits, as the ASCII Table defines. Standard ASCII, and signed char’s represent 0 thru 127. With those numbers, the char reads them as letters, or in the ASCII environment. To explain a character array is in the same line:

int main() {
	int iCh;
	char ch;			// signed
	char ca[3];

	ch = 'a';			// or 97 in ASCII
	iCh = 98;			// 98 is 'b' in ASCII
	ca[0] = ch;			// first index is 'a'
	ca[1] = (char)iCh;		// second index is 'b' [type cast the integer to char]
	ca[2] = 'c';			// third index is 'c'
	ca[3] = '\0';			// fourth ends here

	return 0;
}
Example 2.1: Character arrays in the integer environment

The example shown is still within the “one-dimensional� environment. Character pointers also need a valid memory address to write to, like integers. Pointers our pointers, so that rule applies always.

Pointing a character pointer to a valid memory address isn’t as easy as seen before in the integer arena. The following can be utilized, but is not recommended by most:

int main() {
	char text[6] = “Hello�;
	char *ptr;

	ptr = &text[0];	// not recommended

	return 0;
}
Example 2.2: Pointing a pointer to, though not recommended

As seen above, we initialized text to “Hello� which is 5 letters long resulting {‘H’, ‘e’, ‘l’, ‘l’ ‘o’, ‘\0’} 4 in the array world. Arrays always start at 0, and ‘\0’ is at location [5] in this case.

Next, I will display a more efficient way of receiving the memory address of a local variable. Even though it’s not recommended, it ensures more linkage between the two:

void pointTo(char **src, char *dst);

int main() {
	char text[3];
	char *ptr;

	pointTo(&ptr, text);

	ptr[0] = ‘A’;
	ptr[1] = ‘\0’;

	return 0;
}

void pointTo(char **src, char *dst) {
	*src = dst;
}
Example 2.3: Linking a pointer to a local variable

Not exactly a two-dimensional pointer yet, we just need to send a pointer’s address to a function resulting in the pointer’s “*� pointer “*�. In void pointTo(char **, char *); we point dst to the pointed pointer *src.

To ensure a pointer has a memory block without risking the chance of our local variable failing, we would take an opposite approach and allocate memory right from your machine. The first explanation is in C.

Memory allocation in C
We previously learned how to link memory addresses to pointers, but now its time to move to a more stable and serious approach: Handling memory from the core.

This is no time at all to write a function or algorithm to space partition memory and issue out how much is asked for or called. That’s why the ANSI standard incorporated a pre-made function for us called void *malloc(unsigned int);. This function works in a unique way, sending the pointer a memory address of empty/unused memory to the size you request. This function can fail if insufficient memory is provided. Here is an example of how this function is used in programming:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int main() {
	char *ptr;

	ptr = (char *)malloc(6);
	if (!ptr)
		return 0;

	strcpy(ptr, "Hello");

	printf(ptr);

	free(ptr);

	return 0;
}
Code 2.1: Allocating memory the right way

Let’s ask for 6 bytes of memory to work with. If it can’t be found, end program before a fatal crash, else, copy 5 letters to our 5 bytes leaving enough room for the NULL terminator ‘\0’. Let’s print our pointer to the screen, and last of all, and never forget, free the memory. void free(void *); works like malloc(), though it frees the memory of the memory address sent in the first and only argument. This function is also provided by the standard library stdlib.h. char *strcpy(char *, const char *); is also within the included function(s) written in the standard header files, though this one is declared in string.h. This function, strcpy(), isn’t hard to re-implement. In fact, it just takes a few pointer skills:

char* strcpy(char *dest, const char *src) {
	char *s = dest;

	while (*src)
		*s++ = *src++;
	*s = 0;

	return dest;
}
Example 3.1: Copy one string to another
Note: Remember, if you have <string.h> included, don’t add these functions to our code example. Library’s and functions will conflict, yet leading to errors.

I won’t get into great detail on this function. The main functioning of this is, that we increment *src and *s while copying the data from *src to *s while *src still exists. Once done, set the null terminator, and return dest as *s points to it.

Multi-dimensional pointers
As tricky as it may sound, multi-dimensional pointers are just as easy as one-dimensional pointers, so don’t give up!

As opposed to pointers, arrays can also work in a multi-dimensional realm. For example:

Lets take:
int myValue[2][3];
Or for a more detailed look would be as the following:

  1. Rows/Columns Column 0 Column 1 Column 2 Column 3
  2. Row 0 myValue[0][0] myValue[0][1] myValue[0][2] myValue[0][3]
  3. Row 1 myValue[1][0] myValue[1][1] myValue[1][2] myValue[1][3]
  4. Row 2 myValue[2][0] myValue[2][1] myValue[2][2] myValue[2][3]

That should make a lot of sense. If its to confusing, lets break it down:
int myValue[2][3] = { {5, -3, 0}, {10, 17, -25} };
Could be looked at as:

  1. Rows/Columns Column 0 Column 1 Column 2
  2. Row 0 5 -3 0
  3. Row 1 10 17 -25

This is beginning to look simpler by the minute. As we previously discussed, the character environment is somewhat different, but not always.

Look at this example:
char letters[2][3] = { {‘A’}, {‘D’, ‘E’} };
  1. Rows/Columns Column 0 Column 1 Column 2
  2. Row 0 A ‘\0’ ‘\0’
  3. Row 1 D E ‘\0’

As seen above, two-dimensional arrays consist of “row� and “column�, as one-dimensional consists of “column�. Allocating memory to two-dimensional arrays can be tricky, so here are some good steps to remember:

· Know your Row count first.
· Know your Column count next.
· Know your Column length

In this order, everything should come together smoothly. Lets take a look at an example:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
	int i, j, p;
	int rows = 6;
	char word[6][12] = {"Hello", "Good-Bye!", "Greetings",
						"Pointers", "Arrays", "Programming"};
	char **ptr;

	ptr = (char **)malloc(rows * (sizeof *ptr)); // allocate room for rows
	// If allocation succeeded
	if (ptr) {
		// Loop through all columns
		for (i = 0; i < rows; i++) {
			// Allocate
			ptr[i] = (char *)malloc(strlen(word[i]) + 1 * (sizeof **ptr));
			// If allocation succeeded
			if (ptr[i])
				// Copy data to our pointers memory	
				strcpy(ptr[i], word[i]);
		}
	}

	// Print data
	for (i = 0; i < rows; i++)
		printf("%s\n", ptr[i]);

	// Free memory
	for (j = 0; j < rows; j++)
		free(ptr[j]);
	free(ptr);

	return 0;
}
Code 3.1: Using two-dimensional arrays

The comments in the code help guide you through each step. The sizeof function comes in handy during this process. We need to multiply our allocation size with the size of our variable to assure we have enough space to allocate anything else. Without that, our program may terminate unexpectedly.

Pointers may seem difficult at this point, but its making perfect sense. There comes a time when it begins to advance. I do hope this tutorial has been helpful to you. Before I’m done, I’d like to explain and explore three-dimensional pointers. This too has a background of difficulty, but in the right perspective is as easy as everything else.

Three-Dimensional Pointers
This is an easy subject I like to think. It’s as easy as 1, 2, 3. Think of this as a Book. A book is three dimensions; depth, row, and column.

For example:
int Book[2][3][4];
Think of it as:

  1. Book – Page[0]:
  2. Rows/Columns Column 0 Column 1 Column 2
  3. Row 0 Book[0][0][0] Book[0][0][1] Book[0][0][2]
  4. Row 1 Book[0][1][0] Book[0][1][1] Book[0][1][2]
  5.  
  6. Book – Page[1]:
  7. Rows/Columns Column 0 Column 1 Column 2
  8. Row 0 Book[1][0][0] Book[1][0][1] Book[1][0][2]
  9. Row 1 Book[1][1][0] Book[1][1][1] Book[1][1][2]

Or better yet:

int Book[2][3][4] = { 
{ {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} } 		// Page 0
{ {12, 13, 14, 15}, {16, 17, 18, 19}, {20, 21, 22, 23} } // Page 1
};

Or in other terms it would look like:

  1. Book – Page[0]:
  2. Rows/Columns Column 0 Column 1 Column 2 Column 3
  3. Row 0 0 1 2 3
  4. Row 1 4 5 6 7
  5. Row 2 8 9 10 11
  6.  
  7. Book – Page[1]:
  8. Rows/Columns Column 0 Column 1 Column 2 Column 3
  9. Row 0 12 13 14 15
  10. Row 1 16 17 18 19
  11. Row 2 20 21 22 23

I hope this is all coming together. Of course taking special measures for memory allocation is always needed. I’ll show an example:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main() {
	int i, j, p;				// For loops
	int pNum;				// Page number
	int pGraphs;				// Paragraphs per page
	char paragraph[4][256];			// Our paragraphs
	char ***Book;				// Our book

	strcpy(paragraph[0], "Pointers are awesome! Now that I have learned 3-dimensional arrays, I can use this knowledge to write my own programs!");
	strcpy(paragraph[1], "Through learning one-dimensional to multi-dimensional, I now know that pointers aren't as bad as they may seem.");
	strcpy(paragraph[2], "It may be hard to write your own book typing all the text in a 3-dimensional array, but it works for an example!");
	strcpy(paragraph[3], "Good luck with using 3-dimensional pointers, I hope this has helped you alot in understanding how they work.");

	j = p = 0;				// Initialize loop variables
	pNum = 2;				// 2 pages
	pGraphs = 4;				// 2 paragraphs per page

	// Allocate memory
	Book = (char ***)malloc(pNum * (sizeof *Book));
	if (Book) {
		for (i = 0; i < pNum; i++) {
			Book[i] = (char **)malloc(pGraphs * (sizeof **Book));
			if (Book[i]) {
				for (j = 0; j < pGraphs; j++) {
					Book[i][j] = (char *)malloc(strlen(paragraph[j]) + 1 * (sizeof ***Book));
					if (Book[i][j])
						strcpy(Book[i][j], paragraph[j]);
				}
			}
		}
	}

	// Print data
	p = 0;
	printf("My two page book\n");
	for (i = 0; i < pNum; i++) {
		printf("\nPage: %i\n", i);
		for (j = p; j < (p + 2); j++) {
			printf("%s\n", Book[i][j]);
		}
		p = j;
	}

	// Free Memory
	for (i = 0; i < pNum; i++) {
		for (j = 0; j < pGraphs; j++)
			free(Book[i][j]);
		free(Book[i]);
	}
	free(Book);

	return 0;
}
Code 4.1: Using three-dimensional pointers

I’ll let you decipher that one on your own. Always remember; think of this code, as a book, and it will make complete sense.

I hope this tutorial shown the simplicity of pointers. Feedback is greatly appreciated, and good luck with your future programming.


- Stack Overflow
Following the rules will ensure you get a prompt answer to your question. If posting code, please include BB [code][/code] tags. Your question may have been asked before, try the search facility.

IRC
Channel: irc.daniweb.com
Room: #c, #shell
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 1
Reputation: karthik is an unknown quantity at this point 
Solved Threads: 0
karthik karthik is offline Offline
Newbie Poster

Re: Pointers

 
0
  #2
Sep 12th, 2004
In example 1.4 it is said that

++*ptr points to n[2].

That is wrong.

++*ptr will increment the value of the content of the location pointed by ptr.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 4
Reputation: dampy is an unknown quantity at this point 
Solved Threads: 0
dampy dampy is offline Offline
Newbie Poster

Re: Pointers

 
0
  #3
Sep 13th, 2004
in the code 1.1 which is used for reversing a A=3 and B=5 i am not quite sure why u have used

void reverse(int *x, int *y);

this is there in the first line.....

even if u do not write this line there program shud work ... well as such here u r basically calling a function in the beginning

and then again u r calling the function reverse inside the main block also ...

dunn think this will work...

making call 2 times when one would work...
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 9
Reputation: kind4ever is an unknown quantity at this point 
Solved Threads: 0
kind4ever kind4ever is offline Offline
Newbie Poster

Re: Pointers

 
0
  #4
Sep 18th, 2004
how i can use it in c++ please

and what adefintion of apointer?
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 185
Reputation: Stack Overflow is an unknown quantity at this point 
Solved Threads: 4
Stack Overflow's Avatar
Stack Overflow Stack Overflow is offline Offline
C Programmer

Re: Pointers

 
0
  #5
Sep 18th, 2004
Originally Posted by karthik
++*ptr will increment the value of the content of the location pointed by ptr.
» Ah, yes. Thank you for pointing that out.


Originally Posted by dampy
making call 2 times when one would work...
» The only reason I did this was because the first call on top is a declaration of my function, so my whole code is familiar with it. Some compilers compile source code from top to bottom, so if you write a function and call on one beneath it, it may not know what it is just yet. I only do it for good practice.


Originally Posted by kind4ever
and what adefintion of apointer?
» The difference between C and C++ pointers aren't much different. In fact check out this link, it covers most of the same syntax.
Following the rules will ensure you get a prompt answer to your question. If posting code, please include BB [code][/code] tags. Your question may have been asked before, try the search facility.

IRC
Channel: irc.daniweb.com
Room: #c, #shell
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 3
Reputation: samar is an unknown quantity at this point 
Solved Threads: 0
samar samar is offline Offline
Newbie Poster

Re: Pointers

 
0
  #6
Oct 5th, 2004
could you help me in some questions
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 3
Reputation: samar is an unknown quantity at this point 
Solved Threads: 0
samar samar is offline Offline
Newbie Poster

Re: Pointers

 
0
  #7
Oct 5th, 2004
I have a homework to show which of these codes are wrong if i is an integer and p, q are pointers to integers
p*&i;
p=&*i;
i=*&*p;
i=*&p;
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 1
Reputation: shivendra is an unknown quantity at this point 
Solved Threads: 0
shivendra shivendra is offline Offline
Newbie Poster

Re: Pointers

 
0
  #8
Oct 21st, 2004
if my fundamentals about c are not clear then i can understand pointer
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 1
Reputation: invserver is an unknown quantity at this point 
Solved Threads: 0
invserver invserver is offline Offline
Newbie Poster

Re: Pointers

 
0
  #9
Oct 23rd, 2004
Originally Posted by shivendra
if my fundamentals about c are not clear then i can understand pointer
There have been general misconception that one has to learn c to have better understanding on C++. This is not at all true. And this is also true for the pointers also. Its unnecessary to go to C to learn C++.
Reply With Quote Quick reply to this message  
Join Date: Jan 2005
Posts: 41
Reputation: free_eagle is an unknown quantity at this point 
Solved Threads: 0
free_eagle's Avatar
free_eagle free_eagle is offline Offline
Light Poster

Re: Pointers

 
0
  #10
Feb 6th, 2005
Good tutorial .

Thanks for the person who made it available this for us ....
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC