Programming in C - 161-180
Programming in C - 161-180
You can use a null pointer as a placeholder to remind yourself (or, more
importantly, to help your program remember) that a pointer variable does
not point anywhere at the moment and that you should not use the “contents
of'' operator on it (that is, you should not try to inspect what it points to, since
it doesn't point to anything). A function that returns pointer values can return
a null pointer when it is unable to perform its task. (A null pointer used in this
way is analogous to the EOF value that functions like getchar return.)
As an example, let us write our own version of the standard library function
strstr, which looks for one string within another, returning a pointer to the
string if it can, or a null pointer if it cannot.
Example 9.1: Here is the function, using the obvious brute-force algorithm:
at every character of the input string, the code checks for a match there of
the pattern string:
#include <stddef.h>
The start pointer steps over each character position in the input string. At
each character, the inner loop checks for a match there, by using p1 to step
over the pattern string (pat), and p2 to step over the input string (starting at
start). We compare successive characters until either (a) we reach the end
of the pattern string (*p1 == '\0'), or (b) we find two characters which differ.
When we're done with the inner loop, if we reached the end of the pattern
string (*p1 == '\0'), it means that all preceding characters matched, and we
found a complete match for the pattern starting at start, so we return start.
Otherwise, we go around the outer loop again, to try another starting
position. If we run out of those (if *start == '\0'), without finding a match, we
return a null pointer.
Notice that the function is declared as returning (and does in fact return) a
pointer-to-char.
In general, C does not initialize pointers to null for you, and it never tests
pointers to see if they are null before using them. If one of the pointers in
your programs points somewhere some of the time but not all of the time, an
excellent convention to use is to set it to a null pointer when it doesn't point
anywhere valid, and to test to see if it's a null pointer before using it. But you
must use explicit code to set it to NULL, and to test it against NULL. (In
other words, just setting an unused pointer variable to NULL doesn't
guarantee safety; you also have to check for the null value before using the
pointer.) On the other hand, if you know that a particular pointer variable is
always valid, you don't have to insert a paranoid test against NULL before
using it.
Self Assessment Questions
1. A ______ is a special pointer value that is known not to point anywhere.
2. A function that returns ____________ values can return a null pointer
when it is unable to perform its task.
3. In general, C does not initialize pointers to null for you, and it never
tests pointers to see if they are null before using them. (True/False)
unwritable arrays which the compiler generated for you in response to one
of your string constants. (The only exception is array initialization, because if
you write to such an array, you're writing to the array, not to the string literal
which you used to initialize the array.)
Example 9.3: Breaking a Line into “Words''
First, break lines into a series of whitespace-separated words. To do this,
we will use an array of pointers to char, which we can also think of as an
“array of strings,'' since a string is an array of char, and a pointer-to-char can
easily point at a string. Here is the declaration of such an array:
char *words[10];
This is the first complicated C declaration we've seen: it says that words is
an array of 10 pointers to char. We're going to write a function, getwords,
which we can call like this:
int nwords;
nwords = getwords(line, words, 10);
where line is the line we're breaking into words, words is the array to be
filled in with the (pointers to the) words, and nwords (the return value from
getwords) is the number of words which the function finds. (As with getline,
we tell the function the size of the array so that if the line should happen to
contain more words than that, it won't overflow the array).
Here is the definition of the getwords function. It finds the beginning of each
word, places a pointer to it in the array, finds the end of that word (which is
signified by at least one whitespace character) and terminates the word by
placing a '\0' character after it. (The '\0' character will overwrite the first
whitespace character following the word.) Note that the original input string
is therefore modified by getwords: if you were to try to print the input line
after calling getwords, it would appear to contain only its first word (because
of the first inserted '\0').
#include <stddef.h>
#include <ctype.h>
getwords(char *line, char *words[], int maxwords)
{
char *p = line;
int nwords = 0;
while(1)
{
while(isspace(*p))
p++;
if(*p == '\0')
return nwords;
words[nwords++] = p;
if(*p == '\0')
return nwords;
*p++ = '\0';
Each time through the outer while loop, the function tries to find another
word. First it skips over whitespace (which might be leading spaces on the
line, or the space(s) separating this word from the previous one). The
isspace function is new: it's in the standard library, declared in the header
file <ctype.h>, and it returns nonzero (“true'') if the character you hand it is a
space character (a space or a tab, or any other whitespace character there
might happen to be).
When the function finds a non-whitespace character, it has found the
beginning of another word, so it places the pointer to that character in the
next cell of the words array. Then it steps through the word, looking at non-
whitespace characters, until it finds another whitespace character, or the \0
at the end of the line. If it finds the \0, it's done with the entire line; otherwise,
it changes the whitespace character to a \0, to terminate the word it's just
found, and continues. (If it's found as many words as will fit in the words
array, it returns prematurely.)
Each time it finds a word, the function increments the number of words
(nwords) it has found. Since arrays in C start at [0], the number of words the
function has found so far is also the index of the cell in the words array
where the next word should be stored. The function actually assigns the
next word and increments nwords in one expression:
words[nwords++] = p;
You should convince yourself that this arrangement works, and that (in this
case) the preincrement form
words[++nwords] = p; /* WRONG */
would not behave as desired.
When the function is done (when it finds the \0 terminating the input line, or
when it runs out of cells in the words array) it returns the number of words it
has found.
Here is a complete example of calling getwords:
char line[] = "this is a test";
int i;
nwords = getwords(line, words, 10);
for(i = 0; i < nwords; i++)
printf("%s\n", words[i]);
9.6 Summary
A pointer is a variable that represents the location of a data item, such as a
variable or an array element. A pointer may be set to a null pointer. A null
pointer is a special pointer value that is known not to point anywhere.
Passing pointers as arguments to functions is called pass by reference.
Because of the similarity of arrays and pointers, it is extremely common to
refer to and manipulate strings as character pointers. We can define a two
dimensional array as a pointer to a group of contiguous one-dimensional
arrays. A two-dimensional array can also be expressed in terms of an array
of pointers rather than as a pointer to a group of contiguous arrays.
9.10 Exercises
1. Write a program to find the number of characters in a string using
pointers.
2. Write a program to multiply two matrices using pointers.
3. Suppose a formal argument within a function definition is a pointer to
another function. How is the formal argument declared? Within the
formal argument declaration, to what does the data type refer?
4. Write a program to concatenate two strings.
5. Write a function to sort an array of numbers using pointers.
10.1 Introduction
In the previous units, you studied about the pointers as a most powerful tool
in C programming language. It is due to the pointer only that makes C as the
most beautiful language. In this unit, you will study another useful ways of
making the program easy and efficient. This unit will enable you to learn
about the structures and unions.
As we know an array is a data structure whose elements are all of the same
data type. We now turn our attention to the structure, which is a data
structure whose individual elements can differ in type. Thus, a single
structure might contain integer elements, floating-point elements and
character elements. Pointers, arrays and other structures can also be
included as elements within a structure.
This unit is concerned with the use of structures within a C program. We will
see how structures are defined, and how their individual members are
accessed and processed within a program.
Closely associated with the structure is the union, which also contains
multiple members. Unlike a structure, however, the members of a union
share the same storage area, even though the individual members may
differ in type.
Manipal University of Jaipur Page No.: 172
Programming in C Unit 10
Objectives:
After studying this unit, you should be able to:
handle a group of logically related data items known as structures.
declare an array of structures, each element of the array representing a
structure variable.
pass structure as an argument to functions and return structure from
functions.
refer to (i.e., point to) an incomplete type, including itself.
handle a group of logically related data items in terms of unions.
struct book_bank
array of 20 characters
title
pages integer
price float
We can declare structure variables using the tag name anywhere in the
program. e.g, the statement:
struct book_bank book1, book2, book3;
declares book1, book2 and book3 as variables of type book_bank.
Each one of these variables has four members as specified by the template.
The complete declaration might look like this:
struct book_bank
{
char title[20];
char author[15];
int pages;
float price;
};
struct book_bank book1, book2, book3;
It is also allowed to combine both the template declaration and variables
declaration in one statement.
struct book_bank
{
char title[20];
char author[15];
int pages;
float price;
} book1, book2, book3;
Manipal University of Jaipur Page No.: 174
Programming in C Unit 10
Structure Initialization:
void main( )
{
struct st_record
{
char name[20];
int weight;
float height;
};
static struct st_record student1 = {“Suresh”, 60, 180.75};
static struct st_record student2 = {“Umesh”, 53, 170.60};
}
Program 10.1: To print the date of joining of a person
#include<conio.h>
#include<stdio.h>
struct personal
{
char name[30];
int day;
int month;
int year;
float salary;
};
void main()
{
struct personal p;
printf(“Enter the name:\n)";
gets(p.name);
printf(“Enter the day of joining:\n)";
scanf(“%d”,&p.day);
Operation Meaning
void main()
Manipal University of Jaipur Page No.: 177
Programming in C Unit 10
{
int x;
static struct stclass student1 = {111,"Rao",72.50};
static struct stclass student2 = {222,"Reddy",67.00};
struct stclass student3;
student3 = student2;
x=((student3.number == student2.number) && (student3.marks ==
student2.marks))? 1:0;
if(x==1)
{
printf("\nStudent2 and Student3 are same ");
printf(“ %d\t %s\t %f\t“,student3.number,student3.name,student3.marks);
}
else
{
printf("\nStudent2 and student3 are different)";
}
getch();
}
Explanation
1. The function read_student reads values in structures and returns the
structure.
2. The function print_student takes the structure variable as input and
prints the content in the structure.
3. The function read_student_p reads the data in the structure similarly to
read_student. It takes the structure student as an argument and puts
the data in the structure. Since the data of a member of the structure is
modified, you need not pass the structure as a pointer even though
structure members are modified. Here you are not modifying the
structure, but you are modifying the structure members through the
structure.
Self Assessment Questions
7. We cannot write a function that returns the structure. (True/False)
8. We can modify a member of the structure by passing the structure as a
_____________.
main( )