introduction to programming 3d applications ce0056-1 lecture 10 pointers in c
TRANSCRIPT
Introduction to Programming 3D Applications
CE0056-1
Lecture 10
Pointers in C
Pointers
Pointers are necessary for understanding and use of:
Passing Parameters by Reference Arrays (especially strings) Dynamic Allocation of Memory Dynamic Data Structures
A Pointer is a reference to (or address of) a memory location.
1) Passing Parameters by Reference
Function swap exchanges the values of its 2 parameters:
#include “stdio.h”void swap(int *, int *); // prototypeint main(void){int a=3, b=7;swap(&a, &b);
// addresses of values to be swappedprintf(“1st is %d, 2nd is %d”, a, b);return 0;
}
Function swap
void swap(int *x, int *y)
// x, y are copies of the addresses a, b
{
int temp;
temp = *x; // using pointers to access
*x = *y; // originals (not copies)
*y = temp; // and swap them via temp
}
2) Arrays and Strings
Consider the declaration:
char x[10]; // a string of size 10
x[3] is the character in element 3 of array x &x[3] is the address of element 3 of array x x is the address of array x
(actually the same as &x[0]) *x is the character that x points to
(ie same as x[0])
Strings as pointers Strings should always be declared as arrays inside the
main function, so that required storage can be allocated.Thus char x[10] allocates 10 bytes.
Strings can be declared explicitly as pointers – typically inside functions, e.g. char *s;declares variable, s, as a pointer to a character – (ie string pointer). It can point to any string –or any part of a string – or to examine all the characters within a string.
Arrays as parameters Arrays and strings, such as x above, passed to
functions as parameters are already addresses.
Example: int list [100];sort(list, n);
The address of array, list, is passed to the sort function.
void sort(int a[], int n)
So that array, a, also refers to the original elements of list.
Example of a String Function
The function, print_reverse,
given a string (as a parameter)
prints the string in reverse
by dealing with one character at a time, using a pointer
starting with the last and continuing while it has not yet
reached the start of the string.
Main function
Main function reads, reverse and writes a string. #include “stdio.h”int main(void){char line[81] ;// for string storagegets(line); // whole line is the stringprintf(“Reversed line is\n”);print_reverse(line);// line is addressreturn 0;
}
print_reverse function
void print_reverse(char *s) //s is a string{char *ptr;ptr = s + strlen(s) - 1; // last charwhile ( ptr != s) // not start of string{
printf(“%c”, *ptr); // the characterptr--; // previous char
}printf(“%c”, *ptr);// ptr == s
// first character of s}
String function example
The function, string_tolower, converts all upper case letters in a string to lower case and leaves all other characters unchanged.
It uses a standard function, tolower, to convert each character.
A pointer will examine each character one at a time while it has not yet reached the end of the string, i.e. ‘\0’.
A pointer to the beginning of the string is returned.
Function string_tolower
char * string_tolower(char *s)//s is string { // return p as a pointerchar *p;p = s; // start of string, swhile ( *s != ‘\0’) // not end of string{
*s = tolower(*s); // upper to lowers++; // next character
}return p; // start of result
}
Main function
#include “stdio.h”#include “ctype.h” // for tolower functionint main(void){char line[81] ; // for string storagegets(line);
// string of upper & lower case lettersstring_tolower(line);printf(“\nresulting string is:\n”);printf(“%s\n”, line);return 0;
}
The function, string_tower, also returns a pointer to the result –
so that it could be used as follows:
printf(“\nresulting string is:\n%s”,
string_tolower(line));
Another string function example
Function, isinteger, checks whether all the characters in a string are digits or not.
It returns true, i.e. 1, if all characters are the digits ‘0’ to ‘9’, otherwise it returns false, i.e. 0.
It uses a standard function, isdigit, to check each character:
Function isinteger
int isinteger(char *s) // s is a string{ // returns 1(true) or 0(false)
while (*s != ‘\0’){ // while not end of string
if (!isdigit(*s)) // not a digit{
return 0; // false}s++; // next character
}return 1; // true
}
Validate Room Number Example
Here is a program, using our functions, that reads and validates a room number for our computing labs. Room numbers range from KC01 to KC16 inclusive. Note that KC1 and KC01 are the same and that the letter prefixes, ‘K’ and ‘C’ may be in upper or lower case.
#include “stdio.h”#include “string.h”#include “ctype.h” // isdigit, atoi, tolower// prototypes
int isinteger(char *);char *string_tolower(char *);
int main(void){
char room[10];int room_num;printf(“type in room number\n”);scanf(“%s”, room); // read as a
string
if (strlen(room) < 3) // too short
{printf(“\n%s too short\n”,
room);}elseif (strlen(room) > 4) // too long{
printf(“\n%s too long\n”, room);}else // length is ok
{string_tolower(room);// lower caseif ((room[0] != ‘k’) // not k or|| (room[1] != ‘c’)) // not c{
printf(“\nroom must start kc\n”);
}else // kc or KC found
if (!isinteger(room + 2))// integer starting room[2]?
{printf(“\nroom number not
digits”);}else // is integer room no.
{room_num = atoi(room + 2);
// convert to integerif (room_num == 0||room_num >16){
printf(“\nroom %s ”, room);printf(“not a Concourse
lab”);}else // out of range{
printf(“\nroom %s ”, room);printf(“is a Concourse
lab”);}
} // end integer room number} // end length okreturn 0;
} // end main
Allocation of Static Memory
A declaration such as char name[1000][21], allocates sufficient memory for 1000 names of 21 characters each.
This storage of 21 000 characters is reserved at compilation time, i.e. before the program begins execution.
This wastes space as most names are rather less than 20 letters.
It also restricts names to a maximum of 20 characters. We can resolve this wastage and restriction by allocation of
memory as and when required, during execution of the program.
Dynamic Allocation using malloc function
A standard function, malloc(n) allocates n bytes (for n characters) in memory and returns a pointer to it.
For example: the following code Prompts the user for the size of the string Reads the size Allocates memory for a string of this size Reads the string
Example using malloc
int size;
char *s;
printf(“\nhow many characters?\n”);
scanf(“%d”, &size);
s = malloc(size+1); // one extra for ‘\0’
printf(“type string\n”);
gets(s);
allocates only enough memory for the expected string.
Use of malloc for any data type
malloc can be used to allocate memory for any <data type>.
<data type> *<variable>; // pointer to <data type>
// some other code here
<variable> = (<data type> *)malloc(n * sizeof(<data type>));
allocates sufficient memory for n values of <data type> and returns a pointer which must be casted as the same pointer type as the <variable>.
Using malloc for an array of integers
For example:
To allocate storage for 10 integers
int *p;
p = (int *) malloc (10 * sizeof(int));
This is machine-independent, as sizeof returns
size of an integer for any machine.
Ragged Arrays
Declare 6 variable length names – array of string pointers
char *name[6] =
{“abdul”, “abraham”, “al “, “bill”, “fred”, “jean-pierre”};
We can declare functions on ragged arrays:
void print_list(char *table1[ ], int n)
so that it can deal with strings of any length.
Ragged array example
Read a list of strings (one on each line) into an array wherethe size of each element is precisely the length of eachstring, ie the strings are of variable length - a ragged array.
#include "stdio.h"#include "string.h"#include "stdlib.h" // for malloc// prototypes
void sort(char *[], int);int read_strings(char *[], int);void print_strings(char *[], int);
Main function
int main(void){char *list[1000];
// array of 1000 string pointers int n; // actual number of strings n = read_strings(list, 1000);
// read n strings, max of 1000 sort(list, n); // sort n strings print_strings(list, n); // print n strings return (0);}
print_strings function
void print_strings(char *list[], int n)
{
int i;
printf("\nalphabetical order is\n\n");
for (i=0; i<n; i++)
{
printf("%s\n", list[i]);
}
}
void sort(char *a[], int n) { // array of n strings as pointers
int i, j;char *temp; // string pointerfor (j = n -1; j > 0; j--){ // each pass of j
comparisonsfor (i=0; i < j; i++){ // each comparison
if (strcmp(a[i], a[i+1]) > 0)
{ // swap the POINTERS temp = a[i]; a[i] = a[i+1]; a[i+1] = temp; } // else no swap } // end of pass } // end of all passes} // end sort
int read_strings(char *list[], int max){
int i = 0;char line[81]; // store for each lineprintf("\ntype one string per line\n");while (gets(line) != NULL && i < max) { // while not end of input
list[i] = malloc (strlen(line)+1); // list[i] big enough
// for line + 1 for ‘\0’
strcpy(list[i], line); // copy line into list[i]
i++; // next element}return i; // actual number of strings
}